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
= 1; b = 2; a + b a
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
ans
returns previous result;
activates shell mode?
activates help mode, typefunction
to pull up docstring of function, type"function"
for search]
activates Package mode- use an
_
to separate digits (example:1_000
)
Language Features
Variables
Convention: snake case (long_variable_name
) is typically used
= 1 x
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
= 1 + 2im
n + 1 n
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
= "Damien"
name string("My name is ", name)
My name is Damien
= "Damien"
name "My name is " * name
My name is Damien
Interpolation
= "Damien"
name "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)
= (9, 10)
t 1] t[
9
Named Tuples
= (origin = "Montreal", destination = "Toronto")
route route.origin
Montreal
:origin] route[
Montreal
= route
(; origin, destination) 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]
= [1, 2, 3]
a1 = [4, 5, 6]
a2 [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
= [5, 10, 15]
xs 1] xs[
5
= [5 10 15; 20 25 30]
m 2,2] m[
25
Range of Elements
Using end
= [5, 10, 15, 20, 25]
xs 3:end] xs[
[15, 20, 25]
By column
= [5 10 15; 20 25 30]
m :,1] m[
[5, 20]
By row
= [5 10 15; 20 25 30]
m 1,:] m[
[5, 10, 15]
Concatenation
vcat([1, 2], [3, 4])
[1, 2, 3, 4]
= [1, 2]
a1 = [3, 4]
a2 [a1; a2]
[1, 2, 3, 4]
Filter
filter(x -> x < 5, 1:10)
[1, 2, 3, 4]
List Comprehensions
^2 for x = 1:10] [x
[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
= [1, 2, 3]
a, b, c b
2
... = [1, 2, 3]
a, b b
[2, 3]
Delete Element From Array
deleteat!([1, 2, 3], 1)
[2, 3]
Matrix to Vector
= [1 2 3; 4 5 6]
matrix |> vec matrix
[1, 4, 2, 5, 3, 6]
Vector to Matrix
= [1, 2, 3, 4]
vector |> permutedims vector
[1 2 3 4]
Transpose Matrix
= [1 3; 2 4]
matrix |> transpose matrix
[1 2; 3 4]
'
seems to be a shorthand for transpose:
= [1 3; 2 4]
matrix ' 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("key" => "value")
dict
"key"] dict[
value
= Dict("key" => "value")
dict
"another_key"] = "another_value"
dict[ 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)
+ y
x end
f(2, 3)
5
More terse syntax:
f(x, y) = x + y
f(2, 3)
5
Anonymous Functions
-> x*2 x
#1
Named Arguments
function f(x; coef = 2)
* coef
x 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
= 0
i while i < 5
println(i)
+= 1
i end
0
1
2
3
4
Break / Continue
break
stops the loop
= 0
i while i < 10
println(i)
+= 1
i 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
∘ sum)(1:10) (sqrt
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
= 1:20; y = rand(20)
x 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
read
readchomp
readdlm
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)
Genie (MVC web framework)
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
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/