我正在写 SICP 书。我在Windows 上使用SCM 而不是实际的Scheme 程序。当我运行下面的 Filter 函数时,我得到 (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)。
最佳答案
nil
不是当今定义的顶级绑定(bind)的方案报告。如果它存在于实现中,它可以是任何值,因此您不能依赖它。 SICP 使用比 R4RS 更早版本的Scheme,因此当今没有任何现代实现能够完全支持它。我用DrRacket因为它支持许多报告语言,有一个很好的调试器和 IDE,而且它在编写时缩进代码,从而减少了出现语法错误的可能性。它有一个 SICP compatibilty language这样 SICP 代码就可以工作,而无需跳过太多的环节。
历史上,Scheme 源自 Lisp,而 Lisp 并不区分空列表和假值。 Scheme 引入了 #t
和 #f
,但保留了空列表被视为 false 的事实,直到他们更改了它,以便只有 #f
为 false其他一切都被认为是真实的。在早期报告中,nil
是 ()
的绑定(bind),因此 SCM 在进行更改时可能将其更改为 #f
,因为 CL 经常这样做使用 nil
表示假值,使用 ()
表示空列表,即使它们只是同一值的两种表示形式。
许多实现在它们所遵循的报告之上引入了自己的绑定(bind)。使用它们会将您锁定在它们的风格中,因此最好的方法是保持代码标准。 DrRacket 以比其他实现更严格的方式解释报告,因此用 DrRacket 编写的 R6RS 程序很可能无需在其他 R6RS 兼容实现中进行更改即可运行。标准就是这么酷!
关于filter - 在方案 (SCM) 中的 Define Filter 函数的结果末尾获取 #f 或 False,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55754885/