Next: , Previous: Compiler-only Implementation, Up: Idiosyncrasies


1.3.3 Defining Constants

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.