Why Julia doesn't consider maximum function in the chained functions when combining anonymous function?

Viewed 77

I've just got aware of chaining functions (like a pipeline) in Julia for a couple of days. I was trying something today and got an unexpected result. Hence, I decided to ask about the root of the problem better to understand the behavior of Julia in chaining functions. Consider this example:

julia> a = [1 2 3]
1×3 Matrix{Int64}:
 1  2  3

Then I want to chain some functions like the below, and after all, I want the maximum value of the entire Matrix:

julia> a .|> x->x^2 .|> sqrt .|> Int64 |> maximum
1×3 Matrix{Int64}:
 1  2  3

But I expected just a 3! Why doesn't Julia consider that last function of the chain, namely, the maximum function?

PS: Also, I tried this way:

julia> a .|> x->x^2 .|> sqrt .|> Int64 |> x->maximum(x)
1×3 Matrix{Int64}:
 1  2  3

Still not what I expected it to be.

1 Answers

The problem is actually the arrow operator not the pipe! The pipes are fine.

Remember, you can always use the colon operator if you want to examine the parsing order:

julia> :(a .|> x->x^2 .|> sqrt .|> Int64 |> maximum)
:(a .|> (x->begin
              #= REPL[84]:1 =#
              ((x ^ 2 .|> sqrt) .|> Int64) |> maximum
          end))

The arrow first evaluates everything on the right, then pipes the result from the left (right associative), so what you have is the same as:

a .|> x->(x^2 .|> sqrt .|> Int64 |> maximum)

On the right you just create a function that pipes the argument (a single number in our example) all the way to maximum, and the mapping just does it 3 times giving you the result.

What you want is:

a .|> (x->x^2) .|> sqrt .|> Int64 |> maximum

I would generally make sure the arrow is wrapped in parenthesis wherever you use it together with pipes - it is very counter-intuitive otherwise!.

If you would have just done something like

a .|> sqrt |> maximum

you would have not noticed this. Note the associativity of piping makes perfect sense - the above is

maximum(sqrt.(a))

as you would expect. The thing about the right arrow function, is that it cannot really "know" what is supposed to be the function on the right, so it just parses everything.

Related