How to use `Anonymous Function` in `Function Piping`?

Currently, I’m learning the Function Piping. And I try to imitate the following example:

julia> 1:10 |> sum |> sqrt

with function piping to realize my purpose:

  • Step 1: Square each element in the list,
  • Step 2: Sum them up,
  • Step 3: Sqrt(var…)

But I got into trouble even in step 1. My initial code snippet is:

1:5 |> (x->x^2)

the above does not work. Can anyone help me to square each element in the list using Function piping with anonymous function.



Background
I have some experience in Mathematica, and step 1 can be expressed as:

Map[#^2 &, Range[1, 5]] 

where, #^2 & is a pure function, which is called an anonymous function in Julia.

help?> |>
search: |>

  |>(x, f)

  Applies a function to the preceding argument. This allows for easy function chaining.

  Examples
  ≡≡≡≡≡≡≡≡≡≡

  julia> [1:5;] |> x->x.^2 |> sum |> inv
  0.01818181818181818

So:

1:5 |> x -> x .^ 2
3 Likes

By the way, could you help to explain the difference between [1:5] and [1:5;]? And why there should a ; in the end of [1:5;]? (Just any reference is OK.)

I guesstimate that if there is only one element in the array, we should suffix some punctuation (here is the semicolon) to indicate whether this array is an row vector, column vector.

Can someone affirm my guess?

https://docs.julialang.org/en/v1/manual/arrays/#man-array-concatenation

If the arguments inside the square brackets are separated by semicolons ( ; ) or newlines instead of commas, then their contents are vertically concatenated together instead of the arguments being used as elements themselves.

This means on the other side, that [1:5] is an array with a UnitRange as the only element:

julia> [1:5]
1-element Array{UnitRange{Int64},1}:
 1:5

julia> length([1:5])
1
3 Likes

Thanks very much. You illuminate my puzzle.

I think the main issue with your code segment is that you didn’t use a dot to broadcast the operation over the range and perform it elementwise

1:5 |> x -> x^2 # Will error, squaring a range not defined

1:5 .|> x -> x^2 # OK, passes each element of range into function

1:5 |> x -> x.^2 # also ok
3 Likes

I get it. Thank you.

1 Like

By the way, the equivalent of this in Julia is

map(x -> x^2, 1:5)

It’s weird that the documentation suggest collecting a range like this. You should generally never collect ranges, so this

is better.

But if your purpose is to

then you shouldn’t use piping at all, since you will needlessly allocate intermediate arrays. Instead do this:

sqrt(sum(abs2, 1:5))

(You can use abs2 or x->x^2 depending on whatever your specific needs are.)

2 Likes