首页 > 解决方案 > 在 Scheme (SCM) 中定义过滤器函数的结果末尾得到 #f 或 False

问题描述

我正在写 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)。

标签: filterschemesicp

解决方案


nil今天不是计划报告定义的顶级绑定。如果它存在于实现中,它可以是任何值,因此您不能依赖它。SICP 使用了比 R4RS 更早的 Scheme 版本,因此今天没有任何现代实现可以完全支持它。我使用DrRacket是因为它支持许多报告语言,有一个很好的调试器和 IDE,并且由于它在编写时缩进代码,因此减少了语法错误的可能性。它具有SICP 兼容语言,因此 SICP 代码无需跳过太多环节即可工作。

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

许多实现在它们符合的报告之上引入了它们自己的绑定。使用它们可以将您锁定在它们的风味中,因此最好的方法是保持代码标准。与其他实现相比,DrRacket 以非常严格的方式解释报告,因此用 DrRacket 编写的 R6RS 程序很可能会在其他符合 R6RS 的实现中运行而无需更改。这样的标准很酷!


推荐阅读