Common Lisp equality on symbol in web application - lisp

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.

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"

Related

Common Lisp symbol equality

In most of the examples on the Internet, symbol equality is straight-forward:
(eq 'sym 'sym)
t
In my program, I want to compare symbols in a custom package:
(defpackage #:my-package
(:use #:common-lisp)
(:export #:my-function))
(in-package #:my-package)
(defun my-function (value)
(cond
((eq value 'sym)
(format t "SYM: YES~%"))
(t
(format t "SYM: NO~%"))))
(in-package #:common-lisp)
(my-package:my-function 'sym)
But when this code is executed, it displays:
SYM: NO
It seems like the 2 symbols are different:
(eq 'sym 'my-package::sym)
nil
The reason seems easy to understand, a symbol interned in a given package is not equal to a symbol with the same name interned in another package. Fair enough! But what is the idiom to compare 2 symbols, regardless the package?
Should we convert it to a string in a first place and compare strings?
(defpackage #:my-package
(:use #:common-lisp)
(:export #:my-function))
(in-package #:my-package)
(defun my-function (value)
(cond
((string= (symbol-name value) "SYM")
(format t "SYM: YES~%"))
(t
(format t "SYM: NO~%"))))
(in-package #:common-lisp)
(my-package:my-function 'sym)
The result is better, but there is an obvious issue regarding the character case.
How to check that 2 symbols are the same regardless their package?
The usual idiom is string=, which compares the names of symbols without regard to identity.
For example:
(eq 'x:a 'y:a) => nil
(string= 'x:a 'y:a) => t
I think you are confused about what 'being the same symbol' means.
Two symbols are the same symbol iff they are eq, which means that if they are not eq they are not the same symbol. In particular if two symbols have home packages which are different (again: not eq) they are not the same symbol.
If you want to know if two symbols have the same name then simply compare their symbol-names, as strings. But two symbols which merely have the same name are not necessarily the same symbol (for instance (eq '#:foo '#:foo) is false).
There are cases where it is useful to know whether two symbols have the same name (for instance the loop macro must do this so that (loop for ...) and (loop :for ...) mean the same thing) but these cases are fairly rare.
If what you want to do is know if two symbols have the same names you quite likely should be using strings instead.
If what you actually want to know is whether two symbols accessed from different packages are really the same symbol (so (eq 'x:foo 'y:foo), say) then eq is the appropriate test, and understanding the package system also helps.

sublis not substituting symbols when called from another package

In my function I am reading input from the user which is expected to be a lisp form given as a string e.g.:
(sym1 sym2 (sym3 sym4))
My goal is to substitute some of the symbols with other symbols e.g.:
(sublis '((sym1 . sym1%)
(sym2 . sym2%))
str)
Because I am getting the input as a string, I am first converting it to a lisp form. Here is how the final function looks like:
(defun sublis-when-string (str)
(sublis '((sym1 . sym1%)
(sym2 . sym2%))
(read-from-string str)))
When I compile the function and run it in the REPL with (sublis-when-string "(sym1 sym3 (sym2 sym4))") I correctly get:
(SYM1% SYM3 (SYM2% SYM4))
However when I run the whole program the substitutions do not work:
(SYM1 SYM3 (SYM2 SYM4))
This lead me to believe that the problems is with the package. When I changed the package in the REPL the substitutions were still not working.
My question is: How should I change my function so it works when called from other packages?
If you want to use your function independently from the package in which the symbols are read, you can change your definition by adding an explicit test: when the values to be checked are symbols, the string= operator is used instead of default eql. For instance:
(defun sublis-when-string (str)
(sublis '((sym1 . sym1%)
(sym2 . sym2%))
(read-from-string str)
:test (lambda (x y)
(if (and (symbolp x) (symbolp y))
(string= x y)
(eql x y)))))
See the definition of sublis.
You can define a package for your user:
(defpackage :my-user (:use) (:export #:sym1 #:sym2))
Of course, the exported symbols are the one you need to add in your substitution list. And then, you bind the *package* variable before reading:
(let ((*package* (find-package :my-user)))
(read-from-string string))
Notice that all the symbols will be read from the :my-user package.
Depending on how much you trust the source of your strings, you can also set *read-eval* to nil and define a minimalistic readtable too:
disable array notation that allocate very large arrays like #n() (bad user exhausting memory on purpose)
make : a terminating character to make qualified symbols throw an error (bad user interning symbols in other packages)

Are symbols and names different?

Are symbols and names different? On Lisp by Paul Graham, which focuses on common lisp, has some discussions that seem to imply so, e.g.
Since lambda-expressions are also names of functions, they can also appear first in function calls:
((lambda (x) (* x 2) 3)
6
This makes it sound like symbols are names but names aren't symbols. But I don't understand what sort of Lisp "object" symbols are / could be.
This is also deriving from my question here on the sharp-quote (#') operator v. symbol-function. I'm suspecting the only reason these are different is because not all names are symbols but I don't have enough background to understand those answers yet (hence this question).
I'm also asking for clarification in elisp v. common lisp. I'm assuming this pertains to lexical form, which wasn't introduced in elisp until version 24 (24.1 I think).
Lambda Expressions are not names of functions. It's just that ((lambda (...) ...) ...) is allowed in Common Lisp, since it is defined in the standard as legal syntax.
The only allowed function names in Common Lisp are symbols and lists like (setf symbol).
For example one can write
(defun (setf foo) (...) ...)
Here (setf foo) is the function name.
Other function names don't exist in Common Lisp, only symbols and (setf symbol) names.
Common Lisp Hyperspec Glossary: Function Name.
function name n. 1. (in an environment) A symbol or a list (setf
symbol) that is the name of a function in that environment. 2. A
symbol or a list (setf symbol).
Note: the Common Lisp version of 1984 (as published in CLtL1) did only have symbols as function names. Thus the idea of a function name was not defined. The function to retrieve a function from a symbol was called SYMBOL-FUNCTION. In 1989 the ANSI CL standardization group decided to add setf lists as function names. It also introduced the function FDEFINITION, which is like SYMBOL-FUNCTION but also accepts other function names, besides symbols. See here: Issue FUNCTION-NAME.
I think Rainer's answer gets this right, but since the question appeared in a comment on my answer to another question, I'll include (an update to) my response from that comment.
A symbol is an actual object. You can inspect it, you can create them with make-symbol, etc. Importantly, symbols are one of the primary components of source code in Common Lisp. Function names, especially in the context that this question arose in (arguments to the function special operator) are either symbols or lists of the form (setf symbol) according to the glossary entry:
function name n. 1. (in an environment) A symbol or a list (setf symbol) that is the name of a function in that environment. 2. A
symbol or a list (setf symbol).
Function is a special operator that doesn't evaluate its arguments, so passing a symbol or setf list means something like:
(function car)
(function (setf car))
and not:
(function 'car)
(function '(setf car))
Now, lexical variables, e.g., x in (let ((x 42)) x), while represented by symbols in the source code, don't actually have any connection with the symbol at runtime. The compiled version of (let ((x 42)) x) doesn't need to know anything about the symbol x. Intuitively, this makes sense, because we'd expect the code (let ((y 42)) y) to compile to the same thing. However, when a variable is special, there is a connection with the symbol. The difference is clearest with:
(let ((x 42))
(symbol-value x))
;=> NIL
(let ((x 42))
(declare (special x)) ; or (defparameter x ...) or (defvar x ...) earlier
(symbol-value x))
;=> 42
We'd expect the same thing to be true of lexically scoped functions, e.g., the following code causes an error because there's no connection between the symbol x at runtime and the local function:
(flet ((x () 42))
(symbol-function 'x)) ; ERROR, no function value for symbol x
But even so, we can still do:
(flet ((x () 42))
(function x))
This is because function is special operator and can access the environment where is occurs. That means that (because it's special, and the implementation makes it work) it can know that x is defined as function here. It may be interesting to note, now, that since flet and labels are defined to take a function name, you can do:
(flet (((setf kar) (value kons)
...))
...)

Merging symbols in common lisp

I want to insert a char into a list. However, I want to merge this char with the last symbol in the list. With appends and cons the result is always two different symbols. Well, I want one merged symbol to be my result.
Example:
(XXXX 'a '5) ====> (a5)
What I would like to have, instead of:
(XXXX 'a '5) ====> (a 5)
You cannot "merge symbols" in Lisp.
First of all, 5 is not a symbol, but a number. If you want a symbol named "5" you have to type it as |5| (for example).
If a function takes the symbol A and symbol |5|, and produces the symbol A5, it has not merged symbols. It has created a new symbol whose name is the catenation of the names of those input symbols.
Properly designed Lisp programs rarely depend on how a symbol is named. They depend on symbols being unique entities.
If you're using symbols to identify things, and both 5 and A identify some entity, the best answer isn't necessarily to create a new symbol which is, in name at least, is a mashup of these two symbols. For instance, a better design might be to accept that names are multi-faceted or compound in some way. Perhaps the list (A 5) can serve as a name.
Common Lisp functions themselves can have compound names. For instance (setf foo) is a function name. Aggregates like lists can be names.
If you simply need the machine to invent unique symbols at run-time, consider using the gensym function. You can pass your own prefix to it:
(gensym "FOO") -> #:FOO0042
Of course, the prefix can be the name of some existing symbol, pulled out via symbol-name. The symbol #:FOO0042 is not unique because of the 0042 but because it is a freshly allocated object in the address space. The #: means it is not interned in any package. The name of the symbol is FOO0042.
If you still really want to, a simple way to take the printed representation of a bunch of input objects and turn it into a symbol is this:
(defun mashup-symbol (&rest objects)
(intern (format nil "~{~a~}" objects)))
Examples:
(mashup-symbol 1 2 3) -> |123|
(mashup-symbol '(a b) 'c 3) -> |(A B)C3|
Define this:
(defun symbol-append (&rest symbols)
(intern (apply #'concatenate 'string
(mapcar #'symbol-name symbols))))
and then use it as:
* (symbol-append 'a 'b 'c)
ABC
* (apply #'symbol-append '(a b c))
ABC
If you expect your arguments to contain stuff besides symbols, then replace symbol-name with:
(lambda (x)
(typecase x ...))
or a pre-existing CL function (that I've forgotten :() that stringifies anything.
The answer to the question you ask is
(defun concatenate-objects-to-symbol (&rest objects)
(intern (apply #'concatenate 'string (mapcar #'princ-to-string objects))))
(concatenate-objects 'a 'b) ==> ab
Oh, if you want a list as the result:
(defun xxxx (s1 s2) (list (concatenate-objects-to-symbol s1 s2)))
However, I am pretty sure this is not the question you actually want to ask.
Creating new symbols programmatically is not something beginners should be doing...

Uninterned symbols symbols

There is something I can't understand about Common lisp.
Assume I'm writing a macro similar to this:
(defmacro test-macro ()
(let ((result (gensym)))
`(let ((,result 1))
(print (incf ,result)))))
Than I can do
> (test-macro)
2
2
Now I want to see how it expands
> (macroexpand-1 '(test-macro))
(LET ((#:G4315 1)) (PRINT (INCF #:G4315))) ;
T
Ok. There are unique symbols generated with gensym that were printed as uninterned.
So as far as I know the uninterned symbols are the symbols for which the evaluator does't create symbol-data binding internally.
So, if we macro-expand to that form there should be an error on (incf #:G4315).
To test this we can just evaluate that form in the REPL:
> (LET ((#:G4315 1)) (PRINT (INCF #:G4315)))
*** - SETQ: variable #:G4315 has no value
So why does the macro that expands to this string works perfectly and the form itself does not?
Symbols can be interned in a package or not. A symbol interned in a package can be looked up and found. An uninterned symbol can't be looked up in a package. Only one symbol of a certain name can be in a package. There is only one symbol CL-USER::FRED.
You write:
So as far as I know the uninterned symbols are the symbols for which the evaluator does't create symbol-data binding internally.
That's wrong. Uninterned symbols are symbols which are not interned in any package. Otherwise they are perfectly fine. interned means registered in the package's registry for its symbols.
The s-expression reader does use the symbol name and the package to identify symbols during reading. If there is no such symbol, it is interned. If there is one, then this one is returned.
The reader does look up symbols by their name, here in the current package:
(read-from-string "FOO") -> symbol `FOO`
a second time:
(read-from-string "FOO") -> symbol `FOO`
it is always the same symbol FOO.
(eq (read-from-string "FOO") (read-from-string "FOO")) -> T
#:FOO is the syntax for an uninterned symbol with the name FOO. It is not interned in any package. If the reader sees this syntax, it creates a new uninterned symbol.
(read-from-string "#:FOO") -> new symbol `FOO`
a second time:
(read-from-string "#:FOO") -> new symbol `FOO`
Both symbols are different. They have the same name, but they are different data objects. There is no other registry for symbols, than the packages.
(eq (read-from-string "#:FOO") (read-from-string "#:FOO")) -> NIL
Thus in your case (LET ((#:G4315 1)) (PRINT (INCF #:G4315))), the uninterned symbols are different objects. The second one then is a different variable.
Common Lisp has a way to print data, so that the identity is preserved during printing/reading:
CL-USER 59 > (macroexpand-1 '(test-macro))
(LET ((#:G1996 1)) (PRINT (INCF #:G1996)))
T
CL-USER 60 > (setf *print-circle* t)
T
CL-USER 61 > (macroexpand-1 '(test-macro))
(LET ((#1=#:G1998 1)) (PRINT (INCF #1#)))
T
Now you see that the printed s-expression has a label #1= for the first symbol. It then later references the same variable. This can be read back and the symbol identities are preserved - even though the reader can't identify the symbol by looking at the package.
Thus the macro creates a form, where there is only one symbol generated. When we print that form and want to read it back, we need to make sure that the identity of uninterned symbols is preserved. Printing with *print-circle* set to T helps to do that.
Q: Why do we use uninterned generated symbols in macros by using GENSYM (generate symbol)?
That way we can have unique new symbols which do not clash with other symbols in the code. They get a name by the function gensym- usually with a counted number at the end. Since they are fresh new symbols not interned in any package, there can't be any naming conflict.
CL-USER 66 > (gensym)
#:G1999
CL-USER 67 > (gensym)
#:G2000
CL-USER 68 > (gensym "VAR")
#:VAR2001
CL-USER 69 > (gensym "PERSON")
#:PERSON2002
CL-USER 70 > (gensym)
#:G2003
CL-USER 71 > (describe *)
#:G2003 is a SYMBOL
NAME "G2003"
VALUE #<unbound value>
FUNCTION #<unbound function>
PLIST NIL
PACKAGE NIL <------- no package
gensym generate a symbol and when you print it you get the "string" representation of that symbol which isn't the same thing as "reader" representation i.e the code representation of the symbol.