Functions
The last expression is returned automatically; return is for early exit.
8.1 Defining functions
The last expression is returned automatically; return is for early exit. A function returning nothing returns nothing.
function add(x, y)
return x + y
end
add(x, y) = x + y # one-line (assignment) form
function stats(v)
m = sum(v) / length(v)
return m, maximum(v) # returns a tuple
end
avg, mx = stats([1, 2, 3])8.2 Optional & keyword arguments
Keyword arguments come after ;. Required keywords: f(; x) = x.
greet(name, greeting="Hello") = "$greeting, $name!"
greet("Ann"); greet("Ann", "Hi")
function plotline(x, y; color="blue", width=1, kwargs...)
println("color=$color width=$width extra=$(kwargs)")
end
plotline(1, 2; width=3, style=:dash)
color = "red"
plotline(1, 2; color) # shorthand for color=color8.3 Varargs & splatting
sumall(args...) = sum(args)
sumall(1, 2, 3) # 6
v = [1, 2, 3]
sumall(v...) # splat a collection into arguments
f(a, b, rest...) = rest8.4 Anonymous functions & do-blocks
sq = x -> x^2
add = (x, y) -> x + y
map(x -> x * 2, [1, 2, 3])
filter(iseven, 1:10)
map([1, 2, 3]) do x # do-block syntax: passes the block as the first argument
x^2 + 1
end
open("out.txt", "w") do io # resource management idiom
write(io, "hello")
end8.5 Higher-order functions & composition
map(sqrt, [1, 4, 9])
reduce(+, 1:5) # 15
foldl(-, 1:4), foldr(-, 1:4)
mapreduce(x -> x^2, +, 1:3) # 14
sum(abs2, [1, -2, 3]) # 14
any(iseven, [1, 3, 4]), all(>(0), [1, 2]), count(isodd, 1:10)
(sqrt ∘ abs)(-16) # composition \circ<Tab>: 4.0
[1, 4, 9] .|> sqrt # piping with broadcast
1:5 |> sum # pipe operator
>(3)(5) # partially applied comparison: true
Base.Fix2(-, 1)(10) # 98.6 Closures
function make_counter()
count = 0
return () -> (count += 1)
end
c = make_counter(); c(); c() # 1, 28.7 Argument passing & mutation
Julia uses pass-by-sharing: functions receive references to the same objects. Mutating a mutable argument (array, mutable struct) is visible to the caller; rebinding is not.
function double!(v) # ! convention: mutates its argument
v .*= 2
return v
end
a = [1, 2, 3]; double!(a) # a == [2, 4, 6]8.8 Recursion
Julia doesn't guarantee tail-call optimization; use loops for deep iteration.
fib(n) = n < 2 ? n : fib(n - 1) + fib(n - 2)
factorial_rec(n::Integer) = n <= 1 ? one(n) : n * factorial_rec(n - 1)8.9 Operators are functions
+(1, 2, 3) # 6
⊕(a, b) = a + b # define a new infix operator (\oplus<Tab>)
1 ⊕ 2
Base.:+(a::String, b::String) = a * b # extend an operator (type piracy — avoid in real code!)