Elixir 9. Conditionals
Conditionals
Branching can be done using Multiclause Functions, also Elixir Provides us with standard way of doing branching with if
and case
.
Branching with MULTICLAUSE FUNCTION
defmodule Main do
def test(0), do: :zero
def test(x) when x > 0, do: :positive
def test(x) when x < 0, do: :negative
def empty?([]), do: true
def empty?([_ | _]), do: false
def main do
IO.puts test(-1)
IO.puts test(1)
IO.puts test(0)
IO.puts empty?([])
IO.puts empty?([1, 2, 3])
end
end
Main.main()
We can use multiclause function with pattern matching to create next level branching patterns.
In the typical setup of imperative language, such as JavaScript we do something like this.
function fact(n) {
if (n == 0) return 0;
if (n == 1) return 1;
return n * fact(n - 1);
}
This same fact
factorial function when implemented using elixir look like
defmodule Main do
def fact(0), do: 0
def fact(1), do: 1
def fact(n), do: n * fact(n - 1)
def main do
IO.puts fact(4)
end
end
Main.main()
Not using
if
andcase
.
Another example, finding sum of elements of list.
defmodule Main do
def sum([]), do: 0
def sum([a | b]), do: a + sum(b)
def main do
IO.puts sum([1, 2, 3, 4])
end
end
Main.main()
With the help of
Multiclause Functions
+Pattern Matching
+Guards
, it is possible to achieve anything which can be done using Classical Branching System
Classical Branching Constructs
Elixir provides us with macros if
, unless
, cond
and case
.
IF
if condition do
# condition is true
else
# condition is false
end
An example to check if a given token is string (binary in context of elixir) will be
defmodule Main do
def main(x) do
if is_binary(x) do
IO.puts "IT'S BINARY"
else
IO.puts "IT'S Not-BINARY"
end
end
end
Main.main(1) # IT'S BINARY
Main.main("10") # IT'S Not-BINARY
if
statement can also be inlined like
defmodule Main do
def maxLocal(a, b) do
if a > b, do: a, else: b
end
def main do
IO.puts maxLocal(45, 67)
end
end
Main.main
Unless unless
is just if not
.
Cond
cond
is to solve the if else-if else
condition by simplifying the syntax.
I think
cond
is for condition
cond do
a -> # a
b -> # b
c -> # c
d -> # d
true -> # will always match in the last
end
Which ever expression evaluate first
Here a, b, c, d, are Boolean Expression
. And in line 6 we have true
, this will act a a Default match, because is non of expression will match in the cond
then it will return an error.
Case
case expression do
pattern_1 -> # 1
pattern_2 -> # 2
pattern_3 -> # 3
_ -> # Default (it will match anything)
end
A quick example
defmodule Main do
def max(a, b) do
case a >= b do
true -> a
false -> b
end
end
end
IO.puts Main.max(2, 9)
With Special Form
with pattern_1 <- expression_1,
pattern_2 <- expression_2,
pattern_3 <- expression_3
do
{:ok, {something}} # the return value
end
In this special form, if any of the expression_x failed to match with pattern_x then the {:error, reason}
of that expression_x will be returned.
More about
with
special form: https://hexdocs.pm/elixir/Kernel.SpecialForms.html#with/1
next up we have loops.
As a gentle reminder, there are no loops
in Elixir....