这段代码如何表现(funcall中的函数组合)

时间:2014-10-28 19:13:03

标签: lisp common-lisp

我在lisp中有以下功能:

(defun F(F)
  #'(lambda (n)
      (if (zerop n)
         (funcall F n)
         (1+ (funcall (F F) (1- n))))))

如果我打电话,这段代码的行为如何:

(funcall (F #'(lambda (x) (+ 2 x))) 2)

我不明白为什么输出是4。

提前致谢

2 个答案:

答案 0 :(得分:3)

由于我们知道了这个参数,我们可以简化函数中的if语句:

(funcall (F #'(lambda (x) (+ 2 x))) 2)
(1+ (funcall (F #'(lambda (x) (+ 2 x))) 1))
(1+ (1+ (funcall #'(lambda (x) (+ 2 x)) 0)))
(1+ (1+ 2))
4

前两个转换将(if false A B)替换为B,而第三个转换将(if true A B)替换为A

答案 1 :(得分:3)

首先,解开两个F

(defun foo (fun)
  #'(lambda (n)
      (if (zerop n)
          (funcall fun n)
          (1+ (funcall (foo fun) (1- n))))))

现在,您致电:

(funcall (foo #'(lambda (x) (+ 2 x))) 2)

我们可以给内部lambda命名,我称之为add-2

(funcall (foo #'add-2) 2)

(Foo #'add-2)然后返回函数

(lambda (n)
  (if (zerop n)
      (funcall #'add-2 n) ; n is always 0 here
      (1+ (funcall (foo #'add-2) (1- n)))))

使用2调用此函数,而不是zerop,因此它是:

(1+ (funcall (foo #'add-2) 1))

我们已经知道(foo #'add-2)返回了什么,现在使用1调用它,但仍然不是zerop

(1+ (1+ (funcall (foo #'add-2) 0)))

现在论证是0,所以我们得到了基本情况:

(1+ (1+ (funcall #'add-2 0)))

我们现在可以看到foo创建的函数会将n添加到调用(fun 0)的结果中。