[plt-scheme] Re: command-line, parameters, contracts
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!
>