some thoughts on for-in

Chris Sells Chris.Sells at microsoft.com
Mon Nov 29 11:04:40 PST 2010


I really like the syntax proposed by Brendan in his Paren-Free post (http://brendaneich.com/2010/11/paren-free/) and I agree with the principles of JS-Harmony language changes with which I'm familiar:


1.      Start with strict mode

2.      Take the global object out of the scope chain

In addition, I think there's a great deal of value in another principle:


3.      Maintain source code compatibility with ES5 (so long as it doesn't violate 1 or 2).

#3 is important because that's what let's folks pick up JS-Harmony even with old JS code/information and still be successful with it until (or instead of) learning the "new" way to do things.

With that in mind, I'd love to see for-in become the "sugared" form of the following:

for (var key in keys(primes())) // or "primes().keys" or "keysof primes()" or whatever syntax you like

By making the old for-in syntax the sugared form of a longer statement, we can tell the story that the key is actually the most general thing you can get back from a collection/array/sequence/range/whatever because it's easy to go from a key to a value, but hard to go the other way and sometimes you need the key (ironically, I was writing code that needed keys when Brendan was sitting next to me at the last meeting talking about how broken the current for-in semantics are : ).

Further, the longer form opens the door to two new longer forms:

               for (var val in values(primes())) // or whatever "values" syntax you like
               for (var [key, value] in properties(primes()) // or whatever "key/value pairs" syntax you like

These two new forms are opt-in as an extension to the existing syntax. I know we've discussed this kind of thing before, but the thing I haven't yet seen (and forgive me if I just missed it), is that the "trap" on the proxy return key/value pairs to implement iteration/enumeration/generation/whatever, e.g.

function primes() { // a generator, but the proxy trap would be similar
               yield [0, 2]; // produce key, value pairs for for-in implementation
               yield [1, 3];
               yield [2, 5];
               yield [3, 7];
               // etc.
}

The for-in syntax and semantics stays the same (based on my principle #3 above), but the generator function can do whatever we like - it's new. If we let it produce pairs, that's enough of an implementation for for-in to produce all three forms. Further, as a convenience, we could assume zero-based, sequential, numeric keys and handle that in the case that a pair isn't provided, e.g.

function primes() {
               yield 2; // produce values and let for-in produce the numeric keys
               yield 3;
               yield 5;
               yield 7;
               // etc.
}

In other words, I'd like to extend the semantics of the existing for-in syntax to support key, value and pair semantics, default for-in to keys to maintain backwards compatibility with existing JS source and let the generators produce key/value pairs or just values, as appropriate for their data.

The downside is the extra syntax for values (and pairs), but it's still less than the current conventional syntax and it's semantically clearer. Further, for folks that want to iterate using keys, they have an explicit syntax that also makes their meaning clear.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20101129/bfbb4005/attachment.html>


More information about the es-discuss mailing list