Why can't we update variables inside if statements?
Considering the following code
0
1
2
3
4
def foo do
x = 5
if true, do: x = 10
IO.inspect x
end
Calling this will output 5.
0
1
2
iex()> foo()
5 # the inspect value
5
Why is this?
We know that Elixir is a functional language and, therefore most things we see in
Elixir are functions. For example, both def
and defmodule
are functions. And
within functions, we cannot change variables outside the functions.
0
1
2
3
4
5
6
7
8
def foo do
x = 5
bar()
puts x
end
def bar do
x = 10
end
This will output 5, which surprises no one, and to change the x
in foo we
could write:
0
1
2
3
4
5
6
def foo do
x = 5
x = bar()
puts x
end
def bar, do: 10
In Elixir the if statement is a function with an arity of two. And it becomes evident we should write the following to update x.
0
1
2
3
4
def foo do
x = 5
x = if true, do: x = 10 # same functionality as bar()
puts x
end
This is also the reason why we have to use <%=
instead of <%
in eex
templates.
0
1
2
<%= if condition do %>
# ...
<% end %>
Since if/2
is only conditionally returning the value inside the block.