【问题标题】:Why does my lisp code give me ...should be a lambda expression?为什么我的 lisp 代码给了我……应该是 lambda 表达式?
【发布时间】:2015-01-12 12:57:20
【问题描述】:
(defun helper-2 (list) 
  (if (null (first (rest list)))
      0)
  (+ (distance ((car list) (first (rest list)))) 
     (helper-2 (rest list))))

我是 lisp 的新手,我正在编写一个程序来计算任何多边形的周长,输入遵循顺时针顺序。我的逻辑是我使用辅助方法来计算两个相邻点的长度并求和。递归完成后,我将进行单独调用以计算从起点到终点的长度并将所有内容相加。我已经完成了距离方法,它需要 2 个点并返回长度。

(distance '(2 0) '(4 0)) ;this will output 2

helper-2 逻辑: 假设我们有 3 个点 a (2 0) b (3 3) c (4 0) 这种方法期望将 ab 和 bc 之间的距离相加。但是,我不断收到“(汽车头)应该是一个 lambda 表达式”错误。任何人都可以帮忙吗?谢谢你。或者谁能​​给我一个更好的方法来计算多边形的周长?

(defun square (n) (* n n))

(defun distance (a b)
  (let ((h (- (second b) (second a)))
        (w (- (first b) (first a))))
    (sqrt (+ (square h) (square w)))))

【问题讨论】:

  • 顺便说一句,为了便于阅读,您可能希望保持对first/restcar/cdr 的使用保持一致。在这里混合carfirst/rest 有点令人困惑。还有(cadr list)(first (rest list)) 的作用相同。
  • 在 Scheme 中,((car args1...) args2...) 将首先评估 (car args1...) 以产生一些值 x,然后尝试使用 args2 将 x 作为函数调用。在 Common Lisp 中,函数调用必须采用 (xxx ...) 的形式,其中 xxx 是符号或 lambda 表达式 (car ...) 也不是。实现看到它不是一个符号,所以认为它应该是一个 lambda 表达式,但它不是,并抱怨。

标签: lambda lisp common-lisp


【解决方案1】:

您的helper-2 函数在两个地方有误:

  1. 您应该使用双臂 if,以便它用作 if/else。
  2. (car list) 周围的括号过多。

这是固定版本:

(defun helper-2 (list) 
  (if (null (first (rest list)))
      0
      (+ (distance (car list) (first (rest list))) 
         (helper-2 (rest list)))))

【讨论】:

  • 感谢您的回答。另一个问题。如何使用此功能?我试过 (helper-2 '(2 0) '(4 0)) 它说的参数太多。如何传递积分列表?
  • 听起来你应该使用(helper-2 '((2 0) (4 0)))?不过我还没有测试过。
  • 表示特殊运算符 if 的参数太少
  • 你实际上修改了我所拥有的代码,这是不正确的。请剪切并粘贴我的代码并直接使用它。
【解决方案2】:

HyperSpec 的3.1.2.1.2.3 Function Forms 部分描述了作为缺点的表单如何,例如 ((car list) (first (rest list))),被评估:

如何处理复合形式取决于它是分类为特殊形式、宏形式、函数形式还是 lambda 形式。

您可以阅读从该页面链接到的小节以获取更多详细信息,但本质是,由于此列表的第一个元素不是符号,因此整个表单必须是 lambda 表单。根据3.1.2.1.2.4 Lambda Forms,lambda 形式是一个列表,其中第一个元素是 lambda 表达式。 `但是,(car list) 不是 lambda 表达式,因此您会收到相应的错误消息。

您声称 (distance '(2 0) '(4 0)) 将输出两个,但这表明 distance 是用两个参数调用的。即使 ((car list) (first (rest list))) 可以被评估,它也只会产生一个值,所以 (distance ((car list) (first (rest list) )))) 将只用一个参数调用 distance。你应该这样做:

(distance (car list) (first (rest list)))

另见:

【讨论】:

  • 感谢您的回答。另一个问题。如何使用此功能?我试过 (helper-2 '(2 0) '(4 0)) 它说的参数太多。如何传递积分列表?
  • @AnOverflowedStack 很高兴我直到现在才看到这条评论,因为您似乎同时在一个新问题How do I pass in a list of list into a function? 中问了同样的问题。
猜你喜欢
  • 1970-01-01
  • 2014-07-07
  • 1970-01-01
  • 1970-01-01
  • 2011-02-04
  • 2015-12-20
  • 1970-01-01
  • 2018-05-18
  • 1970-01-01
相关资源
最近更新 更多