summaryrefslogtreecommitdiffstats
path: root/txr.1
diff options
context:
space:
mode:
Diffstat (limited to 'txr.1')
-rw-r--r--txr.1185
1 files changed, 149 insertions, 36 deletions
diff --git a/txr.1 b/txr.1
index 85711d4c..1b9a672a 100644
--- a/txr.1
+++ b/txr.1
@@ -40828,44 +40828,105 @@ if there are no forms.
.desc
The
.code lambda-match
-is closely based on
+is conceptually similar to
.codn match-case .
The arguments of
.code lambda-match
are zero or more clauses similar to those of
-.codn match-case .
+.codn match-case ,
+each consisting of a compound expression headed by a
+.meta pattern
+followed by zero or more
+.metn form -s.
-An invocation of
-.code lambda-match
-evaluates to an anonymous function which can take any number of arguments.
+The macro generates a
+.code lambda
+expression which evaluates to an anonymous function
+in the usual way.
-Whenever the function is called, its arguments are treated as a list object
-which is subject to pattern matching via the clauses. The
-.mets pattern
-from every clause is tested against the argument list. If it matches
-each associated
+When the anonymous function is called, each clause's
+.meta pattern
+is matched against the the function's actual arguments. When a
+match occurs, each
.meta form
-is evaluated in the scope of the variables emanating from that
+associated with the
.meta pattern
-and the value of the last
+is evaluated, and the value of the last
.meta form
-is returned. If no
+becomes the return value of the function.
+If none of the clauses match, then
+.code nil
+is returned.
+
+Whenever
.meta pattern
-matches, the function returns
-.codn nil .
+is a list-like pattern, it is not matched against a list object, as is the
+usual case with a list-like pattern, but against the actual arguments.
+For instance, the pattern
+.code "(@a @b @c)"
+expects that the function was called with exactly three arguments. If
+that is the case, the patterns are then matched to the arguments. The pattern
+.code @a
+takes the first argument, binding it to variable
+.code a
+and so forth.
-Note: the
-.code lambda-macro
-can be understood in terms of the following equivalence:
+If
+.meta pattern
+is a dotted list-like pattern, then the dot position is matched
+against the remaining arguments. For instance, the pattern
+.code "(@a @b . @c)"
+requires at least two arguments. The first two are bound to
+.code a
+and
+.codn b ,
+respectively. The list of remaining arguments, if any, is bound to
+.codn c ,
+which will be
+.code nil
+if there are no remaining arguments.
+
+Any non-list-like
+.meta pattern
+.code P
+is analyzed as an equivalent list-like dotted pattern due to
+.code P
+syntax being equivalent to
+.code "(. P)"
+syntax. Such a pattern matches the list of all arguments.
+Thus, the following are all equivalent:
.verb
- (lambda-match ...) <--> (lambda (. rest) (match-case rest ...))
+ (lambda-match (@a a))
+ (lambda-match ((. @a) a))
+ (lambda a a)
+ (lambda (. a) a)
.brev
-Here, the
-.code rest
-variable is to be understood as a generated, unique symbol.
+The characteristics of the resulting anonymous function are determined as
+follows.
+
+If at least one
+.meta pattern
+specified in a
+.meta lambda-match
+is a dotted pattern, the function is variadic.
+
+The arity of the resulting anonymous function is determined as follows, from
+the lengths of the patterns. The length of a pattern is the number of
+elements, not including the dotted element.
+
+The length of the longest pattern determines the number of fixed
+arguments. Unless the function is variadic, it may not be called with more
+arguments than can be matched by the longest pattern.
+
+The length of the shortest pattern determines the number of required arguments.
+The function may not be called with fewer arguments than can be matched
+by the shortest pattern.
+
+If these two lengths are unequal, then the function has a number of optional
+arguments, equal to the difference.
Note: an anonymous function which takes one argument and matches that
object against clauses using
@@ -40875,6 +40936,34 @@ can be obtained with the
operator, using the pattern:
.codn "(do match @1 ...)" .
+.TP* Examples:
+
+.verb
+ (let ((f (lambda-match
+ (() (list 0 :args))
+ ((@a) (list 1 :arg a))
+ ((@a @b) (list 2 :args a b))
+ ((@a @b . @c) (list* '> 2 :args a b c)))))
+ (list [f] [f 1] [f 1 2] [f 1 2 3]))
+ -->
+ ((0 :args) (1 :arg 1) (2 :args 1 2) (> 2 :args 1 2 3))
+
+ [(lambda-match
+ ((0 1) :zero-one)
+ ((1 0) :one-zero)
+ ((@x @y) :no-match)) 1 0] --> :one-zero
+
+ [(lambda-match
+ ((0 1) :zero-one)
+ ((1 0) :one-zero)
+ ((@x @y) :no-match)) 1 1] --> :no-match
+
+ [(lambda-match
+ ((0 1) :zero-one)
+ ((1 0) :one-zero)
+ ((@x @y) :no-match)) 1 2 3] --> ;; error
+.brev
+
.coNP Macro @ defun-match
.synb
.mets (defun-match < name >> {( pattern << form *)}*)
@@ -40885,21 +40974,9 @@ The
macro can be used to define a top-level function in the style of
.codn lambda-match .
-It works according to the following equivalence:
-
-.verb
- (defun-match name ...) <--> (defun name (. rest) (match-case rest ...))
-.brev
-
-Here, the
-.code rest
-variable is to be understood as a generated, unique symbol.
-
-Because
-.code defun-match
-is defined in terms of
+It produces a form which has all of the properties of
.codn defun ,
-it has all of the properties, such as a block of the same
+such as a block of the same
.meta name
being established around the implicit
.code match-case
@@ -40907,6 +40984,42 @@ so that
.code return-from
is possible.
+The
+.mono
+.meti >> ( pattern << form *)
+.onom
+clauses of
+.code defun-match
+have exactly the same syntax and semantics as those of
+.codn lambda-match .
+
+.TP* Examples:
+
+.verb
+ ;; Fibonacci
+ (defun-match fib
+ ((0) 1)
+ ((1) 1)
+ ((@x) (+ (fib (pred x)) (fib (ppred x)))))
+
+ (fib 0) -> 1
+ (fib 1) -> 1
+ (fib 2) -> 2
+ (fib 3) -> 3
+ (fib 4) -> 5
+ (fib 5) -> 8
+
+ ;; Ackermann
+ (defun-match ack
+ ((0 @n) (+ n 1))
+ ((@m 0) (ack (- m 1) 1))
+ ((@m @n) (ack (- m 1) (ack m (- n 1)))))
+
+ (ack 3 7) -> 1021
+ (ack 1 1) -> 3
+ (ack 2 2) -> 7
+.brev
+
.SS* Quasiquote Operator Syntax
.coNP Macro @ qquote
.synb