
Steven D'Aprano wrote:
Outside of such toys, we often find ourselves closing over at least one variable which is derived from the loop variable, but not the loop variable itself:
Terry's idea of a variant of the for-loop whose body is a nested scope (with everything that implies) would address that, because any name assigned within the body (and not declared nonlocal) would be part of the captured scope.
I would not like to see "new" become a keyword.
I'm open to alternatives. Would "foreach" be better keyword material? We could say foreach i in things: ... although the difference between "for" and "foreach" would be far from obvious. I'd like to do something with "let", which is famliar from other languages as a binding-creation construct, and it doesn't seem a likely choice for a variable namne. Maybe if we had a general statement for introducing a new scope, independent of looping: let: ... Then loops other than for-loops could be treated like this: i = 0 while i < n: let: x = things[i] funcs.append(lambda: process(x)) The for-loop is a special case, because it assigns a variable in a place where we can't capture it in a let-block. So we introduce a variant: for let x in things: funcs.append(lambda: process(x)) Refinements" 1) Other special cases could be provided, but I don't think any other special cases are strictly needed. For example, you might want: with open(filename) as let f: process(f) but that could be written as with open(filename) as f: let: g = f process(g) 2) It may be desirable to allow assignments on the same line as "let", e.g. with open(filename) as f: let g = f: process(g) which seems marginally more readable. Also, the RHS of the assignment would be evaluated outside the scope being created, allowing with open(filename) as f: let f = f: process(f) although I'm not sure that's a style that should be encouraged. Code that apparently assigns something to itself always looks a bit wanky to me. :-( -- Greg