As said, Goblins follows what is called the vat model of computation. A vat is simply an event loop that manages a set of objects which are near to each other (and similarly, objects outside of a vat are far from each other).
Objects which are near can perform synchronous call-return
invocations in a manner familiar to most sequential programming
languages used by most programmers today. Aside from being a somewhat
more convenient way to program, sequential invocation is desirable
because of cheap transactionality, which we shall expand on
more later. In Goblins, we use the $
operator to perform
synchronous operations.
Both near and far objects are able to invoke each other
asynchronously using asynchronous message passing (in the same style
as the classic actor model). It does not generally matter
whether or not a far object is running within the same OS
process or machine or one somewhere else on the network for most
programming tasks; asynchronous message passing works the same either
way. In Goblins, we use the <-
operator to perform
asynchronous operations.
For both programmer convenience and for networked efficiency, Goblins supports promise pipelining: messages can be sent to promises which have not yet resolved, and will be forwarded to the target once the promise resolves. The sender of the message is handed back a promise to which it can supply callbacks, listening for the promise to be fulfilled with a value or broken (usually in case of an unexpected error).
As usual in the vat model of computation, individual message sends to a vat (event loop) are queued and then handled one turn at a time, akin to the way board game players take turns around a table (which is indeed the basis for the term turn).
The message, addressing a specific object, is passed to the recipient object’s current behavior. This object may then invoke other near objects (residing within the same vat), which may themselves invoke other near objects in a synchronous and sequential call-return style familiar to most users of most contemporary programming languages. Any of these invoked objects may also change their state/behavior (behavior changes appear purely functional in Goblins; invocations of other actors do not), spawn new objects, invoke ordinary expressions from the host language, or send asynchronous messages to other objects (which are only sent if the turn completes successfully).
While the vat model of computation is not new (it originates in the E programming language and can trace some of its ideas back to E’s predecessor Joule, and has since reappeared in systems such as Agoric’s SwingSet kernel), Goblins brings some novel contributions to the table in terms of transactionality and time-travel debugging, enhancing an already powerful distributed programming paradigm.