Next: Style Warnings, Previous: Compiler-only Implementation, Up: Idiosyncrasies
SBCL is quite strict about ANSI's definition of defconstant
.
ANSI says that doing defconstant
of the same symbol more than
once is undefined unless the new value is eql
to the old value.
Conforming to this specification is a nuisance when the “constant”
value is only constant under some weaker test like string=
or
equal
.
It's especially annoying because, in SBCL, defconstant
takes
effect not only at load time but also at compile time, so that just
compiling and loading reasonable code like
(defconstant +foobyte+ '(1 4))
runs into this undefined behavior. Many implementations of Common Lisp try to help the programmer around this annoyance by silently accepting the undefined code and trying to do what the programmer probably meant.
SBCL instead treats the undefined behavior as an error. Often such
code can be rewritten in portable ANSI Common Lisp which has the
desired behavior. E.g., the code above can be given an exactly defined
meaning by replacing defconstant
either with
defparameter
or with a customized macro which does the right
thing, eg.
(defmacro define-constant (name value &optional doc) `(defconstant ,name (if (boundp ',name) (symbol-value ',name) ,value) ,@(when doc (list doc))))
or possibly along the lines of the defconstant-eqx
macro used
internally in the implementation of SBCL itself. In circumstances
where this is not appropriate, the programmer can handle the condition
type sb-ext:defconstant-uneql
, and choose either the
continue or abort restart as appropriate.