Lisp语言中优化的Lambda函数

Lisp语言中优化的Lambda函数,lambda,lisp,common-lisp,Lambda,Lisp,Common Lisp,请考虑Lisp中的以下函数定义: (defun f (l) (cond ((null l) 0) ((> (f (car l)) 2) (+ (car l) (f (cdr l)))) (T (f (car l))) ) ) 给出避免双重递归调用的解决方案(f(carl))。您将不使用set、setq、setf。证明答案的正确性 我是这样继续的: (defun f2 (l) (cond ((null

请考虑Lisp中的以下函数定义:

(defun f (l)
    (cond
        ((null l) 0)
        ((> (f (car l)) 2) (+ (car l) (f (cdr l))))
        (T (f (car l)))
    )
)
给出避免双重递归调用的解决方案
(f(carl))
。您将不使用set、setq、setf。证明答案的正确性

我是这样继续的:

(defun f2 (l)
    (cond
        ((null l) 0)
        ((lambda (x) 
           (cond
                ((> x 2) (+ (car l) (f2 (cdr l))))
                (T x)
           )
         ) (f2 (car l)) 
        )
    )
)

我想听听你的意见。顺便说一下,这只是个练习。此函数不用于执行连贯的操作。

在这里,我尝试用Lisp方式重新格式化代码:

(defun f2 (l)
  (cond
    ((null l) 0)
    ((lambda (x)
       (> x 2)
       (+ (car l) (f (cdr l)))
       (T (f (car l))))
     (f (car l)))))
使用
lambda
可以计算一次值并将其绑定到变量,实际上,您可以在lambda中合并
cond
的最后两个原始情况

但是,有多个问题使得代码不正确

  • 递归调用应该调用
    f2
    ,而不是
    f
  • 不能在
    lambda
    中移动
    cond
    的测试子句,这不是Lisp语法的工作方式。您可能只需要一个
    if
    ,但是如果
    (>x2)
    案例的lambda中缺少一个
    cond
  • lambda
    内部,不要调用
    (f2(car l))
    ,因为使用中间函数的全部目的是使用参数
    x
    (这是关于
    (T(f(car l)))
    表单,它看起来像一个cond子句,但被解释为函数调用)

如果您更仔细地格式化代码,它将帮助所有人,包括您自己。有很好的理由,惯用的Lisp看起来与您的完全不同。首先停止括号在多行上的散射;parenth不是分号,Lisp也不是C。现在,当您尝试验证
f
f2
是否具有相同的行为时,
f2
是否编译?它不编译,但只是一个练习。我把这些偏执放在这里是为了看事情从哪里开始和结束,我认为它更具可读性。“它不是编译,而是一个练习。”这个练习是关于产生正确的代码,认为编译器可以帮助你做that@hackermanwasd--
f
编译,但是
f2
没有:这是一个暗示,说明有些地方出错了,转换没有成功。为什么f2不无处不在呢?因此,您不需要并行使用2个函数。我对f2进行了重构,现在一切正常吗?不,您的条件格式不正确,请尝试使用lisp解释器运行代码,例如sbcl(steel bank common lisp)、ecl(embedded common lisp)甚至emacs,因为您使用的代码子集也可以作为emacs lispEdited有效,希望现在很好。通常我在VisualStudio代码中编写公共Lisp,并在命令行中使用“clisp program.Lisp”运行它。从未使用过其他IDE,但我将来可能会尝试其他IDE