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 + b3
org-babel
https://github.com/shg/ob-julia-vterm.el to use :results output, Suppressor.jl needs to be installed in Julia environment
REPL
ansreturns previous result;activates shell mode?activates help mode, typefunctionto 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
x = 11
Constant
Constant variables can be defined with const
const x = 2Primitive Types
Booleans
true / false
truetrue
falsefalse
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 + 12 + 2im
Rational Numbers
1 // 3 + 1 // 32//3
Strings
Double quotes for strings:
"Damien"Damien
Characters
Single quotes (apostrophes) for single char:
'd'd
Numbers
1 + 12
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 " * nameMy 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").capturesUnion{Nothing, SubString{String}}["1337"]
match(r"value = (.*)", "value = 1337").captures |> first1337
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.originMontreal
route[:origin]Montreal
(; origin, destination) = route
originMontreal
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]
b2
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"
dictDict{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] |> length3
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"
end2 is larger than 1
For loop
for i in 1:5
println(i)
end1
2
3
4
5
Works on strings too:
for char in "Damien"
println(char)
endD
a
m
i
e
n
and Dicts:
for (key, value) in Dict("France" => "Paris", "Germany" => "Berlin", "Canada" => "Ottawa")
println(value)
endBerlin
Ottawa
Paris
Eachindex
eachindex(['a', 'b', 'c'])Base.OneTo(3)
While loop
i = 0
while i < 5
println(i)
i += 1
end0
1
2
3
4
Break / Continue
break stops the loop
i = 0
while i < 10
println(i)
i += 1
if i == 5
break
end
end0
1
2
3
4
continue stops this iteration
for i in 1:5
if i == 3
continue
end
println(i)
end1
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 |> sqrt7.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 DatesParsing
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")
endUndefVarError(:undefined_method)
this gets printed regardless
Type Annotations
Adding thing::Type ensure thing is of type Type
"Damien"::StringDamien
Typically done inside a function:
concat_string(x::String, y::String)::String = x * yconcat_string
concat_string("Hello, ", "World")Hello, World
Fails:
concat_string("Hello, ", 9)Files
readreadchompreaddlm
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 == 1Test 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/