[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] /srv/bzr/emacs/emacs-24 r111014: * doc/lispref/control.tex
From: |
Stefan Monnier |
Subject: |
[Emacs-diffs] /srv/bzr/emacs/emacs-24 r111014: * doc/lispref/control.texi (Pattern maching case statement): New node. |
Date: |
Sun, 09 Dec 2012 10:36:46 -0500 |
User-agent: |
Bazaar (2.5.0) |
------------------------------------------------------------
revno: 111014
committer: Stefan Monnier <address@hidden>
branch nick: emacs-24
timestamp: Sun 2012-12-09 10:36:46 -0500
message:
* doc/lispref/control.texi (Pattern maching case statement): New node.
modified:
doc/lispref/ChangeLog
doc/lispref/control.texi
=== modified file 'doc/lispref/ChangeLog'
--- a/doc/lispref/ChangeLog 2012-12-06 18:26:11 +0000
+++ b/doc/lispref/ChangeLog 2012-12-09 15:36:46 +0000
@@ -1,3 +1,7 @@
+2012-12-09 Stefan Monnier <address@hidden>
+
+ * control.texi (Pattern maching case statement): New node.
+
2012-12-06 Stefan Monnier <address@hidden>
* customize.texi (Variable Definitions): Mention the default :group
=== modified file 'doc/lispref/control.texi'
--- a/doc/lispref/control.texi 2012-11-11 00:37:40 +0000
+++ b/doc/lispref/control.texi 2012-12-09 15:36:46 +0000
@@ -285,6 +285,110 @@
@end group
@end example
address@hidden
+* Pattern maching case statement::
address@hidden menu
+
address@hidden Pattern maching case statement
address@hidden Pattern maching case statement
address@hidden pcase
address@hidden pattern matching
+
+To compare a particular value against various possible cases, the macro
address@hidden can come handy. It takes the following form:
+
address@hidden
+(pcase @var{exp} @var{branch}1 @var{branch}2 @var{branch}3 @dots{})
address@hidden example
+
+where each @var{branch} takes the form @code{(@var{upattern}
address@hidden@dots{})}.
+
+It will first evaluate @var{exp} and then compare the value against each
address@hidden 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:
+
address@hidden
+(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)))
address@hidden 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:
+
address@hidden
+(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))))
address@hidden 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}.
address@hidden(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
address@hidden and @emph{Q-patterns}. The @var{upattern} mentioned above
+are U-patterns and can take the following forms:
+
address@hidden @code
address@hidden address@hidden
+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:
address@hidden @code
address@hidden (@var{qpattern1} . @var{qpattern2})
+This pattern matches any cons cell whose @code{car} matches @var{QPATTERN1} and
+whose @code{cdr} matches @var{PATTERN2}.
address@hidden @var{atom}
+This pattern matches any atom @code{equal} to @var{atom}.
address@hidden ,@var{upattern}
+This pattern matches any object that matches the @var{upattern}.
address@hidden table
+
address@hidden @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.
address@hidden _
+This so-called @emph{don't care} pattern matches anything, like the previous
+one, but unless symbol patterns it does not bind any variable.
address@hidden (pred @var{pred})
+This pattern matches if the function @var{pred} returns address@hidden when
+called with the object being matched.
address@hidden (or @var{upattern1} @address@hidden)
+This pattern matches as soon as one of the argument patterns succeeds.
+All argument patterns should let-bind the same variables.
address@hidden (and @var{upattern1} @address@hidden)
+This pattern matches only if all the argument patterns succeed.
address@hidden (guard @var{exp})
+This pattern ignores the object being examined and simply succeeds if @var{exp}
+evaluates to address@hidden 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}.
address@hidden table
+
@node Combining Conditions
@section Constructs for Combining Conditions
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] /srv/bzr/emacs/emacs-24 r111014: * doc/lispref/control.texi (Pattern maching case statement): New node.,
Stefan Monnier <=