David Van Horn

This collection provides the record-case form for pattern matching
lists as used at Indiana University (in particular the 1996 Compiling
Scheme Workshop uses this form in its expository Scheme compiler).

The Indiana documentation can be found here:

The Compiling Scheme Workshop compiler can be found here:

> record-case  SYNTAX
> record-case* SYNTAX

The record-case form supports a very restricted form of pattern
matching, which dispatches on a symbol in the car of a list and binds
the elements of the cdr of a matching list to given formal
parameters. This allows dispatch on the form of expressions in
Scheme-like syntax, in the manner of variant-case in EOPL, but without
requiring a parser. The syntax of a record-case expression is

   (record-case expression clause +.. [(else expression +..])

where each clause is of the form

   (symbol formals expression +..)

+.. indicates a sequence of one or more of the preceding syntactic
elements.  A record-case* expression assumes, but does not check, that
the expression is well-formed.

Each clause should have a different symbol.

The formals is a formal parameter specification of any form that might
be used in a lambda expression immediately following the keyword

The expression following record-case is evaluated first; call its
value V, which should be a pair. If the car of V is the same as that
of one of the clauses, then that clause is selected. It is then almost
as if

    (apply (lambda formals expression +..) (cdr V))

were evaluated with V bound to V and formals and expression ... taken
from the selected clause, with the resulting value returned as the
value of the record-case expression. The diffence is that if the cdr
of V contains more values than match the formals, the extra values are
ignored, and if it contains fewer values, an error will be reported by
car or cdr. (Car-cdr chains are used instead of apply for efficiency.)

If the car of V does not match any of the clause symbols, the else
clause is selected and evaluated as in a cond clause, and otherwise an
unspecified value is returned.

For example:

> (define test
    (lambda (e)
      (record-case e
      (a (b c) (list b c))
      (b c c)
      (c (a . b) (list a b))
      (else 'whatever))))
> (test '(a 1 2))
(1 2)
> (test '(b 1 2 3 4))
(1 2 3 4)
> (test '(c 1 2 3 4))
(1 (2 3 4))
> (test '(d 1 2 3 4))
> (test '(a 1 2 3 4))
(1 2)
> (test '(a 1))

Error in car: () is not a pair.