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

From: Greg Hendershott (greghendershott at gmail.com)
Date: Tue May 18 18:00:58 EDT 2010

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.