3

I'm reading chapter 5.2 of PAIP. And when I try define a constant using the following form, taken exactly from the book, I get the error shown below. I'm using SBCL 1.1.14.debian as the interpreter. What am I doing wrong?

(defconstant no-bindings '((t . t))
  "Indicates pat-match success, with no variables.")

The constant NO-BINDINGS is being redefined (from (T T) to ((T . T)))

Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
flingjie
  • 53
  • 8

2 Answers2

2

The error means that you have done a previous definition of the same name no-bindings with the value '(T T).

For instance in the REPL you have done a definition:

(defconstant no-bindings '(t  t)
  "Indicates pat-match success, with no variables.")

and then you have redefined no-bindings with:

(defconstant no-bindings '((t . t))
  "Indicates pat-match success, with no variables.")

The manual specifies:

A constant defined by defconstant can be redefined with defconstant. However, the consequences are undefined if an attempt is made to assign a value to the symbol using another operator, or to assign it to a different value using a subsequent defconstant.

Updated

Note that in SBCL, even a double definition of the same value, for instance, writing twice in the REPL:

(defconstant no-bindings '((t . t))
  "Indicates pat-match success, with no variables.")

causes a constant redefinition error, while in other systems (I tried CCL), this does not happen. Actually this is due to the interpretation of "different value" in the above definition. The Glossary says the different is not the same, and same is not eql, and

 (eql '((t . t)) '((t . t)))

gives NIL, while other equality operators, as, for instance:

 (equal '((t . t)) '((t . t)))

returns T.

So, it seems that SBCL follows correctly the formal specification, differently from other systems.

Renzo
  • 26,848
  • 5
  • 49
  • 61
  • Thank you for your answer. I have checked my code, and don't find redefination. My code have added on my question. Could you help me to check out what cause that error? – flingjie Jul 08 '15 at 09:33
  • 3
    The CLHS indirectly defines “same” to mean “same under EQL” via the Glossary: “2. (of objects if no predicate is implied by context) indistinguishable by eql.” – BRPocock Jul 08 '15 at 18:14
  • 2
    Note also, ALEXANDRIA:DEFINE-CONSTANT allows specification of the test predicate, which is convenient for EQUALP structures. – BRPocock Jul 08 '15 at 18:15
  • flingjie, it is true that in your code you don't have a redefinition, but if you recompile or reload the file this is equivalent to a redefinition. – Renzo Jul 08 '15 at 20:37
  • @BRPocock, you are correct about CLHS, I changed my answer, thanks. – Renzo Jul 08 '15 at 20:51
1

A constant is per spec a value that is not suppose to be changed.. Thus you should use it for absolute certainties like (defconstant +pi+ 3.1415927).

In practice it's changeable, but every function or macro where it has been used might have taken advantage of it being a constant and compiled in the actual value so changing it won't be affected by those. Thus changing a constant should be done by a complete recompile/reload of everything to make make sure it's updated.

For values that are considered constant but you might change, use defparameter. eg. (defparameter *no-bindings* '((t . t)) "Indicates pat-match success, with no variables.").

Sylwester
  • 47,942
  • 4
  • 47
  • 79