[plt-scheme] Dynamic Contracts

From: Carl Eastlund (cce at ccs.neu.edu)
Date: Fri Jul 21 14:00:26 EDT 2006

Chris, you should look at the ->d and ->r contract forms in the
contract.ss library.  They allow higher-order function contracts whose
result position can depend on the values of the inputs.  For instance,
in your case:

(provide/contract
 [make-list (natural-number/c any/c . ->d .
  (lambda (count val)
    (and/c
     (listof (lambda (elem) (eq? elem val)))
     (lambda (list) (= (length list) count)))))])

If I've written it right, this enforces that the result is a list,
that it contains only the given value, and that its length is the
given count.

--Carl

On 7/21/06, Chris Warrington <gcw5217 at rice.edu> wrote:
> Does contract.ss support what I want to call "dynamic contracts?"
>
> Consider this function:
> ; make-list : natural-number X -> [X]
> ; Creates a list of the given length in which each element
> ; is the provided element.
> (define (make-list count val) ...)
>
> Using provide/contract (yes, I'm doing this in a module), I can attach a simple
> contract to this:
> (provide/contract [make-list (natural-number/c any/c . -> . (listof any/c))])
>
> However, this contract can be made stronger. For example, the length of the list
> should be equal to count. However, I can't find a good way to do this.
> Thus far, the best I have is this:
>
> ; dc:make-list
> ; Dynamic contract for make-list
> (define (dc:make-list count val)
>   ((contract (natural-number/c any/c . -> . (and/c (listof any/c)
>                                                    (&#955; (lst) (= (length lst)
> count))))
>              make-list
>              'callee
>              'caller)
>    count val))
>
> Is there an easier way to do these "dynamic contracts?" How would one go about
> enforcing the type contraint in this case (i.e., the list should be of the same
> type as val)?
>
> --
> Chris Warrington <chrisw at rice.edu>
> (away from his normal computer)


Posted on the users mailing list.