# Basic usage

Alan Thompson edited this page Jun 23, 2015 · 15 revisions

## Matching Literals

The simplest thing you can do is match literals:

```(let [x true
y true
z true]
(match [x y z]
[_ false true] 1
[false true _ ] 2
[_ _ false] 3
[_ _ true] 4
:else 5))
;=> 4```

Note that the only clause that matches the values of the local variables is the fourth one. "Wildcards", the `_`, in the pattern signifies values that are present that you don't actually care about.

When matching on a single variable you may omit the brackets:

```(let [x true]
(match x
true 1
false 2
:else 5))
;=> 1```

## Binding

You may match values and give them names for later use:

```(let [x 1 y 2]
(match [x y]
[1 b] b
[a 2] a
:else nil))
;=> 2```

This may seem pointless here but in complex patterns this feature becomes more useful (consider red black tree balancing for example).

## Sequential types

You may match sequences by using the sequence matching facility:

```(let [x [1 2 nil nil nil]]
(match [x]
[([1] :seq)] :a0
[([1 2] :seq)] :a1
[([1 2 nil nil nil] :seq)] :a2
:else nil))
;=> :a2```

Note this works on all `ISeqs` as well as `Sequential` types.

## Vector types

You can also match vector types, the benefit is much better performance when you want to test something internal without looking at earlier values - random access:

```(let [x [1 2 3]]
(match [x]
[[_ _ 2]] :a0
[[1 1 3]] :a1
[[1 2 3]] :a2
:else :a3))
;=> :a2```

core.match will optimize this case and test the third column first.

## Rest patterns

Both seq and vector patterns support rest patterns. As in Clojure's builtin destructuring, rest pattern will capture the "rest" of a collection.

```(let [x '(1 2)]
(match [x]
[([1] :seq)] :a0
[([1 & r] :seq)] [:a1 r]
:else nil))
;=> [:a1 (2)]```

## Map patterns

core.match supports matching maps. Here is a simple example:

```(let [x {:a 1 :b 1}]
(match [x]
[{:a _ :b 2}] :a0
[{:a 1 :b 1}] :a1
[{:c 3 :d _ :e 4}] :a2
:else nil))
;=> :a1```

This will return `:a1`. Note that if you specify a key but you don't care about its value, you are asserting that the key must at least be present. For example:

```(let [x {:a 1 :b 1}]
(match [x]
[{:c _}] :a0
:else :no-match))
:=> :no-match```

will return `:no-match` since the map does not have the key `:c`.

It's also useful to specify that some map has only a set of specified keys, this can be accomplished with the `:only` map pattern modifier:

```(let [x {:a 1 :b 2}]
(match [x]
[({:a _ :b 2} :only [:a :b])] :a0
[{:a 1 :c _}] :a1
[{:c 3 :d _ :e 4}] :a2
:else nil))
:=> :a0```

This will return `:a0` however the following:

```(let [x {:a 1 :b 2 :c 3}]
(match [x]
[({:a _ :b 2} :only [:a :b])] :a0
[{:a 1 :c _}] :a1
[{:c 3 :d _ :e 4}] :a2
:else nil))
;=> :a1```

Will return `:a1`.

## Or patterns

core.match supports "or" patterns - sugar for specifying alternatives.

```(let [x 4 y 6 z 9]
(match [x y z]
[(:or 1 2 3) _ _] :a0
[4 (:or 5 6 7) _] :a1
:else nil))
;=> :a1```

This is much more succinct that having to define six separate clauses.

## Guards

core.match supports arbitrary guards on patterns:

```(match [1 2]
[(_ :guard #(odd? %)) (_ :guard odd?)] :a1
[(_ :guard #(odd? %)) _] :a2
:else :a4)
:=> :a2```

## Nesting

It is possible to match on nested maps:

```(match [{:a {:b :c}}]
[{:a {:b nested-arg}}] nested-arg)
;=> :c```

## Function application

core.match supports pattern matching on the result of function applications

```(let [n 0]
(match [n]
[(1 :<< inc)] :one
[(2 :<< dec)] :two
:else :no-match))
;=> :one```

The right hand side is the function to apply, the left hand side is any valid pattern.

## Arrays (Experimental)

For performance reasons it may be useful to match on host arrays (Java, JavaScript). The vector matching logic can be specialized on host arrays. See Advanced Usage for a longer description.

## Binary data (Experimental)

Similar to arrays it's useful to use the same vector matching syntax to match on binary data. Currently there is only a proof of concept in the repository. See Advanced Usage for a longer description.