Patterns have the same structure as terms, with the addition that they can include variables. Variables start with an upper-case letter.
Examples of patterns:
{A, a, 12, [12,34|{a}]}
{A, B, 23}
{x, {X_1}, 12, My_cats_age}
[]
In the above A
, B
, X_1
, and My_cats_age
are variables.
Pattern matching provides the basic mechanism by which values become assigned to variables. A variable whose value has been assigned is said to be bound – otherwise it is said to be unbound. The act of assigning a value to a variable is called binding. Once a variable has been bound its value can never be changed. Such variables are called bind once or single assignment. This contrasts with conventional imperative languages which have destructive assignment.
A pattern and a term are said to match if the pattern and term are structurally isomorphic and if, whenever an atomic data type is encountered in the pattern, the same atomic data type is encountered at the same position in the corresponding term. In the case where the pattern contains an unbound variable, the variable is bound to the corresponding element in the term. If the same variable occurs more than once in the pattern then all items occurring at corresponding positions in the term must be identical.
Pattern matching occurs:
- when evaluating an expression of the form
Lhs = Rhs
- when calling a function
- when matching a pattern in a
case
orreceive
primitive.
2.2.1. Pattern = Expression
The expression Pattern = Expression
causes Expression
to be evaluated and the result matched against Pattern
. The match either succeeds or fails. If the match succeeds any variables occurring in Pattern
become bound.
In the following we assume that the pattern matching always succeeds. The treatment of failure will be discussed in detail in a following Chapter.
Examples:
{A, B} = {12, apple}
succeeds with the bindings A → 12^3
and, B → apple
.
{C, [Head|Tail]} = {{222, man}, [a,b,c]}
succeeds with the bindings C → {222, man}
, Head → a
and, Tail → [b, c]
.
[{person, Name, Age, _}|T] =
[{person, fred, 22, male},
{person, susan, 19, female}, ...]
succeeds with the bindings T → [{person, susan, 19, female}, ...]}
,
Name → fred
and Age → 22
. In the last example we made use of the anonymous variable written _
– anonymous variables are used when the syntax requires a variable but we are not interested in its value.
If a variable occurs more than once in a pattern then the match will only suc- ceed if the corresponding elements being matched have the same value. So, for example, {A, foo, A} = {123, foo, 123}
succeeds, binding A
to 123
, whereas {A, foo, A} = {123, foo, abc}
fails since we cannot simultaneously bind A
to 123
and abc
.
=
is regarded as an infix right associative operator. Thus A = B = C = D
is parsed as A = (B = (C = D))
. This is probably only useful in a construction like {A, B} = X = ...
where we want both the value of an expression and its constituents. The value of the expression Lhs = Rhs
is defined to be Rhs
.
2.2.2. Pattern matching when calling a function
Erlang provides choice and flow of control through pattern matching. For ex- ample, Program 2.1 defines a function classify_day/1
, which returns weekEnd
if called with argument saturday or sunday, or it returns weekDay
otherwise.
-module(dates).
-export([classify_day/1]).
classify_day(saturday) -> weekEnd;
classify_day(sunday) -> weekEnd;
classify_day(_) -> weekDay.
When a function is evaluated, the arguments of the function are matched against the patterns occurring in the function definition. When a match occurs the code following the ->
symbol is evaluated, so:
> dates:classify_day(saturday). weekEnd > dates:classify_day(friday). weekDay
The function call is said to fail if none of its clauses match (failure causes the error-trapping mechanisms described later in this book to be used).
Any variables occurring in the patterns describing the different clauses of a function become bound when a particular clause in a function is entered. So, for example, evaluating math3:area({square, 5})
causes the variable Side
to be bound to 5
.