为什么我的lisp代码给我…应该是lambda表达式?

为什么我的lisp代码给我…应该是lambda表达式?,lambda,lisp,common-lisp,Lambda,Lisp,Common Lisp,我是lisp新手,我正在编写一个程序来计算任意多边形的周长,输入按顺时针顺序。我的逻辑是,我使用助手方法计算相邻两点的长度,然后求和。递归完成后,我将执行一个单独的调用来计算从起点到终点的长度,并对所有内容进行汇总。我已经完成了距离方法,它需要2个点并返回长度 (defun helper-2 (list) (if (null (first (rest list))) 0) (+ (distance ((car list) (first (rest list))))

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

(defun helper-2 (list) 
  (if (null (first (rest list)))
      0)
  (+ (distance ((car list) (first (rest list)))) 
     (helper-2 (rest list))))
helper-2逻辑: 假设我们有3个点a(2 0)b(3 3)c(4 0)。该方法预计将ab和bc之间的距离相加。然而,我不断得到“(车头)应该是一个lambda表达式”的错误。有人能帮忙吗?非常感谢。或者谁能给我一个更好的方法来计算多边形的周长

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

您的
helper-2
功能有两处错误:

  • 您应该使用双臂的
    if
    ,这样它就可以充当if/else
  • (车辆列表)
    周围的括号太多
  • 以下是固定版本:

    (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)))))
    

    您的
    helper-2
    功能有两处错误:

  • 您应该使用双臂的
    if
    ,这样它就可以充当if/else
  • (车辆列表)
    周围的括号太多
  • 以下是固定版本:

    (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)))))
    
    HyperSpec的一节描述了一个表单是如何成为cons的,例如 ((车辆列表)(第一个(休息列表)),进行评估:

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

    您可以阅读该页面链接到的小节以了解更多详细信息,但本质是,由于此列表的第一个元素不是符号,因此整个表单必须是lambda表单。根据lambda表单,第一个元素是lambda表达式的列表`但是,(汽车列表)不是lambda表达式,因此您会收到相应的错误消息

    您声称(distance'(2 0)'(4 0))将输出两个,但这表明使用两个参数调用distance。即使可以计算((汽车列表)(第一(休息列表)),它也只会产生一个值,因此(距离((汽车列表)(第一(休息列表)))只需一个参数即可调用距离。您应该这样做:

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

    HyperSpec部分描述了一个表单是如何成为cons的,例如 ((车辆列表)(第一个(休息列表)),进行评估:

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

    您可以阅读该页面链接到的小节以了解更多详细信息,但本质是,由于此列表的第一个元素不是符号,因此整个表单必须是lambda表单。根据lambda表单,第一个元素是lambda表达式的列表`但是,(汽车列表)不是lambda表达式,因此您会收到相应的错误消息

    您声称(distance'(2 0)'(4 0))将输出两个,但这表明使用两个参数调用distance。即使可以计算((汽车列表)(第一(休息列表)),它也只会产生一个值,因此(距离((汽车列表)(第一(休息列表)))只需一个参数即可调用距离。您应该这样做:

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


    顺便说一句,为了可读性,您可能希望保持您对
    首先
    /
    休息
    汽车
    /
    cdr
    的使用一致。将
    汽车
    第一个
    /
    休息
    混合在一起有点混乱。还有
    (cadr列表)
    的工作原理与执行
    (first(rest list))
    相同。在Scheme中,
    ((car args1…)args2…
    将首先计算
    (car args1…
    以生成一些值x,然后尝试使用args2调用x作为函数。在通用Lisp中,函数调用的形式必须是
    (xxx…
    ,其中xxx要么是符号,要么是lambda表达式
    (car…
    )。实现看到它不是一个符号,所以认为它应该是一个lambda表达式,但它不是,并抱怨。另外,为了可读性起见,您可能希望首先保持对
    /
    rest
    car
    /
    cdr
    的使用保持一致。将
    汽车
    第一个
    /
    休息
    混合在一起有点混乱。还有
    (cadr列表)
    的工作原理与执行
    (first(rest list))
    相同。在Scheme中,
    ((car args1…)args2…
    将首先计算
    (car args1…
    以生成一些值x,然后尝试使用args2调用x作为函数。在通用Lisp中,函数调用的形式必须是
    (xxx…
    ,其中xxx要么是符号,要么是lambda表达式
    (car…
    )。实现看到它不是一个符号,所以认为它应该是一个lambda表达式,但它不是,并抱怨。谢谢您的回答。另一个问题。如何使用此功能?我试过(helper-2'(20)'(40))它说的参数太多了。如何传递点列表?听起来您应该使用
    (helper-2'((20)(40))
    ?不过我还没有测试过,它说如果你真的修改了我得到的代码,那么特殊操作符的参数太少了,这是不正确的。请剪下并粘贴我的代码,直接使用。谢谢你的回答。另一个问题。如何使用此功能?我试过(helper-2'(20)'(40))它说的参数太多了。我如何传递点列表?听起来不错