Am Mi., 15. Apr. 2020 um 12:54 Uhr schrieb Lassi Kortela <
xxxxxx@lassi.io>:
> 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.
My example is not a test that fails to report a violation (this can always happen); it is a test that reports a violation where there is none. This is far more serious and just shows that the test is wrong.
> 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.
That's why I am saying that `arity-error?' isn't helpful for checking that a procedure does not accept the wrong number of arguments.
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.)
For a particular implementation, `arity-error?' may be helpful, but not for a test suite that is supposed to be (mostly) portable. A test using `arity-error?' would depend on implementation details of the procedures being tested (see the examples above), which goes against the very basic principles of good tests.