1.2.0 permalink Arrow_down_16x16
  • (match value & clauses)
Given a value and a list of template-expr clauses, evaluate the first
expr whose template matches the value. There are four kinds of templates:
1) Lists of the form (tag x1 x2 ...) match instances of types
whose constructor has the same form as the list.
2) Quoted lists of the form '(x1 x2 ...) match lists of the same
length.
3) Vectors of the form [x1 x2 ...] match vectors of the same length.
4) Maps of the form {:key1 x1 :key2 x2 ...} match maps that have
the same keys as the template, but which can have additional keys
that are not part of the template.
The values x1, x2, ... can be symbols or non-symbol values. Non-symbols
must be equal to the corresponding values in the object to be matched.
Symbols will be bound to the corresponding value in the object in the
evaluation of expr. If the same symbol occurs more than once in a,
template the corresponding elements of the object must be equal
for the template to match.

0 Examples top

Log in to add / edit an example.

See Also top

Log in to add a see also.

Plus_12x12 Minus_12x12 Source clojure/contrib/types.clj:241 top

(defmacro match
  "Given a value and a list of template-expr clauses, evaluate the first
   expr whose template matches the value. There are four kinds of templates:
   1) Lists of the form (tag x1 x2 ...) match instances of types
      whose constructor has the same form as the list.
   2) Quoted lists of the form '(x1 x2 ...) match lists of the same
      length.
   3) Vectors of the form [x1 x2 ...] match vectors of the same length.
   4) Maps of the form {:key1 x1 :key2 x2 ...} match maps that have
      the same keys as the template, but which can have additional keys
      that are not part of the template.
   The values x1, x2, ... can be symbols or non-symbol values. Non-symbols
   must be equal to the corresponding values in the object to be matched.
   Symbols will be bound to the corresponding value in the object in the
   evaluation of expr. If the same symbol occurs more than once in a,
   template the corresponding elements of the object must be equal
   for the template to match."
  [value & clauses]
   (when (odd? (count clauses))
     (throw (Exception. "Odd number of elements in match expression")))
  (let [vsymbol (gensym)
	cfsymbol (gensym)
	terms (mapcat (fn [[template expr]]
			(if (= template :else)
			  [template expr]
			  (let [[tests bindings]
				(tests-and-bindings template vsymbol cfsymbol)]
			    [tests
			     (if (empty? bindings)
			       expr
			       `(let ~bindings ~expr))])))
		      (partition 2 clauses))]
    `(let [~vsymbol ~value
	   ~cfsymbol (constructor-form ~vsymbol)]
       (cond ~@terms))))
Vars in clojure.contrib.types/match: count defmacro let odd? when apply concat cond list seq vector
Used in 0 other vars

Comments top

2 comment(s) for match.

This function isn't particularly useful for matching the length of lists or vectors. For example:

(clojure.contrib.types/match [] [a] (prn a) _ (prn "fail"))

Fires an IndexOutOfBoundsException, which defeats the point of using pattern matching in the first place. If you include a '[]' clause before the single element clause - it matches that one erroneously so it doesn't match the correct pattern. For example:

(clojure.contrib.types/match ["hi"] [] (prn "nothing") [a] (prn a) _ (prn "fail"))

prints "nothing" when it should print "hi"

Ah, pattern matching a la MLs!

Something this important/useful deserves at least ONE example!

Log in to add a comment.