Common lisp 由两个管道包围的关键字符号
假设下面的代码中有一个函数Common lisp 由两个管道包围的关键字符号,common-lisp,symbols,Common Lisp,Symbols,假设下面的代码中有一个函数fun,我的目标是评估下面的expr2 (defun fun (&key (x nil)) x) (defparameter expr1 (list 'fun :x 2)) (defparameter expr2 (list 'fun (intern "x" "KEYWORD") 2)) 正如所料,(eval expr1)给出了2,但是(eval expr2)给出了如下错误 ***-乐趣:非法关键字/值对:| x |,参数列表中有2个。 允许的关键字为(:X)
fun
,我的目标是评估下面的expr2
(defun fun (&key (x nil)) x)
(defparameter expr1 (list 'fun :x 2))
(defparameter expr2 (list 'fun (intern "x" "KEYWORD") 2))
正如所料,(eval expr1)
给出了2
,但是(eval expr2)
给出了如下错误
***-乐趣:非法关键字/值对:| x |,参数列表中有2个。
允许的关键字为(:X)以下重新启动可用:中止:R1中止主循环
为什么会发生这种错误?我该如何修复它呢?原因是,通常在Common Lisp中,每个符号在读取时都会转换为大写字母(这是标准行为,可以更改),因此:
(defun fun (&key (x nil)) x)
(defparameter expr1 (list 'fun :x 2))
实际上被理解为:
(DEFUN FUN (&KEY (X NIL)) X)
(DEFPARAMETER EXPR1 (LIST 'FUN :X 2))
而intern
获取一个字符串作为第一个参数,并且不转换它,因此在您的示例中,“x”作为符号:x
,这与符号:x
不同(这就是错误的原因)。请注意,在REPL中打印带有小写字母的符号时,它会被管道字符(|
)包围,就像在|x |
中一样,因此,当再次读取时,小写字符不变:
CL-USER> :x
:X
CL-USER> :|x|
:|x|
CL-USER> (format t "~a" :|x|)
x
NIL
要解决您的问题,您只需直接用大写字母书写字符串:
(defparameter expr2 (list 'fun (intern "X" "KEYWORD") 2))
然后
(eval expr2)
按预期工作。注意\
和|
是符号中的转义字符:
? '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?|