Anonymous Functions and Do-block#

While you can write everything without anonymous functions and do-blocks, they are common syntax used in the Julia code base and make code easier to read & write for humans.

Anonymous function#

As a reminder, anonymous functions are useful for writing one-liners:

sort([-2, 0, 1]; by = x -> x^4)
3-element Vector{Int64}:
  0
  1
 -2

of course, you can always define a separate named function, although this pollutes the namespace if you’re only using it once:

_my_by(x) = x^4
sort([-2, 0, 1]; by = _my_by)
3-element Vector{Int64}:
  0
  1
 -2

Do-block syntax#

The do-block syntax helps when your anonymous function is too long but doesn’t deserve its own name.

This:

function _one_off(x)
    if x>=1
        return 1.0
    elseif x<0
        return -1.0
    else
        return NaN
    end
end

map(_one_off, -1:1)
3-element Vector{Float64}:
  -1.0
 NaN
   1.0

is equivalent to writing the following do-block:

map(-1:1) do x
    if x>=1
        return 1.0
    elseif x<0
        return -1.0
    else
        return NaN
    end
end
3-element Vector{Float64}:
  -1.0
 NaN
   1.0

More throughly speaking, the do-block syntax makes an anonymous function using the body (between do and end), taking variable names immediately after the do as parameters, and passes this function as the first argument of map(). Note, this works on any function (that expects first argument to be callable), not just map().

Many functions in the Julia standard library have alternate forms which take a function as their first argument to allow this kind of style. Generally, such functions also perform clean-up after the do-block has completed, making this a lot like with blocks in Python.

For example, there is a version of open which enables a very familiar form to Python programmers:

open("somefile.txt", write=true) do io
    write(io, "I added this line!\n")
end
19