Suppose a function fun
in the code below, my goal is evaluating expr2
below.
(defun fun (&key (x nil)) x)
(defparameter expr1 (list 'fun :x 2))
(defparameter expr2 (list 'fun (intern "x" "KEYWORD") 2))
As expected, (eval expr1)
gives 2
, but (eval expr2)
gives an error like
*** - FUN: illegal keyword/value pair :|x|, 2 in argument list. The allowed keywords are (:X) The following restarts are available: ABORT :R1 Abort main loop
Why does this error occurs? and How can I fix it?
The reason is that normally in Common Lisp every symbol is translated to uppercase letters when read (this is the standard behaviour, and can be changed), so that:
(defun fun (&key (x nil)) x)
(defparameter expr1 (list 'fun :x 2))
is actually read as:
(DEFUN FUN (&KEY (X NIL)) X)
(DEFPARAMETER EXPR1 (LIST 'FUN :X 2))
while intern
gets a string as first parameter and does not transform it, so that in your example "x" is interned as the symbol :x
, which is different from the symbol :X
(and this is the reason of the error). Note that when a symbol with lowercase letters is printed in REPL, it is surrounded by pipe characters (|
), like in |x|
, so that, when read again, lowercase characters are unchanged:
CL-USER> :x
:X
CL-USER> :|x|
:|x|
CL-USER> (format t "~a" :|x|)
x
NIL
To solve your problem, you can simply write the string directly in uppercase:
(defparameter expr2 (list 'fun (intern "X" "KEYWORD") 2))
and then (eval expr2)
works as intended.
Note that \
and |
are escape characters in symbols:
? 'foo\xBAR
FOO\xBAR
? '|This is a symbol|
|This is a symbol|
? ':|This is a keyword symbol with spaces and Capital letters!!!|
:|This is a keyword symbol with spaces and Capital letters!!!|
? 'what|? wow |this| also works|?
|WHAT? wow THIS also works?|
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With