Search code examples
common-lispclosdescribe

Specializing behavior of describe method, as explained by Sonya E. Keene


In the book Object Oriented Programming in COMMON LISP by S. Keene, she introduces specializing the behavior of the describe generic function by providing an :after method for some classes, but this will result in an error in SBCL and Clozure:

COMMON-LISP:DESCRIBE already names an ordinary function or a
macro. [Condition of type SB-INT:SIMPLE-PROGRAM-ERROR]

This happens when i try to modify the behavior of describe for my class:

(defclass klasse ()
  ())

(defmethod describe :after ((obj klasse))
  (print "Klasse!"))

As the book is from 1989, are these locking policies something which has happened after the release of the book, or am i missing something else?


Solution

  • As far as i know, the book describes the language of a before ANSI standartization era (standartization happened in 1994). In ansi cl describe is indeed on ordinary function, while there is a generic one, named describe-object

    CLHS says the following on this subject:

    The actual act of describing the object is implemented by describe-object. describe exists as an interface primarily to manage argument defaulting (including conversion of arguments t and nil into stream objects) and to inhibit any return values from describe-object.

    So, what you need to do, is to specify

    (defmethod describe-object :after ((obj klasse) stm) 
        (print "Klasse!" stm)) 
    

    and call it with describe:

    CL-USER> (describe (make-instance 'klasse))
    ;;=> #<KLASSE {1001C3C1F3}>
    ;;     [standard-object]
    ;;   No slots.
    
    ;;   "Klasse!" 
    ;;   ; No values