Common Lisp equality on symbol in web application
common-lisp, equality, hunchentoot, lisp, symbols
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"
Problem
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.