lexical for-in/for-of loose end

Brendan Eich brendan at mozilla.org
Thu Feb 2 13:38:17 PST 2012

Allen Wirfs-Brock wrote:
> On Feb 1, 2012, at 7:13 PM, Brendan Eich wrote:
>> So far, so good, and latent here is the best case for not elaborating 
>> the left-hand side to include destructuring, if you can avoid 
>> bloating the grammar too much. Contra my "regularity plus small 
>> use-cases" argument, we leave for-in alone. We can even leave it 
>> underspecified as in ES5.
> but still loose the initializer on var, right?

I think so. We can try. I'll see if Oliver and Gavin are game to try in JSC.

> Also, for consistency I still allow let/const in place or var with 
> with fresh bindings on each iterations.  These are really orthogonal 
> issues relating to the new blocked scoped declaration and we should 
> handle them constantly everywhere.

Yes! Good news is we agreed (most of us, it was late the second day of 
last month's TC39 meeting) to make for(;;) have the same fresh binding 
per iteration.

>>> From that perspective,  own-ness again is something that should 
>>> primarily be an implementation concern.
>> Historically this came up because pre-ES5 people couldn't extend 
>> Array.prototype, e.g., without making enumerable properties. But of 
>> course then the wisdom said don't use for-in on arrays. 
>> Object.prototype is verboten, and at some cost in using custom 
>> functional-programming style iteration, we're ok (PrototypeJS status 
>> quo).
>> The problem that may remain is that
>>  for own (k in o) ...;
>> still beats
>>  for (k in keys(o)) ...;
>> not only by a couple of chars not counting import or assuming 
>> prelude, but in terms of people's historical memory and folk-wisdom 
>> learning.
> I would think we could make this
>    for (k in own(o)) ...;
> and
>    for (k of own(o)) ...;

keys etc. are currently spec'ed to to do own-only, you want allKeys to 
do the crazy thing:


Let's not go around and around on this. Enumerable proto-properties are 
harmful, no one wants them.

> if the object produced by own() provides appropiate definitions for 
> [[Enumerate]] and [[Iterate]]

Jason's cheat-sheet (I cited it fully) shows "good enough" sugar if you 
do the import, or we agree on the prelude.

> Presumably, the only prior leaning that applies comes from 
> CoffeeScript.  While CS is popular, it isn't at all close to being 
> used by the majority of JS developers.  CS experience is informative 
> but I don't think we have to worry so much about CS derived habits.

It's informative, agreed, and competitive -- my point. TC39 does poorly 
inventing new and untested API. We do better paving cowpaths. I think we 
should be careful not to get too far ahead of de-facto standards, while 
avoiding being hostage to language design flaws from the past. We also 
should not oversell Smalltalk, etc. -- Smalltalk is informative (your 
collections port especially) but not particularly more important (or 
less) than CS.

>> Should we ignore all this and say "just use for-of with the right 
>> iterator?"
> probably...

Ok. Is this what you are doing (modulo the initialiser removal)?
I assume that you are arguing that the default @iterator for 
Object.prototype (however it is provided)

>> No! I clearly said there is no @iterator in Object.prototype.
>>> does a key enumeration just like ES1-5 for-in.  Or are you arguing 
>>> that it produces nothing?
>> No @iterator in Object.prototype. We've been over this, Jason argued 
>> convincingly against pre-defining one because it is future-hostile to 
>> collection iteration.
> I just need to find the right thread...

Me too.

> There is still a default.  The iterators proposal says that for-of 
> falls back to @enumerate if @iterate isn't present.

That's a proxy trap, and I believe that dates from before for-of. We 
need to revisit this now, based on splitting iteration out to for-of and 
leaving for-in the old enumerating mystery meat that it has always been. 
Cc'ing Tom.

It's important to distinguish property default from proxy trap built-in.

If there's an Object.prototype. at iterator that iterates values, or 
[key,value] pairs, or whatever, then we make it hard for new collections 
and set-like abstractions to do something slightly different.

> BTW, this is a good example of something that should not be built into 
> statement semantics.  Why should |for (v or values(o))...| iterate 
> differently than |values(o).forOf({|v|...})|

Do you mean forEach?

Who says values(o) returns an array? That is costly and the point of 
iterators is to use a lazy protocol. Indeed the


proposal has values a generator (returns an iterator).

> My currently thinking (working off of the current wiki proposal) is to 
> have [[Enumerate]] and [[Iterate]] internal methods (for all objects) 
> and it is in their default implementation that [[Iterate]] delegates 
> to [[Enumerate]].

No, see above. We do not want to mix these up. Iteration via for-of uses 
the iteration protocol.

>> No issue here, I think. We want for (x of {p:1, q:2}) to throw, 
>> without the user first having defined @iterator in Object.prototype 
>> (and that would not be recommended practice).
> Not what the wiki proposal currently says...


Stopping for now to avoid mega-reply syndrome.


More information about the es-discuss mailing list