This page's source is located here . Pull requests are welcome!
What is…? Collection functions
Julia is an open-source, multi-platform, high-level, high-performance
programming language for technical computing. map(f, coll) or map(coll) do elem Julia has an LLVM-based JIT compiler that allows it to match the Apply f to all elements of collection # do stuff with elem performance of languages such as C and FORTRAN without the hassle of coll # must contain return low-level code. Because the code is compiled on the y you can run (bits of) code in a shell or REPL , which is part of the recommended work ow . end Filter coll for true values of f filter(f, coll) Julia is dynamically typed, provides multiple dispatch , and is designed for arr = [f(elem) for elem in parallelism and distributed computation. List comprehension coll] Julia has a built-in package manager. Julia has many built-in mathematical functions, including special functions (e.g. Gamma), and supports complex numbers right out of the box. Types Julia allows you to generate code automagically thanks to Lisp-inspired macros. Julia has no classes and thus no class-speci c methods. Julia was born in 2012. Types are like classes without methods. Abstract types can be subtyped but not instantiated. Basics Concrete types cannot be subtyped. By default, struct s are immutable. Immutable types enhance performance and are thread safe, as they can be answer = 42 shared among threads without the need for synchronization. Assignment x, y, z = 1, [1:10; ], "A string" x, y = y, x # swap x and y Objects that may be one of a set of types are called Union types. Constant declaration const DATE_OF_BIRTH = 2012 End-of-line comment i = 1 # This is a comment Type annotation var::TypeName Delimited comment #= This is another comment =# struct Programmer name::String x = y = z = 1 # right-to-left Type declaration birth_year::UInt16 Chaining 0 < x < 3 # true fave_language::AbstractString 5 < x != y < 5 # false end function add_one(i) Mutable type declaration replace struct with mutable struct Function de nition return i + 1 Type alias const Nerd = Programmer end Type constructors methods(TypeName) Insert LaTeX symbols \delta + [Tab] me = Programmer("Ian", 1984, "Julia") Type instantiation me = Nerd("Ian", 1984, "Julia") abstract type Bird end Operators struct Duck <: Bird Subtype declaration pond::String end Basic arithmetic +, -,*,/ struct Point{T <: Real} Exponentiation 2^3 == 8 x::T Division 3/12 == 0.25 Parametric type y::T Inverse division 7\3 == 3/7 end Remainder x % y or rem(x,y) p =Point{Float64}(1,2) Negation !true == false Union types Union{Int, String} Equality a == b Traverse type hierarchy supertype(TypeName) and subtypes(TypeName) Inequality a != b or a ≠ b Default supertype Any Less and larger than < and > All elds fieldnames(TypeName) Less than or equal to <= or ≤ All eld types TypeName.types Greater than or equal to >= or ≥ [1, 2, 3] .+ [1, 2, 3] == [2, 4, 6] When a type is de ned with an inner constructor, the default outer Element-wise operation [1, 2, 3] .* [1, 2, 3] == [1, 4, 9] constructors are not available and have to be de ned manually if need be. An inner constructor is best used to check whether the parameters Not a number isnan(NaN) not(!) NaN == NaN conform to certain (invariance) conditions. Obviously, these invariants can Ternary operator a == b ? "Equal" : "Not equal" be violated by accessing and modifying the elds directly, unless the type Short-circuited AND and OR a && b and a || b is de ned as immutable. The new keyword may be used to create an object Object equivalence a === b of the same type. Type parameters are invariant, which means that Point{Float64} <: Point{Real} is false, even though Float64 <: Real. The shell a.k.a. REPL Tuple types, on the other hand, are covariant: Tuple{Float64} <: Tuple{Real}. The type-inferred form of Julia’s internal representation can be found with Recall last result ans code_typed(). This is useful to identify where Any rather than type-speci c Interrupt execution [Ctrl] + [C] native code is generated. Clear screen [Ctrl] + [L] Run program include("filename.jl") Get help for func is de ned ?func Missing and Nothing See all places where func is de ned apropos("func") Command line mode ; Package Manager mode ] Programmers Null nothing Help mode ? Missing Data missing Exit special mode / Return to REPL [Backspace] on empty line Not a Number in NaN Exit REPL exit() or [Ctrl] + [D] Float Filter missings collect(skipmissing([1, 2, missing])) == [1,2] Replace missings collect((df[:col], 1)) Standard libraries Check if missing ismissing(x) not x == missing
To help Julia load faster, many core functionalities exist in standard
libraries that come bundled with Julia. To make their functions available, Exceptions use using PackageName. Here are some Standard Libraries and popular functions. Throw throw(SomeExcep()) Random rand, randn, randsubseq SomeExcep Statistics mean, std, cor, median, quantile Rethrow current rethrow() LinearAlgebra I, eigvals, eigvecs, det, cholesky exception struct NewExcep <: Exception SparseArrays sparse, SparseVector, SparseMatrixCSC v::String Distributed @distributed, pmap, addprocs end Dates DateTime, Date De ne NewExcep Base.showerror(io::IO, e::NewExcep) = print(io, "A problem with $(e.v)!") Package management throw(NewExcep("x")) Throw error with error(msg) Packages must be registered before they are visible to the package msg text manager. In Julia 1.0, there are two ways to work with the package try manager: either with using Pkg and using Pkg functions, or by typing ] in # do something potentially iffy the REPL to enter the special interactive package management mode. (To return to regular REPL, just hit BACKSPACE on an empty line in package catch ex if isa(ex, SomeExcep) management mode). Note that new tools arrive in interactive mode rst, then usually also become available in regular Julia sessions through Pkg # handle SomeExcep module. elseif isa(ex, AnotherExcep) Handler # handle AnotherExcep Using Pkg in Julia session else # handle all others end List installed packages (human-readable) Pkg.status() finally List installed packages (machine-readable) Pkg.installed() # do this in any case Update all packages Pkg.update() end Install PackageName Pkg.add("PackageName") Rebuild PackageName Pkg.build("PackageName") Use PackageName (after install) using PackageName Modules Remove PackageName Pkg.rm("PackageName") In Interactive Package Mode Modules are separate global variable workspaces that group together similar functionality.
Add PackageName add PackageName module PackageName Remove PackageName rm PackageName # add module definitions Update PackageName update PackageName De nition # use export to make definitions accessible dev PackageName or end Use development version dev GitRepoUrl Include Stop using development version, revert to include("filename.jl") free PackageName filename.jl public release using ModuleName # all exported names using ModuleName: x, y # only x, y using ModuleName.x, ModuleName.y: # only x, y Characters and strings Load import ModuleName # only ModuleName import ModuleName: x, y # only x, y import ModuleName.x, ModuleName.y # only x, y Character chr = 'C' # Get an array of names exported by Module String str = "A string" names(ModuleName) Character code Int('J') == 74 # include non-exports, deprecateds Character from code Char(74) == 'J' Exports # and compiler-generated names chr = '\uXXXX' # 4-digit HEX names(ModuleName, all::Bool) Any UTF character chr = '\UXXXXXXXX' # 8-digit HEX for c in str #also show namesexplicitely imported from other Loop through characters println(c) modules end names(ModuleName, all::Bool, imported::Bool) Concatenation str = "Learn" * " " * "Julia" There is only one di erence between using and import : with using you a = b = 2 need to say function Foo.bar(.. to extend module Foo’s function bar with String interpolation println("a * b = $(a*b)") a new method, but with import Foo.bar, you only need to say First matching character or regular findfirst(isequal('i'), "Julia") function bar(... and it automatically extends module Foo’s function bar . expression == 4 Replace substring or regular replace("Julia", "a" => "us") == expression "Julius" Expressions Last index (of collection) lastindex("Hello") == 5 Number of characters length("Hello") == 5 Regular expression pattern = r"l[aeiou]" Julia is homoiconic: programs are represented as data structures of the str = "+1 234 567 890" language itself. In fact, everything is an expression Expr. pat = r"\+([0-9]) ([0-9]+)" Symbols are interned strings pre xed with a colon. Symbols are more Subexpressions m = match(pat, str) e cient and they are typically used as identi ers, keys (in dictionaries), or m.captures == ["1", "234"] columns in data frames. Symbols cannot be concatenated. [m.match for m = eachmatch(pat, Quoting :( ... ) or quote ... end creates an expression, just like All occurrences str)] parse(str) , and Expr(:call, ...). All occurrences (as iterator) eachmatch(pat, str) x = 1 Beware of multi-byte Unicode encodings in UTF-8: line = "1 + $x" # some code 10 == lastindex("Ångström") != length("Ångström") == 8 expr = parse(line) # make an Expr object Strings are immutable. typeof(expr) == Expr # true dump(expr) # generate abstract syntax tree eval(expr) == 2 # evaluate Expr object: true Numbers Macros
IntN and UIntN, with Integer types Macros allow generated code (i.e. expressions) to be included in a program. N ∈ {8, 16, 32, 64, 128}, BigInt FloatN with N ∈ {16, 32, 64} Floating-point types macro macroname(expr) BigFloat De nition # do stuff Minimum and maximum typemin(Int8) end values by type typemax(Int64) Usage macroname(ex1, ex2, ...) or @macroname ex1, ex2, ... Complex types Complex{T} @test # equal (exact) Imaginary unit im @test_approx_eq # equal (modulo numerical errors) Machine precision eps() # same as eps(Float64) @test x ≈ y # isapprox(x, y) round() # floating-point @assert # assert (unit test) Rounding round(Int, x) # integer @which # types used convert(TypeName, val) # @time # time and memory statistics attempt/error @elapsed # time elapsed Type conversions typename(val) # calls Built-in macros @allocated # memory allocated convert @profile # profile pi # 3.1415... @spawn # run at some worker Global constants π # 3.1415... @spawnat # run at specified worker im # real(im * im) == -1 @async # asynchronous task More constants using Base.MathConstants @distributed # parallel for loop Julia does not automatically check for numerical over ow. Use package @everywhere # make available to workers SaferIntegers for ints with over ow checking. Rules for creating hygienic macros: Declare variables inside macro with local . Do not call eval inside macro. Random Numbers Escape interpolated expressions to avoid expansion: $(esc(expr))
Many random number functions require using Random.
Parallel Computing
Set seed seed!(seed) rand() # uniform [0,1) Parallel computing tools are available in the Distributed standard library. Random numbers randn() # normal (-Inf, Inf) Launch REPL with N workers julia -p N using Distributions Number of available workers nprocs() my_dist = Bernoulli(0.2) # Add N workers addprocs(N) Random from Other Distribution For example for pid in workers() rand(my_dist) See all worker ids println(pid) Random subsample elements from A with randsubseq(A, p) end inclusion probability p Random permutation elements of A shuffle(A) Get id of executing worker myid() Remove worker rmprocs(pid) r = remotecall(f, pid, args...) Arrays # or: Run f with arguments args on r = @spawnat pid f(args) pid ... fetch(r) Declaration arr = Float64[] Run f with arguments args on Pre-allocation sizehint!(arr, 10^4) remotecall_fetch(f, pid, args...) pid (more e cient) arr = Any[1,2] Run f with arguments args on Access and assignment r = @spawn f(args) ... fetch(r) arr[1] = "Some text" any worker a = [1:10;] Run f with arguments args on r = [@spawnat w f(args) for w in b = a # b points to a all workers workers()] ... fetch(r) Comparison a[1] = -99 Make expr available to all @everywhere expr a == b # true workers b = copy(a) sum = @distributed (red) for i in Copy elements (not address) Parallel for loop with reducer 1:10^6 b = deepcopy(a) Select subarray from m to n arr[m:n] function red # do parallelstuff end n-element array with 0.0s zeros(n) Apply f to all elements in pmap(f, coll) n-element array with 1.0s ones(n) collection coll n-element array with #undefs Vector{Type}(undef,n) Workers are also known as concurrent/parallel processes. n equally spaced numbers from start range(start,stop=stop,length=n) to stop Modules with parallel processing capabilities are best split into a functions Array with n random Int8 elements rand(Int8, n) le that contains all the functions and variables needed by all workers, and Fill array with val fill!(arr, val) a driver le that handles the processing of data. The driver le obviously has to import the functions le. Pop last element pop!(arr) Pop rst element popfirst!(a) A non-trivial (word count) example of a reducer function is provided by Push val as last element push!(arr, val) Adam DeConinck. Push val as rst element pushfirst!(arr, val) Remove element at index idx deleteat!(arr, idx) Sort sort!(arr) I/O Append a with b append!(a,b) Check whether val is element in(val, arr) or val in arr Scalar product dot(a, b) == sum(a .* b) stream = stdin for line in eachline(stream) reshape(1:6, 3, 2)' == [1 2 3; Read stream Change dimensions (if possible) 4 5 6] # do stuff end To string (with delimiter del between join(arr, del) elements) open(filename) do file for line in eachline(file) Read le # do stuff end Linear Algebra end using CSV Read CSV le For most linear algebra tools, use using LinearAlgebra. data = CSV.read(filename) using CSV Write CSV le I # just use variable I. Will automatically CSV.write(filename, data) Identity matrix conform to dimensions required. using JLD Save Julia Object De ne matrix M = [1 0; 0 1] save(filename, "object_key", object, ...) Matrix dimensions size(M) using JLD Load Julia Object Select i th row M[i, :] d = load(filename) # Returns a dict of objects Select i th column M[:, i] using HDF5 Save HDF5 h5write(filename, "key", object) Concatenate M = [a b] or M = hcat(a, b) horizontally using HDF5 Load HDF5 h5read(filename, "key") Concatenate M = [a ; b] or M = vcat(a, b) vertically Matrix transpose(M) transposition DataFrames Conjugate matrix M' or adjoint(M) transposition Matrix trace tr(M) For dplyr-like tools, see DataFramesMeta.jl. Matrix det(M) Read Stata, SPSS, etc. StatFiles Package determinant Matrix rank rank(M) Describe data frame describe(df) Matrix eigenvalues eigvals(M) Make vector of column col v = df[:col] Matrix Sort by col sort!(df, [:col]) eigvecs(M) eigenvectors Categorical col categorical!(df, [:col]) Matrix inverse inv(M) List col levels levels(df[:col]) Solve M*x == v M\v is better than inv(M)*v All observations with col==val df[df[:col] .== val, :] Moore-Penrose pinv(M) stack(df, [1:n; ]) pseudo-inverse Reshape from wide to long stack(df, [:col1, :col2, ...] format Julia has built-in support for matrix decompositions. melt(df, [:col1, :col2]) [ Julia tries to infer whether matrices are of a special type (symmetric, Reshape from long to wide unstack(df, :id, :val) hermitian, etc.), but sometimes fails. To aid Julia in dispatching the optimal format algorithms, special matrices can be declared to have a structure with Make Nullable allowmissing!(df) or functions like Symmetric , Hermitian , UpperTriangular, LowerTriangular, allowmissing!(df, :col) Diagonal , and more. for r in eachrow(df) # do stuff. Loop over Rows # r is Struct with fields of col names. Control flow and loops end for c in eachcol(df) # do stuff. Conditional if-elseif-else-end Loop over Columns # c is tuple with name, then for i in 1:10 vector Simple for loop println(i) end end Apply func to groups by(df, :group_col, func) for i in 1:10, j = 1:5 using Query Unnested for loop println(i*j) query = @from r in df begin end @where r.col1 > 40 for (idx, val) in enumerate(arr) Query @select {new_name=r.col1, r.col2} Enumeration println("the $idx-th element is $val") @collect DataFrame # Default: end iterator while bool_expr end while loop # do stuff end Exit loop break Introspection and reflection Exit iteration continue
Type typeof(name) Functions Type check isa(name, TypeName) List subtypes subtypes(TypeName) List supertype supertype(TypeName) All arguments to functions are passed by reference. Function methods methods(func) Functions with ! appended change at least one argument, typically the JIT bytecode code_llvm(expr) rst: sort!(arr). Assembly code code_native(expr) Required arguments are separated with a comma and use the positional notation. Optional arguments need a default value in the signature, de ned with =. Noteworthy packages and projects Keyword arguments use the named notation and are listed in the function’s signature after the semicolon: Many core packages are managed by communities with names of the form function func(req1, req2; key1=dflt1, key2=dflt2) Julia[Topic]. # do stuff end Statistics JuliaStats The semicolon is not required in the call to a function that accepts keyword Automatic di erentiation JuliaDi arguments. Numerical optimization JuliaOpt The return statement is optional but highly recommended. Plotting JuliaPlots Network (Graph) Analysis JuliaGraphs Multiple data structures can be returned as a tuple in a single return Web JuliaWeb statement. Geo-Spatial JuliaGeo Command line arguments julia script.jl arg1 arg2... can be processed Machine Learning JuliaML from global constant ARGS: DataFrames # linear/logistic regression for arg in ARGS Distributions # Statistical distributions println(arg) Flux # Machine learning end Super-used Packages Gadfly # ggplot2-likeplotting Anonymous functions can best be used in collection functions or list LightGraphs # Network analysis comprehensions: x -> x^2. TextAnalysis # NLP Functions can accept a variable number of arguments: function func(a...) println(a) Naming Conventions end The main convention in Julia is to avoid underscores unless they are func(1, 2, [3:5]) # tuple: (1, 2, UnitRange{Int64}[3:5]) required for legibility. Functions can be nested: Variable names are in lower (or snake) case: somevariable. function outerfunction() # do some outer stuff Constants are in upper case: SOMECONSTANT. function innerfunction() # do inner stuff Functions are in lower (or snake) case: somefunction. # can access prior outer definitions Macros are in lower (or snake) case: @somemacro. end # do more outer stuff Type names are in initial-capital camel case: SomeType. end Julia les have the jl extension. Functions can have explicit return types For more information on Julia code style visit the manual: style guide . # take any Number subtype and return it as a String function stringifynumber(num::T)::String where T <: Number return "$num" end Performance tips Functions can be vectorized by using the Dot Syntax # here we broadcast the subtraction of each mean value Avoid global variables. # by using the dot operator Write type-stable code. julia> using Statistics Use immutable types where possible. julia> A = rand(3, 4); Use sizehint! for large arrays. julia> B = A .- mean(A, dims=1) Free up memory for large arrays with arr = nothing. 3×4 Array{Float64,2}: Access arrays along columns, because multi-dimensional arrays are 0.0387438 0.112224 -0.0541478 0.455245 stored in column-major order. 0.000773337 0.250006 0.0140011 -0.289532 Pre-allocate resultant data structures. -0.0395171 -0.36223 0.0401467 -0.165713 Disable the garbage collector in real-time applications: disable_gc(). julia> mean(B, dims=1) Avoid the splat (...) operator for keyword arguments. 1×4 Array{Float64,2}: Use mutating APIs (i.e. functions with ! to avoid copying data structures. -7.40149e-17 7.40149e-17 1.85037e-17 3.70074e-17 Use array (element-wise) operations instead of list comprehensions. Julia generates specialized versions of functions based on data types. Avoid try-catch in (computation-intensive) loops. When a function is called with the same argument types again, Julia can Avoid Any in collections. look up the native machine code and skip the compilation process. Avoid abstract types in collections. Avoid string interpolation in I/O. Since Julia 0.5 the existence of potential ambiguities is still acceptable, but Vectorizing does not improve speed (unlike R, MATLAB or Python). actually calling an ambiguous method is an immediate error. Avoid eval at run-time. Stack over ow is possible when recursive functions nest many levels deep. Trampolining can be used to do tail-call optimization, as Julia does not do that automatically yet. Alternatively, you can rewrite the tail recursion as IDEs, Editors and Plug-ins an iteration. Juno (editor) JuliaBox (online IJulia notebook) Dictionaries Jupyter (online IJulia notebook) Emacs Julia mode (editor) vim Julia mode (editor) d = Dict(key1 => val1, key2 => val2, VS Code extension (editor) ...) Dictionary d = Dict(:key1 => val1, :key2 => val2, ...) Resources All keys (iterator) keys(d) All values (iterator) values(d) O cial documentation . for (k,v) in d Learning Julia page. Loop through key-value println("key: $k, value: $v") Month of Julia pairs end Community standards . Check for key :k haskey(d, :k) Julia: A fresh approach to numerical computing (pdf) Copy keys (or values) to arr = collect(keys(d)) Julia: A Fast Dynamic Language for Technical Computing (pdf) array arr = [k for (k,v) in d] Dictionaries are mutable; when symbols are used as keys, the keys are Videos immutable. The 5th annual JuliaCon 2018 The 4th annual JuliaCon 2017 (Berkeley) Sets The 3rd annual JuliaCon 2016 Getting Started with Julia by Leah Hanson Intro to Julia by Huda Nassar Declaration s = Set([1, 2, 3, "Some text"]) Introduction to Julia for Pythonistas by John Pearson Union s1 ∪ s2 union(s1, s2) Intersection s1 ∩ s2 intersect(s1, s2) Di erence s1 \\ s2 setdiff(s1, s2) Di erence s1 △ s2 symdiff(s1, s2) Subset s1 ⊆ s2 issubset(s1, s2) Checking whether an element is contained in a set is done in O(1).
Country ag icons made by Freepik from www. aticon.com is licensed by CC 3.0 BY.