Recursion 匿名函数在Scheme中调用自身的机制?

Recursion 匿名函数在Scheme中调用自身的机制?,recursion,scheme,the-little-schemer,anonymous-recursion,Recursion,Scheme,The Little Schemer,Anonymous Recursion,我正在阅读《小阴谋家》,对以下代码感到困惑: ((lambda (len) (lambda (l) (cond ((null? l) 0) (else (+ 1 (len (cdr l))))))) eternity) (define eternity (lambda (x) (eternity x))) 代码用于确定空列表,否则它永远不会停止 为什么“len”不是递归?正如您所说

我正在阅读《小阴谋家》,对以下代码感到困惑:

((lambda (len)
   (lambda (l)
      (cond
         ((null? l) 0)
         (else 
            (+ 1 (len (cdr l)))))))
   eternity)

(define eternity
    (lambda (x)
         (eternity x)))
代码用于确定空列表,否则它永远不会停止


为什么“
len
”不是递归?

正如您所说,这是一个长度函数作为部分函数的定义,其中它只完成空列表。但这还没有涉及到y-combinator部分,它不是一个匿名函数调用自身的例子

l
是原子列表,它是计算
(lambda(len)…
时返回的函数的参数

len
是作为参数传递到外部lambda的函数

外部表达式创建一个lambda,并将
永恒
作为其参数传入。外部lambda返回一个通过计算内部lambda创建的函数,返回的函数是以
永恒
为参数的函数

如果向代码传递了一个空列表(意味着在另一组参数中包装整个第一部分,后面跟着一个
”()
),那么它的计算结果当然将为0<代码>len永远不会得到评估


如果代码被传递一个非空的lat,那么它将尝试计算
len
参数,您将得到一个无限递归。

尽管将文本替换应用于Lisp表单可能会很危险(因为存在多次计算等危险),但在这种情况下,查看此表单并查看其如何配合可能会有所帮助:

((lambda (len) 
   (lambda (l)
     ...))
 eternity)
是一个应用程序,即函数调用。被调用的函数接受一个名为
len
的参数,并返回另一个接受单个参数
l
的函数。被调用的函数是通过
永恒
调用的。调用完成后,结果是此函数:

(lambda (l)
  (cond
    ((null? l) 0)
    (else (+ 1 (eternity (cdr l))))))
现在,这个函数获取一个列表
l
,如果它为空,则返回
0
。否则,它将计算
(cdrl)
(列表的其余部分),并使用该值调用
永恒
。当返回时,
1
被添加到结果中,这是整个函数的返回值。当然,问题是,
永恒

(define eternity
  (lambda (x)
    (eternity x)))
也可以写成

(define (eternity x)
  (eternity x))
只需获取一个参数
x
,然后使用
x
调用
externature
。这是一个无限循环。在上面,我写了“当它返回时”,但事实上,
(永恒(cdrl))
永远不会返回。所以

((lambda (len)
   (lambda (l)
     (cond
       ((null? l) 0)
       (else (+ 1 (len (cdr l)))))))
 eternity)
是一个函数调用,返回一个函数
(lambda(l)…
,如果使用空列表调用,则返回
0
,并使用非空列表进入无限循环


从程序分析的角度来看,值得注意的是,还有一些其他值不会进入无限循环。例如,如果用字符串调用它,则
(cdr l)
将是一个错误。

“len”不是递归,因为它是lambda表达式的参数。它的价值可以是任何东西。这就是永恒。还要注意,第一个表达式不是定义。计算第一个表达式时,
永恒
仍未定义。谢谢。我明白了。