Lisp 函数的意外结果(递归)

Lisp 函数的意外结果(递归),lisp,common-lisp,Lisp,Common Lisp,我需要实现一个函数,该函数根据传递给函数的参数创建一个列表 这是我的密码: (defun lstbuilder (&rest args) (if (eq (car args) NIL) NIL (cons (car args) (lstbuilder (cdr args))))) 此功能无法正常工作。 结果: 您需要使用(apply#'lstbuilder(cdr args)),以“splat”列表的内容作为函数调用参数。样式 请使

我需要实现一个函数,该函数根据传递给函数的参数创建一个列表

这是我的密码:

(defun lstbuilder (&rest args)
  (if (eq (car args) NIL)
      NIL
      (cons (car args)
            (lstbuilder (cdr args)))))
此功能无法正常工作。 结果:

您需要使用
(apply#'lstbuilder(cdr args))
,以“splat”列表的内容作为函数调用参数。

样式

  • 请使用标准Lisp格式。使用编辑器将帮助您缩进Lisp代码

  • 不要把括号单独放在一行上。这只会浪费空间,毫无益处

  • 较长的名称在单词之间有一个
    -
    列表生成器

  • 不要使用
    car
    cdr
    进行列表操作。首先使用
    rest

  • 列表结束测试是
    endp

例如:

(defun list-builder (&rest args)
  (if (endp args)
      nil
    (cons (first args)
          (apply #'list-builder (rest args)))))
由于
args
变量已经是一个列表,我们可以复制它:

(defun list-builder (&rest args)
  (copy-list args))
或者我们可以重用
list
函数,它已经创建了一个参数列表:

(setf (symbol-function 'list-builder)
      #'list)

谢谢您能告诉我如何从函数返回此列表吗?“&rest参数的传入列表已经是新分配的列表。”实际上,它不一定是新分配的列表。使用APPLY调用的函数的&rest参数的值可以与要应用的列表参数共享结构。具体地说,函数说:“当函数通过&rest接收其参数时,实现允许(但不是必需)将rest参数绑定到与要应用的最后一个参数共享结构的对象。因为函数既无法检测是否通过apply调用它,也无法检测是否(如果是)调用它最后一个要应用的参数是一个常量,一致性程序既不能依赖新创建的rest列表的列表结构,也不能修改该列表结构。“@Joshua谢谢!那么我将删除该注释。仅供参考,这里是R5R的一部分,它说列表总是新分配的。In:“syntax:(lambda)…应具有以下形式之一:…(…):…存储在最后一个变量的绑定中的值将是一个新分配的实际参数列表,其中列出了所有其他实际参数与其他形式参数匹配后剩余的实际参数。”如果您没有用
(defun lstbuilder(&rest args)args)
这种更简单的方法实现它,那么我认为if是根据elisp样式而不是普通的lisp缩进的,结果是缩进更多。@puercopp:实际上这是LispWorks中的默认缩进样式。我不知道这一点。我想知道为什么,在elisp中,这是因为else子句被包装在一个外部progn中,所以这就是justification@PuercoPop:也许它提供了更多的视觉线索。顺便说一句,在Zmacs中,可以缩进,然后通过几个缩进备选方案进行旋转。
(setf (symbol-function 'list-builder)
      #'list)