Elixir Pattern Matching and Control Structures
Note: this page has been created with the use of AI. Please take caution, and note that the content of this page does not necessarily reflect the opinion of Cratecode.
Elixir, a dynamic functional language built on the Erlang VM, has a unique approach to handling data and control flow. One of its most powerful features is pattern matching. Combined with Elixir's control structures, such as case
, cond
, and if
, pattern matching allows for clean, efficient, and expressive code.
Pattern Matching
In Elixir, pattern matching works by decomposing data structures and assigning their components to variables. This is done using the match operator =
. Unlike in many other programming languages, the equals sign does not mean "assign the value on the right to the variable on the left." Instead, it means "try to make the patterns on both sides of the equals sign match."
Here's a simple example:
{a, b} = {1, 2}
In this case, the pattern on the left is {a, b}
and on the right is {1, 2}
. Elixir tries to match the patterns, which results in the variable a
being bound to the value 1
, and b
to 2
.
When the patterns don't match, Elixir raises a MatchError
. For instance:
{a, b} = {1, 2, 3} # This will raise a MatchError, as the patterns cannot match
Pin Operator
The pin operator ^
is used when you want to match against an existing variable's value rather than reassigning it. Here's an example:
x = 1 {^x, y} = {1, 2} # This will match, as x == 1 and y will be assigned the value 2 {^x, y} = {3, 2} # This will raise a MatchError, as x (1) does not match 3
Control Structures
Elixir offers several control structures that work well with pattern matching, making code more readable and expressive.
case
The case
construct allows you to match a value against multiple patterns. Here's an example using a tuple to represent different shapes and their dimensions:
shape = {:circle, 5} area = case shape do {:circle, radius} -> 3.14 * radius * radius {:rectangle, w, h} -> w * h {:triangle, b, h} -> 0.5 * b * h _ -> "Unknown shape" end IO.puts "The area is #{area}"
In this example, the case
statement checks the shape
tuple against various patterns and computes the area of the shape accordingly. The _
pattern acts as a catch-all for unknown shapes.
cond
The cond
construct is similar to case
, but it matches against the first truthy expression. It's useful when you need to test multiple conditions that don't fit into neat patterns. Here's an example with a simple grade calculator:
score = 85 grade = cond do score >= 90 -> 'A' score >= 80 -> 'B' score >= 70 -> 'C' score >= 60 -> 'D' true -> 'F' end IO.puts "Your grade is #{grade}"
if and unless
if
and unless
are basic control structures in Elixir, used for single condition checks. They are macros built on top of case
. Here's an example:
age = 18 if age >= 18 do IO.puts "You are eligible to vote!" else IO.puts "Unfortunately, you cannot vote yet." end
In conclusion, Elixir's pattern matching and control structures provide a powerful way to write clean, expressive, and efficient code. By leveraging these features, you can create elegant solutions to complex problems.
Hey there! Want to learn more? Cratecode is an online learning platform that lets you forge your own path. Click here to check out a lesson: Rust Enums (psst, it's free!).