Next: Synchronous calls, Up: Objects [Contents][Index]
Objects can be spawned with the spawn
operator:
Construct and return a reference to a new object.
bcom
, which can be used to change the object’s behavior.
For example, given the following constructor:
(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)
The instantiation…
(define some-cell (spawn ^cell 42))
will bind val
to 42
.
The 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 bcom
returns a
datastructure demonstrating that this object is choosing to change its
value (part of Goblins’ quasi-functional design).
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:
(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))
Here’s how this works at the REPL:
> ,vr (define root-beer (spawn ^drink "root beer" 3)) > ,vr ($ root-beer) => "*GLUG!* You drink your root beer. Still some left!" > ,vr ($ root-beer) => "*GLUG!* You drink your root beer. Still some left!" > ,vr ($ root-beer) => "*GLUG!* You drink your root beer. It's empty!" > ,vr ($ root-beer) => "Sadly, your glass appears to be empty!"
As you can see above, bcom
is also a handy way to construct
state machines, as ^drink
moves from drinkable to empty as it
is consumed.
spawn
also has a few variants:
Like spawn
, and set the object’s debug name to name.
Return a promise and its associated resolver.
(define-values a-promise a-resolver (spawn-promise-values))
Return a promise and its associated resolver as a cons
pair.
(define promise-pair (spawn-promise-cons)) (define a-promise (car promise-pair)) (define a-resolver (cdr promise-pair))
Next: Synchronous calls, Up: Objects [Contents][Index]