# Help understanding broadcasted pipe operator

I would expect the result of

[1, 2] .|> u->u^2 |> sum

to give the answer 5 since

[1, 2] .|> u->u^2

gives

2-element Array{Int64,1}:
1
4

and

[1, 4] |> sum

gives 5.

[1, 2] .|> u->u^2 |> sum

2-element Array{Int64,1}:
1
4

What’s going on here? It seems like the second pipe is broadcasting over the vector even though I am not using the dot pipe operator.

What’s weird is I can call them separately in the REPL and it works the way I expect it to:

julia> [1, 2] .|> u->u^2
2-element Array{Int64,1}:
1
4

julia> ans |> sum
5
1 Like
julia> ([1, 2] .|> u->u^2) |> sum
5

Can’t explain why though

I think it gets parsed as [1, 2] .|> (u->u^2) |> sum)

julia> Meta.lower(Main,:([1, 2] .|> u->u^2 |> sum))
# ...
│   %2  = (Core.svec)(##10#11, Core.Any)
│   %3  = (Core.svec)()
│   %4  = (Core.svec)(%2, %3)
#...
(%1)()
(Base.literal_pow)(^, u, %2)
%3 |> sum
return %4
end)))
#...
2 Likes

Even simpler than Meta.lower, you can just see it by quoting it:

julia> :([1, 2] .|> u->u^2 |> sum)
:([1, 2] .|> (u->begin
#= REPL[2]:1 =#
u ^ 2 |> sum
end))

This is how it works without broadcasting, too:

julia> :([1, 2] |> u->u^2 |> sum)
:([1, 2] |> (u->begin
#= REPL[3]:1 =#
u ^ 2 |> sum
end))

The trick is that the last |> is becoming a part of the anonymous function! Here’s another fix:

julia> [1, 2] .|> (u->u^2) |> sum
5
8 Likes

Oh, that makes sense. Thanks!