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

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Tue Sep 6 10:07:43 EDT 2011

Here is a simplistic teachpack: 

#lang racket/base

(require rackunit)

(provide internal-check-expect)

  (internal-check-expect call expected)
  (begin (check-equal? call expected) #true))

It is simplistic in that its error messages are probably not up to the Guillaume standards. I placed it in the same folder as a minor variation of your program: 

(require "ice.rkt") ;; and required it explicitly but you could go thru the teachpack menu

(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))

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

(check-divides divides-modulo?)
(check-divides divides-divide?)
(check-divides divides?)

This runs fine. The 'and' is needed because we need to combine expressions in a functional language. The 'true' that you see then is the result of the two. 

Does this help? 

Thanks for reporting the error in the teachpack docs. -- Matthias

On Sep 5, 2011, at 5:42 PM, John Riedl wrote:

> 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,
> consider:
> ; 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.
> Thanks,
> John
> _________________________________________________
>  For list-related administrative tasks:
>  http://lists.racket-lang.org/listinfo/users

Posted on the users mailing list.