racket / rackunit

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Check contracts

jackfirth opened this issue · comments

Since custom checks aren't functions, they can't be protected by contract-out without disabling their location-capturing capabilities. A check-out provide form that allows contracts to be added could work like this:

(provide
  (check-out check-foo (check-> foo?)))

(define-check (check-foo foo) ...)

A check that has its contract violated should raise an error rather than causing a check failure. The check-> combinator is used instead of a normal -> combinator because 1) checks always return void?, 2) checks have extra "secret" arguments (#:location and #:expression specifically) passed in by their macro expansion, and 3) checks don't support user-defined keyword, optional, or rest arguments.

Hmm, check-out seems like a bad way to fix because it's new & very special purpose syntax.

What about, instead, define-check/contract?

(Also since check-> is nothing like -> I think it should be named check/c ... but that's besides the point.)

contract-out and define/contract use different parties for blaming: contract-out uses a boundary between the exporting and importing modules, but define/contract uses a boundary between the function itself and the rest of the module it's defined in. define-check/contract would definitely be useful, but it could only work in the way define/contract does where there's a boundary between the check and it's surrounding module. I think we'd need some sort of provide form to blame in terms of client modules.

Also, +1 to check/c.

Good point about the boundaries.

Well I think the best fix would be changing contract-out to handle macros.
I'm not sure how to do that, so +1 to check-out.