Desugaring "for" and "let"
On Jul 11, 2011, at 7:18 AM, Axel Rauschmayer wrote:
I remember that this has been previously discussed, but can't find the thread. For me, the above desugaring is easier to understand than the lambda coding.
Just recently:
esdiscuss/2011-June/015615 (thread head)
and previously:
Compare: With Java, you have to declare final int finalI = i; inside a for loop if you want to refer to i from an inner class.
Yeah, but that sucks so let's not cite it as any kind of precedent :-|.
Anyway, for-in and for-of with let give fresh binding per iteration -- that's the plan for ES.next.
Ye olde C-style for(init; cond; update) {...} loops are thin veneer for init; while (cond) {... update}, and as Jon Z. pointed out, since you can take them apart accordingly, the binding semantics should not shift as you do.
Just recently:
esdiscuss/2011-June/015615 (thread head)
and previously:
Thanks!
Compare: With Java, you have to declare final int finalI = i; inside a for loop if you want to refer to i from an inner class.
Yeah, but that sucks so let's not cite it as any kind of precedent :-|.
Anyway, for-in and for-of with let give fresh binding per iteration -- that's the plan for ES.next.
Ye olde C-style for(init; cond; update) {...} loops are thin veneer for init; while (cond) {... update}, and as Jon Z. pointed out, since you can take them apart accordingly, the binding semantics should not shift as you do.
==== Example ====
for(let i=0; i < arr.length; i++) { // ... }
==== Desugars to ====
let i=0; while(i < arr.length) { // ... i++; }
As per "Jon’s criticism", I would expect every iteration to create a new environment whose outer environment is always the same – the environment where "i" is bound (right?). That is: "i" is stored outside the environments that are created by repeatedly "invoking" the loop body.
Furthermore, I always thought that there was an additional block wrapped around a for loop with a let, because once you leave the loop, "i" usually ceases to exist.
==== Additional block ====
{ let i=0; while(i < arr.length) { // ... i++; } }
One also has to consider the case where a loop is used to increment a non-local variable. That is, loops should be allowed to have side effects. I’m not sure how this applies to iterators, as they are handled by reference.
On Jul 11, 2011, at 2:54 PM, Axel Rauschmayer wrote:
As per "Jon’s criticism", I would expect every iteration to create a new environment whose outer environment is always the same – the environment where "i" is bound (right?). That is: "i" is stored outside the environments that are created by repeatedly "invoking" the loop body.
Yes, there's an implicit block snugly wrapping the for(let...;...;...){...} loop to hold the let's bindings.
harmony:let
Given the following code: var a = []; for (let i = 0; i < 3; i++) { a.push(function () { return i; }); } print(a0); // 0 or 3?
I would expect this “desugaring”: var a = []; (function() { var i; for (i = 0; i < 3; i++) { (function() { a.push(function () { return i; }); }()); } }()); print(a0); // 3
I remember that this has been previously discussed, but can't find the thread. For me, the above desugaring is easier to understand than the lambda coding.
Compare: With Java, you have to declare final int finalI = i; inside a for loop if you want to refer to i from an inner class. Similarly, if you want the result "0", you would need to write:
Axel