10 Julia Recipes You Can't Miss

I have published a blog titled : 10 Julia Recipes You Can’t Miss.

Please suggest alternate or efficient methods to recipes or additionally what and all other recipes that can be included in the list.

15 Likes

Suggested recipe: Unpack a subset of a named tuple:

julia> t = (a=1, b="hello", c = 3.14)
(a = 1, b = "hello", c = 3.14)

julia> (; a, c) = t; @show a; @show c;
a = 1
c = 3.14

julia> b
ERROR: UndefVarError: `b` not defined
8 Likes

Updated.

3 Likes

Of any type with named fields

4 Likes

I’m not sure what you are trying to achieve in c, but I would prefer doing

filtered = filter(>(50), temp)

or

filtered = filter(temp) do x
    x > 50
end

if the filter function was more complex.

I would only use the array comprehension if I was mapping as well, e.g.

filtered = [x + x^2 for x in temp if x > 50]

(My reason for this preference is readability, I have not tested execution speed)

1 Like

Updated.
The first one
filtered = filter(>(50), temp)
is a brilliant short hand

1 Like

I can’t resist posting my favourite:

points = [(; x=rand(), y=rand()) for i in 1:10]
distances = [sqrt(p.x^2 + p.y^2) for p in points if p.x > p.y]

I don’t know about recent Java versions, but some years ago this would have required at least 10 lines of Java code.

6 Likes

Bonus for (b): besides “search-and-replace” text, you can also “search-and-apply-arbitrary-function”, e.g.:

replace(stri, "scream"=>uppercase)

Another thing that I like is nd-array comprehensions easily made by combining iterators:

julia> producttable = [row*col for row=1:10, col=1:3]
10×3 Matrix{Int64}:
  1   2   3
  2   4   6
  3   6   9
  4   8  12
  5  10  15
  6  12  18
  7  14  21
  8  16  24
  9  18  27
 10  20  30
3 Likes

Updated.

This trick is absolutely brilliant. Is the semicolon before x = rand() necessary. I could run the code without it.

2 Likes

Thank you. I think you are right, it seems like the ; is not necessary, it works without it for me as well even on old versions of Julia.

1 Like

(x = something, y = something_else) for constructing NamedTuples has been around since 1.0. The novelties since then were (; x, y) for constructing a NamedTuple from variables in scope (instead of having to write (x=x, y=y)) in 1.5, and then applying that to destructuring, i.e. (; x, y) = something where something is an object that has fieldnames x and y in Julia 1.7.

8 Likes
julia> abc = (a=1, b="hello", c = 3.14)
(a = 1, b = "hello", c = 3.14)
julia> ac = NamedTuple{(:a, :c)}(abc)
(a = 1, c = 3.14)
"""
    keepkeys(nt::NamedTuple, syms::Tuple{Vararg{Symbol}})

Construct a subset of `nt` using only the keys in `syms`.
""" keepkeys

julia> keepkeys(nt::NamedTuple, ks=NTuple{N,Symbol} where {N}) =
                 NamedTuple{ks}(nt)

julia> b = keepkeys(abc, (:b,))
(b = "hello",)

julia> bc = keepkeys(abc, (:b, :c))
(b = "hello", c = 3.14)

julia> keepkeys(abc, (:z,))
ERROR: type NamedTuple has no field z
"""
    omitkeys(nt::NamedTuple, syms::Tuple{Vararg{Symbol}})

Construct a subset of `nt` omitting the keys in `syms`.
""" omitkeys

julia>  omitkeys(nt::NamedTuple, ks=NTuple{N,Symbol} where {N}) =
                  keepkeys(nt, Tuple(setdiff(keys(nt), ks)))

julia> bc = omitkeys(abc, (:a,))
(b = "hello", c = 3.14)

julia> b = omitkeys(abc, (:a, :c))
(b = "hello",)

julia> abc2 = omitkeys(abc, (:z,))
(a = 1, b = "hello", c = 3.14)
3 Likes

hypot(p.x, p.y) is nicer

3 Likes

Only if you are familiar with that function; otherwise the formula is unambiguous and hence preferable.

3 Likes

When I have to use a for-loop to get an output, I find really useful to initialize the vector as a keyword argument.
Example:

function foo(x)
    output = similar(x)
    
    for i in eachindex(x)
        output[i] = x[i] + 1
    end

    return output
end

instead, I use

function foo(x; output = similar(x))    
    for i in eachindex(x)
        output[i] = x[i] + 1
    end

    return output
end

This is possible because you can use previous arguments to define default values of a keyword argument.

6 Likes

I like that because the output appears in the function statement: a very handy heads-up for the user.

-100. It is worth it to fire up the Julia REPL just to use this nice function and avoid the pain of writing the square root of the sum of the squares.

+100=0. Sorry, I need a bit of context…

1 Like

quick note: An undefined name inside omitkeys is now repaired.
q.v. two recipes for subselecting entries in a NamedTuple.