Julia basics

This tutorial assumes you have Julia installed. Call julia from the command line, and you should get a prompt that looks like

julia>

This is the Julia REPL. The rest of these commands in this tutorial can be typed right into the REPL. Just hit enter afterwards. I have only written the input below - the output should be self-explanatory, but if you're getting errors, write to me to let me know.

Variables

Julia is an easy-going language. While objects have "types", it's pretty laid back about it.

Say we assign a variable a to be 3:

a = 3

Now you can use the function typeof to find what type of object a is:

typeof(a)

Great. But let's say we don't want a to be 3, we want it to be "CAKE":

a = "CAKE"

Julia is fine with that:

typeof(a)

Julia is "optionally" typed. Julia will try to use the type of an object when it can to optimize its performance, but will let you choose how explicit to be about type in your code - including barely thinking about it at all.

Arithmetic

Julia has all the operations you'd expect

1+2
1-2
1*2
1/2 # returns 0.5; use div(1,2) for integer division
1^2 # ^, not ** for exponentiation
1%2

It also has floats, irrational, and complex numbers

.5 # you don't need the 0
3. # makes it a float
π # to write this in your REPL, type \pi and then tab
im
4.+3im

This last one used a fun piece of syntactic sugar

x = 3
2x

Strings

Use double quotes (not single quotes) for strings

name = "Colloquium for Anteaters, Koalas, and Emus"

Use * to concatenate strings

full_name = "The " * name

Use $() to interpolate in strings

"$(full_name) is the best!"
"$full_name is the best!" # <-- if all you're interpolating is a variable, you can drop the parentheses
"$(3-2) is the loneliest number" # interpolated material doesn't have to be a variable, it can be arbitrary code; it also doesn't have to be a string

Groups of things

First off, Julia is 1-indexed!

a = [1,2,3,"CAKE"]
a[1]

Julia guesses the type of your array from its contents, and complains if you change your mind

b = [1,2,3]
b[1] = "CAKE"

This can easily be remedied by applying the type you want at the beginning of the array,

c = Any[1,2,3]
c[1] = "CAKE"

Arrays can include anything, including other arrays, but if you want to make a multidimensional array, there are other ways to do that:

d = [1 2 3; 4 5 6]
e = rand(2,3,4)

That last line was a function - we'll learn more about them soon. Indexing with multidimensional arrays is easy:

d[2,3]
e[1,end,4]
e[1,end-1,4]

Here, end signifies the last element of a given dimension. Julia has ranges

1:2
4:10:200 # every tenth number
0.0:0.01:1.0

You can use integer ranges to index arrays

d[1:2,1:2]
e[:,1:end-1,2:2:4]

Be careful! Array variables are pointers to the same object

x = y = []
y
push!(x,1) # add 1 to x; the ! indicates a function that changes one of its arguments
y

copy() is your friend

Doing arithmetic with arrays is easy.

a = [1 2 3; 4 5 6]
b = [7 8 9; 10 11 12]
a+b
a*b # a 2x3 matrix times a 2x3 matrix? no way
a*b' # b' is the complex conjugate of b

But what if I wanted element-wise multiplication? Just add a . to an operation or function and it broadcasts that function across an array. For example:

a.*b
a.^2

This is a powerful tool we will come back to.

Other types include immutable arrays called "tuples", written (1,2,3), and Dicts:

z = Dict(
"a" => 1.0,
"b" => [1,2,3]
)

Dicts can be nested.

Control flow

Loops are easy; use a range,

for x in 1:5
println(x) # print to standard output and add a "\n"
end

or an array

for x in [5,2,3]
println(x)
end

You can use = or (that's \in) in place of in Nesting loops is easy too:

for x in [5,2,3], y in 1:5
println(x," ",y)
end

Sometimes you want the output of a loop. Julia has list comprehensions:

[x^2 for x in 0:5:20]
[x^2 + y^2 for x in 0:5:20,y in [4,2,3]]
[n[1] for n in ["John","Lennon"]]

If statements are also simple,

cake = 3
if cake > 4
println("lotsa cake")
elseif cake <= 2
println("lil cake")
else
println("ok cake")
end

There's ternary statements

cake > 10 ? "wow" : "meh"

And you can use && for control flow

cake > 10 && "this gets called"
cake = 12
cake > 10 && "this gets called"

Functions

typeof, rand, and println were all functions - as were + and ^. You can write your own:

function initials(a)
join([s[1] for s in a])
end
initials(["John","Lennon"])

You could write this function as a oneliner,

oneliner(a) = join([s[1] for s in a])
oneliner(["John","Lennon"])

or as an anonymous function

anon = a -> join([s[1] for s in a])
anon(["John","Lennon"])

Right now, our function initials doesn't care about type:

initials(["John","Lennon"]) # takes the first letter in each word
initials([[1,2,3],[4,5,6]]) # takes the first number in each array

but it's annoying to write names as arrays. What if the function could tell when we passed it a string instead of an array, and when it did, split the string into an array of names?

function initials(st::String)
join([s[1] for s in split(st)])
end
initials("John Lennon")
initials(["John","Lennon"]) # the old function remains too!

Choosing which action ("method") to perform based on the types of the input is called "multiple dispatch". We can see both of the methods associated with our function initials using the following:

methods(initials)

Generally, Julia chooses the method that is the most specific to the type of your input.

Packages

A lot of functionality comes from packages that you explicitly include. A number of them come installed with Julia. So, if you want to use mean and var and other statistical functions, you have to include the package Statistics:

using Statistics
mean(rand(100))
var(rand(100))

To get a package not yet installed, use Pkg.add(). For example, one of the packages I often use is called PyCall, and lets you call Python from Julia. You then download it as follows:

Pkg.add("PyCall")

Another way to add packages is in the REPL by using ]

]
add PlotlyJS

That's all for now - check out the Julia homepage for more tutorials!