This section lists the differences between the [AMOP] and the CLISP implementation thereof.
Not implemented in CLISP
The generic function CLOS:MAKE-METHOD-LAMBDA
is not implemented.
See Section 29.5.3.2, “Generic Function Invocation Protocol”.
Features implemented differently in CLISP
The class precedence list of CLOS:FUNCALLABLE-STANDARD-OBJECT
is different. See Section 29.2.2, “Inheritance Structure of Metaobject Classes”.
The DEFCLASS
macro passes default values to CLOS:ENSURE-CLASS
.
See Section 29.3.1, “Macro DEFCLASS
”.
The DEFGENERIC
macro passes default values to ENSURE-GENERIC-FUNCTION
.
See Section 29.5.3.1, “Macro DEFGENERIC
”.
The class CLOS:FORWARD-REFERENCED-CLASS
is implemented differently.
See Implementation of class CLOS:FORWARD-REFERENCED-CLASS
in CLISP.
The function CLOS:GENERIC-FUNCTION-ARGUMENT-PRECEDENCE-ORDER
SIGNAL
s an ERROR
if the generic function has no lambda list.
Extensions specific to CLISP
The Meta-Object Protocol is applicable to classes of type STRUCTURE-CLASS
.
The default superclass for STRUCTURE-CLASS
instances is
STRUCTURE-OBJECT
.
Structure classes do not support multiple inheritance and reinitialization.
See Section 29.3.5.1, “Initialization of class metaobjects”.
See also Section 8.2, “The structure Meta-Object Protocol”.
The DEFGENERIC
macro supports user-defined options.
See User-defined options.
The class METHOD
is subclassable.
See Section 29.2.2, “Inheritance Structure of Metaobject Classes”.
Slot names like NIL
and T
are allowed.
See Section 29.4.2.1.1, “Generic Function CLOS:SLOT-DEFINITION-NAME
”.
The CLOS:VALIDATE-SUPERCLASS
method is more permissive by
default and does not need to be overridden in
some “obvious” cases.
See Section 29.3.6.7, “Generic Function CLOS:VALIDATE-SUPERCLASS
”.
New generic function CLOS:COMPUTE-DIRECT-SLOT-DEFINITION-INITARGS
. It can sometimes
be used when overriding CLOS:DIRECT-SLOT-DEFINITION-CLASS
is cumbersome.
New generic function CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION-INITARGS
. It can sometimes
be used when overriding CLOS:EFFECTIVE-SLOT-DEFINITION-CLASS
is cumbersome.
New function CLOS:COMPUTE-EFFECTIVE-METHOD-AS-FUNCTION
. It
can be used in overriding methods of CLOS:COMPUTE-DISCRIMINATING-FUNCTION
.
The generic function CLOS:ENSURE-GENERIC-FUNCTION-USING-CLASS
accepts a
:DECLARE
keyword.
The functions CLOS:FUNCALLABLE-STANDARD-INSTANCE-ACCESS
and
CLOS:STANDARD-INSTANCE-ACCESS
support non-updated obsolete instances and
also support slots with allocation :CLASS
.
The existence of the function CLOS:CLASS-DIRECT-SUBCLASSES
does not prevent otherwise unreferenced classes from being garbage-collected.
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.
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.
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.
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.
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
method expects that add-to-inventory
@book
*book-counter*
will be incremented.
The programmer who programmed the second
method expects that add-to-inventory
@book
*book-sales-statistics*
gets
augmented. If the implementation gives no warning, one of the two
programmers will waste time debugging.
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.49 | Last modified: 2010-07-07 |