Common Lisp反引号表达式疑问:为何示例1可行示例2报错?
为什么示例1能正常定义,示例2触发错误?
核心区别:反引号(`)和单引号(')的作用
在Common Lisp里:
- 单引号(') 是
quote的简写,作用是原封不动引用整个表达式,让Lisp把括号里的内容当成字面量列表处理。但它不支持任何插值语法,Lisp阅读器碰到单引号里的,,,@这类符号时,会判定这是非法语法——因为这些符号只有在反引号的上下文里才有意义。 - 反引号(
)** 是backquote`的简写,叫准引用**,它允许你在引用的表达式里插入动态计算的值:,用来插入单个值,@用来把一个列表的所有元素直接拼接到当前列表里
具体示例拆解
示例1:用反引号的合法写法
(defun exprbis (&rest xs) `(+ (* 2 ,@xs) 1))
反引号告诉Lisp:整体保留这个列表结构,但要把,@xs替换成参数xs的所有元素(因为xs是&rest参数,本身就是个列表)。比如调用(exprbis 3 4)会生成(+ (* 2 3 4) 1),完全符合语法,所以函数能正常定义。
示例2:用单引号的错误写法
(defun exprbis (&rest xs) '(+ (* 2 ,@xs) 1))
单引号要求Lisp原封不动地把括号里的内容当成字面量,但里面的,@xs是反引号专属的插值语法,Lisp阅读器解析时发现逗号不在反引号包裹的范围内,根本不知道该怎么处理,所以直接抛出SB-INT:SIMPLE-READER-ERROR错误,提示“Comma not inside a backquote”(逗号不在反引号内)。
一句话总结:,,,@是反引号语法的专属内容,只能在反引号包裹的表达式里用,单引号里用这些符号就是语法错误。
内容的提问来源于stack exchange,提问作者Jorge Robla
相关产品推荐
相关产品推荐

