Lackadaisical Contracts
| (require lackadaisical-contract) | |
| package: lackadaisical-contract-lib | |
This library provides contract forms that implement the lackadaisical checking strategy. In lackadaisical, interactions with higher-order values at the contract level are deferred until the program itself exhibits those same interactions.
syntax
(->l ([dom-id dom-expr] ...) pre [cod-id cod-expr] post)
pre =
| #:pre (id ...) expr pre post =
| #:post (id ...) expr post
> (define/contract (bad g) (->l ([g (-> integer? integer?)]) #:pre (g) (zero? (g 1)) [result integer?]) (g 1)) > (bad values) bad: contract violation
failed clause (#:pre (g) (zero? (g 1)))
in: (->l
((g (-> integer? integer?)))
#:pre
(g)
(zero? (g 1))
(result integer?))
contract from: (function bad)
blaming: top-level
(assuming the contract is correct)
at: eval:1:0
> (define/contract (ok g) (->l ([g (-> integer? integer?)]) #:pre (g) (zero? (g 1)) [result integer?]) (g 17)) > (ok values) 17
syntax
(self/c id ([set-id set-ctc] ...) body clause ...)
clause = (∀ ([id dom] ...) prop-expr ...+)
> (define injective/c (self/c f ([A any/c]) (-> A any/c) (∀ ([x A] [y A]) (implies (equal? (f x) (f y)) (equal? x y)))))
> (define/contract (floor* x) injective/c (floor x)) > (floor* 3.5) 3.0
> (floor* 4.5) 4.0
> (floor* 4.85) floor*: broke its own contract
promised: (implies (equal? (f x) (f y)) (equal? x y))
where: x is 4.5, y is 4.85
in: (self/c
f
((A any/c))
(-> A any/c)
(∀
((x A) (y A))
(implies
(equal? (f x) (f y))
(equal? x y))))
contract from: (function floor*)
blaming: (function floor*)
(assuming the contract is correct)
at: eval:6:0