Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Match Operator

reading/match_operator.livemd

Match Operator

Mix.install([
  {:jason, "~> 1.4"},
  {:kino, "~> 0.9", override: true},
  {:youtube, github: "brooklinjazz/youtube"},
  {:hidden_cell, github: "brooklinjazz/hidden_cell"}
])

Navigation

Home Report An Issue Comparison OperatorsFun Formulas

Review Questions

Upon completing this lesson, a student should be able to answer the following questions.

  • What are variables, and how do we use the match operator to bind them?
  • How can we gain insight into our programs and debug them?

Variable Binding

The match operator = is a way of binding some data to a named variable that we can use in place of that data throughout the rest of a program.

For example, you can store the number 9 in a variable named my_variable and then use my_variable in place of 9.

my_variable = 9

my_variable + 1

You can name a variable almost anything and then use that name throughout the rest of your program. In the example above, we use my_variable, but you can name a variable almost anything as long as it doesn’t break certain rules.

a_different_variable_name = 9
a_different_variable_name + 1

Why is storing a value in a variable useful? Imagine you have a program that runs several calculations on a number. Let’s say the number 8.

8 + 7 - 8 * 10 * 8 + 8

If we want to run these operations on the number 7 instead, that suddenly becomes tedious to write.

A variable allows us to store a value and reuse it throughout the program.

my_number = 8
my_number + 7 - my_number * 10 * my_number + my_number

If the desired value changes, you only need to change the variable.

my_number = 7
my_number + 7 - my_number * 10 * my_number + my_number

Variables are also helpful for making programs more clear. There’s an anti-pattern in programming called magic values. Magic values are values in a program that don’t have a name but are important. You’ll see magic numbers and magic strings as common anti-patterns. An anti-pattern means something you should generally avoid doing in your programs otherwise, they become less clear and difficult to work with.

For example, imagine you’re working on a program that accepts payments, and you find the following code

100 * 1.12

What is 1.12? What is 100? These are examples of magic values. They might be important for the code to run properly, but the programmer has provided no context on what they are. This program would be a lot clearer if we used well-named variables.

item_cost = 100
tax_multiplier = 1.12
item_cost * tax_multiplier

Oh! So this is a program that takes the cost of an item and adds tax to it.

Naming Variables

Variable names must follow a few rules:

  • They must start with a letter.
  • They may contain valid alphanumeric characters.
  • They may end with predicates such as ! or ?.
  • They may not contain spaces.
  • They may not contain certain special characters such as $.

In addition to those enforced rules, it’s conventional to separate words in a variable with an underscore _ and only use lowercase letters.

If you break the rules for naming a variable, your program will crash with an error. Much like naming atoms, memorizing the rules of naming variables is unimportant. You will develop an intuition for if your variable name is valid or not through repeated exposure. In practice, most variable names are made of only lowercase letters, underscores, and sometimes numbers.

In general, you should give your variables meaningful names That improve the clarity of your code.

Short generic variable names are often difficult to decipher unless there’s an established convention. For example, you’ll often see the variable i to refer to an index.

Here are some example variable names that do not convey meaning.

t = "12:00"
c = 10

Instead, prefer verbose variable names to improve the clarity of your programs.

time = "12:00"
cost = 10

Unbound Variables

Using an unbound variable will crash your program.

a_variable_that_has_not_been_bound

If you look closely at the error, you’ll see undefined function a_variable_that_has_not_been_bound/0 (there is no such import)

When you use an unbound variable, Elixir assumes it’s a function that has not been defined. You haven’t covered functions yet, but you will learn more about them in future lessons.

For now, it’s enough to be familiar with this error so that if you see it, you’ll know you’re using an unbound variable.

Your Turn

In the Elixir cell below, create a variable hello and bind it to the value "world".

Example solution

hello = "world"

Enter your solution below.

hello = "world"

Mutation

Under the hood, the values bound to variables are stored on the computer in memory.

The variable is pointing to the value in that location.

flowchart LR
    variable --> location

For example, a variable hello with the value "world" would store the string "world" somewhere in memory. memory is a hardware component on the computer. You may have heard of RAM (Random Access Memory).

flowchart LR
    hello --> w["world"]

Object-Oriented Programming languages allow you to mutate the actual value in memory. So when we write hello = 4, the data "world" mutates into 4.

flowchart LR
    hello --> w["4"]

However, we do not allow mutation in a functional programming language like Elixir. So instead of mutating the data, we rebind the variable to new data.

flowchart
    w["world"]
    hello --> 4

That’s why we call data in Elixir immutable.

It may not be clear why this matters, and that’s ok. For now, it’s enough to be aware that data is immutable, as you will have more opportunities to see the impact of immutability in future lessons.

However, we can rebind variables, so the following statement is valid.

my_variable = 1

my_variable = 2

# Returns 2, Because We Rebound My_variable
my_variable

Debugging

Often times it’s useful to debug your code by knowing what the value of variables are.

We can use IO.inspect to log values in our code. IO.inspect returns the value given to it.

my_value = "hello"

IO.inspect(my_value)

We can wrap a value in IO.inspect. So long as we do this correctly, IO.inspect will print the value in our code without affecting it’s behavior.

my_value = IO.inspect("hello")

my_value

Your Turn

Use IO.inspect to print the hello variable.

hello = "world!"

Further Reading

Consider the following resource(s) to deepen your understanding of the topic.

Commit Your Progress

DockYard Academy now recommends you use the latest Release rather than forking or cloning our repository.

Run git status to ensure there are no undesirable changes. Then run the following in your command line from the curriculum folder to commit your progress.

$ git add .
$ git commit -m "finish Match Operator reading"
$ git push

We’re proud to offer our open-source curriculum free of charge for anyone to learn from at their own pace.

We also offer a paid course where you can learn from an instructor alongside a cohort of your peers. We will accept applications for the June-August 2023 cohort soon.

Navigation

Home Report An Issue Comparison OperatorsFun Formulas