Generators and Erlang Processes

December 21st, 2007

I’ve always thought that there’s a convenient symmetry between generators and Erlang-style processes. So it’s neat to see that Alex Graveley has been exploring Erlang-style “concurrency” in JavaScript by piggy-backing off my generator based “threading” library.

I sometimes wonder what it would take to expand JavaScript generators to become truly concurrent. Maybe something as simple as a “start” method on a generator object:

function myConcurrent(param) {
  yield wasteTime(param);
}

let gen = myConcurrent(someValue);
gen.start();
let result = wasteMoreTime();
result += gen.next();
gen.close();

where start() causes the generator to begin execution concurrently, and next() or send() act like a thread join.

It’s such a small but powerful extension. It seems appealing up-front, but the devil is in the details. What’s the memory model? Much of Erlang’s appeal stems from its shared-nothing semantics. How would you replicate that with JS generators? Enforce pass-by-value? If next() and send() join, then how exactly do we get the Erlang-style message passing going?

Or maybe there’s no enforcement of shared nothing and caveat emptor? But then you need synchronization for shared objects. Blech.

An interesting thought experiment. To be clear, there’s no talk of anything like this (AFAIK) amongst the JavaScript language designers. Just a random Friday daydream.

One Response to “Generators and Erlang Processes”

  1. Alex Graveley Says:

    Because generators are expected capture context, I think you really need to coin a new concept. My guts tell me that joins are to be avoided for the most flexibility. And join can always be simulated from e.g. message-passing if really wanted.

    Off the top of my head… a spawn built-in might work. Arguments would pass by-value, and the spawned function run in the main document context, or even some read-only protected context (better).

    spawn() could return an “asynchronous” generator to the caller that would marshal results by-value that the spawned function had yielded in the past. next() might throw a TryAgain to avoid blocking if no messages are available.

    Glad you like the Erjs hack :)

Leave a Reply