Question

The following function:

(defun check-for-arrow (x)
  (format t "**~s**~s**~s**~s**"
          (length (string x))
          x
          (eq x '->)
          (and (eq (elt (string x) 0) #\-)
               (eq (elt (string x) 1) #\>))) ; for debug
  (eq x '->))

when called from REPL, with:

(check-for-arrow '->)

prints, with tracing:

0> Calling (CHECK-FOR-ARROW ->) 
**2**->**T**T**
<0 CHECK-FOR-ARROW returned T

Instead, when called inside a Hunchentoot web application, over data read in a form, when called over the symbol '->', prints:

0> Calling (NORMALIZER::CHECK-FOR-ARROW ->) 
**2**->**NIL**T**
<0 NORMALIZER::CHECK-FOR-ARROW returned NIL

The Lisp is Clozure Common Lisp.

Does this depend on a different way of interning symbols ? It is possible to use 'eq' on symbols or I have to transform the arrow in a string and check for string equality?

Thanks.

Was it helpful?

Solution

Common Lisp has packages. Packages are kind of namespaces for symbols.

Thus one can have many different symbols named "->", each one in a different package.

Thus normalizer::-> is not necessarily EQ to cl-user::->.

Symbols can also be NOT interned in a package, thus one can have many different symbols of the same name and no a package.

CL-USER 2 > '#:->
#:->

CL-USER 3 > (describe *)

#:-> is a SYMBOL
NAME          "->"
VALUE         #<unbound value>
FUNCTION      #<unbound function>
PLIST         NIL
PACKAGE       NIL

CL-USER 4 > '->
->

CL-USER 5 > (describe *)

-> is a SYMBOL
NAME          "->"
VALUE         #<unbound value>
FUNCTION      #<unbound function>
PLIST         NIL

A typical problem:

One has a function which tests for EQ of something with a certain symbol FOO. The user inputs FOO.

But how does your Lisp function convert the user input into a symbol? In which package will the symbol be? Remember symbols differ by name AND package. If you don't specify the package, the default is the value of the variable CL:*PACKAGE*. But this variable can have different values at different times.

Just extend your test function to print the packages of the symbols and you will see the difference.

CL-USER 7 > (package-name (symbol-package '->))
"COMMON-LISP-USER"
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top