File: CLOS-guide-6.html

package info (click to toggle)
cmucl 20c-2
  • links: PTS
  • area: main
  • in suites: wheezy
  • size: 42,524 kB
  • sloc: lisp: 358,331; ansic: 28,385; asm: 3,777; sh: 1,236; makefile: 366; csh: 31
file content (136 lines) | stat: -rw-r--r-- 4,424 bytes parent folder | download | duplicates (12)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
<HTML>
<HEAD>
<TITLE>Brief Guide to CLOS: Generic functions and methods</TITLE>
</HEAD>
<BODY>
<A HREF="CLOS-guide-5.html"><IMG SRC="prev.gif" ALT="Previous"></A>
<A HREF="CLOS-guide-7.html"><IMG SRC="next.gif" ALT="Next"></A>
<A HREF="CLOS-guide.html#toc6"><IMG SRC="toc.gif" ALT="Contents"></A>
<HR>
<H2><A NAME="s6">6. Generic functions and methods</A></H2>

<P>Generic function in <CODE>CLOS</CODE> are the closest thing to &quot;messages&quot;.
Instead of writing</P>
<P>
<BLOCKQUOTE><CODE>
<PRE>
(SEND instance operation-name arg*)
</PRE>
</CODE></BLOCKQUOTE>
</P>
<P>you write</P>
<P>
<BLOCKQUOTE><CODE>
<PRE>
(operation-name instance arg*)
</PRE>
</CODE></BLOCKQUOTE>
</P>
<P>The operations / messages are generic functions -- functions whose
behavior can be defined for instances of particular classes by
defining methods.</P>
<P><CODE>(DEFGENERIC function-name lambda-list)</CODE> can be used to define a generic
function.  You don't have to call <CODE>DEFGENERIC</CODE>, however, because 
<CODE>DEFMETHOD</CODE>
automatically defines the generic function if it has not been defined
already.  On the other hand, it's often a good idea to use <CODE>DEFGENERIC</CODE>
as a declaration that an operation exists and has certain parameters.</P>
<P>Anyway, all of the interesting things happen in methods.  A method is
defined by:</P>
<P>
<BLOCKQUOTE><CODE>
<PRE>
(DEFMETHOD generic-function-name specialized-lambda-list
  form*)
</PRE>
</CODE></BLOCKQUOTE>
</P>
<P>This may look fairly cryptic, but compare it to <CODE>DEFUN</CODE> described in
a similar way:</P>
<P>
<BLOCKQUOTE><CODE>
<PRE>
(DEFUN function-name lambda-list form*)
</PRE>
</CODE></BLOCKQUOTE>
</P>
<P>A &quot;lambda list&quot; is just a list of formal parameters, plus things like
<CODE>&amp;OPTIONAL</CODE> or <CODE>&amp;REST</CODE>.  It's because of such 
complications that we say
&quot;lambda-list&quot; instead of &quot;(parameter*)&quot; 
when describing the syntax.</P>
<P>[I won't say anything 
about <CODE> &amp;OPTIONAL </CODE>, 
<CODE>&amp;REST</CODE>, or <CODE>&amp;KEY</CODE> in methods.
The rules are in CLtL2 or the HyperSpec, if you want to know them.]</P>
<P>So a normal function has a lambda list like <CODE>(var1 var2 ...)</CODE>.
A method has one in which each parameter can be &quot;specialized&quot;
to a particular class.  So it looks like:</P>
<P>
<BLOCKQUOTE><CODE>
<PRE>
((var1 class1) (var2 class2) ...)
</PRE>
</CODE></BLOCKQUOTE>
</P>
<P>The specializer is optional.  Omitting it means that the method
can apply to instances of any class, including classes that were
not defined by <CODE>DEFCLASS</CODE>.  For example:</P>
<P>
<BLOCKQUOTE><CODE>
<PRE>
(defmethod change-subject ((teach teacher) new-subject)
  (setf (teacher-subject teach) new-subject))
</PRE>
</CODE></BLOCKQUOTE>
</P>
<P>Here the new-subject could be any object.  If you want to restrict
it, you might do something like:</P>
<P>
<BLOCKQUOTE><CODE>
<PRE>
(defmethod change-subject ((teach teacher) (new-subject string))
  (setf (teacher-subject teach) new-subject))
</PRE>
</CODE></BLOCKQUOTE>
</P>
<P>Or you could define classes of subjects.</P>
<P>Methods in &quot;classical&quot; object-oriented programming specialize
only one parameter.  In <CODE>CLOS</CODE>, you can specialize more than one.
If you do, the method is sometimes called a multi-method.</P>
<P>A method defined for a class <CODE>C</CODE> overrides any method defined
for a superclass of <CODE>C</CODE>.  The method for <CODE>C</CODE> is 
&quot;more specific&quot;
than the method for the superclass, because <CODE>C</CODE> is more specific
that the classes it inherits from (eg, dog is more specific
than animal).</P>
<P>For multi-methods, the determination of which method is more
specific involves more than one parameter.  The parameters
are considered from left to right.</P>
<P>
<BLOCKQUOTE><CODE>
<PRE>
(defmethod test ((x number) (y number))
  '(num num))

(defmethod test ((i integer) (y number))
  '(int num))

(defmethod test ((x number) (j integer))
  '(num int))

(test 1 1)      =&gt;  (int num), not (num int)
(test 1 1/2)    =&gt;  (int num) 
(test 1/2 1)    =&gt;  (num int) 
(test 1/2 1/2)  =&gt;  (num num) 
</PRE>
</CODE></BLOCKQUOTE>
</P>


<HR>
<A HREF="CLOS-guide-5.html"><IMG SRC="prev.gif" ALT="Previous"></A>
<A HREF="CLOS-guide-7.html"><IMG SRC="next.gif" ALT="Next"></A>
<A HREF="CLOS-guide.html#toc6"><IMG SRC="toc.gif" ALT="Contents"></A>
</BODY>
</HTML>