## 3. Numbers

In Elixir, numbers are divided into two categories: integers and floats. Integers are whole numbers, the type you count on your hand: `3`, `0`, `-1123`, etc. Floats are numbers that can contain fractional parts, like `1.333333` or `-0.01`. They are called "floats" because of the way they are represented in memory. You don’t need to know that, but if you want to learn more you can read up on floating-point arithmetic. To be honest, I had to look it up myself while writing this very paragraph!

In this chapter we will go over the basics of numbers and floats, along with introducing some other pattern matching mechanisms that Elixir has, among other things. Let’s dive in!

### 3.1. Fibonacci

The Fibonacci numbers are a famous set of numbers that form a sequence, where each number is the sum of the two preceding ones. You may have seen them before:

Listing 1. Fibonacci numbers
``0, 1, 1, 2, 3, 5, 8, 13, 21...``

It is represented mathematically like so:

Listing 2. Fibonacci sequence
``````F₀ = 0
F₁ = 1
Fₙ = F₀ + F₁``````

Which means `2` in the sequence above is the 3rd Fibonacci number, and `0` is the 0th (zeroth).

Let’s write a program that can compute any Fibonacci number for us. We can give it a number, `n`, like `6` and it will return the corresponding Fibonacci number, `8`.

#### 3.1.1. Function pattern matching

Listing 3. numbers/fibonacci_test.exs
``````Code.require_file("fibonacci.ex")
ExUnit.start()

defmodule FibonacciTest do
use ExUnit.Case

test "calculates 0th number" do
assert Fibonacci.calculate(0) == 0
end

test "calculates 1st number" do
assert Fibonacci.calculate(1) == 1
end
end``````

Here we are just testing the 0th and 1st number, but we’ll add more later. Run the test to ensure that it fails, as we would expect:

``````** (Code.LoadError) could not load [...]fibonacci.ex
(elixir 1.12.2) lib/code.ex:1807: Code.find_file/2
(elixir 1.12.2) lib/code.ex:1254: Code.require_file/2
fibonacci_test.exs:1: (file)
(elixir 1.12.2) lib/code.ex:1261: Code.require_file/2``````

Our `fibonacci.ex` file doesn’t exist yet, so our test is failing to run. Note that "failing to run" is not the same as "running, then failing". In this case, our tests are not actually running! Let’s create `fibonacci.ex` and add the minimal code needed to make our `fibonacci_test.exs` actually run:

Listing 4. numbers/fibonacci.ex
``````defmodule Fibonacci do
end``````

With that in place, we can see the familiar `ExUnit` output:

``````\$ elixir fibonacci_test.exs
warning: Fibonacci.calculate/1 is undefined or private
Found at 2 locations:
fibonacci_test.exs:8: FibonacciTest."test calculates 0th number"/1
fibonacci_test.exs:12: FibonacciTest."test calculates 1st number"/1

1) test calculates 0th number (FibonacciTest)
fibonacci_test.exs:7
** (UndefinedFunctionError) function Fibonacci.calculate/1 is undefined or private
code: assert Fibonacci.calculate(0) == 0
stacktrace:
Fibonacci.calculate(0)
fibonacci_test.exs:8: (test)

2) test calculates 1st number (FibonacciTest)
fibonacci_test.exs:11
** (UndefinedFunctionError) function Fibonacci.calculate/1 is undefined or private
code: assert Fibonacci.calculate(1) == 1
stacktrace:
Fibonacci.calculate(1)
fibonacci_test.exs:12: (test)

Finished in 0.1 seconds (0.1s on load, 0.00s async, 0.01s sync)
2 tests, 2 failures

Randomized with seed 362639``````

Now let’s write the code needed to make it pass:

Listing 5. numbers/fibonacci.ex
``````defmodule Fibonacci do
def calculate(0) do
0
end

def calculate(1) do
1
end
end``````

In Elixir, we can also do "matching" within the function definition itself, which is what we are doing here. When you call `calculate/1` with a parameter, Elixir will find the function definition that "matches" the parameter you provide. This works similarly to how `case` works, which we saw in action in the previous chapter.

So when we call `calculate/1` with the value of `1`, as we do in our test, Elixir will first look at `def calculate(0)`, see that `1 != 0`, and then look at the next definition. The next definition, `def calculate(1)` does match, and Elixir will in turn execute the `do`/`end` block associated with that definition.

Since functions are dispatched in this "matching" manner, we can define the same function multiple times. That is, in addition to defining functions with different arities, like `greet/0` and `greet/1`, we can also define multiple functions with the same arity, like we do here with `calculate/1`. Functions, just like `case`, are matched in order from the first definition in the module to the last, too.

If you haven’t already, run the tests to verify that your code passes:

``````\$ elixir fibonacci_test.exs
..

Finished in 0.04 seconds (0.03s on load, 0.00s async, 0.01s sync)
2 tests, 0 failures

Randomized with seed 601683``````

#### 3.1.2. Recursion

Let’s define the rest of the behavior we want from our `calculate/1` function with some more tests:

Listing 6. numbers/fibonacci_test.exs
``````Code.require_file("fibonacci.ex")
ExUnit.start()

defmodule FibonacciTest do
use ExUnit.Case

test "calculates 0th number" do
assert Fibonacci.calculate(0) == 0
end

test "calculates 1st number" do
assert Fibonacci.calculate(1) == 1
end

test "calculate 8th number" do
assert Fibonacci.calculate(8) == 21
end
end``````

Here we add a test for the 8th Fibonacci number, which I got from the sequence at the top of this chapter. With that added, let’s run our tests:

Listing 7. FunctionClauseError
``````\$ elixir fibonacci_test.exs
..

1) test calculate 8th number (FibonacciTest)
fibonacci_test.exs:15
** (FunctionClauseError) no function clause matching in Fibonacci.calculate/1

The following arguments were given to Fibonacci.calculate/1:

# 1
8

code: assert Fibonacci.calculate(8) == 21
stacktrace:
fibonacci.ex:2: Fibonacci.calculate/1
fibonacci_test.exs:16: (test)

Finished in 0.09 seconds (0.07s on load, 0.00s async, 0.02s sync)
3 tests, 1 failure

Randomized with seed 30951``````

Our test fails with a `FunctionClauseError`. Though we do have a `calculate/1` function defined, none of its function clauses match the parameter we passed in. This is because our current `calculate/1` only has function clauses for `0` and `1`.

Let’s add a third function clause that handles the case for the third or later Fibonacci number. By referencing the formula in Listing 2, we come up with this:

Listing 8. numbers/fibonacci.ex
``````defmodule Fibonacci do
def calculate(0) do
0
end

def calculate(1) do
1
end

def calculate(n) do
calculate(n-1) + calculate(n-2)
end
end``````

Our code here looks almost exactly like the formula. If the parameter we get is 0 or 1, we return those respective values, otherwise we recursively compute the value by calculating the prior two Fibonacci numbers and adding them together.

Run the tests to verify the solution works.

#### 3.1.3. Function clause guards

Our `Fibonacci` module works great. However, there is one problem: other programmers keep on calling it with strings instead of integers! They pass in `"5"` instead of `5`. They say calling it with these "numbers" results in an `ArithmeticError` in our module. Because the error comes from our module, they insist it is our code that has the bug not theirs!

We did not really expect this sort of usage, so we should guard against it. Our code should be defensive against "bad" inputs, to make it clear to other programmers using our module that the issue is not in our module, but rather in how they are using our module.

Instead of having our code raise an `ArithmeticError`, we should raise an error that indicates to the programmer that our function is not meant to be used in the way they are using it. That it doesn’t accept the parameters that are passed in.

What sort of error should we raise? How about the `FunctionClauseError` that we encountered earlier in Listing 7, when we tried to call `calculate/1` with a number before we defined that functionality. That makes it clear that our function has no clause for their parameter, which is much more clear!

In Elixir, we can assert an error is raised with the handy `assert_raise/2` function. Let’s add a test, using that:

Listing 9. numbers/fibonacci_test.exs
``````defmodule Fibonacci do
def calculate(0) do
0
end

def calculate(1) do
1
end

def calculate(n) do
calculate(n-1) + calculate(n-2)
end
end``````

`assert_raise/2` takes in an exception and a function to run that should raise that exception when executed. In Elixir, in addition to defining a function in a module with `def`, we can also define a function within a block with the `fn ->` shorthand. This is known as an anonymous function, because it has no name. We will cover anonymous functions in much more detail in a later chapter.

Let’s run our test:

``````\$ elixir fibonacci_test.exs
..

1) test handles strings (FibonacciTest)
fibonacci_test.exs:19
Expected exception FunctionClauseError but got ArithmeticError (bad argument in arithmetic expression)
code: assert_raise FunctionClauseError, fn ->
stacktrace:
fibonacci.ex:11: Fibonacci.calculate/1
fibonacci_test.exs:20: (test)

.

Finished in 0.09 seconds (0.06s on load, 0.00s async, 0.03s sync)
4 tests, 1 failure

Randomized with seed 805110``````

Great! Here we have added a test that reproduces what those other programmers were telling us, that our code is raising an `ArithmeticError`. We see that the test fails because our `asset_raise` was expecting a `FunctionClauseError`.

In Elixir, we can guard against bad inputs with Guards. Essentially, in a function clause, we can add a guard that tells Elixir what sort of things the function is willing to accept.

There are many types of guards. For us, we want to check that the parameter is a number. So we can use the `is_integer` one.

Listing 10. numbers/fibonacci.ex
``````defmodule Fibonacci do
def calculate(0) do
0
end

def calculate(1) do
1
end

def calculate(n) when is_integer(n) do
calculate(n-1) + calculate(n-2)
end
end``````

And run the tests again. They all pass! Now next time someone tries to call our `calculate/1` function with a string, they will get a `FunctionClauseError`, making clear to them that our function does not match their parameters.

#### 3.1.4. Just `, do:` it

This pattern of having a variety of short function definitions to implement a given function is quite common in Elixir. It is not unusual to have even up to ten function clauses for a single function. This has the benefit of skimming the various cases the function could handle quite easy. However, it does often feel more verbose than just having that matching logic within a single function via `case` or similar.

Luckily, in addition to the traditional `do`/`end` deliminated function body block, Elixir also has a "shorthand" way of defining the function body by using just `, do:` alone. Update your `fibonacci.ex` file as follows, to see it in action:

Listing 11. numbers/fibonacci.ex
``````defmodule Fibonacci do
def calculate(0), do: 0
def calculate(1), do: 1
def calculate(n) when is_integer(n), do: calculate(n-1) + calculate(n-2)
end``````

This shorthand style is only used when the body of the function only has a single line of code. As you see, it compresses the number of lines a function takes up from three to one, in our case. Note that for this `, do:` style, we have a comma after the closing parenthesis. In the `do`/`end` style, there is no such comma.

After refactoring, run the tests again to make sure your refactor did not introduce any regressions.

### 3.2. FizzBuzz

One of the most common interview questions out there is implementing Fizz buzz. It’s a simple game where we print a range of numbers with the following rules:

• If the number is divisible by 3, print `"Fizz"`

• If the number is divisible by 5, print `"Buzz"`

• If the number is divisible by 3 and 5, print `"FizzBuzz"`

• Otherwise, print just the number.

Actually, one of my first programming jobs I got in college had this question in the interview. I think that was the first time I ever saw it.

Anyway, let’s implement this in Elixir!

#### 3.2.1. Remainders with `rem`

As always, start with a test. Create a new file, `fizz_buzz_test.exs`, and let’s translate the requirements above into code:

Listing 12. numbers/fizz_buzz_test.exs
``````Code.require_file("fizz_buzz.ex")
ExUnit.start()

defmodule FizzBuzzTest do
use ExUnit.Case

test "handles divisible by 3" do
assert FizzBuzz.solve(3) == "Fizz"
end

test "handles divisible 5" do
assert FizzBuzz.solve(5) == "Buzz"
end

test "handles divisible by 3 and 5" do
assert FizzBuzz.solve(15) == "FizzBuzz"
end

test "handles not divisible" do
assert FizzBuzz.solve(7) == 7
end
end``````

Additionally, create a `fizz_buzz.ex` file that simply defines our module:

``````defmodule FizzBuz do
end``````

And let’s run our tests to verify they are failing, as we would expect:

``````\$ elixir fizz_buzz_test.exs
warning: FizzBuzz.solve/1 is undefined or private
Found at 4 locations:
fizz_buzz_test.exs:8: FizzBuzzTest."test handles divisible by 3"/1
fizz_buzz_test.exs:12: FizzBuzzTest."test handles divisible 5"/1
fizz_buzz_test.exs:16: FizzBuzzTest."test handles divisible by 3 and 5"/1
fizz_buzz_test.exs:20: FizzBuzzTest."test handles not divisible"/1

1) test handles not divisible (FizzBuzzTest)
fizz_buzz_test.exs:19
** (UndefinedFunctionError) function FizzBuzz.solve/1 is undefined or private
code: assert FizzBuzz.solve(7) == 7
stacktrace:
FizzBuzz.solve(7)
fizz_buzz_test.exs:20: (test)

2) test handles divisible by 3 (FizzBuzzTest)
fizz_buzz_test.exs:7
** (UndefinedFunctionError) function FizzBuzz.solve/1 is undefined or private
code: assert FizzBuzz.solve(3) == "Fizz"
stacktrace:
FizzBuzz.solve(3)
fizz_buzz_test.exs:8: (test)

3) test handles divisible by 3 and 5 (FizzBuzzTest)
fizz_buzz_test.exs:15
** (UndefinedFunctionError) function FizzBuzz.solve/1 is undefined or private
code: assert FizzBuzz.solve(15) == "FizzBuzz"
stacktrace:
FizzBuzz.solve(15)
fizz_buzz_test.exs:16: (test)

4) test handles divisible 5 (FizzBuzzTest)
fizz_buzz_test.exs:11
** (UndefinedFunctionError) function FizzBuzz.solve/1 is undefined or private
code: assert FizzBuzz.solve(5) == "Buzz"
stacktrace:
FizzBuzz.solve(5)
fizz_buzz_test.exs:12: (test)

Finished in 0.1 seconds (0.1s on load, 0.00s async, 0.00s sync)
4 tests, 4 failures

Randomized with seed 702309``````

We haven’t implemented `solve/1` yet, so these `UndefinedFunctionError` failures are exactly what we would expect.

In Elixir, we can find whether one number is divisible by another with the built-in `rem/2` function. If you have worked with other programming languages, this is the equivalent of the module operator, `%`. It simply returns the remainder of the division operation. For example `rem(10,2) == 0` and `rem(10,3) == 1`.

Let’s try implementing this with guards and `case`:

Listing 13. numbers/fizz_buzz.ex
``````defmodule FizzBuzz do
def solve(num) do
case num do
num when rem(num, 3) == 0 and rem(num, 5) == 0 ->
"FizzBuzz"
num when rem(num, 3) == 0 ->
"Fizz"
num when rem(num, 5) == 0 ->
"Buzz"
not_divisible ->
not_divisible
end
end
end``````

The same guards we used on our function clauses earlier can also be used on case clauses. Here we also use the `and` operator to combine two guards for our first clause, to ensure it is divisible by both 3 and 5.

You may be asking: why don’t we use function guard clauses instead, like we did with Fibonacci? There is no particular reason, and using function guard clauses would work just as well. In fact, that is one of the exercises at the end of this chapter.

Run the tests again to verify everything passes.

#### 3.2.2. Conditions with `cond`

In addition to `case` and `if`/`else`, Elixir has the `cond` flow control structure.

To review, `if` evaluates a single expression, and runs the associated block if that expression evaluates to true, otherwise evaluating the `else` block, if it exists. `case` uses pattern matching, evaluating the block of code associated with the matching clause.

`cond` is similar to `else if` in other programming languages. Instead of working on matching, it works in the same way `if` does: by evaluating expressions one by one and running the block of code associated with the first expression that evaluates to true.

Let’s refactor our code to use `cond`, to explore further:

Listing 14. numbers/fizz_buzz.ex
``````defmodule FizzBuzz do
def solve(num) do
cond do
rem(num, 3) == 0 and rem(num, 5) == 0 ->
"FizzBuzz"
rem(num, 3) == 0 ->
"Fizz"
rem(num, 5) == 0 ->
"Buzz"
true ->
num
end
end
end``````

As you can see, `cond` is a bit more succinct in this case. As mentioned, `cond` is used when we have a variety of expressions to evaluate. It is typically used less frequently that `case` and pattern matching in general.

Our last condition is simply `true`, which is always true, so serves as our final catch-all. If a `cond` construct has no expression that evaluates to true, then a `CondClauseError` will be raised.

Run the tests to ensure that our little refactor did not introduce any regression, and that the tests still pass.

### 3.3. Whirlwind operator tour, with tests

In a chapter called "Numbers", we’ve only used the `rem` and `+` operators so far! Let’s fix that by doing a bit of a whirlwind tour of all the operators we typically use with numbers. We won’t be creating a module this time, but will instead be expanding and reinforcing our understanding by creating a series of tests that explore each of them.

Create a file called `numbers_test.exs`, where we will add our tests:

``````ExUnit.start()

defmodule NumbersTest do
use ExUnit.Case
end``````

Let’s get started!

#### 3.3.1. Number operators

In addition to the `+` operator, Elixir of course also has the `-` operator. It works just as you would expect it to:

Listing 15. numbers/numbers_test.exs
``````  test "- operator" do
assert 1 - 5 == -4
end``````

Related to the `rem` operator is the `div` operator. `div` is the integer division operator. It only returns the result rounded towards zero.

Listing 16. numbers/numbers_test.exs
``````  test "div operator" do
assert div(10, 2) == 5
assert div(11, 2) == 5
assert div(12, 2) == 6
end``````

You may want a float result instead. For that you can use the `/` operator.

Listing 17. numbers/numbers_test.exs
``````  test "/ operator" do
assert 10 / 2 == 5.0
assert 11 / 2 == 5.5
assert 12 / 2 == 6.0
end``````

When any sort of operation uses both an integer and a float, the result is usually a float. We can show this by way of the `*` operator, which multiplies.

Listing 18. numbers/numbers_test.exs
``````  test "* operator" do
assert 1.0 * 5 == 5.0
assert 50 * 20 == 1000
assert 2.2 * 4.1 == 9.02
end``````

#### 3.3.2. Comparison operators

All of our tests already use at least one comparison operator: `==`! It compares the value between the two operands, as we know. It isn’t very strict when comparing between floats and integers though.

Listing 19. numbers/numbers_test.exs
``````  test "== operator" do
assert 1.0 == 1
assert 1.0000000000000001 == 1
end``````

The `===` operator is more strict when comparing between floats and integers.

Listing 20. numbers/numbers_test.exs
``````  test "=== operator" do
refute 1.0 === 1
refute 1.0000000000000001 === 1
assert 1 === 1
assert 1.01 === 1.01
end``````

Here we use the `refute/1` macro. It’s the opposite of `assert`, and only succeeds if the operation does not return a truthy value.

We also have the `!=` and `!==` operators, which test that two values do not match. The `!==` operator, like the `===` operator, is more strict in its comparison.

Listing 21. numbers/numbers_test.exs
``````  test "!= and !== operators" do
refute 1.0 != 1
assert 1.0 !== 1
end``````

Of special interest to numbers is determining whether a number is smaller or larger. We can do this with the `<` and `>` operators, respectively.

Listing 22. numbers/numbers_test.exs
``````  test "> and < operators" do
assert 1 < 2
assert 1 < 1.00001
assert 9001 > 9000
assert -55 > -60
end``````

We can tack on a `=` to the end of each to also return true if the values are equal.

Listing 23. numbers/numbers_test.exs
``````  test ">= and <= operators" do
assert 1 >= 1.0
assert 1 <= 1.00001
end``````

Whew! And with that, we know all the operators we need to know for numbers.

### 3.4. Conclusion

In this chapter we got to explore more of the basics. You are now equipped to pass two of the most common interview questions: Fibonacci and FizzBuzz! Next up is learning about two of the more unique parts of Elixir: tuples and the `=` match operator, among many other things. Onward!

#### 3.4.1. What we learned in this chapter

• Function definitions can utilize pattern matching, just like `case`.

• Guards are used for making our match more specific. They can be added to match clauses, like function definitions and `case` clauses.

• We can use the shorthand `, do:` syntax to make our function bodies more concise.

• `rem/2` can be used to calculate the remainder of a division operation.

• `cond` can be used to evaluate a series of expressions to determine what block of code to execute. It is similar to "else-if" chains in other programming languages.

• A whirlwind tour of all the other operators in Elixir!

#### 3.4.2. Exercises

• Calling `Fibonacci.calculate/1` with a negative number like `-1` results in the program hitting an infinite loop. Add a functional guard clause to guard against negative numbers. Hint: you can use comparison operators in guard clauses.

• Convert `FizzBuzz.solve/1` to use function clause guard matching instead of `cond`.

• Convert `Fibonacci.calculate/1` to use `cond` instead of function clause guard matching.

• Update `FizzBuzz` to print `"aww"` if a number is not divisible by 3 or 5, instead of printing the number. As always, update the test, first!

• `FizzBuzz.solve/1` currently does not guard against non-number parameters. Add a guard clause doing just that.