Damien Gonot
Home Blog Notes About

Julia

Homepage / Notes / Computer Science / Programming Languages / Julia

Base

https://docs.julialang.org/en/v1/base/base/ Fast and computation oriented

Logging

Log: println() Pretty log: display() Log with colours: printstyled() https://docs.julialang.org/en/v1/base/io-network/#Base.printstyled

Importing

using HTTP to import packages though import HTTP works too

Keywords

... "splat" operator represents a sequence of arguments

add(xs...) = reduce(+, xs)

add(1, 2, 3)
6
add([1, 2, 3]...)
6

;

; is used to separate statements that are on the same line

a = 1; b = 2; a + b
3

org-babel

https://github.com/shg/ob-julia-vterm.el to use :results output, Suppressor.jl needs to be installed in Julia environment

REPL

Language Features

Variables

Convention: snake case (long_variable_name) is typically used

x = 1
1

Constant

Constant variables can be defined with const

const x = 2

Primitive Types

Booleans

true / false

true
true
false
false

Integers

Int or UInt for unsigned (positive integers only) Comes in Int8, Int16, Int32, Int64 and Int128 sizes Julia will default to the processor's size (32/64-Bit) by default if not specified

Floats (decimals)

Float16, Float32, Float64

Complex Numbers

n = 1 + 2im
n + 1
2 + 2im

Rational Numbers

1 // 3 + 1 // 3
2//3

Strings

Double quotes for strings:

"Damien"
Damien

Characters

Single quotes (apostrophes) for single char:

'd'
d

Numbers

1 + 1
2

Parsing

Parse integer from strings

parse(Int64, "1337")
1337

Parse float from strings

parse(Float64, "13.37")
13.37

Ranges

collect(1:10)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Min / Max

Min

min() returns the minimum from any number of arguments

min(2, 3)
2
min(2, 3, 4)
2

Or using the splat operator, to expand an array to the arguments:

min([2, 3, 4]...)
2

More efficient way and avoiding the splat operator using minimum():

minimum([2, 3, 4])
2
Max

Similar for max() and maximum():

max(2, 3, 4)
4
maximum([2, 3, 4])
4
Extrema

A useful function is extrema() that returns a tuple with the min and max

extrema([2, 3, 4])
(2, 4)
extrema(1:99)
(1, 99)

Strings

https://docs.julialang.org/en/v1/base/strings/ Double quotes are always used for strings, single quotes are used for chars

Concatenation

name = "Damien"
string("My name is ", name)
My name is Damien
name = "Damien"
"My name is " * name
My name is Damien

Interpolation

name = "Damien"
"My name is $name"
My name is Damien
"1 + 1 = $(1 + 1)"
1 + 1 = 2

Split

split("x,y,z", ",")
SubString{String}["x", "y", "z"]

Join

join(["x", "y", "z"], "\n")
x
y
z

Starts With

startswith("bonjour", "bon")
true

Ends With

endswith("bonjour", "soir")
false

Contains

contains("hello", "x")
false

Strip

Remove leading and trailing characters from str (by default whitespace characters)

strip("     hello")
hello

Can remove a specific character

strip("hello!", '!')
hello

Or a vector of characters

strip(": hello!", [':', ' ', '!'])
hello

Chomp

Removes trailing newline

chomp("hello\nworld\n")
hello
world

Regex Match

match(r"value = (.*)", "value = 1337")
RegexMatch("value = 1337", 1="1337")
match(r"value = (.*)", "value = 1337").captures
Union{Nothing, SubString{String}}["1337"]
match(r"value = (.*)", "value = 1337").captures |> first
1337

Find

Find First
findfirst("Julia", "I love Julia but Julia doesn't love me")
8:12
Find Last
findlast("Julia", "I love Julia but Julia doesn't love me")
18:22
Find Next
findnext("Julia", "I love Julia but Julia doesn't love me", 1)
8:12
findnext("Julia", "I love Julia but Julia doesn't love me", 9)
18:22
Find Prev
findprev("Julia", "I love Julia but Julia doesn't love me", 1)
nothing
findprev("Julia", "I love Julia but Julia doesn't love me", 17)
8:12

Replace

replace("hello NAME", "NAME" => "Damien")
hello Damien

Data Structures

Vector is a 1-dimensional array, Matrix a 2-dimensional array

Tuples

Immutable, ordered, fixed-length

(1, 2)
(1, 2)
t = (9, 10)
t[1]
9
Named Tuples
route = (origin = "Montreal", destination = "Toronto")
route.origin
Montreal
route[:origin]
Montreal
(; origin, destination) = route
origin
Montreal

Arrays

[1, 2, 3]
[1, 2, 3]
Matrix
[1 2 3; 4 5 6]
[1 2 3; 4 5 6]
Horizontal Concatenation
hcat([1, 2, 3], [4, 5, 6])
[1 4; 2 5; 3 6]
a1 = [1, 2, 3]
a2 = [4, 5, 6]
[a1 a2]
[1 4; 2 5; 3 6]
Push / Pop / Append
array = []

# pushing an element to an array
push!(array, "element")

# remove last element from array
pop!(array)

# appending another array to an array
append!(array, [1, 2, 3])
Any[1, 2, 3]
Length / Size
length([1, 2, 3])
3
size([1, 2, 3])
(3,)
size([1 2 3; 4 5 6])
(2, 3)
Zeros / Ones / Rand(n)

Fill an array with n zeros:

zeros(5)
[0.0, 0.0, 0.0, 0.0, 0.0]

Fill an array with n zeros with Type specified:

zeros(Int, 5)
[0, 0, 0, 0, 0]

For 2D/3D… arrays:

zeros(Int, 5, 2)
[0 0; 0 0; 0 0; 0 0; 0 0]

Same thing with ones:

ones(Int, 5)
[1, 1, 1, 1, 1]

And random numbers:

rand(5)
[0.20655599984205453, 0.764336425218688, 0.707929049283852, 0.5403245301033117, 0.5747141117006983]

Using standard Normal:

randn(5)
[1.2611015684267128, 0.5431280372799115, -1.0866220141038392, 0.5592503716247522, -0.19501274806221938]
Accessing Values
Single Element
xs = [5, 10, 15]
xs[1]
5
m = [5 10 15; 20 25 30]
m[2,2]
25
Range of Elements

Using end

xs = [5, 10, 15, 20, 25]
xs[3:end]
[15, 20, 25]

By column

m = [5 10 15; 20 25 30]
m[:,1]
[5, 20]

By row

m = [5 10 15; 20 25 30]
m[1,:]
[5, 10, 15]
Concatenation
vcat([1, 2], [3, 4])
[1, 2, 3, 4]
a1 = [1, 2]
a2 = [3, 4]
[a1; a2]
[1, 2, 3, 4]
Filter
filter(x -> x < 5, 1:10)
[1, 2, 3, 4]
List Comprehensions
[x^2 for x = 1:10]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
Resources

https://blog.lojic.com/2020/12/26/comprehensions-in-julia.html

End
['a', 'b', 'c'][end]
c
Sort
[3, 2, 1] |> sort
[1, 2, 3]
Sort by
sort([Dict("x" => 3, "y" => 'a'), Dict("x" => 2, "y" => 'b'), Dict("x" => 1, "y" => 'c')], by = i -> i["x"])
Dict{String, Any}[Dict("x" => 1, "y" => 'c'), Dict("x" => 2, "y" => 'b'), Dict("x" => 3, "y" => 'a')]
Reverse sort
sort([1, 2, 3], rev = true)
[3, 2, 1]
Partial sort
partialsortperm([1, 2, 3, 4, 5, 6], 1:3, rev = true)
3-element view(::Vector{Int64}, 1:3) with eltype Int64:
 6
 5
 4
Destructuring
a, b, c = [1, 2, 3]
b
2
a, b... = [1, 2, 3]
b
[2, 3]
Delete Element From Array
deleteat!([1, 2, 3], 1)
[2, 3]
Matrix to Vector
matrix = [1 2 3; 4 5 6]
matrix |> vec
[1, 4, 2, 5, 3, 6]
Vector to Matrix
vector = [1, 2, 3, 4]
vector |> permutedims
[1 2 3 4]
Transpose Matrix
matrix = [1 3; 2 4]
matrix |> transpose
[1 2; 3 4]

' seems to be a shorthand for transpose:

matrix = [1 3; 2 4]
matrix'
[1 2; 3 4]
Circshift
circshift(1:9, 1)
[9, 1, 2, 3, 4, 5, 6, 7, 8]
circshift(1:9, -1)
[2, 3, 4, 5, 6, 7, 8, 9, 1]

Sets

No duplicate elements

Set([1, 2, 3, 3])
Set([2, 3, 1])

Dict

dict = Dict("key" => "value")

dict["key"]
value
dict = Dict("key" => "value")

dict["another_key"] = "another_value"
dict
Dict{String, String} with 2 entries:
  "key"         => "value"
  "another_key" => "another_value"

Functions

https://docs.julialang.org/en/v1/manual/functions/

Basic syntax:

function f(x, y)
    x + y
end

f(2, 3)
5

More terse syntax:

f(x, y) = x + y

f(2, 3)
5

Anonymous Functions

x -> x*2
#1

Named Arguments

function f(x; coef = 2)
    x * coef
end

f(4)
8
f(4, coef = 4)
16

Pipe Operator

[1, 2, 3] |> length
3

Vectorized Functions f.(x)

https://docs.julialang.org/en/v1/manual/functions/#man-vectorized Applies function to all elements of vector, similar to map()

f(x) = x*2

f.([1, 2, 3])
[2, 4, 6]

Even works on the |> pipe operator!

["list", "of", "string"] .|> [uppercase, reverse, length]
Any["LIST", "fo", 6]

Other

Do-Block Syntax for Function Arguments

Passing functions as arguments to other functions is a powerful technique, but the syntax for it is not always convenient. Such calls are especially awkward to write when the function argument requires multiple lines. As an example, consider calling =[map](https://docs.julialang.org/en/v1/base/collections/#Base.map)= on a function with several cases:

map(x->if x < 0 && iseven(x)
           return 0
       elseif x == 0
           return 1
       else
           return x
       end,
    [-2, -1, 0, 1, 2])
[0, -1, 1, 1, 2]

Julia provides a reserved word =do= for rewriting this code more clearly:

map([-2, -1, 0, 1, 2]) do x
    if x < 0 && iseven(x)
        return 0
    elseif x == 0
        return 1
    else
        return x
    end
end
[0, -1, 1, 1, 2]

https://docs.julialang.org/en/v1/manual/functions/#Function-composition-and-piping

Control Flow

If statement

if 1 > 2
    "1 is larger than 2"
else
    "2 is larger than 1"
end
2 is larger than 1

For loop

for i in 1:5
    println(i)
end
1
2
3
4
5

Works on strings too:

for char in "Damien"
    println(char)
end
D
a
m
i
e
n

and Dicts:

for (key, value) in Dict("France" => "Paris", "Germany" => "Berlin", "Canada" => "Ottawa")
    println(value)
end
Berlin
Ottawa
Paris

Eachindex

eachindex(['a', 'b', 'c'])
Base.OneTo(3)

While loop

i = 0
while i < 5
    println(i)
    i += 1
end
0
1
2
3
4

Break / Continue

break stops the loop

i = 0
while i < 10
    println(i)
    i += 1
    if i == 5
        break
    end
end
0
1
2
3
4

continue stops this iteration

for i in 1:5
    if i == 3
        continue
    end
    println(i)
end
1
2
4
5

Symbols

(\in) / d (\notin)

1  [1, 2, 3]
true
1  [1, 2, 3]
false

(\subseteq) / (\nsubseteq) / (\subsetneq)

[1, 2]  [1, 2, 3]
true
[1, 2]  [1, 2, 3]
false
[1, 2]  [1, 2]
true

"True" subset, can't be equal

[1, 2]  [1, 2]
false

Pipe |> vs Composition operator

1:10 |> sum |> sqrt
7.416198487095663
(sqrt  sum)(1:10)
7.416198487095663

Cartesian Indices

https://julialang.org/blog/2016/02/iteration/

CartesianIndex(1, 1)
CartesianIndex(1, 1)
CartesianIndex(1, 1):CartesianIndex(3, 3)
CartesianIndex{2}[CartesianIndex(1, 1) CartesianIndex(1, 2) CartesianIndex(1, 3); CartesianIndex(2, 1) CartesianIndex(2, 2) CartesianIndex(2, 3); CartesianIndex(3, 1) CartesianIndex(3, 2) CartesianIndex(3, 3)]

Packages

using Package will make all functions defined "exportable" by Package available to use directly

using Statistics

mean([1,2,3])
2.0

import Package means you have to type Package.function() to access each function

import Statistics

Statistics.mean([1,2,3])
2.0

Plots

http://docs.juliaplots.org/latest/

using Plots
x = 1:20; y = rand(20)
plot(x, y)
savefig("julia-plots/plot.png")

Unicode Plots

using UnicodePlots
lineplot(sin, 1:.5:20, width = 50)
        ┌──────────────────────────────────────────────────┐
      1 │⠀⠀⢀⠎⠢⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⠊⢇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡜⠉⢆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠│ sin(x)
        │⠀⠀⠈⠀⠀⢣⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠇⠀⠈⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠸⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡜│
        │⠀⠀⠀⠀⠀⠘⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡼⠀⠀⠀⢱⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⢣⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠃│
        │⠀⠀⠀⠀⠀⠀⢇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠈⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⠁⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡸⠀│
        │⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⢳⠀⠀⠀⠀⠀⠀⠀⠀⠀⡞⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀│
        │⠀⠀⠀⠀⠀⠀⠈⡆⠀⠀⠀⠀⠀⠀⠀⠀⡎⠀⠀⠀⠀⠀⠸⡀⠀⠀⠀⠀⠀⠀⠀⢀⠇⠀⠀⠀⠀⠀⢱⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀│
        │⠀⠀⠀⠀⠀⠀⠀⢳⠀⠀⠀⠀⠀⠀⠀⢀⠇⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠘⡄⠀⠀⠀⠀⠀⠀⠀⡜⠀⠀│
f(x)    │⠤⠤⠤⠤⠤⠤⠤⠼⡤⠤⠤⠤⠤⠤⠤⢼⠤⠤⠤⠤⠤⠤⠤⢵⠤⠤⠤⠤⠤⠤⠤⡮⠤⠤⠤⠤⠤⠤⠤⡧⠤⠤⠤⠤⠤⠤⠤⡧⠤⠤│
        │⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⡎⠀⠀⠀⠀⠀⠀⠀⠸⡀⠀⠀⠀⠀⠀⢀⠇⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀│
        │⠀⠀⠀⠀⠀⠀⠀⠀⢱⠀⠀⠀⠀⠀⢀⠇⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠘⡄⠀⠀⠀⠀⠀⡜⠀⠀⠀│
        │⠀⠀⠀⠀⠀⠀⠀⠀⠸⡀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⢱⠀⠀⠀⠀⠀⡎⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⢀⠇⠀⠀⠀│
        │⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⡄⠀⠀⠀⢠⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⢸⠀⠀⠀⠀│
        │⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⢰⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢇⠀⠀⠀⡜⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⡆⠀⠀⠀⡇⠀⠀⠀⠀│
        │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢇⠀⢀⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⡀⠀⢠⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢱⠀⠀⡰⠁⠀⠀⠀⠀│
     -1 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣄⠼⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠱⣠⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠧⣠⠃⠀⠀⠀⠀⠀│
        └──────────────────────────────────────────────────┘
        ⠀0⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀20⠀
        ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀x⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

Dates

using Dates

Parsing

Date("2021-01-01")
2021-01-01

Calling C

ccall(:clock, Int32, ())
5291220
ccall(:getenv, Cstring, (Cstring,), "SHELL") |> unsafe_string
/bin/zsh

Try / Catch

try
    undefined_method()
catch e
    println(e)
finally
    println("this gets printed regardless")
end
UndefVarError(:undefined_method)
this gets printed regardless

Type Annotations

Adding thing::Type ensure thing is of type Type

"Damien"::String
Damien

Typically done inside a function:

concat_string(x::String, y::String)::String = x * y
concat_string
concat_string("Hello, ", "World")
Hello, World

Fails:

concat_string("Hello, ", 9)

Files

Macros

@code_llvm

Can be used to view the actual LLVM code generated by the Julia compiler

@code_llvm 1 + 1
;  @ int.jl:87 within `+`
define i64 @"julia_+_955"(i64 signext %0, i64 signext %1) #0 {
top:
  %2 = add i64 %1, %0
  ret i64 %2
}

@test

using Test

@test 1 == 1
Test Passed
  Expression: 1 == 1
   Evaluated: 1 == 1

Tests can be wrapped in a @testset

Packages

JSON.jl

https://github.com/JuliaIO/JSON.jl

HTTP.jl

https://github.com/JuliaWeb/HTTP.jl

CSV.jl

https://github.com/JuliaData/CSV.jl

DataFrames.jl

https://github.com/JuliaData/DataFrames.jl

Optics (HN Discussion)

https://news.ycombinator.com/item?id=26538150

MLJ.jl (Machine Learning)

https://github.com/alan-turing-institute/MLJ.jl

FinancialToolbox.jl

https://github.com/rcalxrc08/FinancialToolbox.jl

Pluto.jl (notebook)

https://github.com/fonsp/Pluto.jl

CUDA.jl (GPU programming)

https://github.com/JuliaGPU/CUDA.jl

Flux.jl (Machine Learning)

https://github.com/FluxML/Flux.jl

Documenter.jl

https://github.com/JuliaDocs/Documenter.jl

Distributions.jl

https://github.com/JuliaStats/Distributions.jl

Makie (Data Visualization)

https://makie.org/

Genie (MVC web framework)

https://genieframework.com/

Climate

https://github.com/JuliaClimate

JuliaDB

https://github.com/JuliaData/JuliaDB.jl

Revise.jl (Automatically update function definitions in a running Julia session)

https://github.com/timholy/Revise.jl

SimpleChains.jl

https://github.com/PumasAI/SimpleChains.jl

Weave.jl - Scientific Reports Using Julia

https://weavejl.mpastell.com/stable/#Weave.jl-Scientific-Reports-Using-Julia

Oxygen.jl (micro web framework)

https://github.com/ndortega/Oxygen.jl

Term.jl

https://github.com/FedeClaudi/Term.jl

Metal.jl (GPU programming on Apple M-series chip)

https://github.com/JuliaGPU/Metal.jl

Resources

Learn Julia in Y minutes

https://learnxinyminutes.com/docs/julia/

Think Julia: How to Think Like a Computer Scientist

https://benlauwens.github.io/ThinkJulia.jl/latest/book.html

How to Build a Deep Neural Network from Scratch with Julia

https://medium.datadriveninvestor.com/how-to-build-a-deep-neural-network-from-scratch-with-julia-862116a194c

Julia Bootcamp 2022: Julia Basics

https://www.youtube.com/watch?v=BnTYMOOPEzw

Guide for writing shell scripts in Julia

https://github.com/ninjaaron/administrative-scripting-with-julia

Romeo and Julia, where Romeo is Basic Statistics

https://b-lukaszuk.github.io/RJ_BS_eng/