Lisp 应用#和#x27;或不适用#';

Lisp 应用#和#x27;或不适用#';,lisp,common-lisp,Lisp,Common Lisp,我刚刚开始使用Lisp(Common Lisp),这里有一个函数可以计算一组数字的平均值 CL-USER> (defun average (list) (/ (apply #'+ list) (length list))) AVERAGE CL-USER> (average '(1 2 3 4)) 5/2 但是如果我像这样重写函数 CL-USER> (defun average (list) (/ (+ list) (length list))) 它不起作用,因为(+'(数

我刚刚开始使用Lisp(Common Lisp),这里有一个函数可以计算一组数字的平均值

CL-USER> (defun average (list) (/ (apply #'+ list) (length list)))
AVERAGE
CL-USER> (average '(1 2 3 4))
5/2
但是如果我像这样重写函数

CL-USER> (defun average (list) (/ (+ list) (length list)))
它不起作用,因为(+'(数字列表))无法计算,因此长度参数和+中的表达式不兼容

有没有一种方法可以诱使(list)通过+自然地作为表达式进行计算,并作为数据传递给length?而不是使用apply#'

我试过这个:

(defun average (list) (/ (+ list) (length '(list))))
但这似乎也不行

最好使用
(reduce#'+list)
而不是
(apply#'+list)
,因为
apply
受函数可以接受的参数数量限制

因此,您的平均函数应该如下所示:

(defun average (list)
  (/ (reduce #'+ list)
     (length list)))

顺便说一句,代码
(length'(list))
返回1,因为它返回包含符号的列表的长度。

没有理由不使用
APPLY
或者更好的方法是
REDUCE
。这里
REDUCE
是正确的功能

如果使用Lisp编程,大多数情况下必须使用符号,命名操作,后跟参数。这是Lisp中的通用基本表达式样式。您可能期望有更简短的方法来编写类似于使用函数缩减列表的内容。但在basic Lisp中没有

(+(列表1 2 3 4))
是一个错误,因为
+
需要的是数字,而不是列表

如果要对列表中的所有数字求和,必须使用
REDUCE
。这种操作也称为折叠

将列表中的数字相加:

(reduce #'+ (list 1 2 3 4))
另一个简单的方法是使用
循环

(loop for n in (list 1 2 3 4) sum n)
写一些类似于
(length'(list))
的东西是没有意义的,因为你引用的是一个列表。引用的列表被视为数据,而不是代码。因为它是常量数据,所以结果总是
1

获取简短程序的Lisp方法之一是建立可重用函数的词汇表。我们不使用最短的表示法,而是创建具有明显名称的可重用函数。因此,如果我们求和很多,我们就编写一个
sum
函数:

(defun sum (list)
  (reduce #'+ list))
那么平均值是:

(defun average (list)
  (/ (sum list) (length list)))

您希望能够做到这一点有什么实际原因吗?我认为你的问题在于语法(函数(arg1 arg2))比(函数arg1 arg2)更“自然”这一概念。没有理由,我只是想理解!同样,不,(函数arg1 arg2)似乎更“自然”(高度主观!不可否认),在我看来,操作函数如何看待args将更“自然”,而不是“凌驾”函数(用尖锐的引号)以适应args。如果你明白我的意思。由于quote(list)绕过了默认的评估规则,我只是想知道是否有一些我在某处遗漏的quote的“反向”。