On 7 February 2012 13:32, Andreas Rossberg <rossb...@google.com> wrote: > What are the "closures that were created",
They are the closures that lie lexically within the loop's code, outside of the init, (or, put differently, those that have the loop's environment record in scope) and that were instantiated in the current iteration. > and how do you keep track of them? In a linked list or array. Somewhere that sits with the loop state. In desugaring terms, it could be expressed as an array, perhaps of weak pointers, in the outer loop scope. I haven't got up to speed on Chez Scheme's closures enough to answer this question for those. > What should the following do? > let a = [], b = [], c = [], d = [] > for (int i = 0, f = function(){ return function() { ++i } }; i < 10; > d[i] = function() { return i }, ++i) { > a[i] = f; > b[i] = f(); > c[i] = function(){ return i } > } > print(c[2]()); print(d[2]()) > a[4]()(); print(c[4]()); print(d[4]()) > b[7](); print(c[7]()); print(d[7]()) Here's what it does under the proposed scheme: c[2]() -> 2 d[2]() -> 3 a[4]()() increments the i that is 10 to 11. c[4]() -> 4 d[4]() -> 5 b[7]() increments the i that is now 11 to 12. c[7]() -> 7 d[7]() -> 8 Basically, the closures lexically within the loop init always see the latest version of i. Those lexically within the rest of the loop always see the i that was available at the end of their iteration. The iteration part of the loop is considered to be at the start. A related gotcha is that d[9]() would return 12, if added to the end of that sequence of calls. (I'm answering to the best of my ability, not trying to defend anything.) > And imagine the fun you can have with generators! Indeed, you'd need to alter the [[ExecutionContext]] of suspended generators whose [[Code]] lies within the loop (as well as altering the [[Scope]]), which may be a bigger deal than just modifying [[Scope]]s. > Allow me to be blunt: this is literally raping the concepts of > declarative environment and lexical closure. It is a hack, completely > non-orthogonal, I think that may be more than blunt; it is strongly emotive and also vague enough that it can't really be answered. However, I and others do share the concern that it may introduce too much complexity, and then only really add support for a very rare usage. > and I predict that the hidden statefulness it introduces to closure > environments would be going to bite back in gore proportions. It's a possibility, indeed. The variant that alters only the closures lexically within the loop init has less chance of that, and could potentially have restriction imposed, but all of these variants do indeed introduce a way of (slightly) modifying the scope of a particular group of closures after they have been created. > Seriously, before we consider going there, I'd rather have a step on > the break and stick to C-style for-semantics. I think we wouldn't need to go that far; your generalization of Mark's desugaring covers plenty of use cases and certainly the one of most common loop/closure gotchas. To my understanding, that's the favoured idea, so far, and we're just exploring this one to see where it might lead. Regards, Grant Husbands. _______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss