lexical for-in/for-of loose end

Brendan Eich brendan at mozilla.org
Wed Feb 1 15:05:07 PST 2012


Allen Wirfs-Brock wrote:
> On Feb 1, 2012, at 2:13 PM, Brendan Eich wrote:
>> >  Allen Wirfs-Brock wrote:
>>> >>  Another loose end.
>>> >>  
>>> >>  With the addition of for-of, for-in reverts back to always iterating over the property keys of an object as it does not support the generalized iteration protocols.  An implication of this is that using a de-structuring pattern as the iteration variable has very limited utility:
>>> >>  
>>> >>      for (let [c] in obj) print(c);  //print the first character of
>>> >>      each of obj's enumerable property names
>>> >>  
>>> >>      for (const {length:len}  in obj) print(len);  print the length
>>> >>      of each of obj's enumerable property names
>>> >>  
>>> >>  
>>> >>  Given this lack of utility, why should we allow de-structuring in this context?
>> >  
>> >  These are not totally silly examples. I say when in doubt, let language regularity win.
>
> Well, they're at least 98% silly and these were the only even semi-plausable example I could think of.

So you agree with my point about regularity + non-silly use-cases 
winning? :-/


>> >  We are also thereby future-friendly in case some evolution of property keys becomes even more structured. I know, unlikely, but again: regularity when in doubt.
>
> In which case, it would be easy enough to allow them in the future. It's always easer to relax a restriction then it is to add one.

How would you restrict them? Splitting productions, or semantic 
restrictions? It matters, not just aesthetically but for implementation 
simplicity.


> I don't really see the consistency in trying to ban the initializer in
>    for (var k=42 in obj) ;
> because it is a "awful, lazy-grammar-resue error".

ES1 was based on real implementations. The Netscape one did not allow an 
initaliser here. There's no good use for it compared to destructuring 
key lengths or substrings, especially not with var (which hoists). You 
want an initial var value to survive a zero-iteration loop? Hoist the var.

>    While adding
>    for (var [c] in obj) ;

Are you really "adding"? It depends on good vs. bad reuse of 
sub-grammar. I appealed to regularity. That means standard rules for 
conjugating verbs, etc., in natural languages.

In programming languages one would hope that binding forms would compose 
the same with for-in as for-of as for;; and other binding contexts, 
modulo the initialiser. At least, that's what users of JS1.7-and-up have 
hoped.

That evidence is tainted because we did make for-in programmable via an 
iteration protocol, as for-of is in ES6. Granted. But unless there's an 
actual hardship in regularity (I don't believe there is with for-in, but 
I welcome evidence from you on spec front, and other implementors on 
impl front) I still think regularity wins.

> I don't actually feel too strongly either way and it is actually more work for me to disallow the destructuring pattern.

I'm not super-strong on this, don't get me wrong. It's much less of an 
issue either way than banning the initialiser for let and const. I hope 
we agree on that much, as a partial order of preferences or strong 
convictions!

It also seems relevant that you'd have to do more work in the spec, and 
presumably make the grammar bigger, to disallow destructuring (with and 
without var/let/const) in for-in. More spec effort and grammar size make 
for errata habitat. Just as with code.


>    However, I am trying to find some basis for consistency in the design choices we make.

Again, for-in as designed in JS1 never allowed an initialiser and it's 
an unwanted feature added to match JScript or (perhaps JScript too 
lacked it) to reuse part of the grammar a certain way.

Note that the reuse of VariableDeclarationNoIn didn't save anything in 
the grammar, so I bet the issue was JScript allowing an initialiser. 
Anyone know?

It's never inconsistent to allow one thing and disallow another. The 
particulars matter. This isn't "anything goes". Destructuring has a bit 
of utility and a lot of regularity in for-in head position. The 
initialiser from VariableDeclarationNoIn has neither specific utility 
nor regularity with respect to for-in in AWK, Python, or any other 
language with such a construct.

/be


More information about the es-discuss mailing list