29.12. Deviations from [AMOP]

29.12.1. Warning CLOS:CLOS-WARNING
29.12.1.1. Warning CLOS:GF-ALREADY-CALLED-WARNING
29.12.1.2. Warning CLOS:GF-REPLACING-METHOD-WARNING

This section lists the differences between the [AMOP] and the CLISP implementation thereof.

Not implemented in CLISP

Features implemented differently in CLISP

Extensions specific to CLISP

29.12.1. Warning CLOS:CLOS-WARNING

When CLISP encounters suspicious CLOS code, it issues a WARNING of type CLOS:CLOS-WARNING. To suppress the undesired warnings (not recommended!) use EXT:SET-GLOBAL-HANDLER with MUFFLE-WARNING on the appropriate WARNING type;. To find where the warnings come from (recommended), set *BREAK-ON-SIGNALS* to the appropriate WARNING type.

29.12.1.1. Warning CLOS:GF-ALREADY-CALLED-WARNING

This is a hint that the order in which program files are loaded (order of definitions, order of macro expansions, or similar) is wrong. Example:

(defclass ware () ((title :initarg :title :accessor title)))
(defclass book (ware) ())
(defclass compact-disk (ware) ())
(defclass dvd (ware) ())
(defgeneric add-to-inventory (object))
(defmethod add-to-inventory ((object ware)) nil)
(add-to-inventory (make-instance 'book :title "CLtL1"))
(defvar *book-counter* 0)
(defmethod add-to-inventory ((object book)) (incf *book-counter*))
(add-to-inventory (make-instance 'book :title "CLtL2"))
*book-counter*
⇒ 1

Since [CLtL1] and [CLtL2] were already added to the inventory, the programmer might have expected that *book-counter* is 2.

No warning for standard generic functions

A few functions, such as PRINT-OBJECT, are listed in the [ANSI CL standard] and the [AMOP] as standard generic functions, to which users may add methods. This warning is not issued for such functions.

Motivation

A generic function is defined by a contract. Whoever puts a method on a generic function, however, is also expecting a contract to be fulfilled. (In the example above, it is that *book-counter* equals the number of invocations of add-to-inventory on book instances.) If the generic function was already called before the method was installed, the method's contract was definitely broken. Maybe the programmer has foreseen this case (in this example: he could initialize *book-counter* to the number of instances of book that exist at this moment, rather than to 0), or maybe not. This is what the warning is about.

29.12.1.2. Warning CLOS:GF-REPLACING-METHOD-WARNING

This is a hint that different parts of the program, possibly developed by independent people, are colliding. Example: in addition to the code above:

(defvar *book-sales-statistics* (make-hash-table :test 'equal))
(defmethod add-to-inventory ((object book))
  (setf (gethash (title object) sale-stats) (cons 0 0)))
(add-to-inventory (make-instance 'book :title "AMOP"))
*book-counter*
⇒ 1
*book-sales-statistics*
⇒ #S(HASH-TABLE :TEST FASTHASH-EQUAL ("AMOP" . (0 . 0)))

The programmer who programmed the first add-to-inventory@book method expects that *book-counter* will be incremented. The programmer who programmed the second add-to-inventory@book method expects that *book-sales-statistics* gets augmented. If the implementation gives no warning, one of the two programmers will waste time debugging.

Motivation

This warning can be warranted for the same reason as above: if the old method and the new method have a different contract, something is fishy and possibly wrong. Additionally, the programmers may not even have intended to replace the method. They may have intended cumulative effects of the two methods.


These notes document CLISP version 2.49Last modified: 2010-07-07