some generator issues

Yuh-Ruey Chen maian330 at gmail.com
Mon Apr 23 10:53:54 PDT 2007



Brendan Eich wrote:
> On Apr 23, 2007, at 9:39 AM, Yuh-Ruey Chen wrote:
>
> > The generator-iterator is
> > accessed within the generator function via arguments.generator.
>
> This is still a bit awkward for the reason given by Neil, and with  
> rest parameters, we are trying to avoid arguments being a commonly  
> used object (so that some day it might become deprecate-able -- it's  
> far from that now).
>   

Well then I'm stumped. We can't reuse |this|, shouldn't introduce a new
keyword, and are trying to disuage usage |arguments|. Using the
generator function itself (like how recursive functions reference
themselves) is a non-starter too.

A comment on |arguments| though: Although I think it is more elegant to
use the new rest parameters than the arguments object, the arguments
object does have a very useful property that I use all the time:
arguments.callee. I often use this within recursive functions, since if
I ever rename my function (which is common with helper functions), I
don't need to mess with the function body at all. So even if arguments
is deprecated, I would still want some |arguments.callee| equivalent.

> > Then I
> > proposed that next() and send() are bound class methods rather than
> > unbound prototype methods.
>
> Right, and I pointed out how they're uselessly re-bindable (to any  
> object), but that if re-bound (I mean |this| binding here) to a non- 
> generator-iterator object, you'll get a type error trying to call them.
>
> > I'm not exactly sure how class methods are
> > implemented, but in ES3, this is practically equivalent to:
> >
> > // constructor for generator-iterators
> > function Generator(...) {
> >     ...
> >     var self = this;
> >     this.next = function() { return Generator.prototype.next.call 
> > (self); };
> >     this.send = function(x) { return Generator.prototype.send.call 
> > (self,
> > x); };
> >     ...
> > }
> >
> > ...with the added benefit that Generator.prototype.send/next can still
> > be overwritten meaningfully.
>
> That's not always a benefit. See https://bugzilla.mozilla.org/ 
> show_bug.cgi?id=354750.
>
> > But as I said before, it seems odd that
> > only next() and send() are special, or that Generator (and possibly  
> > its
> > counterpart, Iterator) is special with respect to the builtin
> > constructors already in ES3.
>
> Sorry, not sure what you mean here. There is no Iterator nominal type  
> proposed for ES4. There's no Generator or Iterator in ES3.
>
> Locking up methods against AOP-style overriding via mutable prototype  
> bindings is sometimes the right thing for integrity, which is a  
> security property.
>   

I didn't mean that Generator or Iterator were already in ES3 - I was
just saying that existing ES3 builtin constructors already use prototype
methods, so it would make sense for Generator and Iterator to follow
suite. But in this case, the next() and send() being special may be
warranted in light of the integrity concerns you raise.

> > In any case, I've been experimenting with Python lately to see if
> > there's some convenient solution for the intended use case (async  
> > calls
> > and returns), since Python's generator functions also lack a way to
> > access their "parent" generator-iterators. One library I've been  
> > looking
> > at is the Twisted framework, or rather it's Deferred component. It's
> > solution to this issue is an inlineCallbacks function intended to  
> > wrap a
> > generator function within some sort of generator manager:
> > http://twistedmatrix.com/documents/current/api/ 
> > twisted.internet.defer.html#inlineCallbacks.
>
> Yes, this is familiar too from MochiKit, which was inspired by  
> Twisted. But the question you raise remains: should there be a more  
> convenient, primitive way to denote the current generator-iterator  
> from within its generator function?
>
> /be
>   

That was what I was trying to answer. Playing devil's advocate here. Are
there any other use cases where accessing the current generator from
within a generator function would be useful (and can't otherwise be
"easily" simulated)? If the only use case I was thinking of it for can
already be handled well enough (albeit somewhat awkwardly), that
functionality may not be needed. Furthermore, if we really want to
support async programming seamlessly in the language, I think it would
take more than just arguments.generator (or the equivalent).

-Yuh-Ruey Chen



More information about the Es4-discuss mailing list