[plt-scheme] contracts and structure subtypes?

From: Robby Findler (robby at cs.uchicago.edu)
Date: Sun May 23 18:19:32 EDT 2004

This has been on my list of things to do for some time now. Thanks for
the prodding. The v299-tagged version of contracts now supports parent
structs (299 is very much still a work in progress, so you may have to
wait a while before this becomes useful to you).

Here are the revised docs:

  p/c-item :==
  (struct identifier ((identifier contract-expr) ...))
  (struct (identifier identifier) ((identifier contract-expr) ...))
  ... and the old stuff ...

  The \scheme|struct| form of a \scheme|provide/contract| clause
  provides a structure definition. Each field has a contract that
  dictates the contents of the fields.

  If the struct has a parent, the second \scheme|struct| form (above)
  must be used, with the first name referring to the first struct and
  the second name referring to the second one. Unlike
  \scheme|define-struct|, however, all of the fields (and their
  contracts) must be listed. The contract on the sub-structs common
  fields are only used in the contract for the sub-struct's maker (but
  not the selector or mutators).

  Note that the struct definition must come before the provide clause
  in the module's body.

Robby

At Sun, 23 May 2004 15:00:08 -0400, "Richard C. Cobbe" wrote:
>   For list-related administrative tasks:
>   http://list.cs.brown.edu/mailman/listinfo/plt-scheme
> 
> Greetings, all.
> 
> I'm trying to get the contract system to work in conjunction with
> structure subtypes, and I'm running into difficulties.  Consider the
> following module:
> 
> (module foo mzscheme
>   
>   (require (lib "contract.ss"))
>   
>   (define-struct base (x y))
>   (define-struct (derived base) (z))
>   
>   (provide/contract
>    (struct base ([x integer?] [y boolean?]))
>    (struct derived ([z string?]))))
> 
> I don't seem to be able to apply derived's constructor:
> 
> Welcome to DrScheme, version 207.1-cvs23may2004.
> Language: Pretty Big (includes MrEd and Advanced).
> > (require foo)
> > (make-base 3 #f)
> #<struct:base>
> > (make-derived 3 #f "foo")
> 6.3: top-level: foo broke make-derived's contract: (-> string? derived?): expected a 
> procedure that accepts 1 arguments, given: #<struct-procedure:make-derived>
> 
> Adding the inherited fields to derived's contract doesn't work any
> better (although this isn't surprising):
> 
> (module foo mzscheme
>   
>   (require (lib "contract.ss"))
>   
>   (define-struct base (x y))
>   (define-struct (derived base) (z))
>   
>   (provide/contract
>    (struct base ([x integer?] [y boolean?]))
>    (struct derived ([x integer?] [y boolean?] [z string?]))))
> 
> Welcome to DrScheme, version 207.1-cvs23may2004.
> Language: Pretty Big (includes MrEd and Advanced).
> expand: unbound variable in module in: derived-x
> >
> 
> Is there some way to make the contracts do the right thing?  Or can I
> simply not use the (struct ...) form for structures that inherit fields?
> Having to write the contracts for all of the relevant functions is
> possible but awfully annoying.
> 
> So far as I can tell, the MzLib manual doesn't address this, and
> Google's let me down as well.  Any ideas?
> 
> Thanks,
> 
> Richard


Posted on the users mailing list.