keyword symbol enclosed by two pipes
Asked Answered
O

2

5

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?

Octahedral answered 19/6, 2019 at 0:37 Comment(0)
E
8

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.

Eldrida answered 19/6, 2019 at 6:37 Comment(0)
C
5

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?|
Charo answered 19/6, 2019 at 7:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.