[plt-scheme] Best style on argument checking...

From: Robby Findler (robby at cs.uchicago.edu)
Date: Tue Mar 27 17:51:19 EDT 2007

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
>


Posted on the users mailing list.