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

App*_*ish 17 lisp common-lisp

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

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

`(5 6 7 ,@'(8 9) 10 11)
;=> (5 6 7 8 9 10 11)
Run Code Online (Sandbox Code Playgroud)

我很满意这种用法,但我想知道我是否理解@正确的行为?它有其他用途吗?以下成绩单中的错误是什么原因(来自CLISP)?

[1]> (list 1 2 3 4 @'(5 6 7))

*** - SYSTEM::READ-EVAL-PRINT: variable @ has no value
Run Code Online (Sandbox Code Playgroud)

最后,到底 @什么?它似乎不是一个功能:

[3]> (print #'@)

*** - FUNCTION: undefined function @
Run Code Online (Sandbox Code Playgroud)

我猜这是一个基本的语法,如backquote(`)或逗号(,).它是否正确?对不起,如果这是重复的,但是再一次,据我所知,它是不可能搜索的@.

Jos*_*lor 14

",@"用于在反引号内拼接...

它在HyperSpec的backquote部分中描述:

2.4.6反引号

如果逗号后面紧跟着符号,则会评估符号后面的表单以生成对象列表.然后将这些对象"拼接"到模板中的适当位置.例如,如果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)
Run Code Online (Sandbox Code Playgroud)

值得注意的是,这,@并非总是必要的; 根据相同的文件:

可以使用Anywhere",@",而不是使用语法",."来表示允许在","之后的表单生成的列表结构上进行破坏性操作(实际上,使用nconc代替附加).

......但"@"本身只是另一封信......

你问道时,你的直觉大多是正确的,"所以基本上@本身就没有任何意义,唯一真正的运算符是,@?" @可以在其他地方用作普通字母.这就是为什么你得到你提到的错误:(list 1 2 3 4 @'(5 6 7))简单

(list 1 2 3 4 @ '(5 6 7))
Run Code Online (Sandbox Code Playgroud)

并且@是一个变量,但它在这里没有值.与之相比:

(let ((@ 4.5))
  (list 1 2 3 4 @ '(5 6 7)))
;=> (1 2 3 4 4.5 (5 6 7))
Run Code Online (Sandbox Code Playgroud)

......遗憾的是,这很难找到.

很抱歉,如果这是重复的,但据我所知,再一次,我不可能搜索"@".

搜索某些非字母数字字符的文档可能很困难,但我发现了一些可以提供帮助的技术.例如,如果你去lispdoc.com,你可以搜索comma,结果会让你走向反引号.(搜索at-sign虽然没有帮助.)这不是一个完美的解决方案,但它有时会有所帮助.


650*_*502 5

,@应被视为单个实体,其含义,@是将以下表达式拼接到当前的准引用列表中.

例如,你不能使用

`,@x
Run Code Online (Sandbox Code Playgroud)

因为准引用的表达式不是列表,,@需要拼接列表.同样(在我阅读标准时)你不能使用

`(list ,@5)
Run Code Online (Sandbox Code Playgroud)

因为5它不是一个列表(但是SBCL和CLISP都允许它并扩展到(list . 5)).

编辑

实际上,SBCL和CLISP的行为是可以接受的,但如果,@与非列表参数一起使用,则兼容的实现也可以接受错误.

CLHS第2.4.6节最后可能扩展的`((,a b) ,c ,@d)节目也可以接受为非列表提出错误.