R7RS小标准,第20-21页第4.2.8节Quasiquote说
(let ((a 3)) `((1 2) ,a ,4 ,'five 6))
相当于
`((1 2) 3 4 five 6)
和
(let ((a 3)) (cons '(1 2) (cons a (cons 4 (cons 'five '(6))))))
但不等同于:
(let ((a 3)) (list (list 1 2) a 4 'five 6))
上面的表达式怎么可能与前三个不同呢?以上四个表达式的求值结果都是一样的:'((1 2) 3 4 five 6)
。
示例前几行给出了原因(重点是我的):
对于在表达式求值期间运行时构造的任何结构,准引号表达式可以返回新分配的可变对象或文本结构不需要重建的部分始终是文字
这意味着在:
(let ((a 3)) `((1 2) ,a ,4 ,'five 6))
准引号内的部分(1 2)
必须视为文字,如在...'(1 2)...
中,而不是视为由其组件构建的结构,如在:...(list 1 2)...
中。
这似乎是一种过度指定,因为'(1 2)
的打印与(list 1 2)
完全相同,但第一个列表不能发生突变(或者,更好的是,如果发生突变,则存在未定义的行为),而第二个列表可以合法地发生突变。