Skip to content
AgileLogics
5 min read

Anonymous Functions and do Blocks

Prerequisites: Functions

Functions are values: you can store them in variables, pass them to other functions, and return them.

square = x -> x^2
add = (a, b) -> a + b
println(square(5), " ", add(2, 3))

apply_twice(f, x) = f(f(x))
println(apply_twice(square, 3))
println(apply_twice(s -> s * "!", "hi"))

ops = [sin, cos, sqrt]
for f in ops
    println(f, "(1.0) = ", round(f(1.0), digits = 4))
end
25 5
81
hi!!
sin(1.0) = 0.8415
cos(1.0) = 0.5403
sqrt(1.0) = 1.0
  • x -> x^2 is an anonymous function. Several arguments go in parentheses: (a, b) -> a + b.
  • A function that takes or returns another function is a higher-order function.

reduce and friends

xs = [3, 1, 4, 1, 5]
println(reduce(+, xs))
println(reduce(max, xs))
println(foldl((acc, x) -> acc * 10 + x, xs; init = 0))
println(sum(abs2, [1, -2, 3]))
println(any(x -> x > 4, xs), " ", all(x -> x > 0, xs))
14
5
31415
14
true true

Many functions accept a function as their first argument: sum(abs2, xs) squares each element before adding, without building a temporary array.

do blocks

When the function argument is long, a do block lets you write it after the call. These two lines do the same thing:

words = ["kiwi", "fig", "banana"]
println(map(w -> length(w) > 3 ? uppercase(w) : w, words))

result = map(words) do w
    if length(w) > 3
        uppercase(w)
    else
        w
    end
end
println(result)
["KIWI", "fig", "BANANA"]
["KIWI", "fig", "BANANA"]

f(args) do x ... end passes the block as an anonymous function to be the first argument of f. You'll see it everywhere — for example open("file.txt") do io ... end opens a file and closes it automatically when the block ends.

Closures

A function defined inside another function can use (and remember) the outer function's variables:

function make_multiplier(factor)
    return x -> x * factor
end

double = make_multiplier(2)
triple = make_multiplier(3)
println(double(21), " ", triple(7))
42 21