Next: , Previous: , Up: Tutorial   [Contents]


4.3 Methods aren’t essential, but they are useful

The most common way to select different sub-behaviors isn’t by the number of arguments though. It’s much more common to have “methods” that are selected by name. We can use the methods macro to do just that:

(use-modules (goblins actor-lib methods))

(define* (^mcell bcom #:optional [val #f])
  (methods
   ((get)
    val)
   ((set new-val)
    (bcom (^mcell bcom new-val)))))

The use of ^mcell is similar, but now we pass in a first argument as a symbol selecting the method, and the rest of the arguments are passed to the object:

goblins[1]> (define jar
              (spawn ^mcell "cookies"))
goblins[1]> ($ jar 'get)
; => "cookies"
goblins[1]> ($ jar 'set "crumbs")
goblins[1]> ($ jar 'get)
; => "crumbs"

Methods aren’t particularly magical… the methods macro just returns a procedure which is convenient to use for procedure dispatch:

> (define foo-or-bar
    (methods
     ((foo)
      'called-foo)
     ((bar arg)
      (list 'called-bar-with arg))))
> (foo-or-bar 'foo)
; => called-foo
> (foo-or-bar 'bar "meep")
; => (called-bar-with "meep")

So really, methods just makes a particularly useful kind of behavior procedure for us, one which takes a first argument for the method name, grabs the rest of the arguments, and then applies them to the relevant method.