# -*- mode: org -*- Julia memos (based on the Julia 0.4 manual, with some fixes for later versions) * Julia Shell |--------------------------------------------------+--------------------| | exit | C-d / quit() | | hide return value | foo(); | | last value | ans | | evaluate file | include("file.jl") | | completion | TAB | | greek letters (π, etc.) and other LaTeX features | \piTAB | | help on foo | ?foo | | commands relevant to foo | apropos("foo") | | run shell command | ;foo | | reverse search | C-r | | forward search | C-s | | abort command | C-g | | interrupt | C-c | | clear screen | C-l | | standard movements | as in Emacs | |--------------------------------------------------+--------------------| * Basic Syntax - case sensitive - rest-of-line comment: # - multiline comment: #= ... =# - statements are delimited by newlines or semicolons * Variables - variable names: conventionally lowercase, with as few underscores as possible - lexical scoping - assignment: x = 1, can be parallel: x, y = y, x (swapping) - assignment creates a variable locally, if it is not in a lexically enclosing environment, so variables do not need to be declared before assignment - variables are "born" at the start of the scope, so they can be referenced before the assignment, e.g. foo(n) = (f = y -> n + x + y; x = 1; f(2)) [this allows function definition in any order] - global variables can be assigned by first declaring them with: global var[=val][, var2...] - new local variables: local var[=val] / const var=val [consts cannot be assigned again], - new local variables (allocated each time): let [var1[=val1][, var2[=val2]...]]; ... end - use const only for globals [local constants are automatically determined by the compiler] - the Julia shell uses the global scope as a local scope * Basic Types - boolean: Bool (false / true) ** Numbers - digits can be separated by underscores: 10_000 (10000) - maximum / minimum value of a given type: typemax / typemin [used with either a value or a type] - explicit type conversion with the type name: Int32(number), etc. - binary representation: bits - explicit zero and one: zero / one [used with either a value or a type] useful for avoiding type conversions, e.g. if x == zero(x) ... *** Integers - signed/unsigned integers: Int8/UInt8,Int16/UInt16,Int32/UInt32,Int64/UInt64,[Int128/UInt128] - arbitrary precision integers: BigInt, construct from string: parse(BigInt, "123") or with big() - automatic promotion between most fixed precision types (but not Int128/UInt128/BigInt) - integers are normally Int32/Int64, depending on the system => Int / UInt types *** Floats - floating point types: Float16,Float32,Float64 - arbitrary precision floats: BigFloat, construct from string: parse(BigFloat, "123.0") - floats are normally Float64, unless using f-exponent for Float32: 1.5f0 - positive and negative zero and infinity: 0.0 / -0.0 / Inf(16|32)? / -Inf(16|32)? - not a number (not equal to anything, even itself): NaN(16|32)? - machine epsilon for a type: eps(Float32), and eps() = eps(Float64) - next/previous representable floating point number: nextfloat, prevfloat - standard rounding mechanism override: (with|get|set)_rounding - bigfloat precision settings: (with|get|set)_bigfloat_precision *** Radix - binary: 0b[01]+ - octal: 0o[0-7]+ - hexadecimal: 0x[0-9a-fA-F]+ - the type of these expressions is unsigned(!) and depending on the number of digits - hexadecimal floats use 'p' instead of 'e' => 0x2f.8p0 (47.5) *** Complex - imaginary unit: im - construction: complex(realpart, imagpart) - real/imaginary part: real / imag - conjugate: conj - angle: angle *** Rational - construction: // - numerator/denominator: numerator / denominator - convert to float: float ** Characters - type: Char (32-bit) - integer conversion: Int / Char - validity check: isvalid(Char, 0x2f) - unicode character codes: '\u2f' / '\U2f' (u: max 4 hex digits, U: max 8 hex digits) - arithmetic/comparison work as expected ** Strings - construction: "foo" / """foo""" (latter one can contain ", and skips the first newline) - multiline strings are 'dedented' to the indentation of the closing """ - standard C escape sequences: \n,\r,\t,\\, etc. and also \$ for $ sign - types: ASCIIString, UTF8String, UTF16String, UTF32String, WString (UTF-16 or UTF-32) - explicit type conversion: ascii, utf8, utf16, utf32, wstring - indexable (see Indexing), last index is the length in bytes - substring by range indexing: str[2:5] (<- but these are byte indices, so may not be valid) - conversion between indices and # of characters: ind2chr, chr2ind - next valid index: nextind(str, index) / next(index) [next: first skips to the next valid char] - length: length (length of Unicode characters, so length(str) <= endof(str)) - iterable, comparable - concatenation: string("Hello ", "world!") - variable interpolation with $ sign: "x = $x", even "x = $(x+1)", etc. - search character index: search - search substring: contains - repeated string: repeat(str, n) - joining with a delimiter: join(strarray, delimiter, finaldelimiter = delimiter) *** Regexps - construction: r"foo" - matching: ismatch(regexp, str) / match(regexp, str) [match returns a RegexMatch object] - matched substring and its offset: m.match, m.offset - captured substrings and their offsets: m.captures, m.offsets - replacing: replace(str, regexp, substitution) *** Byte Arrays - construction: b"foo" - octal/hexadecimal codes: \057, \x2f *** Version Numbers - construction: v"1.0.5" - uses semantic versioning (see semver.org) - format: major.minor.patch[-pre-release-data.1][+build-meta-data.2] ** Symbols - construction: :foo / symbol("foo") / symbol("f", :o, "o") ** Pairs - construction: Pair(val1, val2) / val1 => val2 - immutable, mainly used for dictionaries ** Tuples - construction: (val1, val2, ...) [use (val1,) for a one-element tuple] - tuples can have any number of values, of any type - tuples are covariant, i.e., Tuple{Int64,Bool} <: Tuple{Int,Bool} - elements can be indexed: (1,2,3)[2] == 2 ** Arrays / Cells - see Abstract Arrays ** Sets - construction: Set(iterable) ** Dictionaries - construction: Dict(key1=>val1, key2=>val2, ...) / Dict([(key1,val1), (key2,val2), ...]) ** Streams - methods: at least read and write - standard streams: STDIN, STDOUT, STDERR - read binary data: read! / readbytes - read text: readline / eachline [iterable] - writing data: show / print [pretty] - opening / closing files: open / close - open, with a functional argument, also closes the file [convenient with the do syntax] * Arithmetic - usual boolean arithmetic: !,&&,|| (&& and || have short-circuit evaluation semantics) - usual unary operators: +,-,sqrt,abs,sign,exp,log,log2,log10,a?(sin|cos|tan|cot|sec|csc)h? - usual binary operators: +,-,*,/,^,%(rem),div,mod,gcd,lcm,log,atan2 - usual bitwise operators: ~,&,|,>>,<< (& and | can be used with booleans [not short-circuit]) - usual rounding functions: round,floor,ceil,trunc (these can take a type argument, as well) - element-wise operators are prefixed with a dot: .+,.-,.*,./,.\,.^,.==,.!=,.<,.<=.>,.>= - also: iseven, isodd, \ (swapped division), fld (floored division), cld (ceiling division), mod2pi, divrem (returns a tuple), fldmod (returns a tuple), abs2 (squared absolute value), signbit (returns a boolean), copysign (|x|*sign(y)), flipsign (|x|*sign(x*y)),, cbrt (cube root), hypot (hypotenuse), expm1 (1/exp), ldexp (x*2^n), log1p (log(1+x)), exponent (binary exponent), significand (binary mantissa), sinc (sin(pi*x)/(pi*x)), cosc (derivative of sinc), sinpi (sin(pi*x)), cospi (cos(pi*x)), a?(sin|cos|tan|cot|sec|csc)d (using degrees instead of radians), ⊻ (bitwise xor), >>> (logical shift right, different from >> for negative numbers), and a few others (erf,dawson,gamma,beta,eta,zeta,airy*,bessel*,hankel*) - aliases: √(\sqrtTAB),÷(\divTAB),∛(\cbrtTAB) - update operators: +=,-=,*=,/=,\=,÷=,%=,^=,&=,|=,⊻=,>>>=,>>=,<<= - normal precedence ** Implicit multiplication - whitespace is not allowed in these cases - between numbers and variables: 2x^3 (=> 2 * x^3), 2^3x (=> 2^(3*x)) - as the first term, parentheses work similarly: (x-1)x, but not: x(x-1) or (x-1)(x+1) ** Comparisons - usual: ==,!=,<,<=,>,>= - also: isequal (like ==, but isequal(NaN,NaN) and !isequal(0.0,-0.0)), isfinite, isinf, isnan - aliases: ≠(\neTAB),≤(\leTAB),≥(\geTAB) - comparisons can be chained: 1 < 2 <= 3 == 3 >= 2 > 1 != 0 * Control Flow ** Sequential evaluation - begin ... end - (...; ...) - these do not have local scoping(!), so variables defined inside are seen outside ** Conditionals - if[-elseif][-else] expression (i.e., has a value) - 'if' blocks do not have local scoping(!), so variables defined inside are seen outside - condition must be a boolean(!) - C-style ?: shorthand (right-associative) ** Short-circuit evaluation - && and || - the last (and only the last) value of a conditional chain can be anything (not just booleans) ** Loops - while loop: while condition ... end - for loop: for var = iterable ... end / for var in iterable ... end - the iterable can be any container, or a linear sequence (Range) like 1:5 (see special operators) - nested for loops can be written as one: for var1 = iterable1, var2 = iterable2 ... end - exiting the loop: break (exits the current loop, which may be a multiple loop written as one) - next iteration: continue * Functions - function names: conventionally lowercase, without underscores - name of destructive functions end with '!' - construction: function foo(args...) ... end / foo(args...) = ... - function object is first-class, can be used as a value - operators are actually functions: +(), etc., and can be passed around - return value: (last value) / return val - multiple return values are possible (delimited by commas) - arguments can be spliced into a call by appending "...", e.g.: mod((15,6)...) == 3 ** Arguments - pass by sharing - general format: foo(n1, n2, o1 = 1, o2 = 2; key3 = 3, key4 = 4, rest...) - optional arguments: after normal arguments, using equation sign - named arguments: after normal and optional arguments and a semicolon - variable arguments: the variable before the ellipsis (...) contains the list of values - default values for optional arguments can use only previous arguments - default values for named arguments can use all arguments ** Anonymous functions - args -> expr, e.g.: x -> x^2, or (x,y) -> x*y, etc. [for zero argument: () -> ...] - do notation: foo(x, y) do a ... end == foo(a -> ..., x, y) and foo(x, y) do ... end == foo(() -> ..., x, y) and foo(x, y) do a,b ... end == foo((a,b) -> ..., x, y) ** Higher-order functions - usual functions: map ** Special operators - horizontal array concatenation: [A B C] == hcat(A, B, C) - vertical array concatenation: [A, B, C] == vcat(A, B, C) - 2D array concatenation: [A B; C D; E F] == hvcat((2,2,2), A, B, C, D, E, F) - conjugate transposition of an array: A' == ctranspose(A) - normal transposition of an array: A.' == transpose(A) - linear number sequence: a:b == a:1:b == colon(a, 1, b) == colon(a, b) - array getter using indices: A[i,j] == getindex(A, i, j) - array setter using indices: A[i,j] = x == setindex!(A, x, i, j) - function call: foo(args...) == call(foo, args...) - subtype checking: Child <: Parent == issubtype(Child, Parent) - identicality: x≡(\equivTAB)y == x === y - key-value pair creation: x => y == Pair(x, y) * Macros - macro names: conventionally lowercase, without underscores - except for the definition, macro names have an '@' sign prefix - construction: macro foo(args...) ... end - macro expansion can be viewed with: macroexpand - macros can be called with the alternative syntax: @foo arg1 arg2 ... ** Quoting - quoting: quote ... end / :(...) => Expr object - unquoting: $, e.g. :($a + b) - Expr object fields: head, args, typ [result type] - construction: Expr(:call, :+, 1, 2) == :(1+2) = parse("1+2") - displaying Expr objects: dump - displaying Expr objects as S-expressions: Meta.show_sexpr - evaluating an Expr object: eval ** Hygiene - normally variables are automatically assigned a symbol by gensym() - this can be locally turned off by using esc() ** Syntactic sugar - instead of eval(quote(...)), one can write @eval [begin ... end] ** Generated functions - a special type of macro - construction: @generated function foo(args...) ... end - arguments have the types as values at runtime - it may (or may not) run only once for a given argument signature - should return a quoted expression, that is actually run each time the function is called * Tasks - suspendable / resumable procedures - state field: :runnable / :waiting / :queued / :done / :failed - high-level data transfer: use Channel objects - low-level data transfer: yieldto(task, value) - other low-level functions: current_task, istaskdone, istaskstarted, task_local_storage - waiting: wait / notify - running a task: schedule (and also @schedule / @async) * Exceptions - basic exception type: Exception (user exception should be a subtype of this) - some common exceptions: ArgumentError, DomainError, ErrorException, TypeError, UndefVarError - throwing exceptions: throw, e.g. throw(DomainError()), throw(UndefVarError(:x)) - throwing ErrorExceptions: error("message") == throw(ErrorException("message")) [plus metadata] - showing information/warnings: info("message"), warn("message") - catching exceptions: try ... [catch [var] ...] [finally ...] end - because of the syntax, a semicolon is needed after catch when writing in one line without var - without a catch clause the return value is nothing - also see: rethrow, backtrace, catch_backtrace * Type System - dynamic nominative parametric types - abstract and concrete types - concrete types cannot have subtypes(!) - everything is an object, top type: Any, bottom type: Union{} - the type of all types: Type - type names: conventionally capitalized with camel case - type queries: typeof(val) / isa(val, Foo) - hierarchical queries: Child <: Parent / issubtype(Child, Parent) / super(Foo) - add type signature: val :: Foo (mostly optional) - for variables, this defines the type of the variable in the following three cases: (1) var::Foo, (2) local var::Foo, and (3) var::Foo = val ** Abstract Types - construction: abstract type Foo [<: ParentType] end - default supertype is Any ** Bits Types - construction: primitive Foo [<: ParentType] bits end - bits must be a multiple of 8 - default supertype is Any ** Composite Types - construction: mutable struct Foo [<: ParentType] var1[::Type1]; var2[::Type2]... end - default supertype, and default type for fields is Any - default constructor: Foo(var1, var2, ...) - field names: fieldnames(Foo) / fieldnames(foo) - accessing fields: foo.var1 - types with no fields are automatically singleton (all instances are the same) ** Immutable Types - construction: struct Foo [<: ParentType] var1[::Type1]; var2[::Type2]... end - same as composite types, but the fields cannot be modified - passed around by copying (not by reference, as composite types) ** Type Aliases - construction: typealias NewType OldType ** Type Unions - special abstract type - construction: Foo = Union{Type1, Type2, ...} ** Type Parameters - parameters can be anything for which isbits returns true, or tuples thereof - construction: curly braces after the type name, e.g. type Point{T} x::T; y::T end - may have a subtype restriction, e.g. type Point{T<:Number} x::T; y::T end - A <: B does not mean that Foo{A} <: Foo{B} (actually, it is always false) - even bits types can have type parameters *** Variable Argument Type - special Vararg{T} type - e.g. Tuple{AbstractString,Vararg{Int}} is a tuple of a string and any number of ints, as in ("1",) or ("1",2) or ("1",2,3), but not ("1",2,3.0) *** Singleton Types - singleton type for T: Type{T} - the only instance of this type is T - used for multiple dispatch on types as arguments *** Value Types - creates a type from a single value - construction: Val{val} *** Nullable Types - construction: Nullable{T} - instances represent values that are maybe missing, such as the result of a lookup - check if an instance has a value or not: isnull(nullableval) - take out the value from the instance: get(nullableval) / get(nullableval, defaultval) ** Type Conversion and Promotion - conversion to the type Foo: convert(Foo, val) - new conversions are defined as methods: convert(::Type{ToType}, val::FromType) = ... - promotion converts several values to a common type: promote(args...) - promotions are defined by promote_rule(::Type{Type1}, ::Type{Type2}) = ResultType - promoted type can be queried with promote_type(Type1, Type2) * Methods - multiple dispatch on argument types (Any is implied when a type is not given) - the most specific method will be called (ambiguities generate warnings) - list all method signatures of foo: methods(foo) - methods can have type parameters: foo{T}(arg1::T, ...) = ... - this is needed when two or more arguments should have the dependent types - the type parameter can have subtype restriction: foo{T<:Number}(arg1::T, ...) = ... - type parameters can be written as foo(arg1::T, ...) where {T<:Number} = ... - optional arguments are tied to the function, not the method - keyword arguments do not take part in the dispatching process - empty generic function (for documentation purposes): function foo end ** Constructors - outer constructors are just functions that call the default constructor, e.g. Foo(x) = Foo(x,x) - inner constructors: declared inside the type definition, using the new(...) default constructor - with parametric types => type Foo{T,S<:Real} x Foo{T,S}(x) where {T,S<:Real} = new(x) end - if there are inner constructors, there are no default constructors - the new constructor can have less arguments, returning a partially-initialized instance - parameterized outer constructors are (restricted) constructors of the general type, while inner constructors of a parameterized type are constructors of the parameterized type - for constructors representing lossless conversion, Base.convert should be used - adding a Base.convert(::Type{Foo}, args...) method also defines a Foo(args...) constructor - outer-only constructors can be created by explicit overloading of call() * Interfaces ** Iteration - required: start(iter), next(iter, state), done(iter, state) - optional: eltype(IterType) = Any, length(iter) - any object defining these can be iterated - functions on iterables: collect, in, sum, mean, std, etc. - aliases for in(x,coll): x∈(\inTAB)coll, !(x∉(\notinTAB)coll), coll∋(\niTAB)x, !(coll∌(\nniTAB)x) ** Indexing - required: getindex(coll, i), setindex!(coll, val, i), endof(coll) - indexing starts from 1, last index is end = endof(coll) ** Abstract Arrays - two parameters: element type & number of dimensions, e.g. immutable A <: AbstractArray(Int, 2) - required: size(A), Base.linearindexing(::Type{A}) [values: Base.LinearFast() / Base.LinearSlow()] - also, if linear-indexed: getindex(A, i), setindex!(A, val, i) - also, if n-dim-indexed: getindex(A, indices...), setindex!(A, val, indices...) - optional: getindex/setindex (non-scalar case), start/next/done, length, similar - functions on arrays: eltype, ndims, eachindex, stride, strides, fill!, minimum, maximum - most arithmetic functions work on arrays, can be generated by the @vectorize_(1|2)arg macros - expanding singleton dimensions can be done with: broadcast *** Constructors - Array, cell, zeros, ones, trues, falses, reshape, copy, deepcopy, similar, reinterpret, rand, randn, eye, linspace, fill, cat, vcat, hcat, hvcat - an array of a specific type can be created by Foo[A B;C D] - arrays can be created by list comprehensions - syntax: [expr for var1 = iterable, var2 = iterable...], e.g. [x*y for x=1:2, y=1:3] *** Indexing - general syntax: A[I1, I2, ...], where each I is a scalar, a range, or an integer/bool vector - a whole dimension can be indexed with a ':', e.g. [1 2;3 4][1,:] == [1 2] - alternative syntax uses tuples: A[(I1,I2,...)] - iteration can be done on A or on eachindex(A) [when the actual indices are needed] *** Sparse Matrices - function names have a sp- prefix: spzeros, speye, sprand, sprandn, sprandbool - conversion with full matrices: sparse / full - query: issparse * Modules - module names: conventionally capitalized with camel case, with dots between hierarchical levels - construction: module Foo ... end - import all exported names: import SomeModule - import names: import SomeModule: def1, def2 ... / import SomeModule.def1, SomeModule.def2 ... - import all names: importall SomeModule - use all exported names: using SomeModule - use names: using SomeModule: def1, def2 ... / using SomeModule.def1, SomeModule.def2 ... - all import/use commands work also on relative paths, such as .Child, ..Sibling, ...Uncle - exporting names: export def1, def2 ... ** Standard Modules - Main, Core, and Base - a new module automatically uses Core and Base, imports Base.call, and has an eval function - creating a module without these: baremodule Foo ... end ** File Paths - modules are actually loaded by require - paths searched are in LOAD_PATH ** Precompilation - a module is precompiled, if there is a __precompile__() before the module command - if it is not safe to precompile, use __precompile__(false) - a module is safe, if all actions that should be done runtime are separated - these should be put in an __init__() function [called only once, when the module is loaded] - typical uses: initialization global constants, and setup of external libraries * Documentation - assumes Markdown syntax - docstrings are placed before definitions - for types, docstrings can be prepended to fields, as well * Packages - package manager: Pkg - initalization: Pkg.init() - package directory: Pkg.dir() - installed packages: Pkg.installed() / Pkg.status() - add package: Pkg.add("package") - remove package: Pkg.rm("package") - updating packages: Pkg.update() - using a non-registered version: checkout, pin/free - installing unregistered packages: Pkg.clone("git://...Package.jl.git") ** Package Development - packages are git repositories - initial package generation: Pkg.generate() - [see other details in the manual] * Other Topics in the Manual - parallel computing - dates and times - running external programs - calling C / FORTRAN - embedding Julia - profiling