# Is there a way to repeatedly call a function

**URL:** <https://discourse.julialang.org/t/is-there-a-way-to-repeatedly-call-a-function/107762>\
**Category:** General Usage\
**Created:** [December 18, 2023, 10:03am UTC](https://discourse.julialang.org/t/is-there-a-way-to-repeatedly-call-a-function/107762 "2023-12-18T10:03:54Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Zentrik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zentrik/32/35409_2.png) [@Zentrik](https://discourse.julialang.org/u/Zentrik)\
**Post date:** [December 18, 2023, 10:03am UTC](https://discourse.julialang.org/t/is-there-a-way-to-repeatedly-call-a-function/107762/1 "2023-12-18T10:03:54Z")

</div>

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`.

---

<div class="post-metadata">

**Author:** ![Alseidon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alseidon/32/207775_2.png) [@Alseidon](https://discourse.julialang.org/u/Alseidon)\
**Post date:** [December 18, 2023, 10:18am UTC](https://discourse.julialang.org/t/is-there-a-way-to-repeatedly-call-a-function/107762/2 "2023-12-18T10:18:21Z")

</div>

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 :

```julia
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…

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

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [December 18, 2023, 10:29am UTC](https://discourse.julialang.org/t/is-there-a-way-to-repeatedly-call-a-function/107762/3 "2023-12-18T10:29:39Z")

</div>

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

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

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

```

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

---

<div class="post-metadata">

**Author:** ![Alseidon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alseidon/32/207775_2.png) [@Alseidon](https://discourse.julialang.org/u/Alseidon)\
**Post date:** [December 18, 2023, 10:35am UTC](https://discourse.julialang.org/t/is-there-a-way-to-repeatedly-call-a-function/107762/4 "2023-12-18T10:35:53Z")

</div>

Yes, I assumed it was defined before indeed.

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [December 18, 2023, 10:37am UTC](https://discourse.julialang.org/t/is-there-a-way-to-repeatedly-call-a-function/107762/5 "2023-12-18T10:37:32Z")

</div>

You can do a one-liner like

```julia
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.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [December 18, 2023, 10:38am UTC](https://discourse.julialang.org/t/is-there-a-way-to-repeatedly-call-a-function/107762/6 "2023-12-18T10:38:07Z")

</div>

> [@Alseidon](#):
>
> Although I heard recursive functions can actually be slow, so I don’t know if this is recommended.

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.

```julia
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

```

> [@Alseidon](#):
>
> Yes, I assumed it was defined before indeed.

Even so, it would _only_ work for one specific, named function, `f`.

---

<div class="post-metadata">

**Author:** ![JM\_Beckers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jm_beckers/32/22482_2.png) [@JM\_Beckers](https://discourse.julialang.org/u/JM_Beckers)\
**Post date:** [December 18, 2023, 10:44am UTC](https://discourse.julialang.org/t/is-there-a-way-to-repeatedly-call-a-function/107762/7 "2023-12-18T10:44:53Z")

</div>

Maybe this: ?

> [@Seven Lines of Julia (examples sought)](https://discourse.julialang.org/t/seven-lines-of-julia-examples-sought/50416/160):
>
> using IterTools using Statistics F(x)=[mean(x),prod(x)^(1/length(x)), median(x)] Fnx(x,n)=nth(iterated(F,x),n)

---

<div class="post-metadata">

**Author:** ![mike.ingold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mike.ingold/32/203749_2.png) [@mike.ingold](https://discourse.julialang.org/u/mike.ingold)\
**Post date:** [December 18, 2023, 2:17pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-repeatedly-call-a-function/107762/8 "2023-12-18T14:17:58Z")

</div>

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

```julia
using IterTools

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

```

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [December 18, 2023, 2:21pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-repeatedly-call-a-function/107762/9 "2023-12-18T14:21:44Z")

</div>

> [@Zentrik](#):
>
> Is there a nice notation to do this for `n` not known at compile time, ideally something like `f^n`.

We had discussed supporting `f^n`, but there wasn’t a consensus in favor:

> <https://github.com/JuliaLang/julia/pull/39042>
>
> As suggested in https://github.com/JuliaLang/julia/pull/34251#issuecomment-63620…3066 by @StefanKarpinski and motivated more recently by #39031 for \`dirname\`, this PR defines \`function^n\` as an \[iterated function\](https://en.wikipedia.org/wiki/Iterated\_function).
> 
> For example, \`(dirname^2)("/foo/bar/baz") == dirname(dirname("/foo/bar/baz")) == "/foo"\`, and \`((x -\> (x + 2/x)/2)^10)(1.234)\` performs 10 iterations of \[Newton's method for \`sqrt(2)\`\](http://www.sosmath.com/calculus/diff/der07/der07.html), giving \`1.414213562373095 ≈ sqrt(2)\`.
> 
> (Note that you must call \`f^2\` as \`(f^2)(x)\`, not \`f^2(x)\`, because the latter is parsed as \`f^(2(x))\`.)
> 
> Using \`literal\_pow\`, I made \`f^0 == identity\`, \`f^1 == f\`, and \`f^2 == f ∘ f\`, up to \`f^4\`, for improved type inferability and inlining. (Note that \`f^-1\` already calls \`inv(f)\`, generally giving a \`MethodError\`, from \`literal\_pow\`, and the interpretation as an iterated function is consistent with \`f^-1\` denoting an inverse function.)
> 
> Keyword arguments of \`f^n\` are passed through to \`f\`. I also changed the \`identity\` function to ignore keyword arguments, and changed \`f ∘ g\` to pass any keywords through to both functions — previously, keywords were not allowed in either case, while the documentation for \`f ∘ g\` incorrectly stated that keywords were passed to \`g\`, so the new behavior is backwards compatible and more useful.

---

<div class="post-metadata">

**Author:** ![jd-foster](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jd-foster/32/35824_2.png) [@jd-foster](https://discourse.julialang.org/u/jd-foster)\
**Post date:** [December 20, 2023, 12:33pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-repeatedly-call-a-function/107762/10 "2023-12-20T12:33:27Z")

</div>

Another suggested previously is

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

```

Edit: Better (as suggested below) is either

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

```

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

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

```

---

<div class="post-metadata">

**Author:** ![StevenSiew](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevensiew/32/218393_2.png) [@StevenSiew](https://discourse.julialang.org/u/StevenSiew)\
**Post date:** [December 20, 2023, 8:42pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-repeatedly-call-a-function/107762/11 "2023-12-20T20:42:51Z")

</div>

This is how I do it

```julia
    #=
       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))

```

---

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [December 21, 2023, 9:08pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-repeatedly-call-a-function/107762/12 "2023-12-21T21:08:58Z")

</div>

```julia

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

```

---

<div class="post-metadata">

**Author:** ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)\
**Post date:** [December 21, 2023, 10:41pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-repeatedly-call-a-function/107762/13 "2023-12-21T22:41:31Z")

</div>

> [@jd-foster](#):
>
> `foldl(|>, Iterators.repeated(f, n))`

I think you forgot the `;init = x` parameter.

More options:

```julia
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.
