Re: Why can’t for-of be applied to iterators?

Claude Pache claude.pache at
Thu Jun 13 00:38:33 PDT 2013

Le 13 juin 2013 à 03:33, Brendan Eich <brendan at> a écrit :

> Andreas Rossberg wrote:
>> On 12 June 2013 23:27, Claude Pache<claude.pache at>  wrote:
>>> Therefore, I think that "For/of coerces its argument to an iterator" is a wrong mental model, and "For/of accepts either a reusable iterable or a disposable iterator" is a better one. And the implicit invocation of `@@iterator` is better thought as Get-the-snark-I-need-for-doing-my-work, than as Coerce-to-a-disposable-object. (And the fact that iterators are also non-reusable iterables is an implementation detail that don't disturb my mental model, because I don't care, thanks to generators.)
>> In other words, you want to program with iterables. That is a
>> perfectly reasonable thing to want. But unfortunately, with the
>> current intermingled protocol, there is no particularly useful
>> contract of what an iterable actually does (i.e., where the state
>> goes).
> No, the contract is perfectly useful and minimal. An array is iterable, it has @iterator.

Yes, the name of the contract is `@@iterator`. A for/of loop is normally used to loop over an entire collection of items, so it is expected that the user provides an object from which one could extract a fresh (i.e. non-consumed) iterator. In order to enforce that requirement, one could ask iterators to remove or poison-pill its own `@@iterator` method as soon as its `next` method is called. *That* would add extra value (better error-checking) to the programmer, if we find it worth. But replacing `@@iterator` with `ToIterator` is mostly changing an implementation detail.

>>  Consequently, if you want to write abstractions, you will
>> likely be better off basing them on iterators, and leave iterables as
>> a mere convenience mechanism for for-of loops over concrete objects.
> This does not follow. It flies in the face of boatloads of experience with JS and Python (itertools and beyond).
> I guess we are going 'round the assertion block. I've seen that building before :-|.
> /be

If I want to write an abstraction in a library which loops over an entire collection (e.g,, an `Iter.reduce` function), I just invoke the `@@iterator` method to get an assumed fresh iterator (and it is the responsibility of the user to not provide me with a consumed or half-consumed iterator, unless we add the error-check I mentioned above). If we replace the `@@iterator` method call by an abstract `ToIterator` or `GetIterator` operation, there should be a, say, `Reflect.ToIterator` function that I could use in my library code.


More information about the es-discuss mailing list