从Scheme(SCM)中的Define Filter函数的结果末尾获取#f或False

从Scheme(SCM)中的Define Filter函数的结果末尾获取#f或False,filter,scheme,sicp,Filter,Scheme,Sicp,我正在写SICP的书。我在Windows上使用SCM而不是实际的Scheme程序。当我运行下面的过滤器函数时,我得到(1 3 5.#f),如代码窗口中所示。我无法理解点和假值是如何附加到奇数整数的 (define (filter odd? lst) (cond ((null? lst) nil) ((odd? (car lst)) (cons (car lst) (filt

我正在写SICP的书。我在Windows上使用SCM而不是实际的Scheme程序。当我运行下面的过滤器函数时,我得到(1 3 5.#f),如代码窗口中所示。我无法理解点和假值是如何附加到奇数整数的

    (define (filter odd? lst)
        (cond ((null? lst) nil)
              ((odd? (car lst))
               (cons (car lst)
                     (filter odd? (cdr lst))))
              (else (filter odd? (cdr lst)))))

    (filter odd? (list 1 2 3 4 5))

    (1 3 5 . #f)

我希望得到(1 3 5)作为结果,而不是(1 3 5.#f)。

当我得到我不理解的行为时,我会将调试输出添加到程序中。当你说:

(define (filter odd? lst)
    (display lst) (newline)
    (cond ((null? lst) (display "1") (newline) nil)
          ((odd? (car lst))
            (display "2") (newline)
            (cons (car lst)
                  (filter odd? (cdr lst))))
          (else (display "3") (newline)
                (filter odd? (cdr lst)))))

您将看到在每个递归调用中传递的参数,并且您将知道在每个递归调用中选择了
cond
的哪个分支。这通常会告诉我问题所在。

我认为问题在于线路:

    (cond ((null? lst) nil)

以及
nil
的值。在这本书的错误方案中,我相信
nil
等同于空列表
'()
。我怀疑SCM认为
nil
等同于false、
#f
。因此,如果您将
nil
替换为
”()
,您可能会得到预期的结果。

nil
现在不是顶级绑定定义的方案报告。如果它存在于一个实现中,那么它可以是任何值,因此您不能依赖它。SICP使用了比R4RS更早的Scheme版本,因此今天没有任何现代实现能够完全支持它。我之所以使用它,是因为它支持许多报表语言,有一个很好的调试器和IDE,而且它在编写代码时缩进代码,从而减少了语法错误的可能性。它有一个简单的接口,这样SICP代码就可以工作,而无需跳转太多的障碍

从历史上看,Scheme来自Lisp,Lisp不区分空列表和假值。Scheme引入了
#t
#f
,但保留了一个事实,即空列表被认为是错误的,直到他们更改它,所以只有
#f
是错误的,其他一切都被认为是真实的
nil
是早期报告中
()
的绑定,因此SCM在进行更改时可能会将其更改为
#f
,因为CL经常使用
nil
表示假值,
()
表示空列表,即使它们只是相同值的两个表示形式


许多实现在它们所遵从的报表之上引入它们自己的绑定。使用它们将您锁定在它们的风格中,因此最好是保持代码标准。与其他实现相比,DrRacket以非常严格的方式解释报告,因此用DrRacket编写的R6RS程序很可能在不改变其他R6RS兼容实现的情况下运行。这样的标准很酷

DrRacket有一个调试器。您可以设置断点,甚至单步执行代码。IMHO比添加打印语句要好得多。