[plt-scheme] contracts and structure subtypes?
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