Functions and Control Flow#

Here are the key constructs for defining functions and using control flow in Julia:

Functions#

Functions are defined in a very straightforward way using the function ... end syntax:

function mymult(a, b)
    a * b
end
mymult (generic function with 1 method)
mymult(3, 7)
21
mymult(6+3im, -9-7im)
-33 - 69im
mymult("gold", "leader")
"goldleader"

Notice our function is working for any types (we used Int64, Complex and String) - this stays fast in Julia because of multiple dispatch that we discuss later.

Function Documentation#

A string directly before a function definition is interpreted by Julia as “documentation” for the function. The ? symbol turns the REPL into help mode. ?foo will display the doc strings for the given function, amongst other things (? also provides help for expressions and other constructs). All of the Julia standard library functions have docstrings. To return from the REPL help mode, press backspace.

"""
    adder(a, b)

This function adds `a` and `b`
"""
function adder(a, b)
    a+b
end
adder
?adder
search: 
adder addenv readdir rad2deg stderr Base.Order
adder(a, b)

This function adds a and b

Compact Function Definition#

If we can write a function on one line then Julia allows us to not bother with function ... end:

mypow(a, b) = a^b
mypow (generic function with 1 method)
mypow(2, 8)
256
mypow("old ", 4)
"old old old old "

Anonymous Functions (lambdas)#

Anonymous functions in Julia are written using ->, like this:

x -> x>2
#1 (generic function with 1 method)

Which is not too useful like that, but comes into its own when used with higher-order functions like map:

map(x -> x>2, 1:5)
5-element Vector{Bool}:
 0
 0
 1
 1
 1

if then else#

Conditional execution is very easily achieved with an if block in Julia:

function gtlteq(a, b)
    if a > b
        println("$a is greater than $b")
    elseif a < b
        println("$a is less than $b")
    elseif a == b
        println("$a is equal to $b")
    else
        println("I have no idea about $a and $(b)!")
    end
end
gtlteq (generic function with 1 method)
gtlteq(2.3, -9)
2.3 is greater than -9
gtlteq("apples", "oranges")
apples is less than oranges

Bonus question: Can you think of inputs to gtlteq that result in the else-branch?

Short Circuit and Ternary Operators#

Short Circuit#

The operators && and || can be used for conditional execution.

  • a && b - evaluate b only if a (i.e., a is true)

  • a || b - evaluate b only if !a (i.e., a is false)

true && "it's true"
"it's true"
false || "it's false"
"it's false"
false && "it's true"
false

Ternary#

A special type of “quick” conditional is the ternary operator, familiar from C:

2 > 4 ? "it's bigger" : "it's smaller"
"it's smaller"

The syntax is a ? b : c meaning if a, evaluate b, else evaluate c.

Since every if ... else ... end expression in julia can also return things, ternary operators are semantically equivalent to if/else.

Loops#

For loops#

For loops are always over an iterator in Julia, allowing a loop over any object that has a beginning and an end:

for number in 1:4
    println("I am at number $number")
end
I am at number 1
I am at number 2
I am at number 3
I am at number 4

enumerate and zip also exist:

for (index, string) in enumerate(["I", "think", "therefore", "I", "am"])
    println("Word $index is $string")
end
Word 1 is I
Word 2 is think
Word 3 is therefore
Word 4 is I
Word 5 is am
for (hip, hop, hup)  zip(1:3, 10:12, ["yes", "no", "maybe"])
    println("The $hip and $hop say $hup")
end
The 1 and 10 say yes
The 2 and 11 say no
The 3 and 12 say maybe

Note that Julia is happy with for z in ... and for z ... (type \in to get a ; note that = can be used, so you might see this, but it is frowned upon!)

for will also naturally form the outer product of a comma-separated set of iterators provided to them, without the need for “nesting” of loops. (This also applies to the for in comprehensions, so you can easily make multi-dimensional arrays with a chain of iterators if you want all the combinations that result as elements.)

for i in 1:3, j in 1:4  #like for i=1:3 ; for j=1:4 ...
    println("The product of $i and $j is $(i*j)")
end
The product of 1 and 1 is 1
The product of 1 and 2 is 2
The product of 1 and 3 is 3
The product of 1 and 4 is 4
The product of 2 and 1 is 2
The product of 2 and 2 is 4
The product of 2 and 3 is 6
The product of 2 and 4 is 8
The product of 3 and 1 is 3
The product of 3 and 2 is 6
The product of 3 and 3 is 9
The product of 3 and 4 is 12

while loops#

By now it is going to be no surprise to you how Julia constructs a while loop:

countdown = 10
while countdown > 0
    println(countdown, "...")
    countdown -= 1
end
println("blast off!")
10...
9...
8...
7...
6...
5...
4...
3...
2...
1...
blast off!

Note that a do-while loop does not exist.