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

From: Asumu Takikawa (asumu at ccs.neu.edu)
Date: Mon Jun 25 22:05:03 EDT 2012

On 2012-06-25 21:28:52 -0400, Asumu Takikawa wrote:
>   (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?)]))]))

Addendum: something you might imagine wanting for a dictionary is a
contract that looks like the following instead:

    (simple-dict/c
     #:params (key/c value/c) ; <--
     [dict-ref (->* (simple-dict? key/c) (any/c) value/c?)]
     [dict-set (-> simple-dict? key/c value/c simple-dict?)]
     [dict-remove (-> simple-dict? key/c simple-dict?)]))]))

taking after similar language constructs like type classes where you can
parameterize the entire family of operations over the types. I
experimented with this idea (where `key/c` and `value/c` are turned into
parameteric contracts), but it turns out to be incompatible with our
design.

For example, there is no way for the dict contract above to apply to the
constructor of the data structure (since that isn't an operation in the
interface). Thus, the initial elements you provide to the constructor
can't be looked up with `dict-ref` with the above parametric contract
(the argument key is made opaque with `key/c` and won't be equal to any
of the existing keys).

My conclusion for now is that it's not obvious how to best handle
contract parameterization over a data structure interface and that it
requires more thought. Let me know if anyone has any ideas. :)

Cheers,
Asumu

Posted on the dev mailing list.