Uninterned symbols symbols - lisp

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.

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.

make-symbol added unwanted formatting to generated symbols

I'm trying to write a function primeify that accepts a symbol and returns the symbol with "-prime" appended to it. My desired output is:
[1] > (primeify 'y)
Y-PRIME
(or y-prime, the case isn't the main point here, although it may become relevant later).
Here's my current (erroneous) implementation:
(defun primeify (sym)
(make-symbol (concatenate 'string (string sym) "-prime")))
However, make-symbol is mangling the output by cluttering it with additional formatting. My output is:
[1]> (primeify 'y)
#:|Y-prime|
Is there any way to avoid this additional processing done by make-symbol, or another function I could use to accomplish this? Is this even possible to accomplish in lisp?
Your symbol:
#:|Y-prime|
This is a non-interned symbol. It is in no package. #: is in front of the symbol because of that.
It is also a symbol name with mixed case. Because of that it is escaped with vertical bars. Remember, by default symbol names are internally stored in UPPERCASE.
(defun primeify (sym)
(let ((name (concatenate 'string
(string sym)
"-PRIME")))
(if (symbol-package sym)
(intern name (symbol-package sym))
(make-symbol name))))
Above function gives the new symbol the same package as the original symbol has, if any.
CL-USER 3 > (primeify 'foo)
FOO-PRIME
NIL
CL-USER 4 > (primeify '#:foo)
#:FOO-PRIME

Common Lisp equality on symbol in web application

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"

How do I define a function that creates a function alias?

The Lisp forum thread Define macro alias? has an example of creating function alias using a form such as
(setf (symbol-function 'zero?) #'zerop)
This works fine, making zero? a valid predicate. Is it possible to parametrize this form without resorting to macros? I'd like to be able to call the following and have it create function?:
(define-predicate-alias 'functionp)`
My take was approximately:
(defun defalias (old new)
(setf (symbol-function (make-symbol new))
(symbol-function old)))
(defun define-predicate-alias (predicate-function-name)
(let ((alias (format nil "~A?" (string-right-trim "-pP" predicate-function-name))))
(defalias predicate-function-name alias)))
(define-predicate-alias 'zerop)
(zero? '())
This fails when trying to call zero? saying
The function COMMON-LISP-USER::ZERO? is undefined.
make-symbol creates an uninterned symbol. That's why zero? is undefined.
Replace your (make-symbol new) with e.g. (intern new *package*). (Or you may want to think more carefully in which package to intern your new symbol.)
Your code makes a symbol, via MAKE-SYMBOL, but you don't put it into a package.
Use the function INTERN to add a symbol to a package.
To expand on Lars' answer, choose the right package. In this case the default might be to use the same package from the aliased function:
About style:
Anything that begins with DEF should actually be a macro. If you have a function, don't use a name beginning with "DEF". If you look at the Common Lisp language, all those are macro. For example: With those defining forms, one would typically expect that they have a side-effect during compilation of files: the compiler gets informed about them. A function can't.
If I put something like this in a file
(define-predicate-alias zerop)
(zero? '())
and then compile the file, I would expect to not see any warnings about an undefined ZERO?. Thus a macro needs to expand (define-predicate-alias 'zerop) into something which makes the new ZERO? known into the compile-time environment.
I would also make the new name the first argument.
Thus use something like MAKE-PREDICATE-ALIAS instead of DEFINE-PREDICATE-ALIAS, for the function.
There are already some answers that explain how you can do this, but I'd point out:
Naming conventions, P, and -P
Common Lisp has a naming convention that is mostly adhered to (there are exceptions, even in the standard library), that if a type name is multiple words (contains a -), then its predicate is named with -P suffix, whereas if it doesn't, the suffix is just P. So we'd have keyboardp and lcd-monitor-p. It's good then, that you're using (string-right-trim "-pP" predicate-function-name)), but since the …P and …-P names in the standard, and those generated by, e.g., defstruct, will be using P, not p, you might just use (string-right-trim "-P" predicate-function-name)). Of course, even this has the possible issues with some names (e.g., pop), but I guess that just comes with the territory.
Symbol names, format, and *print-case*
More importantly, using format to create symbol names for subsequent interning is dangerous, because format doesn't always print a symbol's name with the characters in the same case that they actually appear in its name. E.g.,
(let ((*print-case* :downcase))
(list (intern (symbol-name 'foo))
(intern (format nil "~A" 'foo))))
;=> (FOO |foo|) ; first symbol has name "FOO", second has name "foo"
You may be better off using string concatenation and extracting symbol names directly. This means you could write code like (this is slightly different use case, since the other questions already explain how you can do what you're trying to do):
(defmacro defpredicate (symbol)
(flet ((predicate-name (symbol)
(let* ((name (symbol-name symbol))
(suffix (if (find #\- name) "-P" "P")))
(intern (concatenate 'string name suffix)))))
`(defun ,(predicate-name symbol) (x)
(typep x ',symbol)))) ; however you're checking the type
(macroexpand-1 '(defpredicate zero))
;=> (DEFUN ZEROP (X) (TYPEP X 'ZERO))
(macroexpand-1 '(defpredicate lcd-monitor))
;=> (DEFUN LCD-MONITOR-P (X) (TYPEP X 'LCD-MONITOR))

Am I missing some important fact about interning symbols in LISP?

To be brief. Here is my several tries to intern and use a symbol in clisp.
[1]> (setq sym (intern "foo"))
|foo|
[2]> (eq sym 'foo)
NIL
Why???
[3]> (defun internup (me &optional (package *package*))
(intern (string-upcase me) package))
INTERNUP
[4]> (eq 'abc (internup "abc"))
T
Probably must be upcase.
[12]>(let ((abc 2))
(eval '(+ 2 abc)))
*** - EVAL: variable ABC has no value
The following restarts are available:
ok
[18]> (let ((abc 2))
(eval '(+ 2 'abc)))
*** - +: ABC is not a number
The following restarts are available:
Interesting. Should I set it before.
[14]> (setq a (internup "abc"))
ABC
[15]> (let ((abc 2))
(eval '(+ 2 a)))
*** - +: ABC is not a number
The following restarts are available:
And again wrong. Hmm I must be missing some important fact about interning symbols in LISP. Can you help me ?
Your problem has nothing to do with interning.
The first problem is indeed causes by the fact that the reader will always uppercase the symbols, so you need to call (intern "FOO") in order to get the same result as 'foo.
The problem with EVAL is caused by the fact that LET introduces a lexical binding which is not visible inside EVAL. If you really want this to work you'd have to declare abc to be special, like so:
(let ((abc 2))
(declare (special abc))
(eval '(1+ abc)))
A special declaration will cause the variable to have dynamic binding, instead of lexical binding (the latter means that the binding is limited to the local lexical context, i.e. within the LET form. With the special declaration the variable is available to anything that is called by from that form).
Note that the use of both special declarations and eval is something you should be very careful about and you should probably rethink your use of EVAL in the first place. It is very rare that you actually need to use it. In most cases you're actually looking for the use of lambda functions instead.
Eval evaluates the form in the null lexical environment, i.e. with no lexical bindings. That has nothing to do with the interning of symbols.
The case-sensitivity of the Common Lisp reader is determined by the readtable:
(readtable-case *readtable*)
Typically the reader will initially intern symbols in uppercase (unless you explicitly escape characters). Hence:
(eq (intern "foo") 'foo) => NIL
(eq (intern "FOO") 'foo) => T
(eq (intern "FOo") 'fo\o) => T
You can use backquote syntax to build the form for eval:
(let ((abc 2))
(eval `(+ 2 ,abc)))
=> 4