Re: Detecting arity errors
Lassi Kortela 15 Apr 2020 10:54 UTC
> It doesn't distinguish arity errors from other kinds of errors. An
> `arity-error?` predicate could be plugged into `test-error` (if its
> `error-type` argument is extended to allow predicate procedures, which
> seems reasonable and permitted by the SRFI 64 definition).
>
> I don't see how `arity-error?' will work reliably here. Consider the
> following definition:
>
> (define (member x x* . =?*)
> (let ((=? (cond ((null? =?*) equal?)
> ((null? (cdr =?*)) (car =?*))
> (else (error "member: arity error: two many arguments
> given")))))
> (let f ((x* x*)) (and (not (null? x*)) (if (=? x (car x*)) x* (f
> (cdr x*)))))))
>
> A test like `(test-error arity-error? (member 'a '(b c d) eq? 'junk))'
> will fail.
No test is perfect. It would be a useful safeguard against obvious
mistakes that have practical consequences. No matter how well we write
tests, it's not possible to catch every problem or avoid all ambiguities.
> A related problem is with an implementation like the following one when
> it is used in Schemes that macro-expand `case-lambda' into `lambda':
>
> (define member
> (case-lambda
> ((x x*) (member x x* equal?))
> ((x x* =?) ...)))
That case also cannot be helped.
Another example is, an arity error when calling `foo` does not
necessarily come from passing an incorrect number of args to `foo`. It
could also come from `foo` internally passing incorrect args to some
helper procedure. Or the outer call to `foo` has correct args but `foo`
calls itself recursively with incorrect args, etc. If we wanted to
handle all nuances like this, the tests would probably become so verbose
that no-one would want to write them.
I stand by my claim that such tests are useful in many situations even
if not perfect, or not applicable to all situations. A useful
`arity-error?` also ought to be fairly easy to define. (When in doubt,
just return #f.)