return when desugaring to closures
Brendan Eich
brendan at mozilla.com
Mon Oct 13 16:39:31 PDT 2008
On Oct 13, 2008, at 4:14 PM, Jon Zeppieri wrote:
> Yes, and binding a fresh induction variable on every iteration makes
> sense for a 'for-each' loop (as in the bug report you cited), where
> the user is not in charge of updating the induction variable by means
> of explicit assignment. In a plain 'for' loop, however, it *is* magic
> if an assignment results in a fresh binding.
Why is the assignment operator relevant? The question is the binding
scope of i in
for (let i = 0; i < N; i++) ...
No curly braces required, we already have this in JS1.7+ and the let
is scoped to the for head except for the initializer of i (you can
write let i = x, j = y; too -- x and y are evaluated in the outer
scope). There's scope magic in this form even though it uses = for
assignment and creates only one block scope for the loop, no how many
times the loop iterates.
> And it's unexpected magic.
Users differ on this point, but we've had long-standing confusion and
complaints about closures capturing the last value of i in
let a = [1,2,3,4];
let b = [];
for (let i = 0; i < a.length; i++)
b[i] = function () { return i*i; }
and the like. Getting 16 back from b[0]() is unexpected bad magic.
Users may be modeling closures as capturing bindings, not scope chains
of mutable objects, one per for (let...) statement or explicitly
braced block. If so, could we make let declaration capture this way?
Again, I'm proceeding from real users' complaints, not idle wishes.
> Mark said that there was a desugaring for 'for' to 'lambda,' without
> special cases, where this all works out, but I haven't been able to
> figure out what rewrite he had in mind.
Tail-recursive lambda rewrite of a C-style for loop should be easy for
you :-P.
>> Doing it the way Mark proposes fixes the bug, and has no other bad
>> effects that I can see (but we'll have to implement and user-test to
>> be sure).
>
> Turning an assignment into a non-assignment is bad.
Assignment is not the issue, the binding's scope is.
>> https://bugzilla.mozilla.org/show_bug.cgi?id=449811
>
> Like I said, it makes sense for 'for-each.'
Progress!
/be
More information about the Es-discuss
mailing list