# |n> as notation for function piping n times?

Suppose you wanted to repeatedly compose a certain function via piping. For sake of argument, say we want to do

``````3 |> sqrt |> sqrt |> sqrt |> sqrt
``````

One can do this for an arbitrary number of times `n` (where `n = 4` above) using something relatively convoluted like

``````3 |> ∘(fill(sqrt,n)...)
``````

I think it would be great to have the following notation in Julia for this:

``````3 |n> sqrt
``````

Is this even implementable? Thoughts, either for or against?

Why not overload `^` for functions?
At least that would not require changes to the parser.

``````julia> Base.:(^)(f::Function, n::Integer) = ∘(fill(f,n)...)

julia> sqrt^3
sqrt ∘ sqrt ∘ sqrt

julia> (sqrt^3)(3)
1.147202690439877

julia> cbrt^3
cbrt ∘ cbrt ∘ cbrt

julia> (cbrt^3)(3)
1.041528498231435
``````
6 Likes
4 Likes

Isn’t this syntax ambiguous? One could parse it as `(3 | n) > sqrt`, where `|` is bitwise or and `>` is “greater than”. Currently this fails because `isless` is not defined for function types, but it isn’t hard to imagine an overload.

2 Likes

Thanks for all the responses. I’m still not clear that repeated piping is precisely the same as using function composition “exponentiation”.

Interestingly, the linked PR also links to issue #41579, where this way using the pipe repeatedly is also recorded:

``````foldl(|>, Iterators.repeated(foo, n))
``````

and seems to be quite fast among the alternatives.

1 Like

Toying with it a bit…

``````julia> |>ⁿ(x, (f, n)) = foldl(|>, Iterators.repeated(f, n); init=x)
|>ⁿ (generic function with 1 method)

julia> 3 |>ⁿ (sqrt, 4)
1.0710754830729146
``````
1 Like