在Common Lisp中应用:函数调用一次,还是对列表中的每个元素调用一次?

在Common Lisp中应用:函数调用一次,还是对列表中的每个元素调用一次?,lisp,common-lisp,Lisp,Common Lisp,我试图完全理解apply的工作方式,但找不到足够清楚的解释。。。鉴于此: 这是: 假设我执行以下操作: (defun sum (L) (apply #'+ L)) (sum '(1 2 3 4 5)) (+ 1 2 3 4 5) (+ 1 (+ 2 (+ 3 (+ 4 5)))) 然后拨打以下电话: (defun sum (L) (apply #'+ L)) (sum '(1 2 3 4 5)) (+ 1 2 3 4 5) (+ 1 (+ 2 (+ 3 (+ 4 5))

我试图完全理解apply的工作方式,但找不到足够清楚的解释。。。鉴于此:

这是:

假设我执行以下操作:

(defun sum (L)
  (apply #'+ L))
(sum '(1 2 3 4 5))
(+ 1 2 3 4 5)
(+ 1 (+ 2 (+ 3 (+ 4 5))))
然后拨打以下电话:

(defun sum (L)
  (apply #'+ L))
(sum '(1 2 3 4 5))
(+ 1 2 3 4 5)
(+ 1 (+ 2 (+ 3 (+ 4 5))))
它是否执行以下操作:

(defun sum (L)
  (apply #'+ L))
(sum '(1 2 3 4 5))
(+ 1 2 3 4 5)
(+ 1 (+ 2 (+ 3 (+ 4 5))))
或以下各项:

(defun sum (L)
  (apply #'+ L))
(sum '(1 2 3 4 5))
(+ 1 2 3 4 5)
(+ 1 (+ 2 (+ 3 (+ 4 5))))
换句话说,如果我编写以下函数:

(defun sum2 (L)
  (if (null L)
      0
      (+ (first L) (sum2 (rest L)))))
它是否与上面我的函数apply完全相同

(apply #'+ '(1 2 3 4 5))
基本上与

(+ 1 2 3 4 5)
请注意,在常见的Lisp中,参数列表的长度通常是有限的。最大参数列表长度取决于实现,可以低至50。请参阅变量
调用参数限制

如果要添加较大的数字列表,请使用
reduce

(reduce #'+ '(1 2 3 4 5))
基本上与

(+ 1 2 3 4 5)
请注意,在常见的Lisp中,参数列表的长度通常是有限的。最大参数列表长度取决于实现,可以低至50。请参阅变量
调用参数限制

如果要添加较大的数字列表,请使用
reduce

(reduce #'+ '(1 2 3 4 5))

正如Rainer的回答一样,您的
求和
函数可能与
+
函数在其他更模糊的方面有所不同。这是因为一个实现可以自由地玩一些像
+
这样的操作:例如,它可以将
(+1.0 1 2.0 3)
计算为
(+(+1 3)(+1.0 2.0))
,或者将
(+3 a b 6)
计算为
(+9 a b)
。(但请注意,参数必须从左到右求值:如果发生了操作的重新排序,则会在之后发生。正如Rainer的回答一样,请注意,
sum
函数在其他更模糊的方面可能与
+
函数不同。这是因为实现可以自由地使用一些操作,如
+
:it例如,可以将
(+1.0 1 2.0 3)
计算为
(+(+1 3)(+1.0 2.0))
,或将
(+3 a b 6)
计算为
(+9 a b)
(但请注意,参数必须从左到右进行计算:如果操作发生了重新排序,则在这之后进行。