The objective is to build a JavaScript implementation of an Actor as defined by Professor Carl Hewitt.
The following implementation is proposed:
To illustrate the implementation, we model a client performing a deposit on its account.
Logs
Implementation: GitHub.
- Abstract definition of an Actor deduced from various publications of Professor Carl Hewitt and other sources.
An actor is built using const actor = new Actor(/* init state */)
, which introduces the actor actor
initialized using values in /* init state */
. An Actor may have a private state, so the Actor
class starts with:
An Actor
is constructed by allocating memory, computation, and communication resources, including an address. This process is modeled by the class constructor.
Using actor
means sending messages to actor
. Sending a message hello
to actor
is modeled by a method call:
hello
may be implemented using synchronous or asynchronous code. A synchronous implementation may be:
In the asynchronous case, hello
should send a message to
actor
, let the runtime execute whatever needs to be done and wait
for an answer whenever it is available. Once received, the computation
should continue. In this case, we need to define:
- A
Message
. - A
send(message)
procedure that delivers the message to the target actor. - The actor
behavior
which defines how the actor will react to a given message.
A Message
has an address and content. An address is an immutable piece of data that gives the ability to send a message to an actor.
Then, the send
operation is modeled using:
which leads us to give an Actor
a behavior:
The asynchronous version of hello
may be implemented using:
When waiting for a reply, the calling code may always use const world = await actor.hello()
, which works for both the asynchronous and synchronous implementation of hello()
.
- The JavaScript runtime is single-threaded by default.
- It is not possible to map an actor to a Web Worker because they are too heavy; the number of Web Workers per browser is too limited to use them extensively.
- Because of the points above — and others left implicit — the actor implementation proposed above is not faithful to the Actor definition.
- Despite its limitations, we still get to use the semantics of actors.
- A JavaScript implementation candidate has been given to illustrate how actors work.
- This implementation is enough for simple programs.
- Building this implementation shows the limitations of the JavaScript runtime and similar single-threaded runtimes.
- The need for a special-purpose runtime like the one provided by the EVM is clear since it addresses this central question: how to map actors to isolated processes?