3

In a class I am taking we are using the old R5RS standard of Scheme to solve SICP assignments. I like to do test first development, so I figured a unit testing framework would be nice, and I chose SchemeUnit for writing the small tests.

This has worked fine so far, just testing primitives in the output (strings, numbers, ...), but I hit a road block when trying to test lists. It has probably something to do with differences in the Scheme dialect used to run the tests:

foo.scm: (define a-list (list 2))

foo-tests.scm: (check-equal? a-list (list 2))

Result when running the tests:

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

expected:   (2)

To make the test suite run, I have to add "#lang scheme/base to the top of foo-tests.scm and require the schemeunit package. In foo.scm I need to have #lang r5rs and (#%provide (all-defined)) at the top.

I guess lists are somehow differently implemented in R5RS and "scheme/base". Any way to get them to work together? And why does it fail ({} vs ())?

oligofren
  • 20,744
  • 16
  • 93
  • 180

1 Answers1

4

Yes, as you've noticed, lists are implemented differently in #lang r5rs vs #lang scheme/base. If it's possible to write the tests in your foo-tests.scm in r5rs, that would help to eliminate the possible confusion.

You should be able to do this by having this at the top of your foo-tests.scm file.

#lang r5rs

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

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

If the test suite is written in the same language, then the constructs --- and in particular, the representation for lists --- should match up. The test above should hopefully pass.

To elaborate on the difference between the r5rs lists and the one in #lang scheme (and #lang racket): Racket uses immutable cons pairs to represent lists. Immutable cons pairs do not support the set-car! and set-cdr! functions of r5rs, so it wouldn't be faithful to the standard for the #lang r5rs language to use the built-in immutable pairs. To support the r5rs standard, Racket includes a separate mutable pairs data type, and uses it consistently within r5rs. But it means that the standard pairs in Racket and the mutable pairs do not compare equally.

dyoo
  • 11,795
  • 1
  • 34
  • 44
  • Thank you for an excellent answer. I understand "Planet" to be some kind of dependency management app (like Maven in the Java world). In addition to just scheme unit, I also need a text runner to actually run the tests and display the result. What would I add to the (#require) part that would be the equivalent of (require (planet schematics/schemeunit:3/text-ui))? – oligofren Feb 17 '13 at 21:18
  • In modern Racket, know that the unit testing framework comes with Racket's standard library now. See: http://docs.racket-lang.org/rackunit/index.html. Don't use the one in PLaneT, as it's actually the ancestor of `rackunit`. You don't need an explicit test runner if you're using the `check-equal?` thing: just running the test module should be enough to drive the tests. If you do need a explicit test runner (for more sophisticated testing), see the rest of http://docs.racket-lang.org/rackunit/quick-start.html. But for what you're doing in r5rs, I don't see the complexity to be worth it. – dyoo Feb 17 '13 at 21:24
  • Thanks. Found out that the required syntax was (#%require schemeunit/text-ui). Then I "upgraded" to racket's built-in by changing to #lang r5rs (#%require rackunit) (#%require rackunit/text-ui) (#%require "foo.scm") and defining a minimal test. Seems to work like I want to. Thanks a lot. Mind if I add this info to your answer? – oligofren Feb 17 '13 at 21:51