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
29.12.1.3. Warning CLOS:CLASS-OBSOLESCENCE-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 or suboptimal CLOS code, it issues a WARNING of type CLOS:CLOS-WARNING or a STYLE-WARNING of type CLOS:CLOS-STYLE-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) may be 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.

This is a STYLE-WARNING

This warning is actually a STYLE-WARNING because it indicates the behavior officially sanctioned by the standard and useful in some situations. We only warn on it because it may lead to confusing behavior for inexperienced users.

Motivation

A generic function is defined by a contract. Whoever adds a method to a generic function, however, also expects the contract to be fulfilled. (In the example above, the contract is that *book-counter* equals the number of invocations of add-to-inventory on book instances.) If the generic function has already been called before the method was added, the method's contract is 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.

Disabling the warning for a specific generic function

If your generic function constitutes a public interface which is used by adding methods (similar to aforementioned PRINT-OBJECT), you can declare it as such:

(defgeneric my-public-gf (a b c)
  (declare (clos:dynamically-modifiable))
  ...)

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.

This is a STYLE-WARNING

This warning is actually a STYLE-WARNING because it indicates the behavior officially sanctioned by the standard and useful in some situations. We only warn on it because it may lead to confusing behavior for inexperienced users.

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.

29.12.1.3. Warning CLOS:CLASS-OBSOLESCENCE-WARNING

This is a hint that different parts of the program define the same CLASS incompatibly, and some objects, created to the old specification, have been obsoleted by the new one. Example: in addition to the code above:

(defclass ware ()
  ((title :initarg :title :accessor title)
   (year :initarg :year :accessor year)))

Evaluating the above will obsolete all objects of type wares, books etc created so far, i.e., their components will become inaccessible.

This is a STYLE-WARNING

This warning is actually a STYLE-WARNING because it indicates the behavior officially sanctioned by the standard and useful in some situations. We only warn on it because it may lead to confusing behavior for inexperienced users.

Motivation

In addition to the above, this warning tells the programmers that they are losing some objects they have already created.


These notes document CLISP version 2.49.93+Last modified: 2018-02-19