Lisp中@(at-sign)的含义?

时间:2014-01-30 17:52:33

标签: lisp common-lisp

你们都知道这个故事:程序员读取其他人的代码,程序员看到他们不理解的符号,谷歌失败了,因为搜索非字母数字符号很困难。

这次是@符号,似乎用于将一个列表的内容注入另一个列表的中间。例如:

`(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 @

我猜这是一个基本语法,如反引号(`)或逗号(,)。它是否正确?很抱歉,如果这是重复的,但据我所知,再一次,我无法搜索@

3 个答案:

答案 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,你可以搜索commathe 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的信息,那么这本书是一本很好的阅读。