在我上的一堂课中,我们使用Scheme的旧R5RS标准来解决SICP分配。我喜欢先进行测试开发,因此我认为单元测试框架会很不错,因此我选择SchemeUnit编写小型测试。

到目前为止,这已经很好用了,只测试了输出中的原语(字符串,数字等),但是在尝试测试列表时遇到了障碍。它可能与用于运行测试的Scheme方言的差异有关:

foo.scm: (define a-list (list 2))
foo-tests.scm: (check-equal? a-list (list 2))
运行测试的结果:

Unnamed test
FAILURE
name:       check-equal?
location:   tester.scm:22:3
actual:     {2}

expected:   (2)

为了使测试套件运行,我必须在foo-tests.scm的顶部添加"#lang scheme/base,并在schemeunit软件包中添加require。在foo.scm中,我需要在顶部放置#lang r5rs(#%provide (all-defined))

我想列表在R5RS和“方案/基础”中以某种方式实现了不同。有什么办法可以让他们一起工作?为何失败({} vs())?

最佳答案

是的,您已经注意到,列表在#lang r5rs#lang scheme/base中的实现方式有所不同。如果可以在r5rs中的foo-tests.scm中编写测试,则将有助于消除可能的混淆。

您应该可以通过将其放在foo-tests.scm文件的顶部来执行此操作。

#lang r5rs

(#%require schemeunit)
(#%require "foo.scm")

;; Now you can add your tests here:
(check-equal? a-list (list 1 2 3))

如果测试套件是用相同的语言编写的,则结构---尤其是列表的表示形式–应该匹配。以上测试有望通过。

要详细说明r5rs列表与#lang scheme(和#lang racket)中的列表之间的区别:Racket使用不可变的cons对表示列表。不可变的缺点对不支持r5rs的set-car!set-cdr!函数,因此使用内置的不可变对对#lang r5rs语言的标准并不忠实。为了支持r5rs标准,Racket包含了一个单独的mutable pairs数据类型,并在r5rs中一致地使用它。但这意味着Racket中的标准对和可变对之间的比较并不相同。

10-01 02:55