[racket] Why check-expect only at the top level?

From: John Riedl (riedl at umn.edu)
Date: Mon Sep 5 17:42:49 EDT 2011

Hello Racketeers.

Summary: Why does check-expect only work at the top level?

I often find myself writing a few versions of the same function, to
show students different ways of doing things, or to experiment with
the performance of different approaches.  As a trivial example,

; Check whether one number divides evenly into another.
; The modulo form is common, but the other form might be easier to understand.
; I'd like to check which one is faster.  On my laptop the
divides-modulo function is nearly
; twice as fast as the divides-divide function.
(define (divides-modulo? d n) (= (modulo n d) 0))
(define (divides-divide? d n) (integer? (/ n d)))
(define (divides? d n) (divides-modulo? d n))

I'd like to test that the two divides? functions work the same by
writing a test harness that takes a divides? function and tries it out
on a bunch of values with check-expect.  For instance:

(define (check-divides d?)
  (check-expect (d? 4 16) true)
  (check-expect (d? 4 17) false))

But when I run it I get:
. check-expect: found a test that is not at the top level in:
(check-expect (d? 4 16) true)

I've read http://docs.racket-lang.org/test-engine/index.html, which says:
"Each check form may only occur at the top-level; results are
collected and reported by the test function."

... but it doesn't say *why* this rule.  Is it just to keep things
simple for students, or is there a deep reason for this limitation?

In slightly related news, I can't parse the following, in part because
of what seems to be an accidentally repeated part of the text:

(check-member-of (test any/c) (expected any/c) ...)
Accepts at least two value-producing expressions. Structurally
compares the first value to each value subsequent value specified.


Posted on the users mailing list.