[plt-scheme] Re: command-line, parameters, contracts

From: Greg Hendershott (greghendershott at gmail.com)
Date: Wed May 19 12:43:36 EDT 2010

P.S. Some of the functions in 7.6 turn out to be un-provided. And the
rest don't work as I expect/guess.  Transcript:

Welcome to DrScheme, version 4.2.4 [3m].
Language: Module; memory limit: 1024 megabytes.
> (define/contract (f x) (integer? . -> . integer?) x)

> (has-contract? f)
. . reference to an identifier before its definition: has-contract?

> (value-contract? f)
. . reference to an identifier before its definition: value-contract?

> (flat-contract-predicate? f)
. . reference to an identifier before its definition: flat-contract-predicate?

> (contract? f)
#t    ; comment: I would have guessed f HAS-a contract if I could call
has-contract?. But it IS-a contract?

> (flat-contract? f)
#t

> (contract-first-order-passes? (flat-contract-predicate f) 1)
#t

> (contract-first-order-passes? (flat-contract-predicate f) null)
#t   ; shouldn't this be #f because (integer? null) is #f?



On Tue, May 18, 2010 at 6:00 PM, Greg Hendershott
<greghendershott at gmail.com> wrote:
> The short version: I want to write something like
> (validate-set-parameter parameter value), but I'm lost in 7.6 Contract
> Utilities docs.
>
> The long version:
>
> I like to make contracts for parameters. I made some macros like this:
>
> (define-syntax define/contract/provide-parameter
>  (syntax-rules()
>    [(_ name contract init)
>     (begin
>       (define/contract name
>         (() (contract) . ->* . (or/c contract void?))
>         (make-parameter init))
>       (provide/contract [name (() (contract) . ->* . (or/c contract
> void?))]) )]))
>
> to be able to write
>
> (define/contract/provide-parameter foo boolean? #t)
>
> Working fine.
>
>
> Next, I'm doing a command line utility with a moderately complex set
> of flags and acceptable values.
>
> The obvious approach is:
>
> [1] Specify a parameter for each flag.
> [2] Use command-line to specify the flags, providing some code to get
> values from one or more flags into each parameter.
>
> Working fine.
>
>
> The one piece left to do, is to provide input validation for the
> command line flags.
>
> So I'm thinking, I already have contracts on the params that state
> what's valid. Why not use them? There's got to be some nifty way to
> glue it all together.  Has anyone done this?
>
> One idea I had is to make a "command-line/validate-using-contract",
> with an extra expression for each flag to hold the contract. It would
> of course use each contract to validate, display an error, etc. But in
> use would need to repeat the contract for each flag. It's already
> defined and associated with each parameter, why not just peek at that?
>
> So I think I simply want a (validate-set-param param value) kind of
> helper, to be used like this:
>
> (define/contract-parameter foo exact-positive-integer? 1)
> ; ...
> (command-line
>  #:once-each
>  [("-n" "--number") x "A positive number" (validate-set-param foo x)]
> ; instead of unvalidated (foo x)
> )
>
> So that seems reasonable. The question is, um, how to implement it:
>
> (define (validate-set-param p v)
>  ; (1) how to get the contract associated with p?
>  ; (2) how to see if v satisfies it?
>  ; (3) how to get a somewhat friendlier version as an error message
> (e.g. just "need to provide exact-positive-integer")
>  )
>
> So fine but but re 1-3 I'm pretty lost looking at 7.6 Contract
> Utilities, not sure where to start.  For example, a parameter is a
> proc, so does it have "value contract"? Seems probably not, but in
> that case what do I use instead?  And so on.
>
> Can anyone give me a nudge in the right direction?
>
> Thanks in advance!
>


Posted on the users mailing list.