[plt-scheme] Best style on argument checking...
Also see
http://people.cs.uchicago.edu/~robby/plt-contracts-guide/#genfunc
-- Matthias
On Mar 27, 2007, at 5:51 PM, Robby Findler wrote:
> Contracts work fine for that example:
>
> (opt-> (string?) (number? symbol?) string?)
>
> Robby
>
> On 3/26/07, Paulo J. Matos <pocm at soton.ac.uk> wrote:
>> Hello all,
>>
>> I'd like suggestions on style about arguments checking.
>> This happens to me (and I'm sure to you too) regularly. Guess [to
>> exemplify] you want to define a function with 3 arguments, 2 of them
>> optional. The first obligatory argument should be a string, the
>> second
>> a number and the third a symbol. You just want to append them all and
>> return a string.
>>
>> No arguments checking is easy:
>> (define (append-all str . args)
>> (string-append str
>> (if (>= (length args) 1) (number->string (car
>> args)) "")
>> (if (= (length args) 2) (symbol->string (cadr
>> args)) "")))
>>
>> Problem is str might not be a string and the rest of the arguments
>> may
>> not have correct type. And args can have 3 arguments [probably we
>> would like to warn the user about it].
>>
>> So, the other chance is:
>> (define (append-all1 str . args)
>> (if (<= (length args) 2)
>> (let ([str-ok? (string? str)]
>> [arg2-ok? (or (null? args)
>> (number? (car args)))]
>> [arg3-ok? (or (< (length args) 2)
>> (symbol? (cadr args)))])
>> (if (and str-ok? arg2-ok? arg3-ok?)
>> (string-append str
>> (if (>= (length args) 1) (number->string (car
>> args)) "")
>> (if (= (length args) 2) (symbol->string (cadr
>> args)) ""))
>> (error "args not of correct type but I cannot say
>> which")))
>> (error "usage is append-all1 string [number] [symbol], you
>> passed in too many arguments")))
>>
>> or even this:
>> (define (append-all2 str . args)
>> (cond [(> (length args) 2)
>> (error "too many arguments")]
>> [(not (string? str))
>> (error "first argument needs to be a string")]
>> [(not (or (null? args)
>> (number? (car args))))
>> (error "second argument needs to be a number")]
>> [(not (or (< (length args) 2)
>> (symbol? (cadr args))))
>> (error "third argument needs to be a symbol")]
>> [else
>> (string-append str
>> (if (>= (length args) 1) (number->string
>> (car args)) "")
>> (if (= (length args) 2) (symbol->string (cadr
>> args)) ""))]))
>>
>> I tend to switch between variants of the first way (this cond'ified
>> check is just something that came up while thinking about the issue).
>> However, I might guess other options are:
>> - contracts, however, I'm not sure if they help you checking the
>> types
>> of the optional arguments and the number of optional arguments, I
>> don't think they do.
>> - typed-scheme (?!?), not really sure about this one but that would
>> probably require you to type variables also within the function which
>> you might not want to do.
>>
>> So, given that you have pure scheme, what would be the best style to
>> do this (hopefully portably since this is a general scheme problem)?
>>
>> Cheers,
>> --
>> Paulo Jorge Matos - pocm at soton.ac.uk
>> http://www.personal.soton.ac.uk/pocm
>> PhD Student @ ECS
>> University of Southampton, UK
>> _________________________________________________
>> For list-related administrative tasks:
>> http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>>
> _________________________________________________
> For list-related administrative tasks:
> http://list.cs.brown.edu/mailman/listinfo/plt-scheme