<div dir="ltr"><span class="Apple-style-span" style="font-size: small;"><br><br></span><div class="gmail_quote"><span class="Apple-style-span" style="font-size: small;">On Fri, Oct 3, 2008 at 6:00 PM, Dillon Collins </span><span dir="ltr"><span class="Apple-style-span" style="font-size: small;"><<a href="mailto:dillonco@comcast.net">dillonco@comcast.net</a>></span></span><span class="Apple-style-span" style="font-size: small;"> wrote:<br>
</span><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="Ih2E3d"><span class="Apple-style-span" style="font-size: small;">On Friday 03 October 2008, Greg Ewing wrote:<br>

> My next step would be to propose a 'let' statement<br>
> for dealing with things like that:<br>
><br>
>    for i in range(3):<br>
>      let j = str(i):<br>
>        funs.append(lambda: j)<br>
><br><br></span>
</div><span class="Apple-style-span" style="font-size: small;">Well now, that seems more than a little ridiculous.  If we're going to be<br>
creating a keyword that rescopes variables, why not just use that instead of<br>
messing with the for loop.  </span></blockquote><div><br></div><div>I don't see how this is messing with the for loop at all.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<span class="Apple-style-span" style="font-size: small;">Seems like that would be a generally more useful<br>
solution anyway.<br><br>
Perhaps instead:<br></span>

<div class="Ih2E3d"><span class="Apple-style-span" style="font-size: small;"><br>
for i in range(10):<br></span>
</div><span class="Apple-style-span" style="font-size: small;">    j = str(i)<br>
    scope i, j:<br>
        funs.append(lambda: (j,i))<br></span>
<div class="Ih2E3d"></div></blockquote><div><span class="Apple-style-span" style="font-size: small;"><br></span></div><div><div>The difference between my or Greg's proposal is that the scope of the variable is the inner block while your proposal the variable has two scopes. That is, to annotate the code: </div>
<div><br></div><div>  for i in range(10):  # creates a new variable i in function scope (if it didn't already exist)</div><div>    local k:  # creates a new scope for k</div><div>      k = i**2  # creates a new variable k (every time we execute this block)</div>
<div>      a.append(lambda: k)  # closure references the variable in the enclosing scope (as it normally does)</div><div>  print(k)  # error -- there is no k in this scope</div><div><br></div><div>  for i in range(10):  # creates a new variable i in function scope (if it didn't already exist)</div>
<div>    k = i**2  # creates a new variable k in function scope (if it didn't already exist)</div><div>    scope k:  # creates new variables k and copies the values from the outer scope</div><div>      a.append(lambda: k)  # closure references the variable in the enclosing scope (as it normally does)</div>
<div>  print(k)  # prints 81, the last k from the loop</div><div><br></div><div>I don't care for the fact that there are really two k variables here (or more properly N+1). Also, the implicit copying sort of obscures some details. The fact that my alternative requires explicit setting of the value of the scoped variable is a good thing. </div>
<div><br></div><div>For example, consider this:</div><div><br></div><div>  a = [0,1,2]</div><div>  for i in range(3):</div><div>    scope a:</div><div>      a.append(i)</div><div>      ... lambda: ... a ...</div><div><br>
</div><div>Yes, a is in a different scope, but references the same list so the scope is useless. At least in my or Greg's version, since you have to assign to the local variable, there's a clear place where you can see the copying is missing.</div>
<div><br></div><div>  a = [0,1,2]</div><div>  for i in range(3):</div><div>    local b:</div><div>      b = a  # easy to see that this should be b = copy.copy(a)</div><div>      b.append(i)</div><div>      ... lambda: ... b ...</div>
<div><br></div><div>I've used my suggested syntax because I like it a bit better although the above would also apply to Greg's suggestion. Comparing our suggestions, I think local a,b: is a bit more clear than let a = value, b = value: and mine does not force you to initialize the variables. They could be combined:</div>
<div><br></div><div>  'local' var [ '=' expr ] ( ',' var [ '=' expr ] )* ':'</div><div><br></div><div>with the ',' in the local statement taking priority over ',' in the expressions just as it does for function calls.</div>
<div><br></div><div>--- Bruce</div></div></div></div>