Common LISP Return功能为什么不起作用?

问题描述

我已经用通用Lisp进行了一个项目,但我不知道为什么我使用的循环不会返回列表。如果我在循环末尾使用“ Finally”语句,它将打印新列表(正确!),但不会在其外面打印或让我将其用于任何事情。

我发现的所有示例都表明return语句应该执行此操作,但是当我尝试执行该操作时仍然没有成功。它只是告诉我,当我尝试在循环外使用它时,meanList是未定义的,并且在那里初始化也无效。

最终目标是循环返回每组数据元素的平均值列表。

    (defparameter data
                     ' ((2.0 8.0) (0.9 1.2) (6.0 2.0)
                       (7.0 3.5) (4.0 6.0) (1.0 4.0)))

    (loop for i in data
      do (setq j (mean i)) collect j into meansList
      finally (return (meansList))

平均值函数返回列表的平均值。我已经检查了好几次,并且可以按预期工作,不过如有必要,我可以在这里提供。

解决方法

(meansList)意味着应用不带参数的函数meansList。由于Common Lisp是Lisp2,因此您会收到错误消息,指出函数meansList不存在。如果您了解C类型语言,则可以执行以下操作:

int c = 10;
return c();  // is this the variable that turns into 10? 

您还应该考虑对全局变量使用*earmuffs*,因为它们会动态变化。如果您有一个名为data的参数来调用依赖于全局data的函数,则该参数将被临时更改,即使在中等项目中,也将像在大海捞针中寻找针头一样。>

还请注意,loop创建了一个名为nil的块,并且return使用了最接近的名为nil的块,因此您将从loop返回。例如。它成为循环的评估。要从使用循环的函数返回,您需要使用(return-from function-name whatever-expression-to-compute-value)

我还看到j的突变是不必要的。可以这样写:

(loop :for i :in *data*
      :collect (mean i) :into meansList
      :finally (return meansList))

如果您collect在不提及任何内容的情况下也会返回它,那么它是相同的:

(loop :for i :in *data*
      :collect (mean i))

Loop for black belts中的第Practical Common Lisp章很好地举例说明了,The Loop macro in CL Cookbook