Proposal: generator#clone() and generator#goto()

Salvador de la Puente González salva at unoyunodiez.com
Mon Aug 25 02:17:20 PDT 2014


Sorry, I sent this only to Tab.

On 20 Aug 2014 17:39, "Tab Atkins Jr." <jackalmage at gmail.com> wrote:

>
> On Wed, Aug 20, 2014 at 5:00 AM, Salvador de la Puente González
> <salva at unoyunodiez.com> wrote:
> > Hello.
> >
> > Just a little presentation before the proposal. I'm Salvador de la
Puente
> > González (you can call me Salva, please). I'm working for Telefonica
I+D in
> > Mozilla Firefox OS and I'm a front-end developer, you can know more
about me
> > in http://unoyunodiez.com and my github user is https://github.com/lodr
> >
> > Now, these day I was thinking about a generator feature. I have a use
case
> > for a transpiler I'm developing: in the source language you have
procedures
> > much more like Linux processes. The language have a block sentence
clone for
> > cloning a procedure. After cloning, father procedure simply ignores the
> > block while coned procedure execute sentences inside. Like an
automatized
> > |pid = fork() if (pid != 0) { .... }|.
> >
> > Now I'm addressing this problem from a AST perspective, transpiling
> > procedures to a special generators able to fall through their sentences
> > until reaching a specific yield.
> >
> > But I think it could be easier if I could do something like
> > |generator#clone()| returning a new generator object. This new
generator is
> > paused of the same yield as the original one and have a new variable
> > environment with a shallow copy of the original's variable environment.
The
> > variable environment's parent chain would be the same as the original
one.
> >
> > Notice this is not related with data preservation as most of the objects
> > being used by original generator will be shared with the new one
(although
> > this could be addressed as well) but with execution state.
>
> Generators produce iterables, and you can just use a tee() function to
> "clone" an iterable.  It's not hard to define yourself, and Python has
> a reference implementation:
> https://docs.python.org/2/library/itertools.html#itertools.tee
>

tee() function has two main problems. First and most important, it does not
allow you to communicate different information by using send() on the new
generators. The new generators, though independent, are actually tied to
the state of the original iterator which leads to the second problem: the
waste of space. You need to keep repeated values for each of the cloned
generators.

My proposal performs only a shallow copy of the current state and most
important, the execution state which allow you to send different
information for the next iteration step. They are real independent
generators.

> > In the same way, to provide a complete control over execution state
inside
> > generators I would like to propose |generator#goto(yieldLabel)| that
could
> > allow the developer to transfer the execution cursor to a labeled yield
> > sentence. The result of the yield sentence could be the extended with
the
> > label for that yield.
> >
> > I know it does not suffice to be a cool feature but I think it could
trigger
> > very interesting uses cases and applications in backtracking or temper
> > algorithms.
>
> You can currently pass values back into the generator by passing an
> argument to .next(), and the generator can use that to do whatever it
> wishes, such as changing its internal state or jumping to a label.

AFAIK, jumping to a label is not possible in ES5. You can only skip a
labelled sentence. Indeed you can use the next information for changing the
state. It's how I'm doing it right now but transpiling the functions this
way is quite obscure.

I don't know if there are goto discussions in this list but it is one of my
concerns, if JS is becoming something like the "high level target language
of the web", to provide a powerful enough flow control sentence like goto.

I know the dangers behind this sentence and this is because I propose to
limit its usage inside generators where scope is controlled and limited.
You can not jump between functions and the jumping is controlled
externally. The proposed goto() method does not send or advances the
generator, it only changes the execution point. It can be completed with
gen#yields() which would return all labels for labelled yields.

Cheers!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140825/6bbb2c8b/attachment.html>


More information about the es-discuss mailing list