Re: [julia-users] scoping wat

2016-04-13 Thread Didier Verna
I wrote:

> Consider for example embedding a for loop in a macro, and the risk for
> variable capture.

  Forget that. Macros seem to be hygienic.

-- 
ELS'16 registration open! http://www.european-lisp-symposium.org

Lisp, Jazz, Aïkido: http://www.didierverna.info


Re: [julia-users] scoping wat

2016-04-13 Thread Didier Verna
Jeff Bezanson  wrote:

> Yes, one could argue that a `for` loop variable should always be a new
> variable, but that does make the constructs less orthogonal.

  It's funny that you see this as less orthogonal, considering that, as
  Stefan pointed out, your "for" index will leak its final
  value. Consider for example embedding a for loop in a macro, and the
  risk for variable capture. Sounds pretty anti-orthogonal to me...


> In any case I don't see how this is "do or don't, it depends". Depends
> on what?

  Is the i in for(i=1:3) local to the loop? It depends (on whether there
  is an outer i or not).

  Does assignment create a binding? It depends (on the construct you're
  in). E.g.
  julia> if true; k = 10 end # -> 10
  julia> k # -> 10
  julia> let; l = 10 end # -> 10
  julia> l # -> ERROR: UndefVarError: l not defined

  Does assignment in a function create a local binding? It depends (on
  whether the function is nested).

  etc.

-- 
ELS'16 registration open! http://www.european-lisp-symposium.org

Lisp, Jazz, Aïkido: http://www.didierverna.info


Re: [julia-users] scoping wat

2016-04-13 Thread Didier Verna
Jeff Bezanson  wrote:

> 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.

  I see your point and I understand the concern for Python or Matlab
  users. You see local declarations as noise whereas as I see it as
  explicit intent. I still have a hard time digesting the fact that
  assignment creates new local bindings, but not always though ;-)

-- 
ELS'16 registration open! http://www.european-lisp-symposium.org

Lisp, Jazz, Aïkido: http://www.didierverna.info


Re: [julia-users] scoping wat

2016-04-12 Thread Didier Verna
Cedric St-Jean  wrote:

> Your let is broken, it's a no-op. let always creates local bindings

  :-D I know, it was just for the sake of the example. The let was just
  to introduce a block,  I couldn't do that with begin since begin
  doesn't introduce a block!

> I agree that the hard/soft scoping rules are messy. In practice, it
> doesn't seem to cause a lot of issues

  Granted (although this doesn't really justify doing a mess in the
  first place; the same argument applies to Emacs Lisp's dynamic scoping
  by default for instance).

-- 
ELS'16 registration open! http://www.european-lisp-symposium.org

Lisp, Jazz, Aïkido: http://www.didierverna.info


Re: [julia-users] scoping wat

2016-04-12 Thread Jeff Bezanson
It looks to me like everything in the `for` loop behaves like
variables inside a `let` block. Yes, one could argue that a `for` loop
variable should always be a new variable, making it equivalent to

let i
for i = itr
...
end
end

but that does make the constructs less orthogonal. In any case I don't
see how this is "do or don't, it depends". Depends on what?

On Tue, Apr 12, 2016 at 12:48 PM, Stefan Karpinski  wrote:
> On Tue, Apr 12, 2016 at 12:33 PM, Jeff Bezanson 
> wrote:
>>
>> > 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`.
>
>
> julia> i = 1
> 1
>
> julia> for i = 2:10
>println(i)
>end
> 2
> 3
> 4
> 5
> 6
> 7
> 8
> 9
> 10
>
> julia> i
> 10


Re: [julia-users] scoping wat

2016-04-12 Thread Stefan Karpinski
On Tue, Apr 12, 2016 at 12:33 PM, Jeff Bezanson 
wrote:

> > 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`.
>

julia> i = 1
1

julia> for i = 2:10
   println(i)
   end
2
3
4
5
6
7
8
9
10

julia> i
10


Re: [julia-users] scoping wat

2016-04-12 Thread Jeff Bezanson
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  wrote:
> On Tue, Apr 12, 2016 at 9:05 AM, Cedric St-Jean  
> wrote:
>>
>> On Tuesday, April 12, 2016 at 8:52:23 AM UTC-4, Didier Verna wrote:
>>>
>>> Mauro  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 
> http://www.perimeterinstitute.ca/personal/eschnetter/


Re: [julia-users] scoping wat

2016-04-12 Thread Erik Schnetter
On Tue, Apr 12, 2016 at 9:05 AM, Cedric St-Jean  wrote:
>
> On Tuesday, April 12, 2016 at 8:52:23 AM UTC-4, Didier Verna wrote:
>>
>> Mauro  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 
http://www.perimeterinstitute.ca/personal/eschnetter/


Re: [julia-users] scoping wat

2016-04-12 Thread Cedric St-Jean

On Tuesday, April 12, 2016 at 8:52:23 AM UTC-4, Didier Verna wrote:
>
> Mauro  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

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 
>


Re: [julia-users] scoping wat

2016-04-12 Thread FANG Colin
Python has similar rules.

x = 10 
def foo(): 
print x
x = 5 
print x 
foo()

UnboundLocalError: local variable 'x' referenced before assignment


On Tuesday, April 12, 2016 at 1:52:23 PM UTC+1, Didier Verna wrote:
>
> Mauro  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 
>
> 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 
>


Re: [julia-users] scoping wat

2016-04-12 Thread Didier Verna
Mauro  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

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


Re: [julia-users] scoping wat

2016-04-12 Thread Mauro
Maybe you can be a bit more explicit in what you mean, examples would
help too.

The only bit of the scoping rules which I find a bit questionable is
that functions in a local scope have soft-scope (otherwise they have
hard-scope).  This has been discussed on github, search for "nonlocal".


On Tue, 2016-04-12 at 11:16, Didier Verna  wrote:
>   Hi,
>
> I'm quite puzzled by the complication of Julia's scoping rules, and in
> particular this way of constantly and implicitly mixing binding and
> assignment, with varying semantics according to the context.
>
> The manual is not convincing (at least to me) in justifying what's
> happening. Most of the scoping behavior looks like a big DWIM machinery
> which is evil.
>
> What's the history behind all this? Technical debt? Inspiration from
> other languages (certainly not Scheme!)? Actual, arbitrary design
> decisions?
>
> Thank you!


[julia-users] scoping wat

2016-04-12 Thread Didier Verna

  Hi,

I'm quite puzzled by the complication of Julia's scoping rules, and in
particular this way of constantly and implicitly mixing binding and
assignment, with varying semantics according to the context.

The manual is not convincing (at least to me) in justifying what's
happening. Most of the scoping behavior looks like a big DWIM machinery
which is evil.

What's the history behind all this? Technical debt? Inspiration from
other languages (certainly not Scheme!)? Actual, arbitrary design
decisions?

Thank you!

-- 
ELS'16 registration open! http://www.european-lisp-symposium.org

Lisp, Jazz, Aïkido: http://www.didierverna.info