Little Schemer:为什么将(mk-length mk-length)包装为一个函数? [英] Little Schemer: why wrap (mk-length mk-length) into a function?
问题描述
在第9章的《小策划者》书中,而为任意长输入构建length
函数,建议执行以下操作(在第168页本身):
In The Little Schemer book, in Chapter 9, while building a length
function for arbitrary long input, the following is suggested (on pages 170-171), that in the following code snippet (from page 168 itself):
((lambda (mk-length)
(mk-length mk-length))
(lambda (mk-length)
((lambda (length)
(lambda (l)
(cond
((null? l) 0)
(else (add1 (length (cdr l)))))))
(mk-length mk-length))))
(mk-length mk-length)
部分将永远不会返回,并将无限地将其自身应用于自身:
the part (mk-length mk-length)
, will never return and will be infinitely applying itself to itself:
因为我们一直不断地将
mk-length
应用于自身...
Because we just keep applying
mk-length
to itself again and again and again...
和
但是现在我们已经从使
length
的函数中提取了(mk-length mk-length)
,它不再返回任何函数.
But now that we have extracted
(mk-length mk-length)
from the function that makeslength
it does not return a function anymore.
现在,要治愈这本书,建议:
Now, to cure this the book suggest:
将最后一个正确版本的
length
中的mk-length
应用程序本身转换为函数.
Turn the application of
mk-length
to itself in our last correct version oflength
into a function.
就像这样:
((lambda (mk-length)
(mk-length mk-length))
(lambda (mk-length)
((lambda (length)
(lambda (l)
(cond
((null? l) 0 )
(else
(add1 (length (cdr l)))))))
(lambda (x)
((mk-length mk-length) x)))))
我不解的是:
-
如果
(mk-length mk-length)
不返回函数
does not return a function
我们如何将(mk-length mk-length)
的结果应用于某事物,就好像它是一个函数一样?
how we can apply the result of (mk-length mk-length)
to something, as if it is a function?
(lambda (x)
((mk-length mk-length) x))
如何将(mk-length mk-length)
包装到函数中解决永不返回"(即无限递归)问题?我的理解是:
How wrapping (mk-length mk-length)
into a function solves the 'never returning' (i.e. infinite recursion) problem? My understanding is, that in:
(lambda (x)
((mk-length mk-length) x))
x
将仅传递给永不递归的函数,该函数永远不会返回.
x
will just be passed to infinitely recursive function, which never returns.
推荐答案
您可能复制了错误的代码段,即您实际谈论的代码段之前的代码段.您显示的第一个代码完全没问题.循环是这个:
You probably copied the wrong code snippet, the one before that which you actually talk about. The first code you've shown is totally fine. What loops is, rather, this one:
((lambda (mk-length)
(mk-length mk-length)) ; (1)
(lambda (mk-length)
((lambda (length) ; (2)
(lambda (l)
(cond
((null? l) 0)
(else (add1 (length (cdr l))))))) ; (4)
(mk-length mk-length)))) ; (3)
已经在此处回答了:应用程序(1)
触发应用程序(2)
,触发应用程序(1)
!因此,循环.
This is already answered here: the application (1)
triggers the application (2)
which triggers the application (3)
right away, which is equivalent to (1)
! Thus, the looping.
将其包装为lambda(也称为 eta-expansion )会延迟应用程序(3)
,直到在(4)
中对构造的length
进行调用为止,这完全可以(您复制了还有一些错别字):
Wrapping it in a lambda (aka eta-expansion) delays the application (3)
until the call to the constructed length
is made in (4)
, and that's fully OK (you copied this with some typos as well):
((lambda (mk-length)
(mk-length mk-length)) ; (1)
(lambda (mk-length) ; (5)
((lambda (length) ; (2)
(lambda (l)
(cond
((null? l) 0)
(else (add1 (length (cdr l))))))) ; (4)
(lambda (x) ; (3)
(mk-length mk-length) x))))
(3)
现在是lambda表达式,而不是应用程序.评估此lambda表达式会产生一个匿名函数.当调用length
时,此lambda函数 将执行应用程序(mk-length mk-length)
以后.
(3)
is a lambda expression now, not an application. Evaluating this lambda expression produces an anonymous function. This lambda function will perform the application (mk-length mk-length)
later, when length
is called.
(更长的解释:)
(3)
立即返回绑定到length
的lambda函数,并愉快地返回(lambda (l) ...)
,以便将 that (lambda (l) ...)
will 应用于一些列表,可能导致此length
1 在(4)
中被调用,只有 then 在lambda (3)
内部的应用程序(mk-length mk-length)
才会被实际执行&mdash ;最终为我们提供了新的(lambda (l) ...)
匿名函数,该函数将在那里应用到(cdr l)
.
(a longer explanation:)
(3)
just returns the lambda function right away which gets bound to length
, and (lambda (l) ...)
is happily returned such that when that (lambda (l) ...)
will be applied to some list, possibly causing this length
1 to be called in (4)
, only then the application (mk-length mk-length)
inside the lambda (3)
will actually be performed — giving us the new (lambda (l) ...)
anonymous function eventually, which will get applied to the (cdr l)
there.
1 length
是(lambda (x) ((mk-length mk-length) x))
,这意味着(length (cdr l))
与((mk-length mk-length) (cdr l))
相同(mk-length
绑定到整个lambda表达式(5)
),并最终,((lambda (l) ...) (cdr l))
.
1length
is (lambda (x) ((mk-length mk-length) x))
which means that (length (cdr l))
is the same as ((mk-length mk-length) (cdr l))
(with mk-length
bound to the whole lambda-expression (5)
), and eventually, ((lambda (l) ...) (cdr l))
.
尼娜
这篇关于Little Schemer:为什么将(mk-length mk-length)包装为一个函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!