你们都知道这个故事:程序员读取其他人的代码,程序员看到他们不理解的符号,谷歌失败了,因为搜索非字母数字符号很困难。
这次是@
符号,似乎用于将一个列表的内容注入另一个列表的中间。例如:
`(5 6 7 ,@'(8 9) 10 11)
;=> (5 6 7 8 9 10 11)
我很满意这种用法,但我想知道我是否正确理解了@
的行为?它有其他用途吗?以下成绩单(来自CLISP)导致错误的原因是什么?
[1]> (list 1 2 3 4 @'(5 6 7))
*** - SYSTEM::READ-EVAL-PRINT: variable @ has no value
最后,究竟是什么 @
?它似乎不是一个功能:
[3]> (print #'@)
*** - FUNCTION: undefined function @
我猜这是一个基本语法,如反引号(`
)或逗号(,
)。它是否正确?很抱歉,如果这是重复的,但据我所知,再一次,我无法搜索@
。
答案 0 :(得分:14)
在HyperSpec的背面引用部分中描述了它:
2.4.6 Backquote
如果逗号后面紧跟着一个逗号,那么就是表格 评估at符号以生成对象列表。这些 然后将对象“拼接”到模板中的适当位置。例如, 如果
x
的值为(a b c)
,那么`(x ,x ,@x foo ,(cadr x) bar ,(cdr x) baz ,@(cdr x)) => (x (a b c) a b c foo b bar (b c) baz b c)
值得注意的是,,@
并非总是必要的;根据相同的文件:
可以使用Anywhere“,@”,而不是使用语法“,。” 表明允许在列表上破坏性地操作 由“,”之后的形式产生的结构(实际上,使用 nconc而不是追加)。
当你you ask时,你的直觉大多是正确的,“所以基本上@本身就没有任何意义,唯一真正的算子是,@?” @
可以在其他地方用作普通信件。这就是为什么你得到你提到的错误:(list 1 2 3 4 @'(5 6 7))
只是
(list 1 2 3 4 @ '(5 6 7))
和@
是一个变量,但此处没有值。与之相比:
(let ((@ 4.5))
(list 1 2 3 4 @ '(5 6 7)))
;=> (1 2 3 4 4.5 (5 6 7))
很抱歉,如果这是重复的,但据我所知,再一次 不可能搜索“@”。
搜索某些非字母数字字符的文档可能很困难,但我发现了一些可以提供帮助的技巧。例如,如果你去lispdoc.com,你可以搜索comma
,the results there会让你走向反引号。 (搜索at-sign虽然没有帮助。)这不是一个完美的解决方案,但它有时会有所帮助。
答案 1 :(得分:5)
,@
应被视为单个实体,,@
的含义是将以下表达式拼接到当前的准引用列表中。
例如,您无法使用
`,@x
因为准引用的表达式不是列表而,@
需要拼接列表。
同样(在我阅读标准时)你不能使用
`(list ,@5)
因为5
不是列表(但是SBCL和CLISP都允许它并扩展为(list . 5)
)。
实际上SBCL和CLISP的行为是可以接受的,但如果,@
与非列表参数一起使用,则兼容的实现也会出错。
CLHS section 2.4.6 `((,a b) ,c ,@d)
的最后一次可能扩展表明,为非列表提出错误也是可以接受的。
答案 2 :(得分:1)
逗号用于CL中的列表拼接。它将列表内容放入包含它的表达式中,删除列表的最外面的parantheses。 保罗格雷厄姆现在免费提供的书"On Lisp"包含更多关于它的细节,如果我的思想对我有用,如果你想了解更多有关高级Lisp的信息,那么这本书是一本很好的阅读。