Say I have a function `f`

, I want to call it repeatedly `n`

times. I.e. for `n = 3`

, I want `f ∘ f ∘ f`

. Is there a nice notation to do this for `n`

not known at compile time, ideally something like `f^n`

.

I can’t think of syntaxic sugar that would allow this in Julia. The prettiest way I could think of would be a recursive function :

```
f_rec(x, n) = (@assert n >= 0; n == 0 ? x : f_rec(f(x), n-1))
```

Although I heard recursive functions can actually be slow, so I don’t know if this is recommended.

Another way would be metaprogramming, although I don’t find this very clean…

```
# f^n(x) with n and x defined beforehand
"x" * reduce(*, [" |> f" for _ in 1:n]) |> Meta.parse |> eval
```

This doesn’t look right. You haven’t defined `f`

. Something like

```
apply(f, x, n::Integer) = ((n > 0) ? f(apply(f, x, n-1)) : x)
```

and, yeah, probably throw an error for negative `n`

.

Yes, I assumed it was defined before indeed.

You can do a one-liner like

```
julia> ↑(f, n) = x -> foldl(|>, fill(f, n), init = x)
↑ (generic function with 1 method)
julia> (sqrt ↑ 3)(2)
1.0905077326652577
```

but the `fill`

is wasteful so it can be implemented more efficiently.

Recursion can be slow for large `n`

, and at worst you can get a stack overflow. For small `n`

it should be fine.

For large `n`

, an iterative approach should be better, e.g.

```
function apply(f, n, x::Integer)
if n < 0
error("n must be >= 0.")
elseif n == 0
return x
end
y = f(x)
for _ in 2:n
y = f(y)
end
return y
end
```

Even so, it would *only* work for one specific, named function, `f`

.

Maybe this: ?

This looks like the winner to me. Applied to OP’s case it’s simply:

```
using IterTools
# Recursively apply function f to value x n times
fn(n,x) = nth(iterated(f,x),n)
```

We had discussed supporting `f^n`

, but there wasn’t a consensus in favor:

Another suggested previously is

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

Edit: Better (as suggested below) is either

```
F(f,n)=foldl(∘, Iterators.repeated(f, n))
```

for just the iterated function, or if including the function argument,

```
F(f,n,x) =foldl(|>, Iterators.repeated(f, n); init=x)
```

This is how I do it

```
#=
func_compose(func,n)
Compose a function multiple times
=#
function func_compose(func,n)
newfunc = func
local loop = n
while loop > 1
# help?> ∘
# "∘" can be typed by \circ<tab>
newfunc = func ∘ newfunc
loop -= 1
end
return newfunc
end
f = func_compose(sqrt,5)
println("f(123_456_789.0) = ",f(123_456_789.0))
```

```
F(f,n)=foldl(∘, Iterators.repeated(f, n))
F(f,n)=foldl(∘, ntuple(i->f,n))
F(f, n)=n>1 ? ∘(f,F(f,n-1)) : f
```

I think you forgot the `;init = x`

parameter.

More options:

```
F(f,n) = x->(for _ in 1:n x = f(x) ; end; x) # returns function
F(f,n,x) = (for _ in 1:n x = f(x) ; end; x)
```

Maybe not very tricky, but do the work without allocating on 1.9.4.