Next: multimethods application, Up: multimethods [Index]
Here we look at some examples of what we have to expect from
multimethods dispatching. We will always assume that the code in the
examples is wrapped into a program form as follows:
#!vicare
(program (demo)
(options typed-language)
(import (vicare)
(vicare language-extensions multimethods))
... ;here goes the code
#| end of program |# )
Let’s examine an example using the generic functions definer
define-generic:
(define-record-type <one> (nongenerative one)) (define-record-type <two> (parent <one>) (nongenerative two)) (define-record-type <three> (parent <two>) (nongenerative three))
the type hierarchy is:
<top> -> <struct> -> <record> -> <one> -> <two> -> <three>
the list of UIDs for <three> is:
(type-unique-identifiers <three>)
⇒ (three two one
vicare:scheme-type:<record>
vicare:scheme-type:<struct>
vicare:scheme-type:<top>)
so for the generic function:
(define-generic doit (o))
(define-method (doit {o <one>}) 'one)
(define-method (doit {o <two>}) 'two)
applied to a value of type <three>: the method with <two> in
the signature is more specific than the method with <one>
in the signature:
(doit (new <three>)) ⇒ two
also the method with <one> in the signature is the “next method”
of the method with <two> in the signature, we can call it using
call-next-method. The following example shows a call to the next
method:
(define-generic fluff (o))
(define-method (fluff {o <one>})
'one)
(define-method (fluff {o <two>})
(cons 'two (call-next-method)))
(define o (new <three>))
(fluff o)
⇒ (two . one)
The syntax define-generic defines a macro which can be used as a
function; the syntax define-method adds a new method to the
generic function; define-generic establishes the number of
arguments for the generic function: all the methods must have the same
number of arguments.
It is possible to define a function accepting different numbers of arguments as follows:
(case-define fluff
((a)
(fluff-1 a))
((a b)
(fluff-2 a b))
((a b . rest)
(fluff-3 a b rest)))
(define-generic fluff-1 (o))
(define-generic fluff-2 (o p))
(define-generic fluff-3 (o p rest))
(define-method (fluff-1 {o <one>})
---)
(define-method (fluff-2 {o <one>} {p <two>})
---)
(define-method (fluff-3 {o <one>} {p <two>} rest)
---)
this way we turn a set of macros into a single “generic function” which is truly a function. If we avoid wrapping the macros into a function we may gain a bit of speed in function calls.
Next: multimethods application, Up: multimethods [Index]