On Jun 9, 2013, at 2:34 AM, Jason Orendorff wrote:

> On Sun, Jun 9, 2013 at 2:17 AM, Axel Rauschmayer <[email protected]> wrote:
> > Another use case for iterator support: retrieve the first element from an 
> > iterator, then iterate over the remaining elements via for-of.
> 
> Right, this happens whenever you're doing a fold and your combining function 
> has no handy "zero" value. For the sake of concreteness let's say we're 
> writing code for a robot kitchen, and we've got a function for taking a 
> collection of bowls and dumping all the contents into the first bowl. In 
> Python:
> 
>     def combine(bowls):
>         iterator = iter(bowls)
>         first_bowl = next(iterator, None)
>         for bowl in iterator:
>             dump_into(bowl, first_bowl)
> 
> In JS the same function would be:
> 
>     from "yet_unspecified_standard_module" import iteratorSymbol;
> 
>     function combine(bowls) {
>         let iterator = bowls[iteratorSymbol]();
>         let {value: firstBowl, done} = iterator.next();
>         if (done)
>             return;  // no bowls at all
>         let rest = {};
>         Object.defineProperty(rest, iteratorSymbol, {value: () => iterator});
>         for (let bowl of rest)
>             dumpInto(bowl, firstBowl);
>     }
> 
> If you don't mind copying the source collection into an array, you can use 
> destructuring instead:
> 
>     let [?first, ...rest] = bowls;
> 
> At least, I think that's the current proposed destructuring syntax/semantics. 
> Of course this only works if the use case has a structure that the 
> destructuring mini-language can express.
> 
> Other use cases come up too: (1) you want to process a sequence in one loop 
> until you reach some marker, and then break out of the first loop and process 
> the rest in another loop; or (2) you want to pass the iterator to a separate 
> function that consumes a subsequence of the input. (For example, when the 
> input sequence is from a file, and you're doing some light parsing.)
> 
> I think it's a mistake for iterators not to be iterable. We will have error 
> messages like "Iterator object is not iterable", and users will say 
> "*really*, JavaScript?". Requiring users to build pseudo-collection objects 
> like `rest` in these use cases seems awfully bureaucratic, and hard to 
> justify without resorting to types.

Iterators can be Iterables and any Iterator created as a generator will 
automatically be an Iterator.

But it really comes down to the startup behavior of for-of if the value of the 
|of| expression is not an Iterable.

Currently the spec. days that if it is not an Iterable the for-of loop doesn't 
run (although some of the details in the For In/Of Expression Evaluation looks 
a little bogus).  It would be easy enough to to spec. it such that if the value 
is not an Iterable (does not have an @@iterator property) then it just assumes 
that it must already be an Iterator.

in that case we could say:

    function combine(bowls) {
        let iterator = bowls[iteratorSymbol]();
        let {value: firstBowl, done} = iterator.next();
        if (done)
            return;  // no bowls at all
         for (let bowl of iterator)
            dumpInto(bowl, firstBowl);
    }

Allen
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to