Brendan Eich wrote:
Grant Husbands wrote:
But this is all beyond the spec.

I don't think it is. What Herby's idea and these formulations present
is a way for let-based loops to have modifications in closures
captured in the for-head that alter the loop variables in a way that's
visible to the current loop iteration.

And read back changes from the current iteration.

Yes, I see that a new (novel!) observable semantic model is being
proposed here, not an optimization. At first it seemed Herby was
proposing just the usual optimizations.

Well, I hope I was understood. Even if not and something interesting sprang out, it's ok. I'll go into details later.

I still do not think it's wise to specify in terms of such
pointer-updating reference semantics, not for the body closures that
want to capture loop control variables. But only if closures in the
for-head capture loop variables? That would be Allen's "DWIM" (Do What I
mean) semantics.

DWIM is tempting. Perl is full of it and it can be convenient at first.
It often blows back, badly, due to ambiguity.

As such, choosing whether or
not to use these formulations affects the spec.

Agreed, with caution about bending the body closure model around this
prematurely. If we pull it off, probably the body closures can do the
same "optimization" -- but it's not clear we can pull it off.

Well, in fact what I proposed was not changing the behaviour of head-closures, but body-closures. Basically, the idea was: let the loop run in legacy semantics (only one block for the whole for-loop). All closures (head ones and body ones) access the same let-var and modify it. But, for at the end of each iteration, if body-closures were created, rebind that closures to copy (or, better, child) of actual execution record with let-var being local (de-facto simulating per-iteration binding, but lazily; and only for async closures).

Spec-wise, I think it only needs to define two things, CopyExecutionRecord, which Grant already mentioned, or something similar like CopyWithFixedVars(ExecutionRecord, vars-to-fix) and ReplaceExecutionRecordBinding to allow closure(s) bound to original execution record re-bind it to its copy created by the former.

It's all. It solves this concern of Allen:
In the case where there are no closure captures in the body we
probably all expect implementations to actually share a single set of
bindings across all iterations. If an implementation did that for
this case it would yield the result the programmer to expecting.  But
if an implementation actually did that in this case it would be an
invalid optimization because of the proposed bind to only first
iteration semantics.

With what I proposed, there is no 0th / 1st iteration semantics etc. since all the loop shares the binding through its whole run.

...

Any preference for 0th over 1st iteration scope for closures in INIT
binding initializer expressions?

...

INIT may want the DWIM semantics, but TEST and NEXT before it for 2nd
through Nth iterations really are more like parts of the BODY. Why
should they form closures that magically reference "current iteration
scope" when called later?

I definitely think INIT should not have any "special" behaviour for 1st and for subsequent iterations. The semantics of the loop is then much more straightforward and less magical. So in case of these desugaring, I am for 0th iteration. To be able to read loop as { INIT; for (;TEST;NEXT) BODY }.

DWIM always falls to ambiguity. What did you mean? I dunno, just do it! :-P

/be

Herby
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to