What has been accomplished?
EiL has an implementation of the actors model as illustrated in Erlang. New processes can be spawned, and with the send() and receive() primitives these processes can communicate via message passing. While the spawning of processes is currently limited to a single machine (i.e. not distributed), distribution is possible if processes are spawned by hand on remote machines. Erlang style process registration (mapping a particular process to a name) is supported and is in fact written in EiL using the send() and receive() primitives.
Currently EiL contains two concurrency strategies: unix processes and threads. The decision about which concurrency mechanism to use must be made when EiL is started, and thus the two concurrency strategies cannot be mixed at the moment (some changes to the API should make this possible, and this should be a goal). However, programs written for EiL are unaware of the underlying concurrency mechanism. For example, to run the ping-pong example with unix-process based concurrency we simply:
ERLANG-IN-LISP> (toplevel :process-class ‘unix-process)
ERLANG-IN-LISP> (ping-pong 3)
To use thread-based concurrency we need only change the keyword to the toplevel function:
ERLANG-IN-LISP> (toplevel :process-class ‘thread-process)
Thus the goal of pluggable concurrency as described in the original proposal has been accomplished. To a certain extent, so has the goal of pluggable messaging. However, messaging is tightly coupled to the concurrency mechanism (i.e. processes serialize messages and communicate via sockets while threads simply exchange references to the messages in memory). Truly pluggable messaging is best left to each concurrency strategy (as opposed to introducing another layer of abstraction). Thus unix-processes may choose to communicate via secure or unsecure sockets while these options would be unavailable to threads.
What remains to be accomplished?
Much remains to be accomplished. Most important is linked processes. I believe this can be accomplished by relying on the Common Lisp condition system. Processes will maintain a link set as in Erlang, and conditions will be handled and forwarded via the messaging primitives to interested processes. While I have sketched out a plan to this end, no code has yet been written.
True distribution including the remote spawning of processes remains as well. The main sticking point is how to serialize closures and ship them off to a remote system. While we can easily send a function name and the required arguments to a remote process and hope that the remote process knows about that function, this is not ideal (and, in fact spawn() only takes a thunk at the moment, so we’d need to figure out how to serialize an anonymous function to capture these arguments…that or have two separate APIs like spawn() and remote-spawn()). We may also wish to generate bindings for the erl_interface so that EiL nodes and code written in EiL can play nicely in an Erlang cluster.
Finally, our ultimate goal of compiling Erlang to EiL remains. To this end, we should focus on compiling Core Erlang only. It may be helpful to develop ‘core EiL’ and then build a Lispier macro-based front end for user consumption.