Try   HackMD

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Credit of this fantastic figure to Matthijs Cox's blogs.


My goal with this documents is to hopefully convey to people using languages like MATLAB, Python and R with no background in software development or computer science, the strengths and unique elements of the Julia programming language.

While a lot of the things presented below can be done in other languages, they cannot be done as easily as in Julia

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
.

Meaning that, I hope that more people from the left distribution (scientist/engineers) come to the center (Julia) of the figure above!!

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Right now, it is not very well organized and I still need to include some topics. Feel free to contribute

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
.

TODO:

  • Organize information coherently
  • Add difference between a function and a method
  • Reproducibility: Project.toml, Manifest.toml, Pluto.jl
  • Examples in which the fastest way of doing something is in Julia (DiffEq, Tables/Data, etc)
  • Examples of type piracy
  • JULIA IS A COMPILED LANGUAGE (but interactive, REPL)
  • ?? help needed - fell free to add stuff

Learning Julia

struct Dual{T<:Number} <: Number
    x::T
    d::T
end
struct GNum{T} where T<:Real
  μ::T
  σ::T
end

Showcasing Julia

  • Pluto.jl:
  • KernelAbstractions.jl -> CUDA.jl, AMDGPU.jl, Metal.jl, oneAPI.jl
  • Enzyme.jl
  • Plots (multiple backends):
    • Makie.jl: GPU plotting
    • PyPlot.jl
    • PlotlyJS.jl
  • JuMP.jl: Modeling language for Mathematical Optimization (linear, mixed-integer, conic, semidefinite, nonlinear)
  • Optimization.jl
  • Convex.jl: Stanford
  • DifferentialEquations.jl
  • Unitful.jl: adds units to type, zero overhead
  • Flux.jl: Deep Learning
  • LinearOperators.jl: https://jso.dev/tutorials/introduction-to-linear-operators/

Benchmarks

Julia is one of the most cost-effective languages in terms of the amount of necessary code to achieve high-performance. It has been shown many times that Julia can achieve C/C++ levels of performance with a lot less effort.

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

The Unreasonable Effectiveness of Multiple Dispatch

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

  • There's something unusual about the Julia's ecosystem
    • there's really large amount of code sharing and code reuse

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Generic differential equation solver -> Uncertainty measurements -> Uncertainty propagates through DiffEq solver (solution with uncertainty) -> plotting that solution shows error bars

This isn't entirely surprising, multiple dispatch is good at expressing generic algorithms.

  • Generic algorithms apply to different types
  • Common types shared by very different packages

How can I explain multiple dispatch and code re-usability in practice?

Square root and dual numbers

function mysqrt(a) # <--- My code
	x = a
	for k in 1:100
		x = 0.5 * (x + a / x)
	end
	return x
end

What if I want to compute its derivative?

f(x+δ)=f(x)+δf(x)
Let's implement a custom type for this

struct Dual{T} # Parametric type
	x::T
	δ::T
end
# Extending a function coming from another package (Base) 
Base.:*(m, a::Dual) = Dual(m * a.x, m * a.δ)
Base.:+(a::Dual, b::Dual) = Dual(a.x + b.x, a.δ + b.δ)
Base.:/(a::Dual, b::Dual) = Dual(a.x / b.x, (b.x * a.δ - a.x * b.δ) / b.x^2)

https://juliaepfl.github.io/Website/notebooks/intro-2024.html

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

  • No dispatch: C, one code does exactly one thing f(x₁, x₂, ...)
  • Single dispatch: OOP x₁.f(x₂, ...) (depending on the object
    x1
    the function
    f
    is different)
  • Multiple dispatch: f(x₁, x₂, ...) depends on all the combinations of variables

https://scientificcoder.com/the-art-of-multiple-dispatch

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

How to write generic code?

Remove all types from functions! Only specify the type for dispatch. The types go in the structs.

Generic code

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

It works, but we can do better!

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Common Types

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Inheriting from RGB is ugly, I need to rename the object, and if someone defines a method for RGB, now I need to create a wrapper for MyRGB

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

You can give up dispatch (no generic code), or just copy paste code into your code (no code reuse)

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

You can define methods outside of the type

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

The expression problem

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Traits in RUST

My impression was that, while rust functions don’t have multiple dispatch, generic rust traits can have multiple dispatch, which lets you accomplish pretty much the same thing (though it’s more verbose). - Jasha10 Julia Discourse

I think one problem with multipledispatch comparing to a trait system is that the developer needs to know and fully understand the detail of a function in order to let that function use some optimized operation for calculation. E.g. in the "inner" example, one needs to read the code of the function "inner" then can he know the function "inner" uses "" (multiplication). After that, he can write a specialized "" for the "OneHotVector". This may be obvious for "inner" but sooner it becomes not obvious for other complicated functions. - @weiyuanwu9044 YouTube comments

Why Multiple Dispatch was not used before? Trade-off with performance, In Julia this is not a problem

Code reuse

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

"I see this (telling people to reuse code) like us trying to get people to eat helthy this is something that is good for you in the long run" - Jeff Bezanson

Programmers will reliably do two things:

  • what is easy
  • what runs fast
    In other words: people want to eat junk food.

Have we made Cheetos that are good for you?

broadcast is the same as map for one argument, but it repeats inputs for more arguments.

Type piracy

Type piracy

You need to own either the function or the type of one of the arguments f(arg1, arg2, ...) to add a method to a function.

Science and wasted efforts

In science, most programming languages have used this approach of OOP. For example Python. The main issue is, that if you want to solve a new problem, you need to rewrite the whole algorithm for your problem:

  • We are so used to do this, that we don't question it
  • So many resources have been lost in this
  • Wan't to do Machine Learning? rewrite your code in PyTorch, JAX or TensorFlow
    • TorchNUFFT
    • etc

Julia should be slow

  • All type annotations are optional, let the compiler do the magic
  • Multiple dispatch: specialised on concrete types
  • Compile time: converting code to machine code
  • Run time: when this machine code is actually executed

Julia's compiler

JuliaCon 2024 - Valentin Churavy
JuliaSourcetoMachineCode

JuliaMacrosIntrospectionCode

Performance pitfalls

Engineering Julia for Speed | Lionel Zoubritzky | JuliaCon 2018

JuliaComplierPerformance

Type stability: We can move the cost of type inference from run time to compile time (devirtualization). This is one of the most important aspects of Julia's performance.

JuliaInlining
JuliaInlining2
JuliaInlining3
JuliaUnboxing

The vector can be stored in an unboxed fashion if all types are concrete. Specifying types in methods are good for dispatch and overloading (someone can define a method of that function of their custom type)
JuliaUnboxing2
JuliaLLVMCodeNative

LLVM 27k https://github.com/llvm/llvm-project
CPython 61k https://github.com/python/cpython
Julia 45k https://github.com/JuliaLang/julia

Code:

function add(a, b)
   return a + b
end

Typed code (Typed IR):

julia> @code_typed add(1,1)
CodeInfo(
1 ─ %1 = Base.add_int(a, b):: Int64
└──      return %1
) => Int64

LLVM IR (C++, Rust, Go, etc.)

julia> @code_llvm add(1,1)
;  @ REPL[15]:1 within `add`
define i64 @julia_add_428(i64 signext %0, i64 signext %1) #0 {
top:
;  @ REPL[15]:2 within `add`
; ┌ @ int.jl:87 within `+`
   %2 = add i64 %1, %0
; └
  ret i64 %2
}

CPU/GPU native code (assembly, not really useful to look at):

julia> @code_native add(1, 1)
	.text
	.file	"add"
	.globl	julia_add_451                   # -- Begin function julia_add_451
	.p2align	4, 0x90
	.type	julia_add_451,@function
julia_add_451:                          # @julia_add_451
; ┌ @ REPL[15]:1 within `add` # %bb.0:                                # %top
	push rbp
	mov	rbp, rsp
; │ @ REPL[15]:2 within `add`
; │┌ @ int.jl:87 within `+` lea	rax, [rdi + rsi]
; │└ pop rbp ret .Lfunc_end0: .size	julia_add_451, .Lfunc_end0-julia_add_451
; └
     # -- End function
	.section	".note.GNU-stack","",@progbits

Static analysis

In computer science, static program analysis (also known as static analysis or static simulation) is the analysis of computer programs performed without executing them, in contrast with dynamic program analysis, which is performed on programs during their execution in the integrated environment.

Comparison with Python

JuliaVsPython

You can do the same in Python - Anon

Yes, but not as easily

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
. In Julia you have direct acess to the internals, you can even check how Julia Base does something as it si written in Julia.

Julia coming from MATLAB

But in MATLAB I do it like this - Anon

Sometimes people do not realize that MATLAB is sometimes the only programming language doing something in a way, it is important to enter this learning journey with an open mind

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
.

MATLAB |> Julia JuliaCon2024: https://pretalx.com/media/juliacon2024/submissions/NCVSZ3/resources/MATLAB2Julia_fyD0c1f.pdf

  • Curiosity is key: Tools and languages evolve, never stop asking what's new
  • Respect language diversity: Learning Julia can solidify some concepts
  • Listen before prescribing: "Julia is fast" only matters if the current approach is perceived as slow
  • Don't ask how can I, ask what is the right way to: To really get good at a new language, take your time to loose old bad habits
  • Learning is an investment: Make your peace with being less productive for a while

EmbracingChange

There is a lot of challenges to change, which are not objective. Transition from Python 2 to 3 took almost 15 years.

  • IMPORTANT FOCUS TO: lack of SKILLS, and INCENTIVES
  • Older people built their whole careers using MATLAB, why change?
  • If we change it, suddenly their expertise goes away best approach is map the current methods to the new language.
  • How do we know is good? tell people it will not be compatible, developers can opt-out of it.

Roadblocks

  • Rangest = 0:0.1:2pi Just like in MATLAB! :) (not allocated! StepRangeLen)
  • Broadcasting y = sin.(t) (
    sin: RR
    )
  • Plotting, plot(t, y) needs to import using Plots (you need to install stuff!)
  • surf -> surface(t, t, y * y') (In Julia most functions use complete words)
  • Generic code can change backends, add UniCodoPlots, then setunicodeplots()
  • You can define functions like f(x) = sin.(x) similar to math!
  • You can also pipe functions y = x |> f |> f
  • Pluto is reactive, can define cells like in Excel (we love excel right?)
    • Sliders can be bound to variables, @bind x Slider(0:10)
    • You can mix Markdown and code with string interpolation mystring = "x = $x"
    • Order of the cells does not matter!
  • For loops have their own scope
for i in 1:10
	print(i)
end
print(i) # Not like in MATLAB!!
  • Let's do something more complex, use VSCode:
    • Ctr+Enter: Executes line and shows output inline
    • Docs can be seen inside VSCode
    • Plots appear in the plot pane
using ControlSystems
using Plots

n, b, k = 2, 1, 1
P = tf(1, [m, b, k]) # System, mass-spring-damp
C = pid(1,1,0,1)     # Controler
G = feedback(P * C)  # Feddback loop
plot(step(G, 20))
C_tuned = loopshapingPID(P, 1)
G_tuned = feedback(P * C)
plot!(step(G_tuned, 20)) # No hold on, fun!
# More cool graphs for free
res = step(G_tuned, 20)
plot(stepinfo(res))

Packaging and publishing

  • Very well thought package environment and package manager (Pkg.jl, everything is in the CI PkgTemplates.jl)
  • It force you to write tests (TestItemRunner.jl)
  • Docstrings can be used to create automatic documentations (Documenter.jl)
  • Community is very helpful! Julia's Slack and Discourse are an invaluable source of information
  • TagBot is very useful for tagging new releases (comment@JuliaRegister register)

Benefits of using all of these tools

Tim Holy:

Impacts of continuous integration

CI reduces reviewer workload to make it less of a bottleneck.

"Open-source" project generally have no CI

NoCI

How does it look for Julia?

Julia strongly encourages OSI license and good coding practices

Julia strongly encourages good coding practices, how? because it is easy -> PkgTemplates.jl

DocumentationJuliaStatistics

Median number of contributors: 2

Documentation

Documentation - I can make it work

Different types of documentation (David Laing) https://docs.divio.com/documentation-system/
Documentation types

  • Julia
  • NumPy
  • etc

Why should we use Julia coming from MATLAB?

  • Mathematical computations
  • GPUs on all architectures
  • High-performance computing
  • Unparalleled composability
  • Reproducible
  • Foments good coding practices
  • For scientific minded person, Julia is very attractive
  • For newbies MATLAB is more attractive

Take home message

TwitJuliaYannLecun
MatthijsCoxRemperatureJulia
PersonalityBasedOnProgrammingLanguage