diff options
Diffstat (limited to 'doc/lispref/control.texi')
| -rw-r--r-- | doc/lispref/control.texi | 120 |
1 files changed, 119 insertions, 1 deletions
diff --git a/doc/lispref/control.texi b/doc/lispref/control.texi index 25a7655b7b8..a6d3081c6ba 100644 --- a/doc/lispref/control.texi +++ b/doc/lispref/control.texi @@ -285,6 +285,110 @@ For example: @end group @end example +@menu +* Pattern matching case statement:: +@end menu + +@node Pattern matching case statement +@subsection Pattern matching case statement +@cindex pcase +@cindex pattern matching + +To compare a particular value against various possible cases, the macro +@code{pcase} can come handy. It takes the following form: + +@example +(pcase @var{exp} @var{branch}1 @var{branch}2 @var{branch}3 @dots{}) +@end example + +where each @var{branch} takes the form @code{(@var{upattern} +@var{body-forms}@dots{})}. + +It will first evaluate @var{exp} and then compare the value against each +@var{upattern} to see which @var{branch} to use, after which it will run the +corresponding @var{body-forms}. A common use case is to distinguish +between a few different constant values: + +@example +(pcase (get-return-code x) + (`success (message "Done!")) + (`would-block (message "Sorry, can't do it now")) + (`read-only (message "The shmliblick is read-only")) + (`access-denied (message "You do not have the needed rights")) + (code (message "Unknown return code %S" code))) +@end example + +In the last clause, @code{code} is a variable that gets bound to the value that +was returned by @code{(get-return-code x)}. + +To give a more complex example, a simple interpreter for a little +expression language could look like: + +@example +(defun evaluate (exp env) + (pcase exp + (`(add ,x ,y) (+ (evaluate x env) (evaluate y env))) + (`(call ,fun ,arg) (funcall (evaluate fun) (evaluate arg env))) + (`(fn ,arg ,body) (lambda (val) + (evaluate body (cons (cons arg val) env)))) + ((pred numberp) exp) + ((pred symbolp) (cdr (assq exp env))) + (_ (error "Unknown expression %S" exp)))) +@end example + +Where @code{`(add ,x ,y)} is a pattern that checks that @code{exp} is a three +element list starting with the symbol @code{add}, then extracts the second and +third elements and binds them to the variables @code{x} and @code{y}. +@code{(pred numberp)} is a pattern that simply checks that @code{exp} +is a number, and @code{_} is the catch-all pattern that matches anything. + +There are two kinds of patterns involved in @code{pcase}, called +@emph{U-patterns} and @emph{Q-patterns}. The @var{upattern} mentioned above +are U-patterns and can take the following forms: + +@table @code +@item `@var{qpattern} +This is one of the most common form of patterns. The intention is to mimic the +backquote macro: this pattern matches those values that could have been built +by such a backquote expression. Since we're pattern matching rather than +building a value, the unquote does not indicate where to plug an expression, +but instead it lets one specify a U-pattern that should match the value at +that location. + +More specifically, a Q-pattern can take the following forms: +@table @code +@item (@var{qpattern1} . @var{qpattern2}) +This pattern matches any cons cell whose @code{car} matches @var{QPATTERN1} and +whose @code{cdr} matches @var{PATTERN2}. +@item @var{atom} +This pattern matches any atom @code{equal} to @var{atom}. +@item ,@var{upattern} +This pattern matches any object that matches the @var{upattern}. +@end table + +@item @var{symbol} +A mere symbol in a U-pattern matches anything, and additionally let-binds this +symbol to the value that it matched, so that you can later refer to it, either +in the @var{body-forms} or also later in the pattern. +@item _ +This so-called @emph{don't care} pattern matches anything, like the previous +one, but unless symbol patterns it does not bind any variable. +@item (pred @var{pred}) +This pattern matches if the function @var{pred} returns non-@code{nil} when +called with the object being matched. +@item (or @var{upattern1} @var{upattern2}@dots{}) +This pattern matches as soon as one of the argument patterns succeeds. +All argument patterns should let-bind the same variables. +@item (and @var{upattern1} @var{upattern2}@dots{}) +This pattern matches only if all the argument patterns succeed. +@item (guard @var{exp}) +This pattern ignores the object being examined and simply succeeds if @var{exp} +evaluates to non-@code{nil} and fails otherwise. It is typically used inside +an @code{and} pattern. For example, @code{(and x (guard (< x 10)))} +is a pattern which matches any number smaller than 10 and let-binds it to +the variable @code{x}. +@end table + @node Combining Conditions @section Constructs for Combining Conditions @@ -578,7 +682,8 @@ that throw back to the editor command loop (@pxref{Recursive Editing}). @b{Common Lisp note:} Most other versions of Lisp, including Common Lisp, have several ways of transferring control nonsequentially: @code{return}, @code{return-from}, and @code{go}, for example. Emacs Lisp has only -@code{throw}. +@code{throw}. The @file{cl-lib} library provides versions of some of +these. @xref{Blocks and Exits,,,cl,Common Lisp Extensions}. @end quotation @defspec catch tag body@dots{} @@ -823,6 +928,19 @@ The function @code{signal} never returns. @end example @end defun +@cindex user errors, signaling +@defun user-error format-string &rest args +This function behaves exactly like @code{error}, except that it uses +the error symbol @code{user-error} rather than @code{error}. As the +name suggests, this is intended to report errors on the part of the +user, rather than errors in the code itself. For example, +if you try to use the command @code{Info-history-back} (@kbd{l}) to +move back beyond the start of your Info browsing history, Emacs +signals a @code{user-error}. Such errors do not cause entry to the +debugger, even when @code{debug-on-error} is non-@code{nil}. +@xref{Error Debugging}. +@end defun + @cindex CL note---no continuable errors @quotation @b{Common Lisp note:} Emacs Lisp has nothing like the Common Lisp |
