As for how assignments introduce local variables: it was quite deliberate (and the right decision IMO) that the *presence* of an assignment to a variable creates a local variable, and not whether the assignment has actually executed yet. I'm talking about this example:
x = 10 function foo() println(x) x = 5 println(x) end The new binding for x is the one used throughout the block. The *binding* is indeed visible to the first println, but the value it points to is a non-first-class "undefined" value that raises an error. I don't think you would want a variable to switch from global to local in the middle of a block based on control flow. It works this way because we didn't want to require all variables to be explicitly introduced with a construct like `var x = 0`. This adds a lot of noise to a program and is annoying to those used to python or matlab. > And then, some like "for" do or don't, it depends. Is that really true? I don't believe there is a case where `for` behaves differently than `let`. This approach to scope is not as foreign to Scheme as one might think. You can think of constructs like `for` or `let` as scheme macros, where some introduce implicit letrecs and others don't. Scheme `begin` doesn't have an implicit letrec, but lambda does, etc. On Tue, Apr 12, 2016 at 10:37 AM, Erik Schnetter <schnet...@gmail.com> wrote: > 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/