defclass

Macro

Summary

Remains as defined in ANSI Common Lisp, but extra control over parsing of class options and slot options, optimization of slot access, and checking of initargs, is provided.

Package

common-lisp

Description

The macro defclass is as defined in the ANSI standard with the following extensions.

For extra class options, you may need to define the way these are parsed at defclass macroexpansion time. See process-a-class-option for details.

For non-standard slot options, you may need to define the way these are parsed at defclass macroexpansion time. See process-a-slot-option for details.

By default, standard slot accessors are optimized such that they do not call slot-value-using-class. This optimization can be switched off using the :optimize-slot-accessnil class option.

To add valid initialization arguments for the class, use the class option :extra-initargs. The argument passed via this option is evaluated, and should return a list of extra initialization arguments for the class. make-instance and other CLOS initializations (see set-clos-initarg-checking) will treat these as valid when checking their arguments.

Compatibility notes

When a class is redefined, its extra initargs are always reset.

In early versions of LispWorks 4.3, extra initargs were not reset when a class was redefined without specifying extra initargs.

Example

This session illustrates the effects of the :optimize-slot-access class option. When true, slot access is more efficient but note that slot-value-using-class is not called.

CL-USER 26 > (compile '(defclass foo ()

((a :type fixnum

:initarg :a

:reader foo-a))))

NIL

CL-USER 27 > (compile '(defclass bar ()

((a :type fixnum

:initarg :a

:reader bar-a))

(:optimize-slot-access nil)))

NIL

CL-USER 28 > (setf *foo*

(make-instance 'foo :a 42)

*bar* (make-instance 'bar :a 99))

#<BAR 21D33D4C>

CL-USER 29 > (progn

(time (dotimes (i 1000000)

(foo-a *foo*)))

(time (dotimes (i 1000000)

(bar-a *bar*))))

Timing the evaluation of (DOTIMES (I 1000000) (FOO-A *FOO*))

user time = 0.328

system time = 0.015

Elapsed time = 0:00:00

Allocation = 2280 bytes standard / 11002882 bytes conses

0 Page faults

Timing the evaluation of (DOTIMES (I 1000000) (BAR-A *BAR*))

user time = 0.406

system time = 0.015

Elapsed time = 0:00:00

Allocation = 4304 bytes standard / 11004521 bytes conses

0 Page faults

NIL

CL-USER 30 > (trace

(clos:slot-value-using-class

:when

(and (member (first *traced-arglist*)

(list (find-class 'foo)

(find-class 'bar)))

(eq (third *traced-arglist*) 'a))))

(CLOS:SLOT-VALUE-USING-CLASS)

CL-USER 31 > (foo-a *foo*)

42

CL-USER 32 > (bar-a *bar*)

0 CLOS:SLOT-VALUE-USING-CLASS > ...

>> CLASS : #<STANDARD-CLASS BAR 214897F4>

>> CLOS::OBJECT : #<BAR 2148820C>

>> CLOS::SLOT-NAME : A

0 CLOS:SLOT-VALUE-USING-CLASS < ...

<< VALUE-0 : 99

99

This session illustrates the :extra-initargs class option:

CL-USER 46 > (defclass a () ()

(:extra-initargs '(:a-initarg)))

#<STANDARD-CLASS A 21C2E4FC>

CL-USER 47 > (defclass b (a) ()

(:extra-initargs '(:b-initarg)))

#<STANDARD-CLASS B 2068573C>

CL-USER 48 > (defclass c (a) ())

#<STANDARD-CLASS C 22829D44>

CL-USER 49 > (make-instance 'b :a-initarg "A" :b-initarg "B")

#<B 2068BCE4>

CL-USER 50 > (make-instance 'c :a-initarg "A" :b-initarg "B")

Error: MAKE-INSTANCE is called with unknown keyword :B-INITARG among the arguments (C :A-INITARG "A" :B-INITARG "B") which is not one of (:A-INITARG).

1 (continue) Ignore the keyword :B-INITARG

2 (abort) Return to level 0.

3 Return to top loop level 0.

Type :b for backtrace, :c <option number> to proceed, or :? for other options