On Tue, Apr 12, 2016 at 9:05 AM, Cedric St-Jean <cedric.stj...@gmail.com> wrote: > > On Tuesday, April 12, 2016 at 8:52:23 AM UTC-4, Didier Verna wrote: >> >> Mauro <maur...@runbox.com> wrote: >> >> > Maybe you can be a bit more explicit in what you mean, examples would >> > help too. >> >> Sorry for the fuzziness. This is an example of what I mean: >> >> let >> x = 10 >> end > > > Your let is broken, it's a no-op. let always creates local bindings > > xx = 20 > let xx = 30 > @show xx > end > @show xx > >> xx=30 >> xx=20
The manual is unclear where it introduces let bindings. It says e.g. at one point that let uses soft scope (http://docs.julialang.org/en/release-0.4/manual/variables-and-scoping/), and at another point that "let statements allocate new variable bindings". It doesn't make a distinction between the bindings introduced on the same line as the `let` (or in lines terminated by a colon), and other lines (or after the first semicolon). Compare let a=4 end let; a=4 end let a=4, b=4 end let a=4; b=4 end let a=4, b=4 end let a=4; b=4 end let a=4 b=4 end The manual could be more explicit about this. -erik > I agree that the hard/soft scoping rules are messy. In practice, it doesn't > seem to cause a lot of issues > > >> >> >> here, the same expression "x = 10" will either assign a new value to x >> if such a /global/ exists, or create a new /local/ binding. This is >> already bad enough[1]. Then, begin/end behaves differently. Then, "if" >> doesn't introduce a new block, but some others constructs do, and some >> don't. And then, some like "for" do or don't, it depends. >> >> Now even worse: >> x = 10 >> function foo() >> println(x) >> x = 5 >> println(x) >> end >> >> will break on the first println (one could expect to get 10, the global >> value for x) because since there is an assignment /later on/, a new >> /local/ binding will be created for x (which BTW is the exact opposite >> of what let does!), but this binding isn't available to the first >> println. And also, since a variable cannot switch from global to local >> (or vice-versa) in the same block, the intuition (well, mine anyway ;-)) >> that after the assignment, the scoping changes, is wrong. >> >> And then, as you mention, nested functions will behave yet >> differently. All of this looks really bad. >> >> So IMHO, the real problem is that there are two distinct concepts: >> assigning a new value to an existing binding, and creating a new >> binding, possibly with an initial assignment. These are separate things >> and mixing the two in such ways is wrong, and also quite surprising, >> knowing the lispy side of this language. >> >> >> >> Footnotes: >> [1] consider that a simple typo in your code may lead to silently >> creating a new variable, which will never be used. >> >> -- >> ELS'16 registration open! http://www.european-lisp-symposium.org >> >> Lisp, Jazz, Aïkido: http://www.didierverna.info -- Erik Schnetter <schnet...@gmail.com> http://www.perimeterinstitute.ca/personal/eschnetter/