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/

Reply via email to