From: Ralitsa
Subject: Ralitsa Angelova
Date: 
Message-ID: <96957557.0305211330.751182a8@posting.google.com>
Hello to all of you! I have the following problem: suppose I have defined
a class
 Geometric
 (defclass Geometric ()
   ((color :accessor color :initform 'black))
   (:documentation "The basic class for all graphical objects.Slot:
Color")) 

I want to define a before and after methods that are suppose to
show the color right before/after changing it.
 I tried the following code:

(defgeneric set_color ((new_color list) (obj Geometric))
   (:method ((new_color list)(obj Geometric)) (setf (color obj) new_color)
))
 (defmethod set_color :before ((new_value list) (obj Geometric))
  (print 'before (color obj))
  )

 but the interpreter comes up with an error:

 USER(37):  (set_color 'black g) Error: No methods applicable for generic
function
       #<STANDARD-GENERIC-FUNCTION SET_COLOR> with args
       (BLACK #<GEOMETRIC @ #x2039cd0a>) of classes (SYMBOL GEOMETRIC)
  [condition type: PROGRAM-ERROR]


 Any idea why or where is the mistake? Thank you in advance...

From: Kaz Kylheku
Subject: Re: Ralitsa Angelova
Date: 
Message-ID: <cf333042.0305220844.3e1bd664@posting.google.com>
···@abv.bg (Ralitsa) wrote in message news:<····························@posting.google.com>...
> Hello to all of you! I have the following problem: suppose I have defined
> a class
>  Geometric
>  (defclass Geometric ()
>    ((color :accessor color :initform 'black))
>    (:documentation "The basic class for all graphical objects.Slot:
> Color")) 
> 
> I want to define a before and after methods that are suppose to
> show the color right before/after changing it.

Then add advice to the COLOR accessor.

>  I tried the following code:
> 
> (defgeneric set_color ((new_color list) (obj Geometric))

You have already defined accessors for the color using the :ACCESSOR
COLOR argument in the class definition!

This definition gives you both a read and write accessor. The read
accessor is the COLOR function, and the write accessor is the (SETF
COLOR) function. That's right, (SETF COLOR) is a special kind of
function name in Lisp.

So :BEFORE and :AFTER advice can be added like this:

  ;;; take action before an assignment

  (defmethod (setf color) :before ((color list) (obj geometric))
     ... )


By the way, don't use underscores to separate words in Lisp
identifiers; dashes are permitted, and are commonly used for this.
People use underscores in some other languages because those languages
don't permit any other separator. E.g. in C, an identifier is a letter
or an underscore, followed by any combination of letters, digits and
underscores.

>    (:method ((new_color list)(obj Geometric)) (setf (color obj) new_color)
> ))
>  (defmethod set_color :before ((new_value list) (obj Geometric))
>   (print 'before (color obj))
>   )
> 
>  but the interpreter comes up with an error:
> 
>  USER(37):  (set_color 'black g) Error: No methods applicable for generic
> function

The new_value parameter of your method is specialized to type LIST.
But here you are passing a value of type SYMBOL. You don't have a
method specialized to the SYMBOL type.

But as we discussed, you don't need the redundant set_color accessor.
To change the color slot of the object, use:

   (setf (color g) 'black)

This is why the write accessor is called (SETF COLOR)---it works in
conjunction with the SETF macro (and its various cousins like INCF).
When you write (color g), the reader function is invoked. When you
write (setf (color g) 'black) it calls ((setf color) 'black g).

The write accessor allows the expression which normally retrieves the
color to behave as a place where a new value can be stored.

This is how SETF works in Lisp; it allows expressions which retrieve
values from parts of objects to be used to express places where values
are to be stored. E.g.

   (let ((x (list 1 2 3)))
     (setf (third x) 4)
      x)
   
   --> (1 2 4)
From: Coby Beck
Subject: Re: Ralitsa Angelova
Date: 
Message-ID: <bah58k$1rt$1@otis.netspace.net.au>
"Ralitsa" <···@abv.bg> wrote in message
·································@posting.google.com...
> Hello to all of you! I have the following problem: suppose I have defined
> a class
>  Geometric
>  (defclass Geometric ()
>    ((color :accessor color :initform 'black))
>    (:documentation "The basic class for all graphical objects.Slot:
> Color"))
>
> I want to define a before and after methods that are suppose to
> show the color right before/after changing it.
>  I tried the following code:
>
> (defgeneric set_color ((new_color list) (obj Geometric))
>    (:method ((new_color list)(obj Geometric)) (setf (color obj) new_color)
> ))
>  (defmethod set_color :before ((new_value list) (obj Geometric))
>   (print 'before (color obj))
>   )
>
>  but the interpreter comes up with an error:
>
>  USER(37):  (set_color 'black g) Error: No methods applicable for generic
> function
>        #<STANDARD-GENERIC-FUNCTION SET_COLOR> with args
>        (BLACK #<GEOMETRIC @ #x2039cd0a>) of classes (SYMBOL GEOMETRIC)
>   [condition type: PROGRAM-ERROR]

The message says you have no specialization for the types you have called
the method with and indeed this turns out to be the problem!  You defined it
on types LIST and GEOMETRIC but called it with types SYMBOL and GEOMETRIC.
Change your call or method definition to suit taste...are colors supposed to
be symbols or lists?

Also, I would recomend putting the GEOMETRIC argument first in the methods
parameter list.  That is just a style suggestion, put the "important" class
first...?  I don't know if that is just me or others would do the same.

-- 
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")
From: Kenny Tilton
Subject: Re: Ralitsa Angelova
Date: 
Message-ID: <3ECC3F28.4010908@nyc.rr.com>
Coby Beck wrote:
> "Ralitsa" <···@abv.bg> wrote in message
> ·································@posting.google.com...
> 
>>Hello to all of you! I have the following problem: suppose I have defined
>>a class
>> Geometric
>> (defclass Geometric ()
>>   ((color :accessor color :initform 'black))
>>   (:documentation "The basic class for all graphical objects.Slot:
>>Color"))
>>
>>I want to define a before and after methods that are suppose to
>>show the color right before/after changing it.
>> I tried the following code:
>>
>>(defgeneric set_color ((new_color list) (obj Geometric))
>>   (:method ((new_color list)(obj Geometric)) (setf (color obj) new_color)
>>))
....
> The message says you have no specialization for the types you have called
> the method with and indeed this turns out to be the problem!  You defined it
> on types LIST and GEOMETRIC but called it with types SYMBOL and GEOMETRIC.
> Change your call or method definition to suit taste...are colors supposed to
> be symbols or lists?
> 
> Also, I would recomend putting the GEOMETRIC argument first in the methods
> parameter list.  That is just a style suggestion, put the "important" class
> first...?  I don't know if that is just me or others would do the same.
> 

I'm with you on the style angle, but the value being set precedes the 
instance in the parameter list in the case of (SETF <whatever>). I guess 
the idea is that there is only one value to be set, but the description 
of the place to be set can have more parameters than the instance. Some 
code from a project selected at random:

(defun (setf md-slot-value) (newvalue self slot-spec)
   (let ((c (md-slot-cell self slot-spec)))
      ....))

Then I can:

    (setf (md-slot-cell self slot-name) cell)

...so I would follow that precedent if I had to do a defgeneric on a 
custom setter.

-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Everything is a cell." -- Alan Kay