Newsgroups: comp.lang.clos
Path: cantaloupe.srv.cs.cmu.edu!bb3.andrew.cmu.edu!newsfeed.pitt.edu!dsinc!spool.mu.edu!usenet.eel.ufl.edu!news.mathworks.com!nntp.primenet.com!ddsw1!news.mcs.net!news.abs.net!aplcenmp!hall
From: hall@aplcenmp.apl.jhu.edu (Marty Hall)
Subject: Re: setf method??
Message-ID: <DwJHys.46B@aplcenmp.apl.jhu.edu>
Organization: JHU/APL Research Center, Hopkins P/T CS Faculty
References: <4vh8l9$jnu$1@mhadg.production.compuserve.com>
Date: Thu, 22 Aug 1996 12:42:27 GMT
Lines: 54

In article <4vh8l9$jnu$1@mhadg.production.compuserve.com> Gerald Smith
<70363.2333@CompuServe.COM> writes: 
>I was reading the FAQ about CLOS, and they had this example of a 
>common CLOS blunder:

This is excerpted from my (old) "Common CLOS Blunders" list that I put
together based on experiences of mine, my colleagues, and my students.
You can access the complete list (in PostScript) from the CLOS section
<http://www.apl.jhu.edu/~hall/lisp.html>.

>(defmethod (setf Area) ((Sq Square) (New-Area number))
>  (setf (Width Sq) (sqrt New-Area)))
>
> ;;instead of this correct version
>
>(defmethod (setf Area) ((New-Area number) (New-Area number))
>  (setf (Width Sq) (sqrt New-Area)))
>
>I do not understand using (setf Area) after defmethod.

Assumedly the FAQ has the second version as
(defmethod (setf Area) ((New-Area number) (Sq Square))
  (setf (Width Sq) (sqrt New-Area)))
and is simply illustrating the common beginner mistake of switching
the order of the arguments in setf methods. This part is not trying to
introduce people to setf methods, although I do have a section on that
in the CLOS section of the WWW page above.

Anyhow, a method like (defmethod (setf Foo) (Args) Body) defines what
happens when you do (setf (Foo A B) C). The way to read a form like
this is "arrange it so that next time I call (Foo A B) I get C back".
Thus in the example above, (setf (Area Square1) 100) will set the
Width field of Square1 to 10.

Here's a silly example to illustrate the idea. Suppose I had a function

(defun Add-Some (X) (+ X *Global-Var*))

Thus, 
(setq *Global-Var* 5)
(Add-Some 4) --> 9

Then I could define a setf method:

(defmethod (setf Add-Some) ((Result number) (X number))
  (setq *Global-Var* (- Result X)))

Now, the reading of (setf (Add-Some 12) 20), which is "arrange it so
that calling (Add-Some 12) will return 20" is obeyed by setting
*Global-Var* to 8.

It takes some getting used to, but is quite useful. Happy hacking-

					- Marty
