This is the documentation for the core Goblins API. That is, this is
the documentation for everything imported with
@code{(use-modules (goblins))}.

@menu
* Objects::
* Vats::
* Actormaps::
* Misc::
@end menu

@node Objects
@section Objects

Objects are the core of Goblins.  In general, you'll need to be within
an ambient Goblins Context in order to start programming
against them.  See @ref{Vats} for most event loop type programming, or
@ref{Actormaps} if you want to play with more low-level control over
transactional operations.  Most users will just use vats.

@menu
* Object definition::
* Synchronous calls::
* Promises::
* Asynchronous calls::
* Object reference procedures::
@end menu

@node Object definition
@subsection Object definition

Goblins objects are fundamentally just procedures wrapped in a
constructor definition.  Any procedure accepting at least one argument
(@code{bcom}) and returning another procedure (the behavior) works as an
object constructor, like this one:

@lisp
(define (^greeter bcom our-name)
  (lambda (your-name)
    (string-append "Hello, " your-name "!")))
@end lisp

In some cases, manually defining objects like this may be necessary.
However, in the general case, the recommended approach is to use the
@code{define-actor} macro, which would look like this:

@lisp
(define-actor (^greeter bcom our-name)
  (lambda (your-name)
    (string-append "Hello, " your-name "!")))
@end lisp

@code{define-actor} simplifies common patterns like persistence
(@pxref{Persistence}) and makes live hacking more convenient:

@anchor{define-actor}
@deffn {Syntax} define-actor (object-name var @dots{} @
                             [#:optional vardef @dots{}] @
                             [#:key vardef @dots{}]) @
                             [#:restore procedure] @
                             [#:portrait thunk] @
                             [#:version version] @
                             [#:frozen] @
                             [#:upgrade migrator] @
                             [#:self name] @
                             body @dots{}

Define a Goblins object with @var{object-name}.  The argument syntax
accepts the @code{#:key} and @code{#:optional} keywords from
@code{lambda*} and @code{define*}.  By default, @code{define-actor}
returns a redefinable object to aid in live hacking.

If provided, the argument to @code{#:portrait} must be a procedure that
accepts no arguments (a thunk).  This thunk is called in the context of
the @code{define-actor} body and has access to any arguments or
definitions available there.  Its return value must be a list or
@code{versioned} object (@pxref{Upgrading through persistence})
containing arguments, in order, for the restoration procedure.  If the
return value is a @code{versioned} object and the @code{#:versioned}
argument is provided, the two versions must be @code{equal?}.  If
@code{#:portrait} is not provided, the arguments to the constructor are
used as the portrait data.

If provided, the argument to @code{#:version} is used to tag portrait
data.  If the portrait procedure returns a @code{versioned} object, the
two versions must be @code{equal?}.  If no @code{#:version} argument is
provided and the portrait procedure does not return a @code{versioned}
object, the portrait data will be unversioned; its version will be
treated as @code{0} on restoration.

If provided, the argument to @code{#:restore} must be a procedure that
accepts at least two arguments: the version of portrait data, and the
portrait data proper.  This procedure is applied to the version and the
portrait data.  If no @code{#:restore} procedure is provided, during
restoration, the constructor is applied directly to the portrait data
without the version.

If provided, the argument to @code{#:upgrade} must be a procedure
accepting arguments of the same kind as @code{#:restore}.  It should
return two values: the new version, and the new portrait data as a list.
If @code{#:restore} is also provided, it is applied to the resulting
values; if it is not, the constructor is applied to the new portrait
data.  While @code{#:upgrade} is designed for use with
@code{migrations}, it is generic enough to be used on its own.

If provided, the argument to @code{#:self} must be an identifier (not a
symbol) which is bound to the object's refr inside the object body.
This allows the object to send messages to itself at runtime (but not
construction time).

If provided, the @code{#:frozen} flag indicates that the object will not
be redefinable.  This provides a slight performance improvement to
spawning (@pxref{spawn}) at the cost of less convenient live hacking.
@code{#:frozen} cannot be used with @code{#:restore}.

Here is a very simple example defining a cell object.  Its portrait
would be @code{(list val)}:

@lisp
(define-actor (^cell bcom #:optional val)
  (case-lambda
    ;; Called with no arguments; return the current value
    [() val]
    ;; Called with one argument; become a version with this new value
    [(new-val)
     (bcom (^cell bcom new-val))]))
@end lisp

Here's a more complex example.  This code shows a thermostat object
which is constructed with two arguments: a cell holding the temperature,
and a reference to a heater object.  It defines a portrait procedure
which extracts the value from the cell, serializing the value in the
cell rather than the cell reference.  It specifies a version of @code{1}
so it can upgrade from a prior version.  In the restore function, it
matches on the version, converting from the original Celsius value to
the new Kelvin value if necessary; then spawns @code{^thermostat} with a
new cell holding the temperature and the same reference to the heater:

@lisp
(define-actor (^thermostat bcom set-temp-cell heater-refr)
  #:portrait (lambda ()
	       (list ($ set-temp-cell) heater-refr))
  #:version 1
  #:restore (lambda (version set-temp heater-refr)
	      ;; Version 0 used C; convert to Kelvin
	      (define maybe-converted-temp
		(match version
		  [0 (+ set-temp 273.15)]
		  [1 set-temp]))
	      (spawn ^thermostat
		     (spawn ^cell maybe-converted-temp)
		     heater-refr))
  (methods
   [(set-temp new-temp) ($ set-temp-cell new-temp)]
   ;; Invoked with current room temp
   [(tick current-temp)
    (if (< current-temp ($ set-temp-cell))
	(<-np heater-refr 'turn-on)
	(<-np heater-refr 'turn-off))]))
@end lisp

This actor could very well have kept the temperature in the cell;
there's usually no reason to unpack values like this.  However,
unpacking the value demonstrates that code can be called inside the
portrait thunk, and that the portrait data can be transformed in the
portraitization and restoration process.

Sometimes it's convenient for an actor to be able to refer to itself.
Take the example of a deck of playing cards using its own method within
another method:

@lisp
(define-actor (^deck bcom #:optional crds)
  #:self self
  ;; define helpers etc. here...

  (define-cell cards (or crds (init-deck)))
  (methods
   ...
   ((top) (car ($ cards)))
   ((draw)
    (let ((top ($ self 'top)))
      ($ cards (cdr ($ cards)))
      top))
   ...))
@end lisp

@end deffn

Once you have a constructor, you can use it to create live objects with
the @code{spawn} operator:

@anchor{spawn}
@deffn {Procedure} spawn constructor args @dots{}

Construct and return a reference to a new object.

@itemize
@item
@var{constructor}: Procedure which returns a procedure representing
the object's initial behavior; implicitly passed a first argument,
@code{bcom}, which can be used to change the object's behavior.

@item
@var{args}: Remaining arguments passed to @var{constructor}.

@end itemize

For example, given the following constructor:

@lisp
(define* (^cell bcom #:optional val)  ; constructor (outer procedure)
  (case-lambda                        ; behavior    (inner procedure)
    (()                               ; 0-argument invocation (getter)
     val)                             ;   (return current value)
    ((new-val)                        ; 1-argument invocation (setter)
     (bcom (^cell bcom new-val)))))   ;   ("become" ^cell with new value)
@end lisp

The instantiation@dots{}

@lisp
(define some-cell (spawn ^cell 42))
@end lisp

will bind @code{val} to @code{42}.

@end deffn

@cindex bcom
The @code{bcom} argument warrants further explanation.  It is a
capability which allows the actor to change its own behavior.  It must
be called in a tail position, since @code{bcom} returns a
data structure demonstrating that this object is choosing to change its
value (part of Goblins' quasi-functional design).

@code{bcom} can also take a second argument which will be returned
from the object's invocation as a return value. This allows an object
to both change its behavior and return a value with the same
invocation.

The following actor represents a consumable object that returns a
string explaining its current status:

@lisp
(define (^drink bcom drink-name portions)
  (define (drinkable-beh portions)   ; "-beh" is a common suffix for "-behavior"
    (lambda ()
      (define portions-left
        (- portions 1))
      (if (zero? portions-left)
          (bcom empty-beh
                (format #f "*GLUG!* You drink your ~a. It's empty!"
                        drink-name))
          (bcom (drinkable-beh portions-left)
                (format #f "*GLUG!* You drink your ~a. Still some left!"
                        drink-name)))))
  (define (empty-beh)
    "Sadly, your glass appears to be empty!")
  (drinkable-beh portions))
@end lisp

Here's how this works at the REPL:

@lisp
> (define a-vat (spawn-vat))
> ,enter-vat a-vat
> (define root-beer (spawn ^drink "root beer" 3))
> ($ root-beer)
=> "*GLUG!* You drink your root beer. Still some left!"
> ($ root-beer)
=> "*GLUG!* You drink your root beer. Still some left!"
> ($ root-beer)
=> "*GLUG!* You drink your root beer. It's empty!"
> ($ root-beer)
=> "Sadly, your glass appears to be empty!"
@end lisp

As you can see above, @code{bcom} is also a handy way to construct
state machines, as @code{^drink} moves from drinkable to empty as it
is consumed.

@code{spawn} also has specialized variants:

@deffn {Procedure} spawn-named name constructor args @dots{}

Like @code{spawn}, and set the object's debug name to @var{name}.

@end deffn

@node Synchronous calls
@subsection Synchronous calls

Relative to a given @emph{vat}, there are two types of objects.  A
@dfn{near} object is in the @emph{vat}.  A @dfn{far} object is in a
different @emph{vat}.  Similarly, there are two ways to invoke objects:
@dfn{synchronous}ly, or using traditional call-return, which only
works for @emph{near} objects; or @dfn{asynchronous}ly, which works for
either @emph{near} or @emph{far} objects, and usually returns a
@emph{promise}. @emph{Synchronous} and @emph{asynchronous} invocation
use different but similar procedures.

@deffn {Procedure} $ to-refr args @dots{}

Call a @emph{near} object's behavior and return the result.

@itemize
@item
@var{to-refr}: @emph{Near} object to call.

@item
@var{args}: Arguments to the object's behavior.  If @var{to-refr}
has methods, the first argument will conventionally be a symbol
indicating the behavior/method to be invoked.

@end itemize

@lisp
(define object-a (spawn ^some-object))
;; in the same vat
(define a-val ($ object-a arg1))
(define b-val ($ object-a 'some-method arg2))
@end lisp

@end deffn

@node Promises
@subsection Promises

@cindex promise
The central data type abstracting asynchronous computations in Goblins
is a special object called a @dfn{promise}.  A promise is a
representation of the result of an ongoing or future computation.
Once a promised computation is completed, it can be either
@emph{fulfilled}, indicating success and carrying the value resulting
from the computation; or @emph{broken}, indicating that the
computation failed and carrying an error (or other arbitrary value)
conventionally explaining why.

Goblins promises are conceptually similar to
@url{https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise,JavaScript
promises} which may be familiar from other contexts.  The most
important difference is that Goblins promises support sending messages
to the objects to which they will resolve, called ``promise
pipelining''.  @xref{Promise pipelining} for more information.

Goblins provides @code{(goblins actor-lib joiners)} and @code{(goblins
actor-lib on)} to help flatten out code using
promises.  @xref{On}; @pxref{Joiners}.

@subheading Making promises

Typically, Goblins code will not need to manually create and fulfill
promises unless it is interfacing with an outside system.  However,
even if a user never needs to create and fulfill promises directly, it
is important to understand the process and its mechanisms to
understand promises and asynchronous programming.

On a fundamental level, promises are created alongside their resolvers:

@deffn {Procedure} spawn-promise-and-resolver

Return a promise and its associated resolver in that order as a
@code{values} object.

@lisp
(define-values (a-promise a-resolver)
  (spawn-promise-and-resolver))
@end lisp

@end deffn

The promise portion of a promise pair is what should be returned when
beginning an asynchronous computation.  It can be passed to @code{on}
to access the result.  @code{$} can also return the value of a
resolved promise, but it cannot listen asynchronously for resolution,
limiting its usefulness for this case.

The resolver should be kept private and is used to @emph{fulfill} or
@emph{break} a promise.  It can respond to two messages using standard
Goblins method syntax (@pxref{Methods}):

@itemize
@item
@code{fulfill val}: Successfully fulfill the promise with @var{val}.
@item
@code{break problem}: Indicate promise failure because of
@var{problem}, conventionally an exception object.
@end itemize

@subheading Using promises

The best way to understand promises is to use them, so let's use them.
A new store has just opened in town, and it wants to celebrate its
100th customer.  We can model it like so:

@lisp
;; Imports we'll need
(use-modules (goblins)
             (goblins actor-lib cell)
             (goblins actor-lib methods)
             (goblins vat))

(define (^store _bcom)
  ;; Spawn a promise pair representing the wait for the 100th customer
  (define-values (100th-promise 100th-resolver)
    (spawn-promise-and-resolver))
  ;; Keep track of the customer count in a cell
  (define-cell customer-count 0)
  (methods
   ;; Hand out the promise for the 100th customer
   ((listen) 100th-promise)
   ;; When a customer shops, increment the customer counter.
   ((shop)
    (let ((new-count (1+ ($ customer-count))))
      ($ customer-count new-count)
      (when (= new-count 100)
        ($ 100th-resolver 'fulfill "Woohoo! 100th customer!!"))))))
@end lisp

You can then listen to this actor's promise with @code{on}:

@lisp
;; Spawn a vat
(define a-vat (spawn-vat))

;; Spawn the store actor
(define store (with-vat a-vat (spawn ^store)))

;; Listen for the 100th customer
(with-vat a-vat
  (on ($ store 'listen)
      ;; When the 100th customer enters, announce it
      (lambda (message)
        (display message)
        (newline))))

;; Quickly simulate 100 customers
(with-vat a-vat
  (for-each (lambda _ ($ store 'shop)) (iota 100)))

;; => "Woohoo! 100th customer!!"
@end lisp

@node Asynchronous calls
@subsection Asynchronous calls

@subheading Making asynchronous calls

@deffn {Procedure} <- to-refr args @dots{}

Like @code{$}, but @var{to-refr} may be @emph{near} or @emph{far}, and
@code{<-} returns a promise instead of a result.

@lisp
(define object-a (spawn ^some-object))
;; in a different vat... or the same; it doesn't matter to <-
(define a-promise (<- object-a arg1))
(define b-promise (<- object-a 'some-method arg2))
@end lisp

@end deffn

@code{<-} has a variant that does not return a promise:

@deffn {Procedure} <-np to-refr args @dots{}

Like @code{<-}, but return @code{void} instead of a promise.

@lisp
(define object-a (spawn ^some-object))
;; in a different vat... or the same; it doesn't matter to <-np
(<-np object-a arg1)                ; returns void
(<-np object-a 'some-method arg2)   ; returns void
@end lisp

@end deffn

@deffn {Procedure} <-np-extern to-refr args @dots{}

Like @code{<-np}, but only operate on @emph{far} objects.

This procedure can be used outside of a vat.

@end deffn

@deffn {Procedure} <-hashmap-ref to-refr key

Performs a hashmap lookup on promise @var{to-refr} with the string @var{key}.
If the promise @var{to-refr} breaks or is resolved to a non-hashmap value,
the promise returned will also break.

@var{to-refr} should be a hashmap or a promise which will eventually
resolve to a hashmap.

@lisp
(use-modules (goblins)
             (goblins utils hashmap))

(define-actor (^fruit-colors _bcom)
  (lambda ()
    (hashmap ("banana" 'yellow)
             ("orange" 'orange)
             ("lemon" 'yellow))))

(define vat (spawn-vat))
(with-vat vat
  (define fruit-colors (spawn ^fruit-colors))
  (define fruit-hashmap-vow (<- fruit-colors))
  (on (<-hashmap-ref fruit-hashmap-vow "banana")
      (lambda (banana-color)
        (pk 'banana-color banana-color))))
@end lisp

@end deffn

@deffn {Procedure} <-list-ref to-refr index

Like @code{<-hashmap-ref} but will extract the element at @var{index}
within a list.

@lisp
(use-modules (goblins))

(define-actor (^fruits _bcom)
  (lambda ()
    (list 'banana 'apple 'orange)))

(define vat (spawn-vat))
(with-vat vat
  (define fruits (spawn ^fruits))
  (define fruit-list-vow (<- fruits))
  (on (<-list-ref fruit-list-vow 1)
      (lambda (a-fruit)
        (pk 'fruit a-fruit))))
@end lisp

@end deffn

@deffn {Procedure} <-tagged-ref to-refr label

Like @code{<-hashmap-ref} except for tagged values. These tagged
values are those created with @code{make-tagged} from @code{(goblins
abstract-types)}. @var{label} must be a string.

@lisp
(use-modules (goblins)
             (goblins abstract-types))

(define-actor (^tagged-lemon _bcom)
  (lambda ()
    (make-tagged "lemon" 'yellow)))

(define vat (spawn-vat))
(with-vat vat
  (define tagged-lemon (spawn ^tagged-lemon))
  (define tagged-lemon-vow (<- tagged-lemon))
  (on (<-tagged-ref tagged-lemon-vow "lemon")
      (lambda (lemon-color)
        (pk 'lemon-color lemon-color))))
@end lisp

@end deffn

@subheading Handling asynchronous values

Goblins provides two primary tools for resolving and operating on
promise values, @code{on} and @code{listen-to}.  Neither pauses
program execution, so code following their invocation is conceptually
concurrent with their various handlers.  These handlers therefore
constitute the asynchronous logic of most Goblins programs.

@deffn {Procedure} on vow [fulfilled-handler #f] @
       [#:catch #f] [#:finally #f] [#:promise? #f]

Respond to a promise, optionally with error handling.  Return nothing
unless @var{promise?} is @code{#t}, in which case return a promise.

@itemize
@item
@var{vow}: Promise to which to respond.

@item
@var{fulfilled-handler}: Procedure called with one argument on
success, the result of fulfilling @var{vow}.

@item
@var{catch}: Procedure called with one argument on failure, the
exception object explaining why @var{vow} broke.

@item
@var{finally}: Procedure unconditionally called last with one
argument, the result of either the @var{fulfilled-handler} or the
@var{catch} handler.

@end itemize

As mentioned above, if @code{#:promise?} is @code{#t}, then @code{on}
will itself return a promise.  This promise is resolved as follows:

@itemize
@item
If @code{vow} is fulfilled and @code{fulfilled-handler} is not
provided, the promise returned will share @code{vow}'s resolution.
@item
If @code{vow} is fulfilled and @code{fulfilled-handler} is provided,
the resolution will be whatever is returned from
@code{fulfilled-handler}, unless @code{fulfilled-handler} raises an
error, in which case the promise will be broken with its error-value
set to this exception.
@item
If @code{vow} is broken and @code{catch} is not provided, the promise
returned will share @code{vow}'s broken result.
@item
If @code{vow} is broken and @code{catch} is provided, the resolution
will be whatever is returned from @code{catch}, unless @code{catch}
raises an error, in which case the promise will be broken with its
error-value set to this exception (which may even be the original
exception).

@end itemize

@lisp
;; in the context of some vat
(define object-a (spawn ^some-object))
;; in the context of some vat, possibly different
(on (<- object-a arg1)
    (lambda (val)
      (some-proc val))
    #:catch
    (lambda (err)
      (handle-err err))
    #:finally
    (lambda _
      (other-proc))
    #:promise? #f)      ; the default, written out for demonstration
@end lisp

@end deffn

Goblins also exposes a more primitive interface to listen for promise
resolution, mostly useful if you don't need to know the value a
resolved promise and just want to know that it has resolved:

@deffn {Procedure} listen-to to-refr listener [#:wants-partial? #f]

Wait for @var{to-refr}, a promise, to resolve, then call
@var{listener} with its value.  If @var{wants-partial?} is @code{#t},
return updates rather than waiting for full promise resolution.

The value passed to @var{listener} is a list of the form
@code{('fulfill val)} on success, where @var{val} is the result of
resolving @var{to-refr}; or of the form @code{('break problem)} on
failure, where @var{problem} is the cause of a failed computation.

@end deffn

@node Object reference procedures
@subsection Object reference procedures

Goblins comes with a variety of predicates for identifying and working
with objects.  While these are primarily for internal use, they are
also helpful when defining custom @emph{vat} code.

@deffn {Procedure} local-object-refr? obj

Return @code{#t} if @var{obj} is an object in the current process,
else @code{#f}.

@end deffn

@deffn {Procedure} local-promise-refr? obj

Return @code{#t} if @var{obj} is a promise in the current process,
else @code{#f}.

@end deffn

@deffn {Procedure} local-refr? obj

Return @code{#t} if @var{obj} is an object or promise in the current
process, else @code{#f}.

@end deffn

@deffn {Procedure} remote-object-refr? obj

Return @code{#t} if @var{obj} is an object in a different process,
else @code{#f}.

@end deffn

@deffn {Procedure} remote-promise-refr? obj

Return @code{#t} if @var{obj} is a promise in a different process,
else @code{#f}.

@end deffn

@deffn {Procedure} remote-refr? obj

Return @code{#t} if @var{obj} is an object or promise in a different
process, else @code{#f}.

@end deffn

@deffn {Procedure} promise-refr? maybe-promise

Return @code{#t} if @var{maybe-promise} is a local or remote promise,
else @code{#f}.

@end deffn

@deffn {Procedure} live-refr? obj

Return @code{#t} if @var{obj} is a local or remote object or promise,
else @code{#f}.

@end deffn

@deffn {Procedure} near-refr? obj

Return @code{#t} if @var{obj} is a @emph{near} object or promise, else
@code{#f}.

@end deffn

@deffn {Procedure} far-refr? obj

Return @code{#t} if @var{obj} is a @emph{far} object or promise, else
@code{#f}.

@end deffn

@deffn {Procedure} refr-name refr

Return debug name for @var{refr}, or @code{#f} if there is none.

@end deffn

@node Vats
@section Vats

A @dfn{vat} is an event loop that runs continuously in a single thread
and manages a set of objects which are @emph{near} to each other,
including passing messages between @emph{vats}.  They are one of the
central abstractions of Spritely Goblins facilitating the object
capabilities security model as well as transactionality and
distributed programming through their use of the underlying
@code{actormap} data structure.  All Goblins objects live inside a
@emph{vat}.

@menu
* Vats overview::
* Making vats::
* Using vats::
@end menu

@node Vats overview
@subsection Vats overview

In order to start programming with Goblins, you will need to boot up a
vat somewhere.  In general, Goblins uses
@uref{https://github.com/wingo/fibers/, Fibers} to implement vats.
However, you can also roll your own vats should you have ``unusual''
event loop needs (see @code{make-vat}).

@lisp
> (define my-vat (spawn-vat))
> my-vat
=> #<vat izvD0DJT>
@end lisp

Running @code{spawn-vat} returns a vat object.  Code can be run within
the context of a vat using the @code{call-with-vat} procedure.  This
is useful for bootstrapping vats or hacking at the REPL:

@lisp
> (define my-vat (spawn-vat))
> (call-with-vat my-vat
   (lambda ()
     (define alice (spawn ^greeter "Alice"))
     ($ alice "Bob")))
=> "Hello Alice, my name is Bob!"
@end lisp

For convenience, the @code{with-vat} macro can be used instead of
@code{call-with-vat}.  Here's the above example rewritten to use
@code{with-vat}:

@lisp
> (define my-vat (spawn-vat))
> (with-vat my-vat
   (define alice (spawn ^greeter "Alice"))
   ($ alice "Bob"))
=> "Hello Alice, my name is Bob!"
@end lisp

You can also use the @code{vat-halt!} procedure to stop the vat, and
@code{vat-running?} to check its status:

@lisp
> (vat-halt! my-vat)
> (vat-running? my-vat)
=> #f
@end lisp

@strong{NOTE:} In the future, we would like vats to automatically halt
when no more references exist and thus the vat can do no more work.
The Racket version of vats works this way; it would be good for the
Guile version to do the same.  In the meanwhile, you'll need to call
@code{vat-halt!} manually.

@node Making vats
@subsection Making vats

At a high level, users generally will spawn a @emph{vat}, bind it to a
name in the local namespace, and use it for various operations. This
will usually use @code{spawn-vat}:

@deffn {Procedure} spawn-vat [#:name] [#:log?] [log-capacity]

Create and return a reference to a new @emph{vat}.

@itemize
@item
@var{name}: Name of the vat.  Note that this is @emph{not} the name it is
bound to in the current namespace.

@item
@var{log?}: If @code{#t}, log @emph{vat} events; otherwise, do not.

@item
@var{log-capacity}: Number of events to be retained in the log.
Defaults to 256.

@end itemize

@lisp
(define a-vat (spawn-vat))
@end lisp

@end deffn

Sometimes, it is useful to make and manage a @emph{vat} at a slightly
lower level, such as when using Goblins with a foreign event loop (like
a GUI toolkit or game engine).  In such cases, @code{make-vat} comes
into play:

@deffn {Procedure} make-vat [#:name] [#:start] [#:halt] [#:send] @
                            [#:log?] [log-capacity]

Return a new vat named @var{name}.  Vat behavior is determined by
three event hooks, and logging is controlled by the remaining
arguments:

@itemize
@item
@var{start}: Procedure to start @emph{vat} process in non-blocking
manner such as a new thread.  Accepts a procedure which takes a
message as its single argument and churns the underlying
@emph{actormap} for the @emph{vat}.

@item
@var{halt}: Thunk to stop @emph{vat} process.

@item
@var{send}: Procedure accepting a ``vat envelope'' containing a
message to handle within the @emph{vat} process.  The envelope also
indicates if the caller wants a response, in which case the send
procedure must block until the message has been processed and return
the result.

@item
@var{log?}: If @code{#t}, event logging is enabled, otherwise it is
disabled (the default).

@item
@var{log-capacity}: Number of events to be retained in the log.
Defaults to 256.

@end itemize

Here is a pseudocode example illustrating the basic pattern:

@lisp
(define (make-custom-vat)
  (define thread #f)
  (define (start churn)
    (define (loop)
      (churn (dequeue-msg))
      (loop))
    (set! thread (call-with-new-thread loop)))
  (define (halt)
    (cancel-thread thread))
  (define (send envelope)
    (if (vat-envelope-return? envelope)
        (enqueue-and-wait-for-result envelope)
        (enqueue envelope)))
  (make-vat #:start start
            #:halt halt
            #:send send))
@end lisp

How to implement @code{enqueue-msg},
@code{enqueue-and-wait-for-result}, and @code{dequeue} depends on the
integration target and is left as an exercise for the implementer.

Custom vat implementations @emph{must} enqueue and dequeue messages in
a thread-safe manner because incoming messages from other vats may be,
and likely are, running in a different thread.

The above custom vat would be used like so:

@lisp
> (define custom-vat (make-custom-vat))
> (vat-start! custom-vat)
@end lisp

@end deffn

Custom vats are expected to handle ``vat envelope'' objects which
contain a message, a logical timestamp, and a flag indicating if the
sender wants to know the result of processing the message.

@deffn {Procedure} vat-envelope? obj

Return @code{#t} if @var{obj} is a vat envelope, or @code{#f}
otherwise.

@end deffn

@deffn {Procedure} vat-envelope-message envelope

Return the message contained in @var{envelope}.

@end deffn

@deffn {Procedure} vat-envelope-timestamp envelope

Return the logical timestamp for @var{envelope}.  This timestamp
indicates when @var{envelope} was sent from its origin vat.

@end deffn

@deffn {Procedure} vat-envelope-return? envelope

Return @code{#t} if the result of processing the message within
@var{envelope} should be returned to the caller who deposited the
envelope, or @code{#f} otherwise.  When @code{#t}, a custom vat
implementation @emph{must} block until a result can be returned to the
caller.  Notably, @code{call-with-vat} relies upon this behavior.

@end deffn

@node Using vats
@subsection Using vats

Regardless of whether a @emph{vat} is standard or custom, there are
several procedures supporting their use.

@deffn {Procedure} vat? obj

Return @code{#t} if @var{obj} is a @emph{vat}, else @code{#f}.

@end deffn

@deffn {Procedure} vat-name vat

Return the name of @var{vat}.

@end deffn

@deffn {Procedure} vat-running? vat

Return @code{#t} if @var{vat} is running, else @code{#f}.

@end deffn

@deffn {Procedure} vat-halt! vat

Stop processing @emph{turn}s for @var{vat}.

@end deffn

@deffn {Procedure} vat-start! vat

Start processing @emph{turn}s for @var{vat}.

@end deffn

@deffn {Procedure} call-with-vat vat thunk

Run @var{thunk} in the context of @var{vat} and return the resulting
values.

@lisp
(define a-vat (spawn-vat))
(call-with-vat a-vat
  (lambda ()
    (define an-object (spawn ^some-object))
    ($ an-object 'a-message an-arg)))
@end lisp

@end deffn

@deffn {Syntax} with-vat vat body @dots{}

Execute @var{body} in the context of @var{vat} and return the result.
This is syntax for @code{call-with-vat} so the user does not have to
write a separate lambda expression.

@end deffn

@deffn {Syntax} define-vat-run vat-run-id [vat (spawn-vat)]

This procedure is deprecated.

Return a procedure bound to @var{vat-run-id} accepting a body to be
evaluated in the context of @var{vat}.

@lisp
(define-vat-run run-in-vat)
(run-in-vat
  (define a-near-object (spawn ^some-object))
  (<- a-far-object 'some-message an-arg)
  ($ a-near-object 'some-message))
@end lisp

@end deffn

@node Actormaps
@section Actormaps

An @dfn{actormap} is the transactional data structure underlying
@emph{vat}s.  They are useful for building a custom event loop (such
as for a video game) or as a synchronous one-turn-at-a-time mapping of
actor references to their current behaviors.

@menu
* Actormaps overview::
* Actormap objects::
* Using actormaps::
@end menu

@node Actormaps overview
@subsection Actormaps overview

An @emph{actormap} is fundamentally a place in memory holding
references to objects so that they may be manipulated.  There are two
types of @emph{actormap}s: @dfn{whactormap}s, which use
@url{https://www.gnu.org/software/guile/manual/html_node/Weak-References.html, weak-key hash tables}
as the backing data structure so objects may be garbage collected
automatically, and which serve as the root of a generational
transaction history of @emph{actormap} actions; and
@dfn{transactormap}s, which are backed by standard hash tables and
constitute every other generation of a transaction history.  Aside
from their backing data structures and resulting use cases, all
@emph{actormap}s are very similar; @emph{transactormaps} simply also
hold a reference to a parent, which is either another
@emph{transactormap} or the root @emph{whactormap}.

The best way to understand @emph{actormap}s is by using them.  First,
create one:

@lisp
(define am (make-actormap))
@end lisp

@emph{Actormap}s need actors, so add a simple @code{cell}:

@lisp
(define lunchbox
  (actormap-spawn! am ^cell))
@end lisp

Actors can then be invoked, such as by @code{actormap-poke!}:

@lisp
> (actormap-poke! am lunchbox 'peanut-butter-and-jelly)
> (actormap-peek am lunchbox)
; => 'peanut-butter-and-jelly
@end lisp

For some situations, @code{actormap-poke!} and @code{actormap-peek}
can be interchanged, such as in this version of the above example:

@lisp
> (actormap-poke! am lunchbox 'bbq-tofu)
> (actormap-poke! am lunchbox)
; => 'bbq-tofu
@end lisp

For other situations, they cannot:

@lisp
> (actormap-peek am lunchbox 'chickpea-salad)
> (actormap-peek am lunchbox)
; => 'bbq-tofu
@end lisp

This is due to the @emph{transactional} nature of @emph{actormap}s.
In these examples, you can see that @code{actormap-poke!} returns a
value and commits changes to the transaction history, while
@code{actormap-peek} returns a value and throws away changes.  Both
of these procedures are conveniences over the more powerful and more
cumbersome @code{actormap-turn} family of procedures.

The next sections will cover these and related procedures in greater
detail.

@node Actormap objects
@subsection Actormap objects

At its base level, every @emph{actormap} is either a @emph{whactormap}
or a @emph{transactormap}, as discussed in the last section.

@deffn {Procedure} make-whactormap [#:vat-connector #f]

Return a reference to a new @emph{whactormap}.  @var{vat-connector}, if
provided, is the @emph{syscaller} for the containing @emph{vat}.

@end deffn

@deffn {Procedure} make-actormap

Return a reference to a new @emph{actormap}.  This is a convenience
wrapper around @code{make-whactormap}.

@lisp
(define an-actormap (make-actormap))
@end lisp

@end deffn

@deffn {Procedure} make-transactormap parent

Return a reference to a new @emph{transactormap} with @var{parent} as
its preceding generation.

@end deffn

The two types of @emph{actormap} have corresponding identity
predicates:

@deffn {Procedure} whactormap? obj

Return @code{#t} if @var{obj} is a @emph{whactormap}, else @code{#f}.

@end deffn

@deffn {Procedure} transactormap? obj

Return @code{#t} if @var{obj} is a @emph{transactormap}, else
@code{#f}.

@end deffn

@node Using actormaps
@subsection Using actormaps

As already shown, before using objects in an @emph{actormap}, one must
first create those objects in the context of that @emph{actormap}:

@deffn {Procedure} actormap-spawn actormap actor-constructor args @dots{}

Spawn an actor inside @var{actormap}, but do not commit the
transaction.  Return a reference to the spawned object and a
@emph{transactormap}.

@itemize
@item
@var{actor-constructor}: Constructor for the actor to be spawned.

@item
@var{args}: Arguments to @var{actor-constructor}.

@end itemize

@end deffn

@deffn {Procedure} actormap-spawn! actormap actor-constructor args @dots{}

Like @code{actormap-spawn}, but do commit the transaction.

@end deffn

@deffn {Procedure} actormap-spawn-named actormap name actormap-constructor args @dots{}

Like @code{actormap-spawn}, but uses @var{name} as the debug name for the object
reference.

@end deffn

@deffn {Procedure} actormap-spawn-named! actormap name actormap-constructor args @dots{}

Like @code{actormap-spawn!}, but uses @var{name} as the debug name for the
object reference.

@end deffn

Once objects have been put into an @emph{actormap}, they may be
invoked to perform some action .  There are several ways to do this,
falling into one of two general categories: @emph{turn}s and
@emph{churn}s.  A @dfn{turn} is the processing of a single message.  A
turn may generate additional @emph{near} or @emph{far} messages to be
dispatched afterwards.  A @dfn{churn} starts with a turn but then
takes additional turns to process all subsequent near messages (which
may in turn generate even more messages), halting when only far
messages remain.  In other words, a churn is a loop that takes one or
more turns until it reaches @emph{quiescence}.

@deffn {Procedure} actormap-turn* actormap to-refr args

Perform a single turn in @var{actormap} by invoking @var{to-refr}
with the list of arguments @var{args}.  Return the result of the
invoked behavior, a new @emph{actormap}, and a list of new messages
generated by the turn.

@end deffn

@deffn {Procedure} actormap-turn actormap to-refr args @dots{}

Like @code{actormap-turn*}, but create a new generation of
transaction with @var{actormap} as the parent and operate in it
instead.

@end deffn

@deffn {Procedure} actormap-turn-message actormap msg @
       [#:error-handler simple-display-error] [#:reckless? #f] @
       [#:catch-errors? #t]

Return the result of @var{msg} in the context of @var{actormap}.
How to handle errors and transactions is controlled by keyword args:

@itemize
@item
@var{error-handler}: Procedure to handle errors.  It is passed
@var{msg}, the error, and the stack at the time of the error.

@item
@var{reckless?}: If @code{#t}, operate within @var{actormap} instead
of creating a new generation; otherwise, create a new generation.

@item
@var{catch-errors?}: If @code{#t}, capture the stack and abort to a
prompt; otherwise, propagate the error.

@end itemize

@end deffn

@deffn {Procedure} actormap-peek actormap to-refr args @dots{}

Perform a turn in @var{actormap} only to return the results; do not
commit the transaction to the transaction history.

@itemize
@item
@var{to-refr}: Object to be invoked.

@item
@var{args}: Arguments passed to @var{to-refr}.

@end itemize

@end deffn

@deffn {Procedure} actormap-poke! actormap to-refr args @dots{}

Perform a turn in @var{actormap} and commit the results, but ignore
any messages generated by it.  Return the results.

@itemize
@item
@var{to-refr}: Object to be invoked.

@item
@var{args}: Arguments passed to @var{to-refr}.

@end itemize

@end deffn

@deffn {Procedure} actormap-reckless-poke! actormap to-refr args @dots{}

Like @code{actormap-poke!}, but commit the results to the current
transaction generation without creating a new one.  This voids
Goblin's transactionality guarantees like time travel.

@end deffn

@deffn {Procedure} actormap-run actormap thunk

Execute @var{thunk} in @var{actormap}, but do not commit the results.
Return the results.

@end deffn

@deffn {Procedure} actormap-run! actormap thunk [#:reckless? #f]

Like @code{actormap-run}, and commit the results.  If @var{reckless?}
is @code{#t}, do not create a new generation for the turn.

@end deffn

@deffn {Procedure} actormap-run* actormap thunk

Like @code{actormap-run}, and return a reference to the new
@emph{actormap} as well as any messages generated.

@end deffn

@deffn {Procedure} actormap-churn am msg [#:catch-errors? #t] @
       [#:make-transactormap? #t]

Perform every turn in @var{am} possible without needing to invoke
@emph{far} objects to resolve @var{msg}, then dispatch messages to
the appropriate @emph{far} objects.

@itemize
@item
@var{catch-errors?}: If @code{#f}, do not handle errors.

@item
@var{make-transactormap?}: If @code{#f}, operate and commit in
@var{am} instead of creating a new generation.

@end itemize

@end deffn

@deffn {Procedure} actormap-churn-run actormap thunk @
       [#:catch-errors? #t]

Evaluate @var{thunk} in the context of @var{actormap}, performing all
possible local invocations to resolve @var{thunk}.  If
@code{catch-errors?} is @code{#f}, do not handle errors.  Return the
results, a reference to the new actormap, and any messages generated.

@end deffn

@deffn {Procedure} actormap-churn-run! actormap thunk @
       [#:catch-errors? #t]

Like @code{actormap-churn-run}, but dispatch messages and only return
the results of the @emph{churn}.

@end deffn

When performing any action in a @emph{transactormap}, one may wish to
(but, as has been shown, does not have to) commit the changes to the
generational history of the overarching @emph{actormap}.

@deffn {Procedure} transactormap-merge! transactormap

Commit the changes in @var{transactormap} to the generational history.

@end deffn

@deffn {Procedure} transactormap-buffer-merge! transactormap

Commit the changes in @var{transactormap} to its parent.

@end deffn

@node Misc
@section Misc

@deffn {Syntax} migrations ((version data @dots{}) expr) @dots{}

Syntax to describe a collection of migrations to be used to be applied in order
to upgrade some data to a newer version. This is designed to be used with the
persistence system e.g. to upgrade actor portrait data or graph roots. However,
it is generic enough to be used elsewhere.

The @code{migrations} syntax will generate a procedure with the signature
@code{(lambda (prev-version data ...) ...)} and will return two values, the
version its migrated to and the new data.

@lisp
(define my-migrations
  (migrations
    ;; Version 0 -> 1: ignore what I'm given and return 'i-am-version-1
    [(1 something) (list 'i-am-version-1)]
    ;; Version 1 -> 2: provide two values, 'i-am-version-2 and the something I got
    [(2 something) (list 'i-am-version-2 something)]
    ;; Version 2 -> 3: Swap the two values around
    [(3 something something-else) (list something-else something)]))
@end lisp

When the upgrade procedure is called, it would return version 3 (as it
ran the version 2 migration and so the new version is the next
version, version 3). It'd also return the new data which would be a
list of @code{('i-am-version-1 'i-am-version-2)}.

@end deffn
