Scheme 小阴谋家:length0和mk length

Scheme 小阴谋家:length0和mk length,scheme,the-little-schemer,Scheme,The Little Schemer,小阴谋家给出了下面的函数长度0。但是这是如何工作的呢?看起来长度lambda正在传递给mk length lambda,它使用作为参数传递的长度lambda本身来计算长度lambda。因此,当底部的(length(cdrl))被计算时length就是lambda本身的长度。但是长度lambda采用两个参数:length和l。那么(长度(cdrl))又有什么意义呢 ((lambda (mk-length) (mk-length mk-length)) (lambda (length)

小阴谋家给出了下面的函数长度0。但是这是如何工作的呢?看起来长度lambda正在传递给mk length lambda,它使用作为参数传递的长度lambda本身来计算长度lambda。因此,当底部的
(length(cdrl))
被计算时
length
就是lambda本身的长度。但是长度lambda采用两个参数:
length
l
。那么
(长度(cdrl))
又有什么意义呢

((lambda (mk-length)
   (mk-length mk-length))
 (lambda (length)
   (lambda (l)
     (cond
       ((null? l) 0)
       (else (add1
                (length (cdr l))))))))
这个小阴谋家正在构建一个函数,它可以处理越来越长的列表。长度点的一部分≤0表示它只适用于长度小于或等于零的列表(因为没有长度为负的列表,这意味着长度为零的列表)。您故意显示的代码仅适用于长度为零的列表。事实上,这一点甚至在关于:

A:如果我们现在可以创建另一个mk长度的应用程序到永恒呢?
B:那只会把问题推迟到一个,而且,我们怎么能这样做呢?
A:既然没人关心我们传递给mk length的函数是什么,我们可以先传递给它mk length。
B:这个主意不错。然后我们在永恒上调用mk length,并在cdr上调用结果,这样我们就可以得到塔的另一部分。
A:那么这仍然是长度0

B:是的,我们甚至可以使用mk长度而不是长度:

A:我们为什么要这样做?
B:所有名称都相等,但有些名称比其他名称更相等。
A:True:只要我们始终如一地使用这些名称,我们就很好。
B:而mk length是一个远比length平等的名称。如果我们使用像mk length这样的名称,它会不断提醒我们mk length的第一个参数是mk length

在上,作者展示了一个适用于长度为0或1的列表的版本(即。,≤1). 最后,他们得到了一个适用于任意长度列表的版本。另一个问题更详细地描述了其工作原理:

您可能还会发现以下感兴趣的问题:

  • (涉及第166页长度上使用的
    永恒
    功能≤(一)

从前面的示例中,我会认为仅对长度0有效意味着对任何非空列表都将永远进入递归。通过命中永恒而失败,而不是因为动态键入原因而失败。但是,如果对于非空列表的动态输入原因失败,我会觉得很奇怪。@ USE782220是的,“Works'”在这里是一个奇怪的术语。重要的是要记住,代码不是对已经在工作的代码的不断细化和重构;这本书呈现了一个苏格拉底式的对话,在一系列的尝试之后,最终的代码逐渐被梳理出来;没有。它将
(lambda(l)…
返回到
add1
,从而导致错误;这就是为什么它是
length\u 0
:它只适用于空列表。而且名称
length
也错了,它实际上应该被称为
mk length
——实际上,在该帧的右半部分。
((lambda (mk-length)
   (mk-length mk-length))
 (lambda (length)
   (lambda (l)
     (cond
       ((null? l) 0)
       (else (add1
                (length (cdr l))))))))
((lambda (mk-length)
   (mk-length mk-length))
 (lambda (mk-length)
   (lambda (l)
     (cond
       ((null? l) 0)
       (else (add1
                (mk-length (cdr l))))))))