Multiple dispatch for case-lambda-checked? Antero Mejr (28 Sep 2024 20:41 UTC)
Re: Multiple dispatch for case-lambda-checked? Artyom Bologov (28 Sep 2024 22:15 UTC)
Re: Multiple dispatch for case-lambda-checked? Artyom Bologov (28 Sep 2024 22:26 UTC)

Multiple dispatch for case-lambda-checked? Antero Mejr 28 Sep 2024 20:40 UTC

It might be good to explicitly say if (case-lambda-checked) handles
multiple dispatch. The sample implementation does not - it would have to
implement a different version of case-lambda.

It could be valuable for performance optimization, especially for the
numeric tower. But changing any behavior based on type checks can be
unclear.

Maybe let the implementation decide, and/or connect it to a feature
identifier? For example, specify that implementations must have the
type-checking-dispatch feature if they dispatch, and
type-checking-coercion if they coerce?

Example:
```
(define l (case-lambda-checked
           (((x exact?) (y exact?))
            (+ x y))
           (((a inexact?) (b inexact?))
            (- a b))))

(display (l 3.0 2.0))
(display (l 3 2))
```

Multiple dispatch version:
```
(define (all-true? . rest)
  (if (null? rest)
      #t
      (and (car rest) (apply all-true? (cdr rest)))))

(define-syntax case-lambda-checked
  (syntax-rules ()
    ((_ (((arg pred) ...)  body0 ...) other-clauses ...)
     (lambda args
       (let ((len (length args)))
         (letrec-syntax
             ((cl (syntax-rules ::: ()
                    ((cl)
                     (error "no matching clause"))
                    ((cl (((a p) :::) body :::) rest :::)
                     (if (= len (length '((a p) :::)))
                         (apply (lambda (a :::)
                                  (if (all-true? (p a) :::)
                                      (begin body :::)
                                      (cl rest :::)))
                                args)
                         (cl rest :::))))))
           (cl (((arg pred) ...) body0 ...) other-clauses ...)))))))
```