Has the iteration protocol been given a close look since unique symbols hit
the scene? I know the iterator key was changed to a symbol (which makes
great sense) but ISTM symbols offer up some design flexibility that, as far
as I know, just isn't possible in any of the other languages mentioned WRT
prior art.

For example, the first argument to the iterator function could be a symbol
that acts as a StopIteration semaphore for that iteration run. Obviously
consuming an iterator with `for of` or comprehensions would implement the
protocol for you (generating the symbol and testing it's identity under the
covers), but it'd still be just as easy (perhaps more so) to run off an
iterator run manually. If you happen know the full alphabet of the sequence
you're iterator over you don't even have to use a symbol. I think it's safe
to say very few sequences won't have holes, so providing nothing at all
would do the Right Thing in the vast majority of cases.

I know it's too late in the game for new features. Though, this is really a
small tweak to the current proposal -- it's essentially the same protocol
with a different signaling mechanism. There sure seem to be an awful lot of
pros. It's easier to get right than the throw StopIteration dance, and I
couldn't imagine a way it could be less efficient. AFAICT it's not subject
to the deficiencies I've seen raised about the current spec -- no
instanceof StopIteration confusion and no unnecessary catch blocks, for
instance. I'm not aware of any cons.


On Sun, Feb 10, 2013 at 9:35 PM, Claude Pache <claude.pa...@gmail.com>wrote:

>
> Le 10 févr. 2013 à 22:01, David Bruant <bruan...@gmail.com> a écrit :
>
> > <snip>
> >
> > I have to note that there is a minor security hazard in code using
> iterators naively:
> >    import process from "m";
> >
> >    var a = [1, 2, 3, 4, 5];
> >    var next = 0;
> >    var it = {
> >        next: function(){
> >            if(next < a.length){
> >                // If the call to "process" throws StopIteration because
> it's malicious/buggy,
> >                // so does this code and that's largely unexpected.
> >                return process(a[next++]);
> >            }
> >            else{
> >                throw StopIteration;
> >            }
> >        }
> >    }
> >
> > You can always protect yourself by wrapping the call to "process" with a
> try/catch block.
> > <snip>
>
>
> Note that the same issue arises with generators:
>
>         function* gen(a) {
>                 var next = 0;
>                 if (next < a.length) {
>                         // the iterator will end prematurely if "process"
> throws a StopIteration
>                         yield process(a[next++]);
>                 }
>         }
>
> In order to mitigate the problem, instead of throwing a generic
> StopIteration, I think we ought to throw a specific StopIteration instance
> with information on which iterator has thrown. More precisely, inside a
> generator function, a return statement will throw a StopIteration instance
> with its "source" property set to the generator iterator which was
> terminated.
>
> For manually throwing a StopIteration from inside a "next" method of an
> iterator, we could use:
>
>         throw new StopIteration(this)
>
> And instead of "e instanceof StopIteration", we may use a more precise
> check:
>
>     e instanceof StopIteration && e.source === it
>
>
> —Claude
> _______________________________________________
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to