[racket-dev] [plt] Push #24906: master branch updated

From: Asumu Takikawa (asumu at ccs.neu.edu)
Date: Mon Jun 25 21:28:52 EDT 2012

On 2012-06-25 20:15:49 -0500, Robby Findler wrote:
> This is not directly related to your particular commit, but if I make
> a make-prime-dict, does apply a contract at that point (using
> 'contract')? If so, who are the parties that get blamed?

The short answer is: the generated contract can be applied, for example,
in the range of a constructor and the blame is from whatever contract
boundary it was applied at.

Longer: I'll explain by way of example. Suppose you define a generic
interface:

  (define-generics simple-dict
    (dict-ref    simple-dict key [default])
    (dict-set    simple-dict key val)
    (dict-remove simple-dict key))

then you define an implementation of it (perhaps in a different module):

  (define-struct some-dict (v)
    #:methods gen:simple-dict
    [...])

then you can provide a constructor from that implementing module that
contracts the resulting instance:

  (provide/contract
   [make-int-dict
    (-> key-value-list?
        (simple-dict/c
         [dict-ref (->* (simple-dict? symbol?) (any/c) integer?)]
         [dict-set (-> simple-dict? symbol? integer? simple-dict?)]
         [dict-remove (-> simple-dict? symbol? simple-dict?)]))]))

You could also provide the same constructor under a different contract
(with a subset of the operations if you want):

  (provide/contract
   [make-prime-dict
    (-> key-value-list-of-primes?
        (simple-dict/c
         [dict-set (-> simple-dict? symbol? prime? simple-dict?)]))]))

Instances made with these constructors will have the appropriate checks
when you use `dict-set` on them.

Cheers,
Asumu

Posted on the dev mailing list.