The Goblins actor library, in the @code{(goblins actor-lib ...)}
module namespace, provides implementations for a variety of common
actor model patterns.

@menu
* Cell::
* Common::
* Facet::
* Inbox::
* IO::
* Joiners::
* On::
* Methods::
* Nonce Registry::
* Opportunistic::
* Pubsub::
* Pushdown::
* Queue::
* Sealers::
* Selfish-Spawn (Deprecated)::
* Simple Mint::
* Swappable::
* Ticker::
* Timers::
* Ward::
@end menu

@node Cell
@section Cell

The @code{(goblins actor-lib cell)} module provides a very handy actor
called a ``cell.''  Cells are used to store arbitrary data.  It also
provides some helper functions for cells.

@deffn {Constructor} ^cell bcom [val #f]

Construct an actor which contains @var{val} or @code{#f} if @var{val}
is not provided.

@lisp
> (define empty-chest (spawn ^cell))
> (define chest (spawn ^cell 'gold))
@end lisp

Cells have two possible invocations: with no arguments, which returns
the current value; and with one argument, which sets a new value and
returns nothing.

@lisp
> ($ chest)
=> 'gold
> ($ chest 'sword)
> ($ chest)
=> 'sword
@end lisp

@end deffn

@deffn {Procedure} cell->read-only cell

Create and return a read-only proxy to @var{cell}. It is an error to
attempt to write to such a cell.

@lisp
> (define ro-chest (cell->read-only chest))
> ($ ro-chest)
=> 'sword
> ($ ro-chest 'wand)
=> error: ...
@end lisp

@end deffn

@deffn {Procedure} cell->write-only cell

Create and return a write-only proxy to @var{cell}. It is an error to
attempt to read from such a cell.

@lisp
> (define wo-chest (cell->write-only chest))
> ($ wo-chest 'wand)
> ($ wo-chest)
=> error: ...
@end lisp

@end deffn

@deffn {Syntax} define-cell id [val #f]

Syntax for creating a cell using a form like Scheme @code{define}.

@lisp
> (define-cell chest 'gold)
> ($ chest)
=> 'gold
@end lisp

@end deffn

@defvr {Persistence Environment} cell-env
@end defvr

@node Common
@section Common

The @code{(goblins actor-lib common)} module provides actors wrapping
functional data structures, allowing Goblins transactionality
guarantees while providing an apparently mutable interface.

@deffn {Constructor} ^seteq bcom initial @dots{}

Construct an actor representing a set (each member is unique).  A
@code{seteq} has four methods:

@itemize
@item
@code{add val}: Add @var{val} to the set.

@item
@code{remove val}: Remove @var{val} from the set.

@item
@code{member? val}: Return @code{#t} if @var{val} is in the set, else
@code{#f}.

@item
@code{as-list}: Return a representation of the set as a Scheme list.
Note that the order of items in the list is not specified.

@end itemize

@lisp
> (define a-set (spawn ^seteq 'a 'b 'c))
> ($ a-set 'as-list)
=> (a b c)
> ($ a-set 'member? 'c)
=> #t
> ($ a-set 'member? 'f)
=> #f
> ($ a-set 'add 'f)
> ($ a-set 'remove 'b)
> ($ a-set 'as-list)
=> (f c a)
@end lisp

@end deffn

@deffn {Constructor} ^ghash bcom [ht ghash-null]

Construct an actor representing a hashtable using @code{eq?} for
key lookup and @code{equal?} for other comparisons.  @var{ht}, if
provided, is the underlying @code{ghash} to use as the starting state.
See @code{(goblins ghash)} module for the compatible hashtable
implementation.

A @code{ghash} actor has five methods:

@itemize
@item
@code{ref key [dflt #f]}: Return the value associated with @var{key},
or @var{dflt} if the key is not found.

@item
@code{set key val}: Add @var{key} to the @code{ghash} and associate it
with @var{val}.

@item
@code{remove key}: Delete @var{key} and its associated value from the
@code{ghash}.

@item
@code{data}: Return the underlying @code{ghash}.

@item
@code{has-key? key} (Deprecated): Return @code{#t} if @var{key} is in the
@code{ghash}; otherwise return @code{#f}.

This method is deprecated. Instead use the @code{ref} method checking against
the @code{dflt} value if needed.
@end itemize

@lisp
> (define ag (spawn ^ghash))
> ($ ag 'set "dog" "animal")
> ($ ag 'set "cesna" "plane")
> ($ ag 'data)
=> $<ghash (2)>
> ($ ag 'ref "cesna")
=> "plane"
> ($ ag 'remove "cesna")
> ($ ag 'ref "cesna")
=> #f
> ($ ag 'ref "cesna" 'missing)
=> missing
> ($ ag 'data)
=> $<ghash (1)>
@end lisp
@end deffn

@deffn {Constructor} ^vector size [fill]

Construct an actor providing an actor interface to a vector of size @var{size}
and with initial values of @var{fill}.

The actor has the following methods:

@itemize
@item
@code{ref index}: Return the value at @var{index}.
@item
@code{set index new-value}: Set the value at @var{index} to @var{new-value}.
@item
@code{length}: Return the length of the vector.
@item
@code{as-list}: Return the values within the vector as a list.
@item
@code{resize new-size [fill]}: Resize the vector to @var{new-size}. If the
vector grows, then the new elements will be filled with @var{fill}.
@item
@code{fill new-fill-value}: Fill all elements in the vector with
@var{new-fill-value}.
@end itemize

@lisp
> (define vec (spawn ^vector 5))
> ($ vec 'length)
=> 5
> ($ vec 'set 0 'apple)
> ($ vec 'set 1 'banana)
> ($ vec 'set 2 'pear)
> ($ vec 'set 3 'grapes)
> ($ vec 'set 4 'kiwi)
> ($ vec 'as-list)
=> (apple banana pear grapes kiwi)
> ($ vec 'resize 3)
> ($ vec 'ref 0)
=> apple
@end lisp
@end deffn

@defvr {Persistence Environment} common-env
@end defvr

@node Facet
@section Facet

The @code{(goblins actor-lib facet)} module provides an actor to wrap
another object and only allow certain methods through.  It also
provides a convenience function for constructing such actors.

@deffn {Constructor} ^facet bcom wrap-me [methods @dots{}]

Construct a proxy of the actor @var{wrap-me} with access to only
@var{methods}, a list of symbols corresponding to methods of
@var{wrap-me}.  The @var{wrap-me} will be invoked with @code{$} if
possible, and otherwise will be invoked with @code{<-}.  For cases
where synchronicity is possible but not desired, invoking the
@code{facet} asynchronously has the same effect as invoking
@var{wrap-me} asynchronously.

@end deffn

@deffn {Procedure} facet wrap-me [methods @dots{}]

Spawn and return a reference to a @code{^facet}, passing along
arguments to their equivalents in the constructor.

@end deffn

@defvr {Persistence Environment} facet-env
@end defvr

@node Inbox
@section Inbox

The @code{(goblins actor-lib inbox)} module provides an inbox actor
that serves as a message queue.  Messages can be written to and read
from the inbox.  The inbox can be also be closed to prevent further
messages from accumulating.

When a message is read from the inbox it will return the next message
if available. If no message is available it will return a promise. If
the inbox is stopped it'll break all pending unfulfilled promises.

@deffn {Procedure} spawn-inbox
Spawns a new inbox, returning three actors: read, write, and stop actor.

@lisp
(use-modules (goblins)
             (goblins actor-lib inbox))

(define-values (inbox outbox stop)
  (spawn-inbox))

(define vow-to-first
  ($ inbox))

($ outbox 'first)
($ outbox 'second)

(on vow-to-first pk)
;;; (first)

(pk ($ inbox))
;;; (second)

(define vow-to-third (<- inbox))
($ stop)
(on vow-to-third #:catch (lambda (err) (pk 'err err)))
;;; (err inbox-closed)
@end lisp

@end deffn

@defvr {Persistence Environment} inbox-env
@end defvr

@node IO
@section IO

The @code{(goblins actor-lib io)} module provides a mechanism for
operating on external IO resources in a way which abstracts away
Fibers details such that the user can operate mostly in a
Goblins-oriented interface.

More specific IO interfaces for files, general ports, etc will be
provided in the future, but the mechanism provided by this library
is general enough to fit most use cases.

@deffn {Constructor} ^io _bcom wrapped @
                         [#:init #f] [#:cleanup #f]

Spawns an object which itself spawns a Fibers fiber which wraps
@var{wrapped}.  If @var{init} is provided with a procedure, fiber
will invoke said procedure with @var{wrapped} as the sole argument
before looping over any provided commands.

Invoking the spawned object returns a promise, and said procedure is
executed within the managed fiber's loop.  Any return value will
fulfill as a value for the returned promise, and any exception raised
will break the promise with said exception.

If the object spawned by @var{^io} is invoked with the symbol
@code{'halt}, the fiber will be shut down and will stop responding to
further incoming messages, and @var{cleanup} will be run within the
fiber with the sole argument being @var{wrapped}.  (In the future,
if the reference to the spawned object is garbage collected, the fiber
will be automatically halted.)

As an example:

@lisp
> (use-modules (goblins)
               (goblins actor-lib io)
               (ice-9 textual-ports))
> (define a-vat (spawn-vat #:name 'a))
> ,enter-vat a-vat
goblins/a [1]> (define wraps-input
                 (spawn ^io (open-input-string "Hello!")
                        ;; burns one character off the top
                        #:init get-char))
goblins/a [1]> (on (<- wraps-input get-char)
                   (lambda (c) (format #t "Got: ~a\n" c)))
Got: e
goblins/a [1]> (on (<- wraps-input get-char)
                   (lambda (c) (format #t "Got: ~a\n" c)))
Got: l
goblins/a [1]> (on (<- wraps-input get-char)
                   (lambda (c) (format #t "Got: ~a\n" c)))
Got: l
goblins/a [1]> (on (<- wraps-input get-char)
                   (lambda (c) (format #t "Got: ~a\n" c)))
Got: o
@end lisp

@end deffn

@deffn {Constructor} ^read-write-io _bcom wrapped @
                                    [#:init #f] [#:cleanup #f]

Spawn a read and write interface for running commands over WRAPPED

Like the ^io object, this spawns a separate fiber which processes one
command at a time. This however allows for both reading and writing by
having a 'read method (taking in a procedure as its only argument),
and a 'write method (also taking a single procedure as its only
argument). You can read and write at the same time to the same WRAPPED
resource without blocking the other.

Like ^io, this supports a 'halt method which stops both fibers and
runs any CLEANUP provided.

@end deffn

Note that currently the io actor is not persistence aware and so
cannot appear in a persistence graph.

@node IO Ping Tutorial
@subsection IO Ping Tutorial

This tutorial builds up a simple echo server and client using Goblins'
IO objects. The general way the server works is it has an initial
@code{^ping-server} object which sets up a socket to bind to an IP and
port, it then listens for new connections and for each new connection
spawns a @code{^server-client}. The @code{^server-client} reads a line
on the socket and writes what it read back to the socket.

Similarly, for the client, there is a @code{^echo-client}; this takes
an IP and port to connect to and spawns a socket. Its behavior is
that it takes a message which it writes to the socket and then hands
back a promise to the line it reads back from the socket.

The original ping server in the Fibers manual can be found here:
@uref{https://github.com/wingo/fibers/wiki/Manual#41-ping}).

The server:
@lisp
(use-modules (rnrs bytevectors)
             (ice-9 textual-ports)
             (ice-9 rdelim)
             (ice-9 match)
             (goblins)
             (goblins actor-lib io)
             (goblins actor-lib methods)
             (fibers conditions))

(define (create-non-blocking-socket)
  "Returns a socket configured for non-blocking interaction"
  (let ((sock (socket PF_INET SOCK_STREAM 0)))
    (fcntl sock F_SETFL (logior O_NONBLOCK (fcntl sock F_GETFL)))
    sock))

(define (setup-socket-to-listen! sock address port)
  "Sets up the socket to listen to given ADDRESS and PORT"
  (setsockopt sock SOL_SOCKET SO_REUSEADDR 1)
  (fcntl sock F_SETFD FD_CLOEXEC)
  (bind sock AF_INET (inet-pton AF_INET address) port)
  (listen sock 1024)
  (sigaction SIGPIPE SIG_IGN))

(define (^ping-server _bcom)
  (define sock
    (spawn ^io (create-non-blocking-socket)
           #:init
           (lambda (port)
             ;; This blocks so we want to do it in the #:init
             ;; code as that happens inside the ^io event loop.
             (setup-socket-to-listen! port "127.0.0.1" 11211))
           #:cleanup
           (lambda (port)
             (close port))))

  (define (socket-loop)
    "Accept a new connection and spawn a ^client-server for it"
    (on (<- sock (lambda (port)
                   (accept port SOCK_NONBLOCK)))
        (lambda (client-sock-pair)
          (match client-sock-pair
            [(client-sock . addr)
             (spawn ^server-client client-sock)]))
        #:finally socket-loop))

  ;; Kick off the socket loop
  (socket-loop)

  (methods
   [(shutdown)
    ($ sock 'halt)]))

(define (^server-client _bcom port)
  (define sock
    (spawn ^read-write-io port
           #:init (lambda (port)
                    (setvbuf port 'block 1024)
                    ;; Disable Nagle's algorithm. We buffer ourselves.
                    (setsockopt port IPPROTO_TCP TCP_NODELAY 1))
           #:cleanup (lambda (port)
                       (close port))))
  (define (read-and-reply-loop)
    (on (<- sock 'read read-line)
        (lambda (line)
          (match line
            [(? eof-object?) ($ sock 'halt)]
            [other
             (<-np sock 'write
                   (lambda (port)
                     (put-string port other)
                     (put-char port #\newline)
                     (force-output port)))
             (read-and-reply-loop)]))))

  ;; Kick off loop
  (read-and-reply-loop)
  (methods
   [(shutdown)
    ($ sock 'halt)]))

;; Setup a vat and spawn the server
(define server-vat
  (spawn-vat #:name "server-vat"))
(with-vat server-vat
  (spawn ^ping-server))
@end lisp

The Client:
@lisp
;; Same as above:
(define (create-non-blocking-socket)
  "Returns a socket configured for non-blocking interaction"
  (let ((sock (socket PF_INET SOCK_STREAM 0)))
    (fcntl sock F_SETFL (logior O_NONBLOCK (fcntl sock F_GETFL)))
    sock))

(define (setup-socket-to-connect! sock addr port)
  (let ((connection-info (car (getaddrinfo addr (number->string port)))))
    ;; Disable Nagle's algorithm.  We buffer ourselves.
    (setsockopt sock IPPROTO_TCP TCP_NODELAY 1)
    (setvbuf sock 'block 1024)
    (connect sock (addrinfo:addr connection-info))))

(define (^echo-client _bcom to-address to-port)
  (define sock
    (spawn ^read-write-io (create-non-blocking-socket)
           #:init
           (lambda (port)
             (setup-socket-to-connect! port to-address to-port))
           #:cleanup
           (lambda (port)
             (close port))))

  (lambda (msg)
    ($ sock 'write
       (lambda (port)
         (put-string port msg)
         (put-char port #\newline)
         (force-output port)))
    (<- sock 'read get-line)))

(define client-vat
  (spawn-vat #:name "client-vat"))
(define echo-client
  (with-vat client-vat
    (spawn ^echo-client "127.0.0.1" 11211)))
@end lisp

Finally, lets try this:
@lisp
,enter-vat client-vat
goblins[1]> (define reply-vow
              (<- echo-client "Hello world!"))
goblins[1]> ,vat-resolve reply-vow
"Hello world!"
@end lisp

@node Joiners
@section Joiners

The @code{(goblins actor-lib joiners)} module provides a means of
combining the results of many promises.

@deffn {Procedure} all-of promises @dots{}

Return a promise which resolves on resolution of all @var{promises}.

As an example, suppose there is an actor which waits for a period of
time before returning whatever it received:

@lisp
> (define (^procrastinator bcom delay)
    (lambda (x)
      (sleep delay)
      x))
@end lisp

@code{all-of} can wait for all procrastinators to finish before
writing some output:

@lisp
> (define a-vat (spawn-vat))
> (define b-vat (spawn-vat))
> (define c-vat (spawn-vat))
> (define p1 (with-vat b-vat (spawn ^procrastinator 1)))
> (define p2 (with-vat c-vat (spawn ^procrastinator 2)))
> (with-vat a-vat
    (on (all-of (<- p1 'foo) (<- p2 'bar))
        (lambda (items)
          (display items)
          (newline))))
; (foo bar)
@end lisp

@end deffn

@deffn {Procedure} all-of* promises

Like @code{all-of}, but @var{promises} is a list of promises.

@end deffn

@deffn {Procedure} race promises @dots{}
Return a promise which resolves when the first promise in
@var{promises} settles.  If that promise is broken then so is the
returned promise.

Suppose we'd like to talk to an actor named @code{slowpoke}.  However,
as the name implies, @code{slowpoke} doesn't always respond in a
timely manner.  Suppose also that we had another actor named
@code{timeout} that responds after a specified amount of time has
passed.  We can use @code{race} to wait for @code{slowpoke} but give
up after awhile and move on:

@lisp
;; Say "hey" to slowpoke, but only wait a minute for their response.
(race (<- slowpoke 'hey) (<- timeout 60))
@end lisp

@end deffn

@node On
@section On

The @code{(goblins actor-lib on)} module provides convenient syntax to
facilitate promise pipelining.

@deffn {Syntax} let-on ((var exp) @dots{}) body

Syntax sugar around @code{on}, @code{all-of}, @code{lambda}, and
@code{match-lambda} to allow using promise pipelining with a
@code{let}-like syntax.  Each @var{exp} (an asynchronous invocation of
an actor resulting in a promise) is evaluated concurrently; the
resulting promises are bound to their corresponding @var{var}s; and
finally @var{body} is evaluated in an environment where all promises
are resolved.

For example, given a @code{doubler} object defined as:

@lisp
(define (^doubler bcom)
  (lambda (x)
    (* x 2)))
(define doubler (spawn ^doubler))
@end lisp

This use of @code{let-on}@dots{}

@lisp
(let-on ((four (<- doubler 2))
         (eight (<- doubler 4)))
  (+ four eight))
@end lisp

is equivalent to@dots{}

@lisp
(use-modules (goblins actor-lib joiners))
(on (all-of (<- doubler 2)
            (<- doubler 4))
  (match-lambda*
    ((four eight)
     (+ four eight))))
@end lisp

@end deffn

@deffn {Syntax} let*-on ((var exp) @dots{}) body

Like @code{let-on}, except paralleling @code{let*}; each @var{exp} is
resolved @emph{sequentially} rather than concurrently, and each
@code{var} is available in the body of the succeeding @var{exp}s.
This is equivalent to nested @code{on} and @code{lambda} calls, without
using @code{match-lambda} or @code{all-of}.

So this use of @code{let*-on}@dots{}

@lisp
(let*-on ((four (<- doubler 2))
          (eight (<- doubler four)))
  (+ four eight))
@end lisp

@dots{}is equivalent to@dots{}

@lisp
(on (<- doubler 2)
    (lambda (four)
      (on (<- doubler four)
          (lambda (eight)
            (+ four eight))
          #:promise? #t))
    #:promise? #t)
@end lisp

@end deffn

@deffn {Procedure} on-each proc vow

This procedure is equivalent to an @code{on} with @var{vow}, where
@var{vow} resolves to a list, then doing a @code{for-each} with
@var{proc} and the resolved value. It does not return any values to
the caller.

@lisp
(define my-cell (spawn ^cell (list 1 2 3)))
(on-each pk (<- my-cell))
;;; (1)
;;; (2)
;;; (3)
@end lisp

@end deffn

@deffn {Procedure} on-map proc vow

This procedure is equivalent to an @code{on} with @var{vow}, where
@var{vow} resolves to a list, then doing a @code{map}. @var{proc} will
be invoked with each value in the list. The procedure will return a
promise which will resolve to the return value of @code{map}.

@lisp
(define my-cell (spawn ^cell (list 1 2 3)))
(define (double n) (* n 2))
(define doubled-numbers-vow
  (on-map double (<- my-cell)))
(on doubled-numbers-vow pk)
;;; ((2 4 8))
@end lisp

@end deffn

@deffn {Procedure} on-filter pred vow

This procedure is equivalent to an @code{on} with @var{vow}, where
@var{vow} resolves to a list, then doing a @code{filter}. @var{pred}
will be applied with each value in the list to determine if they will
appear in the result. The procedure will return a promise which will
resolve to the return value of the @code{filter}.

@lisp
(define my-cell (spawn ^cell (list 1 2 3 4)))
(define even-numbers-vow
  (on-filter even? (<- my-cell)))
(on even-numbers-vow pk)
;;; ((2 4))
@end lisp

@end deffn

@deffn {Syntax} on-match vow match-clause @dots{}

This is syntax sugar around @code{on}, @code{match-lambda} to allow
for easier matching on the result of promise values. It's equivalent
to doing an @code{on} with @var{vow} where the on handler is a
@code{match-lambda} with @var{match-clause}s.

@lisp
(define my-cell (spawn ^cell (list 'result 42)))
(define my-result-vow
  (on-match (<- my-cell)
    (('result some-result) some-result)
    (('no-result) (error "Got no result"))))
(on my-result-vow pk)
;;; (42)
@end lisp

@end deffn

@node Methods
@section Methods

The @code{(goblins actor-lib methods)} module provides a simple,
single-dispatch method system for actor behaviors.

@deffn {Syntax} methods ((name args @dots{}) expr) @dots{}

Syntax to describe a collection of methods that an actor accepts.
@var{name} is the symbol upon which the method dispatches, @var{args}
are the arguments it accepts, and @var{expr} is the expression
evaluated when the method is called.

As an example, consider this actor capable of saying hello or goodbye:

@lisp
> (define (^hello-goodbye _bcom)
    (methods
     ((say-hello name)
      (format #f "Hello, ~a!" name))
     ((say-goodbye name)
      (format #f "Goodbye, ~a!" name))))
> (define hello-goodbye (spawn ^hello-goodbye))
> ($ hello-goodbye 'say-hello "Alice")
=> "Hello, Alice!"
> ($ hello-goodbye 'say-goodbye "Alice")
=> "Goodbye, Alice!"
@end lisp

@end deffn

@deffn {Syntax} extend-methods extends ((name args @dots{}) expr) @dots{}

Syntax to expand a collection of methods or an actor @var{extends}.
@var{name}, @var{args}, and @var{expr} are as in @code{methods}.

So this would allow extending the previous example with a method to
ask how the caller is:

@lisp
> (define hello-goodbye-how-are-you
    (extend-methods hello-goodbye
      ((how-are-you name)
       (format #f "How are you, ~a?" name))))
> (hello-goodbye-how-are-you 'how-are-you "Alice")
=> "How are you, Alice?"
@end lisp

You may notice that when extending a live reference, the result is not
a reference to an actor, but rather a procedure which invokes the
original actor.  @code{extend-methods} can also be used to extend
methods directly, as in:

@lisp
> (define behs (methods
                 ((say-hello)
                  (format #f "Hello!"))
                 ((say-goodbye)
                  (format #f "Goodbye!"))))
> (define new-behs (extend-methods behs
                     ((how-are-you)
                      (format #f "How are you?"))))
> (define (^hello-goodbye-how-are-you bcom)
    new-behs)
> (define hello-goodbye-how-are-you
    (spawn ^hello-goodbye-how-are-you))
> ($ hello-goodbye-how-are-you 'how-are-you)
=> "How are you?"
@end lisp

@end deffn

@node Nonce Registry
@section Nonce Registry

The @code{(goblins actor-lib nonce-registry)} module provides an actor
to store and retrieve references using @emph{swiss-num}s.  A
@dfn{swiss-num} is a string of digits which grants anyone with that
string of digits access to whatever it refers to, much as a Swiss bank
account number grants access to the bank account (hence the name).

@deffn {Procedure} spawn-nonce-registry-and-locator

Create and return, as @code{values}, an actor which registers and an
actor which locates objects using Swiss nums.

The first returned value, the @code{registry}, has two methods:
@code{register}, which accepts an object reference and an optional
@emph{swiss-num}, and returns the @emph{swiss-num}; and @code{fetch},
which accepts a @emph{swiss-num} and returns a reference to the
appropriate object.  The second returned value, the @code{locator},
only has one method, @code{fetch}, which operates exactly the same as
that of @code{registry}.

To clarify, here's an example:

@lisp
> (use-modules (goblins actor-lib cell))
> (define-values (nr nr-locator) (spawn-nonce-registry-and-locator))
> nr
=> #<local-object ^nonce-registry>
> (define chest (spawn ^cell 'gold))
> (define chest-token ($ nr 'register chest))
> chest-token
=> #vu8(<32 random 8-bit unsigned integers>)
> ($ nr 'fetch chest-token)
=> #<local-object ^cell>
> ($ nr-locator 'fetch chest-token)
=> #<local-object ^cell>
@end lisp

@end deffn

@defvr {Persistence Environment} nonce-registry-env
@end defvr

@node Opportunistic
@section Opportunistic

The @code{(goblins actor-lib opportunistic)} module provides
procedures to choose synchronous invocation if possible and fallback
to asynchronous invocation only if necessary.

@deffn {Procedure} select-$/<- to-refr

If the actor @var{to-refr} is a @emph{near} object, return @code{$};
otherwise, return @code{<-}.

@end deffn

@deffn {Procedure} run-$/<- to-refr args @dots{}

Invoke the actor @var{to-refr} with the arguments @var{args} using
@code{$} if it is a @emph{near} object and otherwise using @code{<-}.

@lisp
> (define a-vat (spawn-vat))
> (define b-vat (spawn-vat))
> (define a-chest (with-vat a-vat
                    (spawn ^cell 'sword)))
> (with-vat a-vat
    (run-$/<- a-chest))
=> 'sword
> (with-vat b-vat
    (run-$/<- a-chest))
=> #<local-promise>
@end lisp

@end deffn

@node Pubsub
@section Pubsub

The @code{(goblins actor-lib pubsub)} module provides an actor to
publish messages to a set of other, subscribed actors.

@deffn {Constructor} ^pubsub bcom initial-subscribers @dots{}

Construct an actor with references to the other actors
@var{initial-subscribers} and which has the following methods:

@itemize
@item
@code{subscribe subscriber}: Add @var{subscriber} to the list of
subscribed actors.

@item
@code{unsubscribe subscriber}: Remove @var{subscriber} from the list
of subscribed actors.

@item
@code{publish args ...}: Invoke all subscribers with the arguments
@var{args}.

@item
@code{subscribers}: Return a list of all subscribed actors.

@end itemize

@lisp
> (use-modules (goblins actor-lib cell))
;; enter a vat
> (define a-chest (spawn ^cell 'sword))
> (define b-chest (spawn ^cell 'gold))
> (define c-chest (spawn ^cell 'wand))
> (define pubsub (spawn ^pubsub a-chest b-chest))
> ($ pubsub 'subscribers)
=> (#<local-object ^cell> #<local-object ^cell>)
> ($ pubsub 'publish 'boots)
=> #t
> ($ a-chest)
=> 'boots
> ($ b-chest)
=> 'boots
> ($ pubsub 'subscribe c-chest)
> ($ pubsub 'subscribers)
=> (#<local-object ^cell> #<local-object ^cell> #<local-object ^cell>)
> ($ pubsub 'unsubscribe b-chest)
> ($ pubsub 'publish 'crown)
=> #t
> ($ a-chest)
=> 'crown
> ($ b-chest)
=> 'boots
> ($ c-chest)
=> 'crown
@end lisp

@end deffn

@defvr {Persistence Environment} pubsub-env
@end defvr

@node Pushdown
@section Pushdown

The @code{(goblins actor-lib pushdown)} module provides actors
representing
@uref{https://en.wikipedia.org/wiki/Pushdown_automaton,pushdown automata}.

@deffn {Procedure} spawn-pushdown-pair [initial-refr #f]

Return a @code{pd-stack} and @code{pd-forwarder} as @code{values},
which together represent a pushdown automaton.  @var{initial-refr}, if
provided, is the initial object on the stack.

A @code{pd-stack} has four methods:

@itemize
@item
@code{push refr}: Add @var{refr} to the top of the stack.

@item
@code{spawn-push constructor args ...}: Spawn the actor constructed by
@var{constructor}, passing the current top of the stack and the
arguments @var{args} to the constructor; then add the new actor to
the top of the stack.  Return a reference to the new actor.  This
method facilitates implementing the
@uref{https://gameprogrammingpatterns.com/state.html,State} design
pattern.

@item
@code{pop}: Return the top of the stack.  Calling @code{pop} on an
empty stack is an error.

@item
@code{empty?}: Return @code{#t} if the stack is empty, else @code{#f}.

@end itemize

A @code{pd-forwarder} simply invokes the top actor of the stack with
whatever arguments it is passed.

@lisp
> (use-modules (goblins actor-lib cell))
;; enter a vat
> (define a-chest (spawn ^cell 'sword))
> (define b-chest (spawn ^cell 'gold))
> (define-values (pd-stack pd-forwarder)
    (spawn-pushdown-pair a-chest))
> ($ pd-forwarder)
=> 'sword
> ($ pd-stack 'push b-chest)
> ($ pd-forwarder 'wand)
> ($ b-chest)
=> 'wand
> ($ pd-stack 'spawn-push ^cell)
=> #<local-object ^cell>
> ($ pd-forwarder)
=> #<local-object ^cell>
> ($ ($ pd-forwarder))
=> 'wand
> ($ pd-stack 'pop)
=> #<local-object ^cell>
> ($ pd-stack 'empty?)
=> #f
@end lisp

@end deffn

@defvr {Persistence Environment} pushdown-env
@end defvr

@node Queue
@section Queue

The @code{(goblins actor-lib queue)} module provides a FIFO queue.

@deffn {Constructor} ^queue bcom

Constructs a FIFO queue actor which has the following methods:

@itemize

@item
@code{length}: Return the length of the queue.

@item
@code{empty?}: Return @code{#t} if the queue is empty, @code{#f} otherwise.

@item
@code{enqueue val}: Pushes @code{val} onto the queue.

@item
@code{dequeue}: Removes and returns the oldest inserted value from the queue.

@end itemize

@end deffn

@defvr {Persistence Environment} queue-env
@end defvr

@node Ring Buffer
@section Ring Buffer

The @code{(goblins actor-lib ring-buffer)} module provides an actor implementing
a ring buffer data structure.

@deffn {Constructor} ^ring-buffer capacity

Construct new ^ring-buffer actor with a capacity of @var{capacity}.

The actor has the following methods:

@itemize
@item
@code{empty?}: Return @code{#t} if ring buffer is empty.
@item
@code{full?}: Return @code{#t} if ring buffer is full.
@item
@code{capacity}: Return the capacity of the ring buffer.
@item
@code{length}: Return the number of items currently stored in the ring buffer.
@item
@code{put value}: Append @var{value} to the ring buffer.
@item
@code{take}: Dequeue an item from the ring buffer.
@item
@code{ref index}: Return the item @var{index} within the ring buffer.
@item
@code{head amount}: Return up to @var{amount} items from the front of the ring
buffer (i.e. the oldest items).
@item
@code{tail amount}: Return up to @var{amount} items from the end of the ring
buffer (i.e. the newest items).
@item
@code{resize new-capacity}: Resizes the ring buffer to have a new
capacity of @var{new-capacity}. If the @var{new-capacity} is smaller than the
current capacity the oldest items within the ring buffer will be dropped.
@item
@code{clear}: Removes all items from the ring buffer, returning it to be empty.
@end itemize

@lisp
> (define ring-buffer (spawn ^ring-buffer 5))
> ($ ring-buffer 'empty?)
=> #t
> ($ ring-buffer 'put 'one)
> ($ ring-buffer 'put 'two)
> ($ ring-buffer 'put 'three)
> ($ ring-buffer 'put 'four)
> ($ ring-buffer 'put 'five)
> ($ ring-buffer 'head 5)
=> (one two three four five)
> ($ ring-buffer 'put 'six)
> ($ ring-buffer 'head 5)
=> (two three four five six)
> ($ ring-buffer 'resize 3)
> ($ ring-buffer 'head 3)
=> (four five six)
> ($ ring-buffer 'take)
=> four
> ($ ring-buffer 'full?)
=> #f
@end lisp

@end deffn

@defvr {Persistence Environment} ring-buffer-env
@end defvr

@node Sealers
@section Sealers

The @code{(goblins actor-lib sealers)} module provides a mechanism for
ensuring the authenticity of data.  A sealer is used to place data
within a wrapper.  This wrapper can only be unsealed by the
corresponding unsealer, and can be checked with a predicate to ensure
it is authentic.  Sealers and unsealers are analogous to public key
cryptography, but do not use any cryptography at all.

@deffn {Procedure} spawn-sealer-triplet [name] @
       [#:make-sealer-triplet simple:make-sealer-triplet]

Return @code{values} holding a @code{sealer}, @code{unsealer}, and
@code{check} capability.  @var{name}, if provided, is the debug name
of the underlying Scheme record object.  @var{make-sealer-triplet}, if
provided, is the primitive used to create the sealer objects.  Each
sealer object can be invoked with a single argument:

@itemize
@item
@code{sealer value}: Seal @var{value} and return a reference to the
sealed object.

@item
@code{unsealer value}: Unseal the @var{value} sealed with the
corresponding @code{sealer}.  If the unsealed object is @emph{near},
it is returned directly; otherwise, a promise is returned.

@end itemize

As an example, consider a metaphorical food delivery service and its
rival service:

@lisp
> (define-values (our-lunch:seal our-lunch:unseal our-can?)
    (spawn-sealer-triplet))
> (define-values (rival-lunch:seal rival-lunch:unseal rival-can?)
    (spawn-sealer-triplet))
> ($ our-lunch:seal 'fried-rice)
=> #<local-object sealed-value>
> (define chickpea-lunch ($ our-lunch:seal 'chickpea-salad))
> ($ our-can? chickpea-lunch)
=> #t
> ($ our-can? ($ rival-lunch:seal 'melted-ice-cream))
=> #f
> ($ our-lunch:unseal chickpea-lunch)
=> chickpea-salad
@end lisp

@end deffn

@deffn {Procedure} make-spawn-sealer-triplet namespace known-sealers @
                                             [default-make-sealer-triplet]

Returns two values, the first is a @code{spawn-sealer-triplet}
function setup with a set of custom sealers and the second is a
persistence environment for Goblins' persistence system.

@var{namespace} is a atomic value which must uniquely identify this
set of sealers within the object graph.

@var{known-sealers} is an alist mapping a unique name to a thunk which
returns three values (sealer function, unsealer function and trademark
function).

@var{default-make-sealer-triplet} specifies what the default
make-sealer-triplet function is used when none is specified.

If a custom sealer triplet is provided to the returned
@code{spawn-sealer-triplet} function without being specified in the
@var{known-sealers} alist, an error will be thrown.

@lisp
(define* (my-custom-sealer-triplet #:optional name)
  (define-record-type <custom-sealers>
    (seal val)
    sealed?
    (val unseal))
  (values seal unseal sealed?))

(define custom-sealers-list
  `(((ward-sealer-triplet) . ,my-custom-sealer-triplet)))

(define-values (custom-spawn-sealer-triplet custom-sealer-env)
  (make-spawn-sealer-triplet '(my-library sealers) custom-sealers-list
			     #:default-make-sealer-triplet my-custom-sealer-triplet))
@end lisp

@end deffn

@defvr {Persistence Environment} sealers-env
@end defvr

@node Selfish-Spawn (Deprecated)
@section Selfish-Spawn (Deprecated)

@strong{Deprecation Warning}: The selfish-spawn module is deprecated
and will be removed in a future version. Please use
@code{define-actor} along with the @code{#:self} keyword to have
selfish actors. @xref{define-actor}.

The @code{(goblins actor-lib selfish-spawn)} module provides a
@code{spawn}-like procedure which spawns objects able to reference
themselves.

@deffn {Procedure} selfish-spawn constructor args @dots{}

Construct and return a reference to a new object which has a reference
to itself.

@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, and a
second argument, @code{self}, which is a reference to the object being
constructed.

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

@end itemize

This procedure is useful for patterns requiring object introspection.
However, it is usually possible to achieve the same results without
@code{selfish-spawn} so it should be used sparingly.

Here is a simplified example of a deck of playing cards using its own
method within another method:

@lisp
(define* (^deck bcom self #:optional crds)
  ;; 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

This object can then be used more or less like any other:

@lisp
> (use-modules (goblins)
               (goblins actor-lib selfish-spawn))
;; vat setup and entry
> (define deck (selfish-spawn ^deck))
> ($ deck 'draw)
=> #<some-card>
@end lisp

@end deffn

@node Simple Mint
@section Simple Mint

The @code{(goblins actor-lib simple-mint)} module provides an example
actor simulating a mint and currency.  This is a Goblins
implementation of a
@uref{http://erights.org/elib/capability/ode/ode-capabilities.html#simple-money,classic example}
of object capabilities.

@deffn {Constructor} ^mint _bcom

Constructor an actor which in turn constructs and returns
@code{purse}s for its currency.  A @code{mint} only has one method:
@code{new-purse initial-balance} spawns and returns a reference to a
new @code{purse} which holds @var{initial-balance} tokens.

A @code{purse}, on the other hand, has four methods:

@itemize
@item
@code{get-balance}: Return the current number of tokens in the purse.

@item
@code{sprout}: Spawn and return a reference to a new empty
@code{purse} for this currency.

@item
@code{deposit amount src}: Increase the number of tokens in this
@code{purse} by @var{amount}, decreasing the number of tokens in the
@code{purse} of the same currency @var{src} by the same amount.

@item
@code{get-decr}: Return a procedure accepting one argument, an
@var{amount} of tokens to remove from this @code{purse}.

@end itemize

@end deffn

@deffn {Procedure} withdraw amount from-purse

Spawn and return a reference to a new purse holding @var{amount}
tokens of the same type as the @code{purse} @var{from-purse}.  Remove
the same numbers of tokens from @var{from-purse}.

@end deffn

@defvr {Persistence Environment} mint-env
@end defvr

@node Swappable
@section Swappable

The @code{(goblins actor-lib swappable)} module provides a mechanism
to create an actor of one type and change it to another type later.

@deffn {Procedure} swappable initial-target [proxy-name]

Spawn and return @code{values} representing an actor and an actor
which is a capability to swap that actor with another.
@var{initial-target} is the actor at construction.  @var{proxy-name},
if provided, is the debug name for the returned actor.

@end deffn

@node Ticker
@section Ticker

The @code{(goblins actor-lib ticker)} module provides a mechanism to
invoke certain actors at the same time each ``tick'' of a program.

@deffn {Procedure} spawn-ticker

Spawn and return a reference to a @code{ticker} actor which holds
references to a set of actors which it invokes with the same set of
arguments each ``tick''.

A @code{ticker} has four methods:

@itemize
@item
@code{to-tick}: Return a procedure accepting a single argument, a
closure over spawning an actor with a @code{ticky} actor as an
argument.  The @code{ticky} actor is passed to the closure and has
three procedures:

@itemize
@item
@code{die}: Set @code{dead?} to @code{#t}.

@item
@code{dead?}: Return @code{#t} if @code{die} has been invoked, else
@code{#f}.

@item
@code{to-tick}: The same as the @code{to-tick} method of @code{ticker}.

@end itemize

@item
@code{get-ticked}: Return a list holding references to each actor to
tick.

@item
@code{tick}: Invoke all actors which have a @code{ticky}.

@item
@code{foldr proc init [#:include-new? #t]}: A @code{foldr} procedure
over the actors known to @code{ticker}.  If @code{include-new?} is
@code{#t}, also operate on actors registered since the last invocation
of @code{tick}.

@end itemize

@end deffn

@defvr {Persistence Environment} ticker-env
@end defvr

@node Timers
@section Timers

The @code{(goblins actor-lib timers)} module provides a mechanism to
wait or sleep for a set amount of time. If the @code{sleep} procedure
that comes with Guile/Fibers is used, this will cause the entire vat
to stop and sleep, resulting in the vat being ``blocked''. This is
almost always is not what we want, which is where this module comes
in, providing a mechanism to create Goblins promises which will
resolve after a specified amount of time.

Since this is built upon Goblins promises, promise resolutions will be
queued on the relevent vat queue, like all other messages, at the end
of the vat's message queue. This means that it could take longer to
resolve than the time specified to sleep, how much time depends on the
vat message queue at the moment.

@deffn {Procedure} timeout seconds [result #t]

Make a promise which will be fulfilled after @var{seconds}. The value
the promise will be fulfilled with is the optional @var{result}.

@lisp
(use-modules (goblins)
             (goblins actor-lib timer))

(on (timeout 1 'hello) pk)
;; After 1 second, we should see:
;;; (hello)
@end lisp

@end deffn

@node Ward
@section Ward

The @code{(goblins actor-lib ward)} module provides a mechanism for an
actor to restrict access to its behaviors using the conceptual
metaphor of a magical ward.  It is inspired by
@uref{http://www.erights.org/history/joule/MANUAL.B17.pdf,parts of the E ecosystem}.

@deffn {Procedure} spawn-warding-pair [#:async? #f] [#:sealer-triplet #f]

Return @code{values} holding a @code{warden} and an @code{incanter}.
If @code{async?} is @code{#t}, the @code{incanter} will use @code{<-}
to invoke sealed actors; otherwise, it will use @code{$}.
If provided, @code{sealer-triplet} is the set of sealers to use
instead of creating a new set.

The @code{warden} is not meant to be used directly; see @code{ward}
below.

The @code{incanter} can be invoked with a @var{target} actor and the
@code{args} to invoke it with.

@end deffn

@deffn {Procedure} ward warden behavior [#:extends #f] [#:async? #f]

Return @var{behavior} sealed by @var{warden} so that only its
associated @code{incanter} can use the behavior.  @var{extends}, if
provided, is an actor to extend with the warded @var{behavior}.  If
@var{async?} is @code{#t}, invoke @var{behavior} using @code{<-};
otherwise us @code{$}.

The returned behavior can be invoked with either a single list of
sealed arguments or any number of unsealed arguments.

@end deffn

@deffn {Procedure} enchant incanter target [#:async? #f]

Spawn and return a reference to a proxy which invokes @var{target}
using @var{incanter} to access its warded behavior.  If @var{async?}
is @code{#t}, invoke @var{target} using @code{<-}; otherwise, use
@code{$}.

@end deffn

@deffn {Procedure} warden->ward-proc warden

Return a procedure to wrap @code{ward} using @var{warden}.  The
returned procedure accepts two arguments: @var{warded-beh}, which is
the behavior to ward; and @var{extends-beh}, which is the actor to
extend with that behavior.

@end deffn

@defvr {Persistence Environment} ward-env
@end defvr
