Elixir Pattern Matching and Control Structures

a purple bottle of wine in the middle of a black surface with light streaming through

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.

Similar Articles