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