When I talked with Jeff about this yesterday, he felt that since the
current behavior is exactly how a while loop with a let block around the
loop body would behave (this is essentially what our for loops are), the
behavior is in line with all the other scoping rules. Parity with
comprehensions is a good way to think of the argument for making for loop
variables always local. I guess it's the difference between lowering
for x in itr
# loop body
end
like this (current behavior):
state = start(itr)
while !done(itr, state)
value, state = next(itr, state)
let
x = value
# loop body
end
end
or like this (comprehension-like behavior):
state = start(itr)
while !done(itr, state)
value, state = next(itr, state)
let x = value
# loop body
end
end
It's not entirely clear to me that one is obviously preferable to the other.
On Sat, Feb 7, 2015 at 3:12 PM, Kevin Squire <[email protected]> wrote:
> I have mixed feelings, as I'm somehow one of those people who frequently
> breaks out of loops and wants to know the value of the variable at the last
> iteration. That said, I can see how nonlocal semantics can be confusing
> (and the workarounds suggested by Stephen and Mauro).
>
> David, to move this discussion forward, would you care to open an issue at
> https://github.com/JuliaLang/julia/issues?
>
> Cheers,
>
> Kevin
>
> On Sat, Feb 7, 2015 at 1:30 AM, Mauro <[email protected]> wrote:
>
>> > I would be ok with loop variables always being local to the loop so that
>> > this would happen:
>> >
>> > julia> i = 0
>> > 0
>> >
>> > julia> for i = 1:5
>> > println(i)
>> > end
>> > 1
>> > 2
>> > 3
>> > 4
>> > 5
>> >
>> > julia> i
>> > 0
>> >
>> >
>> > That would simplify the semantics of for loops at the cost of making it
>> > harder to access the final value of a loop variable – but that's a
>> somewhat
>> > rare thing to do and explicitly assigning the loop variable to an
>> variable
>> > from outside the loop is arguably clearer.
>>
>> I find the scoping rules complex. I think this might make them a tad
>> less complex as the rules for comprehensions and for-loops become
>> identical (right?). Also it would be more similar to functions, their
>> arguments also being local.
>>
>> If the loop variable is needed then this would work
>>
>> iout = 1
>> for i = 1:5
>> println(i)
>> if i==something
>> iout = i
>> end
>> end
>>
>>
>> > On Fri, Feb 6, 2015 at 7:05 AM, David Higgins <[email protected]
>> >
>> > wrote:
>> >
>> >> So all of this seems to be a result of the for loop basically using a
>> >> range/array type variable on the right hand side of the loop variable.
>> So
>> >> even if I change the value of the iterator variable within the loop I
>> >> cannot change the array over which I am looping (anyone used to Python
>> will
>> >> find this natural, I'm more used to C).
>> >>
>> >> I guess everything is consistent now.
>> >>
>> >> David
>> >>
>> >> On Friday, 6 February 2015 12:25:34 UTC+1, David Higgins wrote:
>> >>
>> >>> I have a use case I found interesting. I guess it's well known to
>> some of
>> >>> you, but I never noticed it in the documentation and I find it
>> >>> counterintuitive, both as an experienced programmer and with respect
>> to the
>> >>> typical scope rules of variables in Julia.
>> >>>
>> >>> I accidentally nested a loop within another loop using the same index
>> >>> variable for both loops. First of all, there are reasons sometimes
>> you'd
>> >>> want to do this but I did it by accident as a typo. But the scope
>> rules of
>> >>> variables for Julia, as applied to functions, state that you can read
>> a
>> >>> variable value at a lower level in the hierarchy but you cannot write
>> to it
>> >>> so I actually assumed that this also applied to loops (*first
>> mistake*).
>> >>>
>> >>> Secondly, as you'll see if you execute the simplified example of what
>> I
>> >>> actually did here:
>> >>> for i = 1:5
>> >>> for j = 1:5
>> >>> for i = 1:3
>> >>> print("tick ");
>> >>> end
>> >>> print(" $i\n");
>> >>> end
>> >>> print(" $j $i\n");
>> >>>
>> >>> Julia still knew to only run the outer loop 5 times, despite the fact
>> >>> that I was setting the variable bound to $i at level 2 to the value 3
>> at
>> >>> level 3 in the nested hierarchy of loops. I suspect that I can see
>> what's
>> >>> happening at the compiler/interpretter level, but I do think that
>> this is
>> >>> confusing.
>> >>>
>> >>> We seem to have the worst of both worlds here in that we can access
>> and
>> >>> change $i at an inner loop level and have the change be persistent,
>> but yet
>> >>> we cannot change the behaviour of the outer loop (as would be the
>> case in
>> >>> C).
>> >>>
>> >>> What do you guys think? Can this be clarified in the documentation, or
>> >>> should the actual behaviour of julia be modified?
>> >>>
>> >>> David.
>> >>>
>> >>
>>
>>
>