TR check-equal does not catch errors?

It appears to me that racket and typed/racket behave differently with respect to errors that occur during the evaluation of arguments to check-equal?. Specifically, the program

#lang typed/racket

(require typed/rackunit)

(check-equal? 3 (/ 1 0))

... halts with an error, whereas

#lang racket

(require rackunit)

(check-equal? 3 (/ 1 0))

... signals a test case failure (and, presumably, continues to run tests).

Is this a deliberate design choice? It certainly looks like a bug.

EDIT: D'oh! yes, mis-pasted the second one.

Is there a typo somewhere? Those programs are identical.

This errs:

#lang typed/racket/baes
(require typed/rackunit)
(check-equal? 3 (/ 1 0))
(check-equal? 5 "not=")
;; . . /: division by zero

This also errs:

#lang racket/base
(require typed/rackunit)
(check-equal? 3 (/ 1 0))
(check-equal? 5 "not=")
;; . . /: division by zero

This fails:

#lang racket/base
(require rackunit)
(check-equal? 3 (/ 1 0))
(check-equal? 5 "not=")
;; --------------------
;; . ERROR
;; name:       check-equal?
;; location:   3-unsaved-editor:3:0
;; 
;; /: division by zero
;; --------------------
;; --------------------
;; . FAILURE
;; name:       check-equal?
;; location:   3-unsaved-editor:4:0
;; actual:     5
;; expected:   "not="
;; --------------------

So it could be typed/rackunit?

1 Like

Well, it looks like check-equal? is a macro, so it's the untyped check-equal? that's special.

I thought I filed an issue relating to this problem. :upside_down_face:

check-equal? is indeed a macro, especially when it is called with arguments. It alone also expands to a function, which is kind of confusing. And the documentation might cause more confusion, as it says check-* are procedures.

In the section 3.2 of RackUnit's doc, it says:

Although checks are implemented as macros, which is necessary to grab source locations (see Custom Checks), they are conceptually functions (with the exception of check-match below).