Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 使用两个反引号和逗号,公共Lisp_List_Syntax_Common Lisp_Comma - Fatal编程技术网

List 使用两个反引号和逗号,公共Lisp

List 使用两个反引号和逗号,公共Lisp,list,syntax,common-lisp,comma,List,Syntax,Common Lisp,Comma,我正在学习common lisp,在理解两个反引号和两个逗号的用法时遇到了一个问题: ``(a ,,(+ 1 2)) 我的意思是,我不知道为什么它被评估为: `(A ,3) 而不是像这样: `(A 3) 我解释说,为了计算表单前面的两个反引号,两个逗号都被“消耗”,所以所有逗号都不应该离开,但仍然有一个。 你看起来怎么样 ``(a ,,(+ 1 2)) 仅使用列表和“?否,两个逗号都被使用。有两级引用和两级逗号。现在有一级引号和一级逗号。事实上,GNU Common Lisp(2.44.

我正在学习common lisp,在理解两个反引号和两个逗号的用法时遇到了一个问题:

``(a ,,(+ 1 2))
我的意思是,我不知道为什么它被评估为:

`(A ,3)
而不是像这样:

`(A 3)
我解释说,为了计算表单前面的两个反引号,两个逗号都被“消耗”,所以所有逗号都不应该离开,但仍然有一个。 你看起来怎么样

``(a ,,(+ 1 2))

仅使用列表和“?

否,两个逗号都被使用。有两级引用和两级逗号。现在有一级引号和一级逗号。事实上,GNU Common Lisp(2.44.1)将表达式计算为

(list 'a 3)
这和我的想法完全一样

`(a ,3)
但更明确的是,已“评估”规范中的两个逗号。

这是公共Lisp HyperSpec关于嵌套的说明:

如果反引号语法是嵌套的,则应首先展开最内部的反引号表单。这意味着,如果一行中出现多个逗号,则最左侧的逗号属于最内侧的反引号

R5RS方案规范还包括以下详细信息:

准注释形式可以嵌套。仅对出现在与最外层反引号相同嵌套级别的未引号组件进行替换。嵌套级别在每个连续的准旋转中增加一个,在每个取消引用中减少一个

还要记住,每次评估只有一个倒勾被折叠,就像一个普通的引号一样,它不是递归的

行动规则 为了了解这三个细节是如何相互作用的,让我们稍微扩展一下您的示例。这句话

``(a ,,(+ 1 2) ,(+ 3 4))
计算结果如下(以SBCL表示法):

  • 左回勾被折叠,因此
    (+12)
    被匹配的逗号(根据HyperSpec,第二个逗号)转义
  • 另一方面,
    (+34)
    没有足够的逗号进行扩展(这就是R5RS提到的)
  • 只有一个backtick被折叠,因为backtick不会递归展开
  • 扩展两个逗号 为了消除其他回扣,需要进行另一个级别的评估:

    (eval ``(a ,,(+ 1 2) ,(+ 3 4)))
    
    两个背景标记都消失了,我们只剩下一个简单的列表:

    (A 3 7)
    

    感谢您进一步举例说明一个更“病态”的案例(尽管我认为这是可怕的,而不是病态的)。此外,要了解“内部回溯形式应首先解释”和“行动规则”之间的关系,请参阅
    (A 3 7)