Control flow
Contents
Control flow¶
Boolean types¶
Booleans are special data types that can have two values, true
or false
.
They are essential for conducting control flow.
Boolean operators (copied from here)
Expression 
Name 


negation 

shortcircuiting 

shortcircuiting 
Numeric comparisons (copied partially from here)
Operator 
Name 


equality 

inequality 

less than 

less than or equal to 

greater than 

greater than or equal to 

approximate equality with relative tolerance error 

programmatically identical equality comparison 
Most operators work exactly the same as in other languages.
2 == 2
true
4>5
false
When I was learning coding in Julia
, two operators were new to me: ≈
and ===
.
Operator ≈
compares two different objects given the tolerance error atol
:
≈(2000, 2000.1, atol=.5)
true
≈(2000, 2000.1; atol=.0001)
false
Operator ===
checks whether two objects are programmatically identical. In case of arrays or dictionaries, it means that we check whether two objects refer to the same memory slots. Illustrative example below:
x = [1,2]
y = x
z = deepcopy(x)
println("x==y: $(x==y)") #both objects have the same values
println("x==z: $(x==z)") #both objects have the same values
println("x===y: $(x===y)") #both objects refer to the same memory
println("x===z: $(x===z)") #both objects refer to different memory slots (even though they may have identical values)
x==y: true
x==z: true
x===y: true
x===z: false
The mentioned operators can be broadcasted. As a result we get arrays:
(1:1:3) .== (3:1:1) #comparing [1 2 3] with [3 2 1]. It's true only for 2nd elements
3element BitVector:
0
1
0
.![true, false] #notice the order of `.` and `!`
2element BitVector:
0
1
Conditional evaluations¶
Implementation of if/elseif/else
is very standard and similar to other languages:
if expr1
sth1
elseif expr2
sth2
else
sth3
end
if
 dosth1
ifexpr1
is trueelseif
 dosth2
ifexpr2
is true andexpr1
is falseelse
 dosth3
if bothexpr1
andexpr2
are false
Example below:
if 2!=2
println("asd")
elseif 3>4
println("3>4")
elseif 5==10
println("5==10")
else
println("nothing")
end
nothing
?:
ternary operator¶
There is a ternary operator ?:
for short conditional evaluations.
Its syntax is cond ? sth1 : sth2
. The result of this operation conducted on scalar is: do sth1
if cond
is true and sth2
otherwise.
x = 4
even_x = x%2==0 ? "x is even" : "x is odd"
"x is even"
Suppose we want to create the CRRA utlity function in Julia
. It is defined as follows:
We can use ?
to define this function:
u(cₜ, η) = η==1 ? log(cₜ) : (cₜ^(1. η)1.)/(1. η)
u (generic function with 1 method)
u(3,2)
0.6666666666666667
?:
can be nested, just like in an example below:
x = 4
x<5 ? (
x%2==0 ? println("x is smaller than 5 and is even") : #x<5 is true and x%2==0 is true
println("x is smaller than 5 and is odd") #x<5 is true and x%2==0 is false
) :
println("x is greater or equal to 5") #x<5 is false and x%2==0 is not evaluated
x is smaller than 5 and is even
We know that the CRRA function is well defined if \(\eta\geq 0.\) We can check this condition using nested ?
:
u(cₜ, η) = η≥0 ?
(η==1 ? log(cₜ) : (cₜ^(1. η)1. )/(1. η)) :
@error "η=$η is not allowed!"
u (generic function with 1 method)
u(3, 2)
0.6666666666666667
u(3, 1)
┌ Error: η=1 is not allowed!
└ @ Main In[13]:3
Elementwise ?:
¶
Note
Suppose that we want to perform a following mapping for \(x\in 1,2, \ldots, 10:\)
Such a task can be done relatively easily in other languages.
For instance in R
we get it by using ifelse
:
result < ifelse(x%%2==0, x^2, x^2 + 1) #this is `R` code. It will not work in `Julia`
We might be tempted to make elementwise comparisons using .?
.
x = collect( 1:10 );
result = ((x) .%2 .==0) .? (x).^2 .: (x).^2.+1
syntax: space before "." not allowed in "((x .% 2) .== 0) ." at In[16]:2
Stacktrace:
[1] toplevel scope
@ In[16]:2
[2] eval
@ ./boot.jl:360 [inlined]
[3] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
@ Base ./loading.jl:1094
As we can see, it will not work the way we would like.
A solution to this problem is to use map
function with an anonymous function:
map(arg > arg%2==0 ? arg^2 : arg^2+1 , x)
10element Vector{Int64}:
2
4
10
16
26
36
50
64
82
100
This works as intended.
Shortcircuit evaluations¶
Julia
exhibits lazy evaluation of formulas.
This means that operations are computed only if they are needed.
This property has some particular consequences for two operators, &&
and 
.
Laziness of Julia
together with necessary condition for true
value in &&
and sufficient condition for false
in 
can be used for conditional evaluations.
More precisely, the second (righthand side) argument of &&
is evaluated if and only if the first (lefthand side) argument is true.
Similarly, the second (righthand side) argument of 
is not valuated if if the first (lefthand side) argument is false.
As the second argument we can put some evaluations that we would like to conduct subject to the lefthand side argument. Simple illustrations below:
(2+2==4) && println("(2+2==4) It's true");
(2+2==4) It's true
(2+2==5) && println("(2+2==5) It's true"); # the latter is not executed as (2+2==5) is false
(2+2==4)  println("(2+2==4) It's false"); # the latter is not executed as (2+2==4) is true
(2+2==5)  println("(2+2==5) It's false");
It's false