Pattern matching allows us to check if an object has some particular structure. For example, that a node of a binary tree has both children, or that it has a left child that has no children, and so on.

h3. Pattern matching operators ({{is}} and {{\!is}})

Pattern matching is performed by *is* operator that returns *true* if the pattern matched successfully and *false* otherwise. It has a negated form *\!is*. The simplest form of pattern matching simply checks if an object conforms to a given type (similar to *Java*'s *instanceof* check):
{jet}
//is
if (obj is String) {
  print(obj.length)
}
// !is
if (obj !is String) {
  print("Not a String")
}
else {
  print(obj.length)
}
{jet}
See [smart casts|Type casts].

*Is* and *\!is* may be used as branch conditions in *when* expressions:
{jet}
when (x) {
  is Int -> print(x)
  is List<Int> -> print(x.sum())
  !is Number -> print("Not even a number")
  else -> print("can't do anything")
}
{jet}
{info:title=When-expressions can replace switch-statement without pattern matching}See more on *when* expressions [here|Control structures#When expression].{info}

h3. Patterns

Patterns on the right-hand side of *is* and *\!is* allow to match against types, constants, structure of tuples and other objects, and to bind objects matched by sub-patterns, to variables.

See the [grammar for patterns|Grammar#pattern].

{note:title=Complex patterns are not implemented} For now you can only use a type after *is*/*!is*. See the corresponding [issue|http://youtrack.jetbrains.com/issue/KT-186].{note}

h4. Tuple patterns, constant and wildcard patterns

One can match not only against a type. One useful kind of patterns is _tuple patterns_. Note that the following code just checks the type of {{x}} to be {{(Int, String)}}:
{jet}
x is #(Int, String)
{jet}
But we can use other things than types as tuple components:
{jet}
x is #(1, String)
{jet}
This matches a tuple whose first component is {{1}}, and the second one is any {{String}} value. One can use any literal constants as patterns, and nest tuples:
{jet}
x is #("a", #(1.0, (false, Any?)))
{jet}
Note that nullable types can also occur in patterns, e.g. {{Any?}} matches any object or *null*, i.e. it matches _anything_. [Kotlin] has a shorthand for this, called a _wildcard pattern_, and written {{\*}}:
{jet}
x is #(*, *, *)
{jet}This matches any tuple of three components.

h4. Binding patterns

Often times we need to capture a part of what we've been matching. This is what _binding patterns_ are for. A binding patterns basically declares a variable iside a pattern. For example, we might want to say "if x is a tuple of two components, named a and b ":
{jet}
if (x is #(val a, val b)) {
  print(a)
  print(b)
}
{jet}
A plain binding pattern {{val a}} matches anything and assigns it to {{a}}. Additionally, it can be restricted by
* a pattern: {{val a is #(*, \*)}}
* a range: {{val a in 1..10}}
* a static type (rarely used): {{val a : Boolean}}

Consider a *when* expression with binding patterns:
{jet}
when (some_complex_expression) {
  is #(val a, val b is String) -> print("$a and ${b.length}")
  is #(val a is Int, val b is Int) -> print(a + b)
  is #(*, val b in 1..100) -> print(b)
}
{jet}

h4. Decomposer patterns

Tuples are not the only structures we can pattern-match against. For regular objects, [Kotlin] provides _decomposer patterns_. For example, when we want to match against a binary tree structure, we can do it this way:
{jet}
when (xml) {
  is Tree#(*, null) -> print("no right child")
  is Tree#(val l is Tree, val r is Tree) -> print("two children: $l and $r")
  is Tree -> print("just a tree")
}
{jet}

Decomposer patterns are available by default for [*enum* classes|Enum classes] and classes that [declare all their primary constructor parameters *val*|Classes and Inheritance#bean-class], i.e. make them properties, e.g. the {{Tree}} class could be defined this way:
{jet}
class Tree(val left : Tree?, val right : Tree?)
{jet}

Actually, this only makes the compiler generate a _decomposer function_ automatically. One can declare such a function by herself.

h5. Decomposer functions

A _decomposer function_ is a function that is called on the pattern-matched object ({{x}} in case of {{x is pattern}}), it must return a tuple that is matched against the one provided after the decomposer name, or *null*. In the {{Tree}} example above, {{Tree}} coming in front of {{#}} is not a class name, but a decomposer function name. This function (automatically generated by the compiler) looks like this:
{jet}
decomposer fun Any?.Tree() : #(Tree?, Tree?)? {
  if (this is Tree)
    return #(this.left, this.right)
  return null
}
{jet}
Note the *decomposer* annotation, it tells the compiler _not to call_ this function outside pattern-matching. Otherwise it would get confused with the constructor for {{Tree}}. This annotation is optional.

Generally, a decomposer is looked up as a function applicable for matching subject, i.e. it can have arbitrary name and it can be an member function:
{jet}
class Date(val timestamp : Long) {
  fun mmddyy() : #(Int, Int, Int)? = #(month, day, year)

  // ...
}

fun demo(d : Date) {
  when (d) {
    is mmddyy#(05, 13, val a) -> print("May 13th of $a"))
    // ...
  }
}
{jet}

or extension function:

{jet}
fun Date.mmddyy() : #(Int, Int, Int)? = #(month, day, year)
{jet}

h3. What's next

* [Classes and Inheritance]