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表达式的参数。它的价值可以是任何东西。这就是永恒。还要注意,第一个表达式不是定义。计算第一个表达式时,永恒
仍未定义。谢谢。我明白了。