Why Julia?
Contents
![julia-logo](_images/julia_logo.png)
Why Julia?¶
Fast
Dynamic, but… optionally typed
Composable (mulitple dispatch)
General Purpose
Open Source
Amazing Packages (e.g. DifferentialEquations.jl, Flux.jl)
Growing community (Slack Workspace)
How fast?¶
![benchmarks](_images/benchmarks.png)
Multiple Dispatch¶
my_add(x::Int, y::Int) = x + y
my_add(x::Float64, y::Float64) = x + y
my_add (generic function with 2 methods)
my_add(1, 2)
3
my_add(1.0, 2)
MethodError: no method matching my_add(::Float64, ::Int64)
Closest candidates are:
my_add(::Int64, ::Int64) at In[1]:1
my_add(::Float64, ::Float64) at In[1]:2
Stacktrace:
[1] top-level scope
@ In[3]:1
[2] eval
@ ./boot.jl:373 [inlined]
[3] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
@ Base ./loading.jl:1196
my_add(x::String, y::String) = "$(x) $(y)"
my_add (generic function with 3 methods)
my_add("Hello", "World!")
"Hello World!"
import Base.+
+(x::String, y::String) = my_add(x, y)
+ (generic function with 209 methods)
"Hello" + "World!"
"Hello World!"
struct Point
x::Float64
y::Float64
end
my_add(A::Point, B::Point) = Point(A.x + B.x, A.y + B.y)
my_add (generic function with 4 methods)
A = Point(1.0, 2.0)
B = Point(1.0, 2.0)
my_add(A,B)
Point(2.0, 4.0)
Generic programming¶
using Measurements
x = 5.23 ± 0.14
y = 45.77 ± 0.1
x + y
\[51.0 \pm 0.17\]
Simple pendulum¶
\[
\ddot{\theta} = \frac{g}{L} \theta
\]
using DifferentialEquations, Measurements, Plots
g = 9.79 ± 0.02; # Gravitational constants
L = 1.00 ± 0.01; # Length of the pendulum
#Initial Conditions
u₀ = [0 ± 0, π / 60 ± 0.01] # Initial speed and initial angle
tspan = (0.0, 6.3)
#Define the problem
function simplependulum(du,u,p,t)
θ = u[1]
dθ = u[2]
du[1] = dθ
du[2] = -(g/L)*θ
end
#Pass to solvers
prob = ODEProblem(simplependulum, u₀, tspan)
sol = solve(prob, Tsit5(), reltol = 1e-6)
# Analytic solution
u = u₀[2] .* cos.(sqrt(g / L) .* sol.t)
plot(sol.t, getindex.(sol.u, 2), label = "Numerical")
plot!(sol.t, u, label = "Analytic")
InterruptException:
Stacktrace:
[1] optimal_ticks_and_labels(ticks::Nothing, alims::Tuple{Float64, Float64}, scale::Symbol, formatter::Symbol)
@ Plots ~/.julia/packages/Plots/cPJQu/src/axes.jl:197
[2] get_ticks(::Symbol, ::Vector{Float64}, ::Vector{Any}, ::Tuple{Float64, Float64}, ::Vararg{Any})
@ Plots ~/.julia/packages/Plots/cPJQu/src/axes.jl:320
[3] get_ticks(sp::Plots.Subplot{Plots.GRBackend}, axis::Plots.Axis; update::Bool)
@ Plots ~/.julia/packages/Plots/cPJQu/src/axes.jl:241
[4] get_ticks
@ ~/.julia/packages/Plots/cPJQu/src/axes.jl:224 [inlined]
[5] _update_min_padding!(sp::Plots.Subplot{Plots.GRBackend})
@ Plots ~/.julia/packages/Plots/cPJQu/src/backends/gr.jl:888
[6] iterate
@ ./generator.jl:47 [inlined]
[7] _collect(c::Matrix{AbstractLayout}, itr::Base.Generator{Matrix{AbstractLayout}, typeof(Plots._update_min_padding!)}, #unused#::Base.EltypeUnknown, isz::Base.HasShape{2})
@ Base ./array.jl:744
[8] collect_similar
@ ./array.jl:653 [inlined]
[9] map
@ ./abstractarray.jl:2849 [inlined]
[10] _update_min_padding!(layout::Plots.GridLayout)
@ Plots ~/.julia/packages/Plots/cPJQu/src/layouts.jl:290
[11] prepare_output(plt::Plots.Plot{Plots.GRBackend})
@ Plots ~/.julia/packages/Plots/cPJQu/src/plot.jl:224
[12] show(io::IOBuffer, m::MIME{Symbol("image/svg+xml")}, plt::Plots.Plot{Plots.GRBackend})
@ Plots ~/.julia/packages/Plots/cPJQu/src/output.jl:204
[13] sprint(::Function, ::MIME{Symbol("image/svg+xml")}, ::Vararg{Any}; context::Nothing, sizehint::Int64)
@ Base ./strings/io.jl:114
[14] sprint
@ ./strings/io.jl:108 [inlined]
[15] _ijulia_display_dict(plt::Plots.Plot{Plots.GRBackend})
@ Plots ~/.julia/packages/Plots/cPJQu/src/ijulia.jl:47
[16] display_dict(plt::Plots.Plot{Plots.GRBackend})
@ Plots ~/.julia/packages/Plots/cPJQu/src/init.jl:92
[17] #invokelatest#2
@ ./essentials.jl:716 [inlined]
[18] invokelatest
@ ./essentials.jl:714 [inlined]
[19] execute_request(socket::ZMQ.Socket, msg::IJulia.Msg)
@ IJulia ~/.julia/packages/IJulia/e8kqU/src/execute_request.jl:112
[20] #invokelatest#2
@ ./essentials.jl:716 [inlined]
[21] invokelatest
@ ./essentials.jl:714 [inlined]
[22] eventloop(socket::ZMQ.Socket)
@ IJulia ~/.julia/packages/IJulia/e8kqU/src/eventloop.jl:8
[23] (::IJulia.var"#15#18")()
@ IJulia ./task.jl:423