Lisp 以列表作为参数进行defun

Lisp 以列表作为参数进行defun,lisp,common-lisp,Lisp,Common Lisp,我正在尝试使用Lisp作为我的新语言,在解决如何让函数的某些部分在传递给它的列表的每个元素上工作时遇到了一些问题 为了学习如何解决这个问题,我试图编写一个相当基本的除法形式,当列表中的一个元素为0时,除法不会发出嘎嘎声(而是只返回0) 我尝试以以下方式运行此操作: (divtest '(20 2 5)) 这将产生: *** - /: (20 2 5) is not a number 失败点似乎源于这样一个事实:在将元素传递给函数之前,我没有“提取”列表中的元素(在这种情况下,dolist和/

我正在尝试使用Lisp作为我的新语言,在解决如何让函数的某些部分在传递给它的列表的每个元素上工作时遇到了一些问题

为了学习如何解决这个问题,我试图编写一个相当基本的除法形式,当列表中的一个元素为0时,除法不会发出嘎嘎声(而是只返回0)

我尝试以以下方式运行此操作:

(divtest '(20 2 5))
这将产生:

*** - /: (20 2 5) is not a number
失败点似乎源于这样一个事实:在将元素传递给函数之前,我没有“提取”列表中的元素(在这种情况下,dolist和/或dolist都不能按预期工作,因为x的计算结果永远不会为0)。 如果我是对的,有人能告诉我如何进行“提取”吗



注意:这个问题与相关,但我不清楚上一个答案的哪一部分实际上允许它在这个特定问题上按预期工作,因此我决定进一步深入基础知识

尝试使用
(apply/elements)
代替
(/elements)
。我认为(?)这在大多数Lisp方言中应该是可行的。

/
将一个或多个数字作为参数,但在代码中,您传递给它的是一个列表-显然这不起作用。函数
apply
是您在这里的朋友-
(apply#foo a b(list c d e))
相当于
(foo a b c d e)
。请注意,要使用的函数和最终列表之间的
apply
参数是可选的,因此
(apply#'/'(20 2 5))
相当于
(/20 2 5)

此外,删除零的尝试也不会起作用
dolist
正在为参数列表
elements
中的每个项评估其主体,但实际上您并没有做任何事情来更改
elements
的内容(评估
dolist
主体的结果并没有像您预期的那样重新分配给源元素)

您需要的功能是
remove if
(及其破坏性对应的
delete if
)。下面展示了如何使用它(它需要很多可选参数,您不必为此担心)

还要注意的是,如果
元素
列表的第一个元素为零(假设我理解函数的作用),那么这将无法正常工作。所以你可能会想要像这样的东西

(defun divtest (elements)
  (apply #'/ (first elements) (remove-if #'zerop (rest elements))))

有关详细信息,请参阅Hyperspec。

或者您可以这样编写它

(defun divtest (elements)
  (if (member 0 elements)
      0
      (apply #'/ elements)))

除非您为
/
的数据单元分配了一个函数,否则您需要引用
/
。好奇的是:这有什么用?这样您可以处理任意长列表,而不仅仅是那些调用参数限制(标准CL常量)最大长度的列表。Common Lisp具有一个依赖于实现的最大参数数。此数字必须为50或更大。这意味着一个实现只需要支持50个参数(或更多)。因此,在某些实现中,如果数字列表长于调用函数/allows的参数数量,则上述函数可能会失败。如果使用REMOVE-IF“尝试处理第一个元素”,则没有任何警告,因为它是一个非破坏性函数。单纯依赖DELETE-IF的副作用有一个警告,其中副作用已破坏列表仍将包含其head元素,因此您仍应将返回值分配给原始存储。
(defun divtest (elements)
  (apply #'/ (first elements) (remove-if #'zerop (rest elements))))
(defun divtest (elements)
  (if (member 0 elements)
      0
      (apply #'/ elements)))
(block exit
  (reduce #'/ '(1 2 3 0 5)
          :key (lambda (x)
                 (if (zerop x)
                     (return-from exit 0)
                   x))))