Why assign if/else to a variable?

In Elixir Succinctly I read:

Since everything in Elixir is an expression, and if is no exception, the if…else construct returns a value that we can assign to a variable for later use:

a = if test_conditional do
# ...

What are some practical usages of this?

You can have the value of a variable depending on some condition.

In other languages you see code like the following which would not work in Elixir due to elixirs scoping rules:

a = 2
if condition then:
    a = 1
2 Likes

if suppose you want to change any variable value inside if block in Elixir. You need to get back and re-assign the value to the same variable.

This is the code you will expect to work. But it won’t.

iex(7)> a = 5
5
iex(8)> is_odd = nil
nil
iex(9)> if rem(a, 2) == 0 do
...(9)>   is_odd = false
...(9)> else 
...(9)>   is_odd = true
...(9)> end
warning: variable "is_odd" is unused (if the variable is not meant to be used, prefix it with an underscore)
  iex:12

warning: variable "is_odd" is unused (if the variable is not meant to be used, prefix it with an underscore)
  iex:10

true
iex(10)> is_odd
nil

So you need to re-assign it back like below:

iex(13)> a = 5
5
iex(14)> 
nil
iex(15)> is_odd = if rem(a, 2) == 0 do
...(15)>   false
...(15)> else 
...(15)>   true
...(15)> end
true
iex(16)> is_odd
true
iex(17)> 
2 Likes

Welcome to the immutable data structure land. Most data in elixir is immutable, in other words, you can’t change the value of a variable. Instead, you can create a new const using old name.

iex(1)> a = 1
1
iex(2)> if true, do: a = 2
warning: variable "a" is unused (if the variable is not meant to be used, prefix it with an underscore)
  iex:2

2
iex(3)> a
1  # didn't change

iex(4)> a = if true, do: 2
2  # new value with old name
1 Like

That’s not really the case for what you show. Your examples work the way they do, because of the lexical scoping rules within elixir. Earlier versions of elixir (until 1.2 iirc) did work differently and allowed rebinding of variables within if blocks. There’s no mutability in both versions though, as that one is enforced by the beam.

So while it might seem related it actually is not.

1 Like

There was a warning about the “imperative assignment” from 1.2 or 1.3 on, and it actually worked until 1.8 or 1.9…

2 Likes