Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/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
在emacs lisp中使用nconc的奇怪行为_Emacs_Elisp - Fatal编程技术网

在emacs lisp中使用nconc的奇怪行为

在emacs lisp中使用nconc的奇怪行为,emacs,elisp,Emacs,Elisp,我有以下功能(简化为该版本): 如果我多次计算函数(append test'((foo))列表的大小会不断增加,但我不明白为什么。ncoc修改原始列表,但是因为原始列表是函数参数或let变量,所以每次调用都应该重新创建它们,对吗?这里发生了什么?如果将`(条形)更改为(列表条形),则代码每次都返回相同的结果 ncoc修改除最后一个参数外的所有参数。显然,如果第一个参数是”(bar),那么函数定义中包含的引用列表将被修改,我们希望看到您看到的结果。显然,使用不包含任何逗号的反引号表达式等同于使用带

我有以下功能(简化为该版本):

如果我多次计算函数
(append test'((foo))
列表的大小会不断增加,但我不明白为什么。
ncoc
修改原始列表,但是因为原始列表是函数参数或let变量,所以每次调用都应该重新创建它们,对吗?这里发生了什么?

如果将
`(条形)
更改为
(列表条形)
,则代码每次都返回相同的结果

ncoc
修改除最后一个参数外的所有参数。显然,如果第一个参数是
”(bar)
,那么函数定义中包含的引用列表将被修改,我们希望看到您看到的结果。显然,使用不包含任何逗号的反引号表达式等同于使用带引号的列表

实际上,下面的代码保留了反引号,但在列表的cdr中添加了一个无意义的表达式。显然,这使得它在每次调用函数时都分配一个新列表,因此每次都返回相同的结果:

(defun append-test (xs)
 (let ((ys `(foo ,(nconc `(bar . ,(ignore)) xs))))
    (nconc ys `((baz)))))

我被这个咬了。下面是一些导致的错误

这个问题似乎是lisp开发人员的必经之路。:-)

据我所知,lisp评估分为两个阶段:
  • 读取:静态分配存储并将窗体读入内存的读取器
  • 评估:对读取的表单进行评估
  • 那么
    报价
    呢?
    quote
    只返回已读表单,无需计算

    含蓄地

  • 当计算
    报价
    表单时,它只返回分配的读卡器 直接反对
  • 当重新评估
    报价
    表单(即函数调用等)时,它返回 同一个读卡器分配的对象
  • 引用
    不分配新内存

  • 塔达

    你能详细说明一下吗?xs是一个参数,ys是let变量,其余的列表是函数返回值(引号或列表)。对于每个函数调用,所有这些都应该是“新的”,但很明显,其中一些是由nconc共享和修改的。共享的是第一次
    nconc
    调用中的
    (条形)
    列表。它在函数定义中保留为带引号的值,因此每次调用
    ncoc
    时它的值都会发生变化。@Masse不要混淆分配和绑定<代码>让绑定,但它不会自行分配新存储。分配取决于绑定的右侧,带引号的列表由读取器静态分配,因此您的
    let
    在每次调用时绑定到相同的静态分配列表。考虑下面的更简单的例子:可能的副本
    (defun append-test (xs)
     (let ((ys `(foo ,(nconc `(bar . ,(ignore)) xs))))
        (nconc ys `((baz)))))