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]