Interesting parallel between Observable and Unity game engine

might be helpful to know!

There’s an interesting parallel between Observable and the Unity game engine—they both use generators in almost identical ways.

Unity was released in 2005 with an async runtime it called Coroutines on top of C# generators. It’s still heavily used today to write asynchronous scripts. For example, this fades out a color:

IEnumerator Fade() {
  for (float f = 1f; f >= 0; f -= 0.1f) {
    Color c = renderer.material.color;
    c.a = f;
    renderer.material.color = c;
    yield return null;                       // <-- continue at next frame
    // yield return new WaitForSeconds(.1f); // <-- or continue in 0.1s
  }
}

StartCoroutine("foo"); // <-- Schedules the generator to start
StopCoroutine("foo");  // <-- Cancels the generator it at next yield

In Observable:

{
  for (const f = 1; f >= 0; f -= 0.1) {
    const c = renderer.material.color;
    c.a = f;
    renderer.material.color = c;
    yield null;                   // <-- continue at next frame
    // yield Promises.delay(0.1); // <-- continue in 0.1s
  }
}

// Schedules the generator to start when cell is evaluated.
// Cancels the generator at next yield (using `.return()`) when cell is re-evaluated.

It’s also interesting that this asynchronous yielding pattern has crystallized recently into a popular language-level feature for Python, C#, Hack, and JavaScript by allowing both yields and awaits in a function—rather than relying on a custom scheduler to check the yielded values for async events. Glad to see Observable take advantage of this pretty quickly after release, whereas Unity is still waiting on the C# proposal to finalize.

Has this pattern been used anywhere else? I’d be interested in tracing more of its history.

1 Like

Python started adding related features piece by piece in ~2000. I think Javascript and possibly others were proximately inspired by those, or at any rate there has been some cross-polination between languages.

You can read the PEPs
2001 https://www.python.org/dev/peps/pep-0234/
2001 https://www.python.org/dev/peps/pep-0255/
2002 https://www.python.org/dev/peps/pep-0289/
2005 https://www.python.org/dev/peps/pep-0342/
2012 https://www.python.org/dev/peps/pep-3156/
2015 https://www.python.org/dev/peps/pep-0492/
2016 https://www.python.org/dev/peps/pep-0525/
(or if you dive into the mailing list archive there was tons of discussion of these features)

You might like Dave Beazley’s talks,
http://www.dabeaz.com/generators/
http://www.dabeaz.com/finalgenerator/

Here are some references w/r/t other languages, cited in one of those
https://msdn.microsoft.com/en-us/library/hh191443.aspx
https://docs.hhvm.com/hack/async/introduction
https://www.dartlang.org/articles/language/await-async
https://docs.scala-lang.org/sips/async.html
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3722.pdf

You can find more in the Wikipedia article,

2 Likes