[plt-scheme] Best style on argument checking...
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
>