Skip to main content

Pattern Matching

Pattern matching is a technique for pulling apart compound data (like lists or dictionaries) by writing a template. For example, to use pattern matching on a list, we'd write down a template that looks similar to that list, with variables that Raven fills in for us.

Say we have the list xs = ["a", "b"]. One way to pull this part is to use indexing.

xs = ["a", "b"]
a = xs[1]
b = xs[2]

However, we can do this more easily by writing a similar-looking list, with a and b as holes to be filled.

xs = ["a", "b"]
[a, b] = xs
# now a == "a", b == "b"

Pattern matching comes up a lot in Raven. If you've run any code at all, you've used it. Even basic assignments like a = b are secretly matches (albeit simple ones that will work whatever b is). Likewise, function signatures like fn foo(a, b) ... are really matches over an argument list.

Matching doesn't always succeed. For example

[a, b] = "foo" # error

doesn't work, because "foo" isn't a list with two elements. When assigning to a variable, a match that fails will turn into an error. When a function signature fails to match, Raven tries each definition in turn. If none match, you get an error again.

Match variables

If a variable appears more than once inside a pattern, each match has to be equal.

[a, a] = ["a", "b"] # fails
[a, a] = ["b", "b"] # assigns a = "b"

You can ignore a variable by using _ as a name. Multiple appearances of _ don't have to be equal.

[a, _] = ["a", "b"] # assigns a = "a"
[_, a, _] = [1, 2, 3] # assings a = 2

Literals

Is-a matching

Lists

Constructors

Operators