Up: simple-match [Index]
The following bindings are exported by the library (vicare
languae-extensions simple-match). The auxiliary syntaxes are the
bindings exported by the library (vicare), which are reexported
by this library.
Match the symbolic expression ?expr against the ?clause arguments. Each clause must have one of the formats:
(?pattern ?body ...) (?pattern (=> ?next) ?body ...) (else ?body0 ?body ...)
?expr is evaluated once and the result is matched against each
?pattern in turn; the first to succeed causes the corresponding
?body forms to be evaluated as in begin, and the remaining
patterns are ignored. However, if the ?next identifier is
labeled, it may be used as a continuation to continue matching, allowing
for additional runtime tests on the pattern.
A clause with no body (?pattern), when matching the input
expression, causes the evaluation of (values) (which returns zero
values).
The syntax for the patterns is:
The literal underscore is the wildcard: it matches anything, it does not reference any variable.
(match "ciao" (_ #t) (else #f)) ⇒ #t (match '(1 2 3) (_ #t) (else #f)) ⇒ #t (match '(1 2 3) ((_ _ _) #t) (else #f)) ⇒ #t (match '(1 2 3) ((_ 2 _) #t) (else #f)) ⇒ #t (match '(1 2 3) ((_ 0 _) #t) (else #f)) ⇒ #f
Matches if the input expression equals ?datum. The pattern ?datum can be a boolean, character, fixnum, bignum, ratnum, flonum, cflonum, compnum, string or bytevector; such data is compared to the input expression using type–specific predicates and unsafe accessors.
(match 1 (1 #t) (else #f)) ⇒ #t
Variable reference: it matches the value bound to ?variable using
equal?.
(let ((X 1))
(match 1
(X #t)
(else #f)))
⇒ #t
(let ((X 1))
(match 1
(X X)
(else #f)))
⇒ 1
Bind the value of the input expression to ?variable, which must be
an identifier; the variable is immediately available to be referenced in
the following subpatterns. The empty let pattern is a syntax
error; the let pattern with multiple subpatterns is a syntax
error, with the exception of the variable with ellipsis.
(match 1
((let X) X)
(else #f))
⇒ 1
(match 1
((let X) #\A)
(else #f))
⇒ #\A
(match '(1)
((let X) X)
(else #f))
⇒ (1)
(match '(1)
(((let X)) X)
(else #f))
⇒ 1
(match '(1 2 3)
(((let X) (let Y) (let Z))
(vector X Y Z))
(else #f))
⇒ #(1 2 3)
(match '(1 2)
(((let X) (let Y) (let Z))
(vector X Y Z))
(else #f))
⇒ #f
(match '(1 (2 3))
(((let X) (let X) (let X))
X)
(else #f))
⇒ 3
(match 123
((and (let X) (eval (positive? X)))
X)
(else #f))
⇒ 123
(match '(1 2 3)
(((and (apply number?)
(let N1))
. (and (apply (lambda (obj)
(for-all number? obj)))
(let N)))
(vector N1 N))
(else #f))
⇒ #(1 (2 3))
This pattern can appear only as last subpattern of a list or vector pattern. Bind the rest of the input expression to ?variable, which must be an identifier, as a list; the variable is immediately available to be referenced in the following subpatterns.
(match '(1 2 3 4 5)
(((let X) (let Y) (let Z ...))
(vector X Y Z))
(else #f))
⇒ #(1 2 (3 4 5))
(match '(1 2)
(((let X) (let Y) (let Z ...))
(vector X Y Z))
(else #f))
⇒ #(1 2 ())
(match '(1 2 . 3)
(((let X) (let Y) (let Z ...))
(vector X Y Z))
(else #f))
⇒ #f
(match '(1 2 3 4 . 5)
(((let X) (let Y) (let Z ...))
(vector X Y Z))
(else #f))
⇒ #f
(match '(1 2 3)
((let id ...) #\A)
(else #\B))
error→ &syntax
(match '(1 2 3 4)
(((and (apply number?) (let N1))
(and (apply number?) (let N))
...)
(vector N1 N))
(else #f))
⇒ (#(1 2) #(1 3) #(1 4))
A quoted datum; it matches if it is equal to the input expression
according to equal?. As special case: if ?datum is a
symbol, it is compared to the input expression with eq?.
(match '(1 2 3)
('(1 2 3) #t)
(else #f))
⇒ #t
(match '(1 X 3)
('(1 X 3) #t)
(else #f))
⇒ #t
(match '(1 X 3)
((1 'X 3) #t)
(else #f))
⇒ #t
A quasiquoted datum; it matches if it the result of the quasiquotation
is equal to the input expression according to equal?.
(let ((X 2))
(match '(2 2)
(`(1 ,X) #\A)
(`(2 ,X) #\B)
(`(3 ,X) #\C)
(else #f)))
⇒ #\B
A syntax-case pattern with optional literal identifiers; the
matching code is built as follows:
(syntax-case input-expr (?literal …) (?pattern #;success) (_ #;failure))
the body of the clause can access pattern variables in the same way they
are accessed from the output expression of a syntax-case use.
(match '(1 2 3)
((syntax (1 2 3))
#t)
(else #f))
⇒ #t
;;match an identifier
(let ((ciao #f))
(match #'ciao
((syntax ciao (ciao))
#t)
(else #f)))
⇒ #t
;;match pattern variables
(let ((ciao #f))
(match '(1 2 3)
((syntax (a b c))
(syntax->datum #'b))
(else #f)))
⇒ 2
Null or proper list of N elements.
(match '() (() #t) (else #f)) ⇒ #t (match '(1 2 3) ((1 2 3) #t) (else #f)) ⇒ #t
Improper list of N or more elements.
(match '(1 . 2) ((1 . 2) #t) (else #f)) ⇒ #t (match '(1 2 3 . 4) ((1 2 3 . 4) #t) (else #f)) ⇒ #t
List of N or more elements with terminating ellipsis; each element of remainder must match ?patternN+1. The body is evaluated once for every element matched by the pattern before the ellipsis and the results are returned in a list.
(match '(1)
((1 ...) #t)
(else #f))
⇒ (#t)
(match '(1 1)
((1 ...) #t)
(else #f))
⇒ (#t #t)
(match '(1 1 1)
((1 ...) #t)
(else #f))
⇒ (#t #t #t)
(match '(1 2)
((0 1 ...) #t)
(else #f))
⇒ #f
(match '(1 2 3)
(((let X) ...)
(+ 10 X))
(else #f))
⇒ (11 12 13)
(match '(1 2 3)
(((let X) (let Y) ...)
(vector X Y))
(else #f))
⇒ (#(1 2) #(1 3))
(match '((1 2 3) (4 5 6) (7 8 9))
((((let X) (let Y) (let Z)) ...)
(vector X Y Z))
(else #f))
⇒ (#(1 2 3) #(4 5 6) #(7 8 9))
(match '((1 2 3)
(4 5 6)
(7 8 9))
((((let X) (let Y) ...) ...)
(vector X Y))
(else #f))
⇒ ((#(1 2) #(1 3))
(#(4 5) #(4 6))
(#(7 8) #(7 9)))
Vector of N elements.
(match '#(1 2 3) (#(1 2 3) #t) (else #f)) ⇒ #t
Vector of N or more elements with terminating ellipsis; each element of remainder must match ?patternN+1. The body is evaluated once for every element matched by the pattern before the ellipsis and the results are returned in a list.
(match '#(1 1 1) (#(1 ...) #t) (else #f)) ⇒ (#t #t #t)
Matches if each ?pattern matches the input expression. The empty
and succeeds.
(match 123 ((and (apply fixnum?) (apply positive?)) #t) (else #f)) ⇒ #t (match 123 ((and (apply fixnum?) (let X)) X) (else #f)) ⇒ 123 (match 123 ((and (let X) X) X) (else #f)) ⇒ 123
Matches if at least one ?pattern matches the input expression.
The empty or fails.
(match 1 ((or 1 2) #t) (else #f)) ⇒ #t (match 1 ((or (apply fixnum?) (apply bignum?)) #t) (else #f)) ⇒ #t
Matches if the subpattern ?pattern does not match the
input expression. The empty not fails. The empty not pattern is
a syntax error; the not pattern with multiple subpatterns is a
syntax error.
(match 9 ((not 1) #t) (else #f)) ⇒ #t (match "ciao" ((not (apply fixnum?)) #t) (else #f)) ⇒ #t
Each ?pred subpattern must be an expression; every time this
pattern is matched against an input expression: ?pred is
evaluated; the value returned by ?pred must be a predicate
function. This pattern matches if all the predicate functions return
true when applied to the input expression; the empty apply
pattern is a syntax error.
(match 1
((apply fixnum? positive?)
#t)
(else #f))
⇒ #t
(match 1
((apply (lambda (x)
(and (fixnum? x)
(positive? x))))
#t)
(else #f))
⇒ #t
The subpattern ?expr must be expression; every time this pattern
is matched against an input expression: ?expr is evaluated. This
pattern matches if the result of ?expr is true. The empty
eval pattern is a syntax error; the eval pattern with
multiple subpatterns is a syntax error.
(match 1 ((eval #t) #t) (else #f)) ⇒ #t (match 1 ((eval #f) #\A) (else #f)) ⇒ #t (match #t ((and (let X) (eval X)) #t) (else #f)) ⇒ #t (match #f ((and (let X) (eval X)) #t) (else #f)) ⇒ #f (match '(1 2) (((let X) (eval X)) ;ignores 2, but consumes it X) (else #f)) ⇒ 1 (match '(1 2 3) (((let X) (eval X) (let Y)) ;ignores 2, but consumes it (vector X Y)) (else #f)) ⇒ #(1 3)
When the escape identifier is present, it is bound to a thunk to be evaluated to jump to matching the next pattern or to the “no match” error.
(match '(1 2 3) ((1 2 3) (=> escape) #t) (else #f)) ⇒ #t (match '(1 2 0) ((1 2 3) (=> escape) #t) (else #f)) ⇒ #f (match '(1 2 3) ((1 2 3) (=> escape) (escape)) (else #f)) ⇒ #f (match '(1 2 3) ((1 2 3) (=> escape) (escape)) ((1 2 3) #t) (else #f)) ⇒ #t (match '(1 2 3) ((1 2 3) (=> escape) (escape))) error→ &error
Up: simple-match [Index]