\documentstyle[abstract,slatex]{article}

% This documentation requires Dorai Sitaram's SLaTeX.

\leftcodeskip=\leftmargin
\rightcodeskip=0pt plus 1fil
\abovecodeskip\abovedisplayskip
\belowcodeskip\belowdisplayskip

\defschememathescape{$}
\def\unconfusedetex{$}
\setkeyword{match match-lambda match-lambda* match-let match-let* match-letrec}
\setkeyword{match-define}
\setkeyword{and or not ? $ _ ... ..0 ..1 =>}
\setkeyword{define-structure define-const-structure}
\setvariable{struct}
\setconstant{&}

\def\beginfig{\begin{figure*}[tbp] {\ \hrulefill\ }\small}
\def\endfig{{\ \hrulefill\ }\end{figure*}}
\def\alt{\mathrel{\mid}}
\def\SF#1{\mbox{\sf #1}}
\def\us{\rule{0.9ex}{0.1ex}}

\begin{document}
\bibliographystyle{acm}

\title{\LARGE Pattern Matching for Scheme}
\author{Andrew K. Wright and Bruce F. Duba \\[1ex]
 Department of Computer Science \\
 Rice University \\
 Houston, TX 77251-1892}

\date{Version 1.12, \today}

\maketitle

\begin{quote}
Please direct questions or bug reports regarding this
software to {\sf wright@research.nj.nec.com}.
The most recent version of this software can be obtained by anonymous
FTP from site {\sf ftp.nj.nec.com} in file {\sf pub/wright/match.tar.gz}.
\end{quote}

\section{Pattern Matching for Scheme}

Pattern matching allows complicated control decisions based on data
structure to be expressed in a concise manner.  Pattern matching is
found in several modern languages, notably Standard ML, Haskell and
Miranda.  This document describes several pattern matching macros for
Scheme, and an associated mechanism for defining new forms of
structured data.

The basic form of pattern matching expression is:
\begin{schemedisplay}
(match exp [pat body] ...)
\end{schemedisplay}
%
where {\it exp\/} is an expression, {\it pat\/} is a pattern, and
{\it body\/} is one or more expressions
(like the body of a {\bf lambda}-expression).%
\footnote{
The notation ``$\langle {\it thing\/} \rangle\: \ldots$''
indicates that $\langle {\it thing\/} \rangle$ is
repeated zero or more times.
The notation ``$\langle {\it thing}_1 \alt {\it thing}_2 \rangle$''
means an occurrence of either ${\it thing}_1$ or ${\it thing}_2$.
Brackets ``$[]$'' are extended Scheme syntax,
equivalent to parentheses ``$()$''.
}
The {\bf match} form matches its first subexpression against a sequence
of patterns, and branches to the {\it body\/}
corresponding to the first pattern successfully matched.
For example, the following code defines the usual {\it map\/} function:
\begin{schemedisplay}
(define map
  (lambda (f l)
    (match l
      [() ()]
      [(x . y) (cons (f x) (map f y))])))
\end{schemedisplay}
The first pattern $()$ matches the empty list.  The second pattern
$(x ~.~ y)$ matches a pair, binding $x$ to the first component of
the pair and $y$ to the second component of the pair.

\subsection{Pattern Matching Expressions}

The complete syntax of the pattern matching expressions follows:
\begin{quote}
\begin{tabular}{rrl}
{\it exp\/} &::=& \scheme{(match exp clause ...)} \\
&$\alt$& \scheme{(match-lambda clause ...)} \\
&$\alt$& \scheme{(match-lambda* clause ...)} \\
&$\alt$& \scheme{(match-let ([pat exp] ...) body)} \\
&$\alt$& \scheme{(match-let* ([pat exp] ...) body)} \\
&$\alt$& \scheme{(match-letrec ([pat exp] ...) body)} \\
&$\alt$& \scheme{(match-let var ([pat exp] ...) body)} \\
&$\alt$& \scheme{(match-define pat exp)}
\\[2ex]
{\it clause\/} &::=& \scheme{[pat body]}
  $~~\alt~~$ \scheme{[pat (=> identifier) body]}
\end{tabular}
\end{quote}
Figure~\ref{fig:patterns} gives the full syntax for patterns.
\beginfig
\begin{minipage}{\linewidth}
\[\begin{array}{rrll}
&& {\it Pattern:\/} & {\it Matches:\/}
\\[0.5ex]
{\it pat\/} &::=& {\it identifier\/}            &
  \mbox{anything, and binds {\it identifier\/} as a variable}
\\
%    &\alt& {\rm repeated}~{\it identifier\/}     &
%  \mbox{anything {\it equal?\/} to what first occurrence matched}
% \\
    &\alt& \_                                    & \mbox{anything}
\\
    &\alt& ()                                    & \mbox{itself (the empty list)}
\\
    &\alt& \SF{\#t}                              & \mbox{itself}
\\
    &\alt& \SF{\#f}                              & \mbox{itself}
\\
    &\alt& {\it string\/}                        & \mbox{an {\it equal?\/} string}
\\
    &\alt& {\it number\/}                        & \mbox{an {\it equal?\/} number}
\\
    &\alt& {\it character\/}                     & \mbox{an {\it equal?\/} character}
\\
    &\alt& \mbox{'{\it s-expression\/}}          & \mbox{an {\it equal?\/} s-expression}
\\
    &\alt& \mbox{'{\it symbol\/}}                & \mbox{an {\it equal?\/} symbol (special case of s-expression)}
\\
    &\alt& ({\it pat\/}_1 \ldots {\it pat\/}_n)  & \mbox{a proper list of $n$ elements}
\\
    &\alt& ({\it pat\/}_1 \ldots {\it pat\/}_n ~.~ {\it pat\/}_{n+1})
                                                & \mbox{a list of $n$ or more elements}
\\
    &\alt& ({\it pat\/}_1 \ldots {\it pat\/}_n ~ {\it pat\/}_{n+1} ~\underline{..k})                                                & \mbox{a proper list of $n+k$ or more elements}\footnote{
The notation $\underline{..k}$ denotes a keyword consisting of
three consecutive dots (ie., ``$...$''), 
or two dots and an non-negative integer (eg., ``$..1$'', ``$..2$''),
or three consecutive underscores (ie., ``$\us\,\us\,\us$''),
or two underscores and a non-negative integer.
The keywords ``$..k$'' and ``$\us\,\us k$'' are equivalent.
The keywords ``$...$'', ``$\us\,\us\,\us$'', ``$..0$'', and ``$\us\,\us0$''
are equivalent. }
\\
    &\alt& \SF{\#}({\it pat\/}_1 \ldots {\it pat\/}_n)
                                                & \mbox{a vector of $n$ elements}
\\
    &\alt& \SF{\#}({\it pat\/}_1 \ldots {\it pat\/}_n ~ {\it pat\/}_{n+1} ~\underline{..k})
                                                & \mbox{a vector of $n+k$ or more elements}
\\
    &\alt& \SF{\#\&}{\it pat\/}                  & \mbox{a box}
\\
    &\alt& (\$ ~ {\it struct\/} ~ pat_1 \ldots pat_n) %$
                                                & \mbox{a structure}
\\
    &\alt& (= ~ {\it field\/} ~ pat)
                                                & \mbox{a field of a structure}
\\
    &\alt& ({\bf and} ~ {\it pat\/}_1 \ldots {\it pat\/}_n) & \mbox{if all of ${\it pat\/}_1$ through ${\it pat\/}_n$ match}
\\
    &\alt& ({\bf or} ~ {\it pat\/}_1 \ldots {\it pat\/}_n) & \mbox{if any of ${\it pat\/}_1$ through ${\it pat\/}_n$ match}
\\
    &\alt& ({\bf not} ~ {\it pat\/}_1 \ldots {\it pat\/}_n) & \mbox{if none of ${\it pat\/}_1$ through ${\it pat\/}_n$ match}
\\
    &\alt& (? ~ {\it predicate\/} ~ {\it pat\/}_1 \ldots {\it pat\/}_n)  & \mbox{if {\it predicate\/} true and ${\it pat\/}_1$ through ${\it pat\/}_n$ all match}
\\
    &\alt& ({\bf set!} ~ {\it identifier\/})     & \mbox{anything, and binds {\it identifier\/} as a setter}
\\
    &\alt& ({\bf get!} ~ {\it identifier\/})     & \mbox{anything, and binds {\it identifier\/} as a getter}
\\
    &\alt& `{\it qp\/}                           & \mbox{a quasipattern}
\\[2ex]
&& \mbox{{\it Quasipattern:\/}} & {\it Matches:\/}
\\[0.5ex]
 {\it qp\/} &::=& ()                            & \mbox{itself (the empty list)}
\\
    &\alt& \SF{\#t}                              & \mbox{itself}
\\
    &\alt& \SF{\#f}                              & \mbox{itself}
\\
    &\alt& {\it string\/}                        & \mbox{an {\it equal?\/} string}
\\
    &\alt& {\it number\/}                        & \mbox{an {\it equal?\/} number}
\\
    &\alt& {\it character\/}                     & \mbox{an {\it equal?\/} character}
\\
    &\alt& {\it identifier\/}                    & \mbox{an {\it equal?\/} symbol }
\\
    &\alt& ({\it qp\/}_1 \ldots {\it qp\/}_n)    & \mbox{a proper list of $n$ elements}
\\
    &\alt& ({\it qp\/}_1 \ldots {\it qp\/}_n ~.~ {\it qp\/}_{n+1})
                                                & \mbox{a list of $n$ or more elements}
\\
    &\alt& ({\it qp\/}_1 \ldots {\it qp\/}_n ~ {\it qp\/}_{n+1} ~\underline{..k})
                                                & \mbox{a proper list of $n+k$ or more elements}
\\
    &\alt& \SF{\#}({\it qp\/}_1 \ldots {\it qp\/}_n)
                                                & \mbox{a vector of $n$ elements}
\\
    &\alt& \SF{\#}({\it qp\/}_1 \ldots {\it qp\/}_n ~ {\it qp\/}_{n+1} ~\underline{..k})
                                                & \mbox{a vector of $n+k$ or more elements}
\\
    &\alt& \SF{\#\&}{\it qp\/}                  & \mbox{a box}
\\
    &\alt& \mbox{,{\it pat}}                    & \mbox{a pattern}
\\
    &\alt& \mbox{,@{\it pat}}                   & \mbox{a pattern, spliced}
\end{array}\]
\caption{Pattern Syntax} \label{fig:patterns}
\end{minipage}
\endfig
%
The next subsection describes the various patterns.

The {\bf match-lambda} and {\bf match-lambda*} forms are convenient
combinations of {\bf match} and {\bf lambda}, and can be explained
as follows:
\begin{quote}
\begin{tabular}{lcl}
\scheme{(match-lambda [pat body] ...)}
 &=& \scheme{(lambda (x) (match x [pat body] ...))}
\\
\scheme{(match-lambda* [pat body] ...)}
 &=& \scheme{(lambda x (match x [pat body] ...))}
\end{tabular}
\end{quote}
where $x$ is a unique variable.
The {\bf match-lambda} form is convenient when defining a single argument
function that immediately destructures its argument.
The {\bf match-lambda*} form constructs a function that accepts any number
of arguments; the patterns of {\bf match-lambda*} should be lists.

The {\bf match-let}, {\bf match-let*}, {\bf match-letrec},
and {\bf match-define} forms generalize
Scheme's {\bf let}, {\bf let*}, {\bf letrec}, and {\bf define}
expressions to allow
patterns in the binding position rather than just variables.
For example, the following expression:
\begin{schemedisplay}
(match-let ([(x y z) (list 1 2 3)])  $body$)
\end{schemedisplay}
binds $x$ to \SF{1}, $y$ to \SF{2}, and $z$ to \SF{3} in {\it body\/}.
These forms are convenient for destructuring the result
of a function that returns multiple values as a list or vector.
As usual for {\bf letrec} and {\bf define},
pattern variables bound by {\bf match-letrec} and {\bf match-define}
should not be used in computing the bound value.

The {\bf match}, {\bf match-lambda}, and {\bf match-lambda*} forms
allow the optional syntax \scheme{(=> identifier)} between the pattern
and the body of a clause.  When the pattern match for such a clause
succeeds, the {\it identifier\/} is bound to a {\em failure
procedure\/} of zero arguments within the {\it body\/}.  If this
procedure is invoked, it jumps back to the pattern matching
expression, and resumes the matching process as if the pattern had
failed to match.  The {\it body\/} must not mutate the object being
matched, otherwise unpredictable behavior may result.

\subsection{Patterns}

Figure~\ref{fig:patterns} gives the full syntax for patterns.
Explanations of these patterns follow.

\paragraph*{${\it identifier\/}$ (\rm
excluding the reserved names
?, \$, =, \_, {\bf and}, {\bf or}, {\bf not}, {\bf set!}, {\bf get!}, $...$, and
$..k$ for non-negative integers $k$):} %$
matches anything, and binds a variable of this name to
the matching value in the {\it body\/}.
% If the identifier is repeated within the same pattern, the
% corresponding values must all be {\it equal?\/} for the match to
% succeed.

\paragraph*{$\_$:}
matches anything, without binding any variables.
% ; hence, \_
% can be repeated within a pattern without requiring the different
% instances to be {\it equal?\/}.

\paragraph*{$()$, \SF{\#t}, \SF{\#f}, {\it string\/}, {\it number\/},
{\it character\/}, '{\it s-expression\/}:}
These constant patterns match themselves, {\it ie.,}
the corresponding value must be {\it equal?\/} to the pattern.

\paragraph*{$({\it pat\/}_1 \ldots {\it pat\/}_n)$:}
matches a proper list of $n$ elements
that match ${\it pat\/}_1$ through ${\it pat\/}_n$.

\paragraph*{$({\it pat\/}_1 \ldots {\it pat\/}_n ~.~ {\it pat\/}_{n+1})$:}
matches a (possibly improper) list of at least $n$
elements that ends in
something matching ${\it pat\/}_{n+1}$.

\paragraph*{$({\it pat\/}_1 \ldots {\it pat\/}_n ~ {\it pat\/}_{n+1} ~ ...)$:}
matches a proper list of $n$ or more elements, where
each element of the tail matches ${\it pat\/}_{n+1}$.  Each pattern variable in
${\it pat\/}_{n+1}$ is bound to a list of the matching values.  For example,
the expression:
\begin{schemedisplay}
(match '(let ([x 1][y 2]) z)
  [('let ((binding values) ...) exp)  body])
\end{schemedisplay}
binds {\it binding\/} to the list \scheme{'(x y)},
{\it values\/} to the list \scheme{'(1 2)},
and {\it exp\/} to \scheme{'z}
in the body of the {\bf match}-expression.
For the special case where ${\it pat\/}_{n+1}$ is a pattern variable, the list
bound to that variable may share with the matched value.

\paragraph*{$({\it pat\/}_1 \ldots {\it pat\/}_n ~ {\it pat\/}_{n+1} ~ \us\,\us\,\us)$:}
This pattern means the same thing as the previous pattern.

\paragraph*{$({\it pat\/}_1 \ldots {\it pat\/}_n ~ {\it pat\/}_{n+1} ~ ..k)$:}
This pattern is similar to the previous pattern, but the tail must be
at least $k$ elements long.
The pattern keywords $..0$ and $...$ are equivalent.

\paragraph*{$({\it pat\/}_1 \ldots {\it pat\/}_n ~ {\it pat\/}_{n+1} ~ \us\,\us k)$:}
This pattern means the same thing as the previous pattern.

\paragraph*{$\SF{\#}({\it pat\/}_1 \ldots {\it pat\/}_n)$:}
matches a vector of length $n$, whose elements match
${\it pat\/}_1$ through ${\it pat\/}_n$.

\paragraph*{$\SF{\#}({\it pat\/}_1 \ldots {\it pat\/}_n ~ {\it pat\/}_{n+1} ~ ...)$:}
matches a vector of length $n$ or more, where each element
beyond $n$ matches ${\it pat\/}_{n+1}$.

\paragraph*{$\SF{\#}({\it pat\/}_1 \ldots {\it pat\/}_n ~ {\it pat\/}_{n+1} ~ ..k)$:}
matches a vector of length $n+k$ or more, where each element
beyond $n$ matches ${\it pat\/}_{n+1}$.

\paragraph*{$\SF{\#\&}{\it pat\/}$:}
matches a box containing something matching {\it pat\/}.

\paragraph*{$(\$ ~ {\it struct\/} ~ pat_1 \ldots pat_n)$:} %$
matches a structure
declared with {\bf define-structure} or {\bf define-const-structure}.
See Section~\ref{sect:struct}.

\paragraph*{$(= ~ {\it field\/} ~ pat)$:}
is intended for selecting a field from a structure.  ``field'' may be
any expression; it is applied to the value being matched, and the
result of this application is matched against {\it pat}.

\paragraph*{$({\bf and} ~ {\it pat\/}_1 \ldots {\it pat\/}_n)$:}
matches if all of the subpatterns match.
At least one subpattern must be present.
This pattern is often used as $({\bf and} ~ x ~ pat)$ to bind $x$ to
to the entire value that matches {\it pat\/}
(cf. ``as-patterns'' in ML or Haskell).

\paragraph*{$({\bf or} ~ {\it pat\/}_1 \ldots {\it pat\/}_n)$:}
matches if any of the subpatterns match.
At least one subpattern must be present.
All subpatterns must bind the same set of pattern variables.

\paragraph*{$({\bf not} ~ {\it pat\/}_1 \ldots {\it pat\/}_n)$:}
matches if none of the subpatterns match.
At least one subpattern must be present.
The subpatterns may not bind any pattern variables.

\paragraph*{$(? ~ {\it predicate\/} ~ {\it pat\/}_1 \ldots {\it pat\/}_n)$:}
In this pattern,
{\it predicate\/} must be an expression evaluating to a single argument
function.
This pattern matches if {\it predicate\/} applied to the corresponding value
is true, and the subpatterns ${\it pat\/}_1 \ldots {\it pat\/}_n$ all match.
The {\it predicate\/} should not have side effects, as
the code generated by the pattern matcher may invoke predicates repeatedly
in any order.
The {\it predicate\/} expression is bound in the same scope as the
match expression, {\it ie.},
free variables in {\it predicate\/} are not bound by pattern variables.
% A {\it predicate\/} may refer to pattern variables bound
% to the left of the predicate pattern.

\paragraph*{$({\bf set!} ~ {\it identifier\/})$:}
matches anything, and binds {\it identifier\/}
to a procedure of one argument that mutates the corresponding field of
the matching value.
This pattern must be nested within a pair, vector, box, or structure
pattern. For example, the expression:
\begin{schemedisplay}
(define x (list 1 (list 2 3)))
(match x [(_ (_ (set! setit)))  (setit 4)])
\end{schemedisplay}
mutates the {\it cadadr\/} of $x$ to \SF{4}, so that $x$ is
\scheme{'(1 (2 4))}.

\paragraph*{$({\bf get!} ~ {\it identifier\/})$:}
matches anything, and binds {\it identifier\/}
to a procedure of zero arguments that accesses the corresponding field of
the matching value.  This pattern is the complement to {\bf set!}.
As with {\bf set!},
this pattern must be nested within a pair, vector, box, or structure
pattern.

\paragraph*{Quasipatterns:}
Quasiquote introduces a quasipattern, in which identifiers are considered
to be symbolic constants.  Like Scheme's quasiquote for data,
{\bf unquote} (,) and {\bf unquote-splicing} (,@) escape back to
normal patterns.

\subsection{Match Failure}

If no clause matches the value, the default action 
is to invoke the procedure {\it match:error\/}
with the value that did not match.  The default definition of
{\it match:error\/} calls {\it error\/} with an appropriate message:
\begin{quote}
\begin{verbatim}
> (match 1 [2 2])

Error: no clause matched 1.
\end{verbatim}
\end{quote}
For most situations, this behavior is adequate, but it can be changed
either by redefining {\it match:error\/}, or
by altering the value of the variable {\it match:error-control\/}.
Valid values for {\it match:error-control\/} are:
\begin{quote}
\begin{tabular}{ll}
{\it match:error-control\/}: & error action:
\\[0.5ex]
\scheme{'error} (default) & call \scheme{(match:error unmatched-value)} \\
\scheme{'match} &
call \scheme{(match:error unmatched-value '(match expression ...))} \\
\scheme{'fail} &
call {\it match:error\/} or die in {\it car\/}, {\it cdr\/}, ...
\\
\scheme{'unspecified} & return unspecified value
\end{tabular}
\end{quote}

Setting {\it match:error-control\/} to \scheme{'match} causes the
entire match expression to be quoted and passed as a second argument
to {\it match:error\/}.  The default definition of {\it match:error\/}
then prints the match expression before calling {\it error\/}; this can
help identify which expression failed to match.  This option causes
the macros to generate somewhat larger code, since each match
expression includes a quoted representation of itself.

Setting {\it match:error-control\/} to \scheme{'fail} permits
the macros to generate faster and more compact code than \scheme{'error} or
\scheme{'match}.  The generated code omits
{\it pair?\/} tests when the consequence is to fail in {\it car\/}
or {\it cdr\/} rather than call {\it match:error\/}.

Finally, if {\it match:error-control\/} is set to
\scheme{'unspecified}, non-matching expressions will either fail in
{\it car\/} or {\it cdr\/}, or return an unspecified value.  This
results in still more compact code, but is unsafe.

\section{Data Definition} \label{sect:struct}

The ability to define new forms of data proves quite useful
in conjunction with pattern matching.  This macro package includes
a slightly altered%
\footnote{
This macro generates additional
numeric selector and mutator names for use by the pattern matcher,
recognizes $\_$ as an unnamed field,
and optionally allows structures to be disjoint from vectors.
Chez Scheme does not provide {\bf define-const-structure}.
}
version of Chez Scheme's {\bf define-structure} macro
for defining new forms of data~\cite{Dybvig87},
and a similar {\bf define-const-structure} macro for defining immutable
data.

The following expression
defines a new kind of data named {\it struct\/}:
\begin{schemedisplay}
(define-structure (struct ${\it arg}_1 \ldots {\it arg}_n$))
\end{schemedisplay}
A {\it struct\/} is a composite data structure with $n$ {\it fields\/}
named ${\it arg}_1$ through ${\it arg}_n$.
The {\bf define-structure\/} macro declares the following procedures
for constructing and manipulating data of type {\it struct\/}:
\begin{quote} \begin{tabular}{ll}
{\it Procedure Name\/}: & {\it Function\/}:
\\[0.5ex]
\SF{make}-{\it struct\/} & constructor requiring $n$ arguments
\\
{\it struct\/}\SF{?} & predicate
\\
{\it struct-arg${}_1$}, \dots, {\it struct-arg${}_n$} & named selectors
\\
\SF{set-}{\it struct-arg${}_1$}\SF{!}, \dots, \SF{set-}{\it struct-arg${}_n$}\SF{!} & named mutators
\\
{\it struct-1}, \dots, {\it struct-$n$} & numeric selectors
\\
\SF{set-}{\it struct-1}\SF{!}, \dots, \SF{set-}{\it struct-$n$}\SF{!}
  & numeric mutators
\end{tabular}\end{quote}
The field name $\_$ (underscore) is special: no named selectors or mutators
are defined for such a field.  Such {\it unnamed\/}
fields can only be accessed
through the numeric selectors or mutators, or through pattern matching.

A second form of definition:
\begin{schemedisplay}
(define-structure (struct ${\it arg}_1 \ldots {\it arg}_n$) ([${\it init}_1$ ${\it exp_1}$] ... [${\it init}_m$ ${\it exp_m}$]))
\end{schemedisplay}
declares $m$ additional fields
${\it init}_1$ through
${\it init}_m$ with initial values ${\it exp}_1$ through ${\it exp}_m$.
The expressions ${\it exp}_1$ through ${\it exp}_m$ are evaluated in
order each time \SF{make}-{\it struct\/} is invoked.

Finally, the macro {\bf define-const-structure}:
\begin{schemedisplay}
(define-const-structure (struct ${\it arg}_1 \ldots {\it arg}_n$))
(define-const-structure (struct ${\it arg}_1 \ldots {\it arg}_n$) ([${\it init}_1$ ${\it exp_1}$] ... [${\it init}_m$ ${\it exp_m}$]))
\end{schemedisplay}
is similar to {\bf define-structure}, but allows immutable fields.
If a field name ${\it arg}_i$ is simply a variable, no (named or numeric)
mutator is declared for that field.  If a field name has the form
\mbox{\scheme|(! x)|} where $x$ is a variable, then that field is
mutable.  Hence \mbox{\scheme|(define-structure (Foo a b))|}
abbreviates \mbox{\scheme|(define-const-structure (Foo (! a) (! b)))|}.


By default, structures are implemented as vectors whose first component
is the name of the structure as a symbol.  Thus a {\it Foo\/}
structure of one field will match both the patterns
\mbox{$(\$ ~ {\it Foo\/} ~ x)$} %$
and \scheme{#('Foo x)}.  Setting the variable
{\it match:structure-control\/} to \SF{'disjoint} causes
subsequent {\bf define-structure} definitions to create structures that
are disjoint from all other data, including vectors.  In this case,
{\it Foo\/} structures will no longer match the pattern
\scheme{#('Foo x)}.%
\footnote{
Disjoint structures are implemented as vectors whose first
component is a unique symbol (an uninterned symbol for Chez Scheme).
The procedure {\it vector?\/}
is modified to return false for such vectors (hence
the \SF{'disjoint} option cannot be used with Chez Scheme's
\SF{optimize-level} set higher than \SF{1}).
For completeness the other vector operations ({\it vector-ref},
{\it vector-set!}, etc.) should also be modified to reject structures,
but we don't bother.
}

\section{Code Generation}

Pattern matching macros are compiled into {\bf if}-expressions
that decompose the value being matched with standard
Scheme procedures, and test the components with standard predicates.
Rebinding or lexically shadowing the names of any of these procedures
will change the
semantics of the {\bf match} macros.  The names that should not be
rebound or shadowed are:
\begin{quote}
\it
\begin{tabular}{l}
null? pair? number? string? symbol? boolean? char? procedure? vector?
box? list?
\\
equal?
\\
car cdr cadr cdddr ...
\\
vector-length vector-ref
\\
unbox
\\
reverse length call/cc
\end{tabular}
\end{quote}
Additionally, the code generated to match a structure pattern like
$(\$ ~ {\it Foo\/}~ {\it pat}_1 \ldots {\it pat}_n)$ %$
refers to the names {\it Foo?\/}, {\it Foo-1\/} through {\it Foo-n\/},
and {\it set-Foo-1!\/} through {\it set-Foo-n!\/}.
These names also should not be shadowed.

\section{Examples}

This section illustrates the convenience of pattern matching with
some examples.
The following function recognizes s-expressions that represent the standard
Y operator:
\begin{schemedisplay}
(define Y?
  (match-lambda
    [('lambda (f1)
       ('lambda (y1)
         ((('lambda (x1) (f2 ('lambda (z1) ((x2 x3) z2))))
           ('lambda (a1) (f3 ('lambda (b1) ((a2 a3) b2)))))
          y2)))
     (and (symbol? f1) (symbol? y1) (symbol? x1) (symbol? z1) (symbol? a1) (symbol? b1)
          (eq? f1 f2) (eq? f1 f3) (eq? y1 y2)
          (eq? x1 x2) (eq? x1 x3) (eq? z1 z2)
          (eq? a1 a2) (eq? a1 a3) (eq? b1 b2))]
    [_ #f]))
\end{schemedisplay}
Writing an equivalent piece of code in raw Scheme is tedious.

The following code defines abstract syntax for a subset of Scheme,
a parser into this abstract syntax, and an unparser.
\begin{schemedisplay}
(define-structure (Lam args body))
(define-structure (Var s))
(define-structure (Const n))
(define-structure (App fun args))

(define parse
  (match-lambda
    [(and s (? symbol?) (not 'lambda))
     (make-Var s)]
    [(? number? n)
     (make-Const n)]
    [('lambda (and args ((? symbol?) ...) (not (? repeats?))) body)
     (make-Lam args (parse body))]
    [(f args ...)
     (make-App
       (parse f)
       (map parse args))]
    [x (error x "invalid expression")]))

(define repeats?
  (lambda (l)
    (and (not (null? l))
         (or (memq (car l) (cdr l)) (repeats? (cdr l))))))

(define unparse
  (match-lambda
    [($\$$ Var s) s]
    [($\$$ Const n) n]
    [($\$$ Lam args body) `(lambda ,args ,(unparse body))]
    [($\$$ App f args) `(,(unparse f) ,@(map unparse args))]))
\end{schemedisplay}
With pattern matching, it is easy to ensure
that the parser rejects {\em all\/}
incorrectly formed inputs with an error message.

With {\bf match-define}, it is easy to define several procedures
that share a hidden variable.  The following code defines three
procedures, {\it inc\/}, {\it value\/}, and {\it reset\/},
that manipulate a hidden counter variable:
\begin{schemedisplay}
(match-define (inc value reset)
  (let ([val 0])
    (list
      (lambda () (set! val (+ 1 val)))
      (lambda () val)
      (lambda () (set! val 0)))))
\end{schemedisplay}
Although this example is not recursive,
the bodies could recursively refer to each other.

The following code is taken from the macro package itself.  The
procedure {\it match:validate-pattern\/} checks the syntax of
match patterns, and converts quasipatterns into ordinary patterns.
\begin{schemedisplay}
(define match:validate-pattern
  (lambda (pattern)
    (letrec
      ([simple?
        (lambda (x)
          (or (string? x) (boolean? x) (char? x) (number? x) (null? x)))]
       [ordinary
        (match-lambda
          [(? simple? p) p]
          ['_ '_]
          [(? match:pattern-var? p) p]
          [('quasiquote p) (quasi p)]
          [(and p ('quote _)) p]
          [('? pred ps ...) `(? ,pred ,@(map ordinary ps))]
          [('and ps ..1) `(and ,@(map ordinary ps))]
          [('or ps ..1) `(or ,@(map ordinary ps))]
          [('not ps ..1) `(not ,@(map ordinary ps))]
          [('$\$$ (? match:pattern-var? r) ps ...) `($\$$ ,r ,@(map ordinary ps))]
          [(and p ('set! (? match:pattern-var?))) p]
          [(and p ('get! (? match:pattern-var?))) p]
          [(p (? match:dot-dot-k? ddk)) `(,(ordinary p) ,ddk)]
          [(x . y) (cons (ordinary x) (ordinary y))]
          [(? vector? p) (apply vector (map ordinary (vector->list p)))]
          [(? box? p) (box (ordinary (unbox p)))]
          [p (match:syntax-err pattern "syntax error in pattern")])]
       [quasi
        (match-lambda
          [(? simple? p) p]
          [(? symbol? p) `(quote ,p)]
          [('unquote p) (ordinary p)]
          [(('unquote-splicing p) . ()) (ordinary p)]
          [(('unquote-splicing p) . y) (append (ordlist p) (quasi y))]
          [(p (? match:dot-dot-k? ddk)) `(,(quasi p) ,ddk)]
          [(x . y) (cons (quasi x) (quasi y))]
          [(? vector? p) (apply vector (map quasi (vector->list p)))]
          [(? box? p) (box (quasi (unbox p)))]
          [p (match:syntax-err pattern "syntax error in pattern")])]
       [ordlist
        (match-lambda
          [() ()]
          [(x . y) (cons (ordinary x) (ordlist y))]
          [p (match:syntax-err pattern
               "invalid use of unquote-splicing in pattern")])])
    (ordinary pattern))))
\end{schemedisplay}

\section{Known Bugs}

A structure pattern like \mbox{\scheme|($\$$ foo a b c)|} is not checked
to ensure that there are enough fields present for a {\it foo\/} object.
This should be fixed in the future.

\section*{Acknowledgments}

Several members of the Rice programming languages community exercised
the implementation and suggested enhancements.  We thank Matthias
Felleisen, Cormac Flanagan, Amit Patel, and Amr Sabry for their
contributions.

\begin{thebibliography}{1}

\bibitem{Dybvig87}
{\sc Dybvig, R.~K.}
\newblock {\em The {Scheme} Programming Language}.
\newblock Prentice-Hall, Englewood Cliffs, New Jersey, 1987.

\end{thebibliography}

\end{document}
