Colons and other annotative characters

Andreas Gal at
Mon Nov 22 16:07:33 PST 2010

I think there is too much fear of changing the "semantics" of for-in. Its semantics is already rather fuzzy. Allowing meta-programmability of for-in (instead of creating a new for-:) syntax doesn't create any additional surprises or hazards for JS programmers.

1. We have already agreed on an enumerate() hook which is triggered by traditional for-in. It returns a list of strings, but those are not necessarily keys.
2. enumerate() can contain arbitrary JS code, so for-in can already trigger all sorts of random behavior, and people seem to be comfortable with it.
3. iterate() is a natural extension of enumerate(). As enumerate(), it should be triggered by for-in. The only difference to the proxy enumerate trap is that iterate() doesn't eagerly force the creation of the list of values to be returned, which may not be possible for very large meta objects (databases, i.e.).

Its seems entirely random to cut off between 2) and 3). We are fine with enumerate(), but iterate() is somehow evil? The only see 2 semantic differences between the outcomes of enumerate() and iterate().
a) enumerate guarantees that all values are strings
b) enumerate guarantees that all strings are unique

So it seems that some people feel that "unique strings" is an appropriate approximation for "keys".

There isn't much I can say about a). I think it would be more flexible and future-proof to allow non-string return values from iterators, but if we have to stringify non-string values returned from iterators, I could live with that.

As for b), the guarantees for it are already extremely weak. With proxies one can already today write code that breaks the uniqueness assumption of for-in.

function visit_keys(obj, f) {
    for (i in obj)

visit_keys(obj, function(i) { delete obj.i; obj.i = 1; })

From my understand of the spec, a spec-conformant implementation is allowed to endless-loop on this code, continuously returning the same property name. So why do we cling to uniqueness where it doesn't exist in the first place?

Executive summary: iterate() is equivalent to enumerate(), both should work with for-in. We already agreed to accept enumerate, forcing iterate() into its own syntax is arbitrary. We can discuss sacrificing future-proofness and stringify return values of iterators, but rejecting iterators because they don't guarantee unique strings is bogus--that uniques doesn't exist elsewhere either.


On Nov 22, 2010, at 3:40 PM, Waldemar Horwat wrote:

> On 11/22/10 15:16, Brendan Eich wrote:
>>> {name: type = value}  // Adding a type annotation
>> Isn't the last ambiguous with legal JS today (well, with const, but that's not important AFAICT):
> Yeah, you're right.  This won't work.
>    Waldemar
> _______________________________________________
> es-discuss mailing list
> es-discuss at

More information about the es-discuss mailing list