1. Benjamin Dumke-von der Ehe
  2. Lyfe
  3. Issues
Issue #2 wontfix

restartable generator possible in javascript?

Anonymous created an issue

Hello, I like lyfe very much. I wanted to use it to implement cooperative multitasking for ai scripts in my game (so every agent will be generator with function like this:

{{{

!javascript

while(alive()) { var enemy = nearestEnemy(sightLimit); while (enemy.alive()) { target(enemy); yield(); attack(enemy); yield(); } yield(); } }}} )

It almost work :) The only problem is - in my game main loop I have:

{{{

!javascript

for (agent : agents) { agent.generator.first(); agent.generator = agent.generator.skip(1); } }}}

But after each skip() generator retains reference to the previous generator (and it makes sense, and I don't see how to change it). So after a few iterations I've used all the memory.

I wondered, if there is a way to do destructive skip(), but I don't see how to do it. Is it even possible? It would require generator function to throw exception, then somehow to return to the place where it has been thrown.

If you know how to do sth like this, please, let me know. Thanks for your great library, it inspired me.

Greetings.

Comments (1)

  1. Benjamin Dumke-von der Ehe repo owner

    No; unfortunately that's not possible.

    Traditionally, yield does indeed enable coroutines; however JavaScript currently does not support this. Quoting from my blogpost at http://balpha.de/2011/06/introducing-lyfe-yield-in-javascript/:

    "Lyfe approaches the whole thing backwards: When encountering yield, instead of leaving the generator function to essentially go down a level in the call stack, instead yield is a function call that creates a new level on top of the stack. [...] It comes with a few drawbacks. For example, it's not possible to implement an iterator protocoll with this (think “next()” [...]"

    In "normal" JavaScript, i.e. JavaScript without "real" yield support, it is impossible to leave a function and later return back to start off where you previously left. The purpose of Lyfe is to make value-generation easier, but the coroutine thing does not work.

    There are of course other ways to reach a similar goal in JavaScript (say, a zero-length timeout where the current state is saved in a closure), but it will not work with yield as seamlessly as it would, say, in Python.

    Sorry to have to say that, and thanks for your kind words.

  2. Log in to comment