On Wed, Jan 4, 2017 at 7:02 PM, Marc Nieper-Wißkirchen <xxxxxx@math.uni-augsburg.de> wrote:

This is not exactly doing what my example does. (In your version, you have no control about the error case - whether it is signaled or not, what the error message is, etc.) If you don't like this argument, consider the following instead:

(define f
  (case-lambda
    ((x y z) (* x y z))
    (args 
      (log "f has been invoked with a wrong number of arguments" args)
      (error "f has to be invoked with exactly three arguments"))))

I could imagine something like this when deprecating
a call signature in a public API.  Again, you can do the
same in a variety of ways, and this falls far short of the
types of changes you'd usually want to track in an API
(e.g. parameter types), so it's once again a matter of
case-lambda being a poor solution for both common
and more general cases.  If this is the best example it
has to offer, then there are a million things I would rather
have had taking up space in the small language, starting
with something actually designed well for optional
parameters like let-optionals[*].

NB: In my Rapid Scheme front-end, I am currently using case-lambda as a core form, but it does replace lambda, so the number of core forms do not change. And handling case-lambda-nodes is no more difficult than handling lambda-nodes in an AST (you just have one more loop, over the clauses).

I don't want the extra loop - in fact, I don't want
extra code at all, I just want to pattern match the
form.

Just two more instances of "..." (or ,@ or whatever, depending on your pattern matcher).

It's worse than that.  Consider the following template for
general transformations on an AST using pattern matching:

  ;; Outline of a typical AST transformer, with AST record types Cnd,
  ;; Seq and Lam, and App.
  (define (foo x)
    (match x
      ;; conditional (if)
      (($ Cnd test pass fail)
       (make-cnd (foo test) (foo pass) (foo fail)))
      ;; sequence
      (($ Seq ls)
       (make-seq (map foo ls)))
      ;; lambda
      (($ Lam name params body)
       (make-lam name params (foo body)))
      ;; application
      (($ App ls ...)
       (make-app (map foo ls)))
      ;; leaf node
      (else
       x)))

Now consider you want to specifically apply a transformation
to functions consisting of a single conditional:

  (define (foo x)
    (match x
      (($ Cnd test pass fail)
       (make-cnd (foo test) (foo pass) (foo fail)))
      (($ Seq ls)
       (make-seq (map foo ls)))
      (($ Lam name params ($ Cnd test pass fail))
       (make-lam name '() (foo-cnd test pass fail)))
      (($ Lam name params body)
       (make-lam name params (foo body)))
      (($ App ls ...)
       (make-app (map foo ls)))
      (else
       x)))

If we replace the Lam nodes with Case-Lam nodes of the form:

  ($ Case-Lam name ((params body) ...))

then we can no longer achieve the same logic with a single
match form, but need to factor out a utility function in order to
perform the recursion you suggest:

  (define (foo x)
    (define (match-body y)
      (match y
        (($ Cnd test pass fail)
         (foo-cnd test pass fail))
        (body
         (foo body))))
    (match x
      (($ Cnd test pass fail)
       (make-cnd (foo test) (foo pass) (foo fail)))
      (($ Seq ls)
       (make-seq (map foo ls)))
      (($ Case-Lam name ((params body) ...))
       (make-case-lam name (map list params (map match-body body))))
      (($ App ls ...)
       (make-app (map foo ls)))
      (else
       x)))

I would not want to write such compiler transformations on an
AST using case-lambda as a core form.

-- 
Alex