# Recursively applied 1D function

**URL:** <https://discourse.julialang.org/t/recursively-applied-1d-function/67602>\
**Category:** General Usage\
**Tags:** function\
**Created:** [September 2, 2021, 9:53pm UTC](https://discourse.julialang.org/t/recursively-applied-1d-function/67602 "2021-09-02T21:53:54Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![cmdenis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cmdenis/32/211517_2.png) [@cmdenis](https://discourse.julialang.org/u/cmdenis)\
**Post date:** [September 2, 2021, 9:53pm UTC](https://discourse.julialang.org/t/recursively-applied-1d-function/67602/1 "2021-09-02T21:53:54Z")

</div>

Hello,

I am trying to compose the same function with itself n times efficiently. I found a way of doing that using macros, but it gave me a lot of problems when being used within functions and using elements that were not parts of the global scope. So, an example that was working well, before using it in a local scope was:

```julia
macro recur(map_name, iter_num, val_input)
	eval(Meta.parse(string(string(map_name, "(")^iter_num, val_input, ")"^iter_num)))
end

```

and then using, for instance:

```julia
g(x) = x^2

@recur g 10 1.001

```

which yields: `2.7828855056543795`. I also did a similar thing using a function, but the core concept remains the same.

My question is: What would be a better way of doing this? Is there some built-in way of manipulating composition of function, without having to write up explicitly the composition, like `g(g(g(g(g(g(g(g(g(g(1.001))))))))))` or `(g∘g∘g∘g∘g∘g∘g∘g∘g∘g)(1.001)`?

Thanks!

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [September 2, 2021, 10:19pm UTC](https://discourse.julialang.org/t/recursively-applied-1d-function/67602/2 "2021-09-02T22:19:36Z")

</div>

The first note I’d make is that it’s ~never necessary to use string manipulation, `eval`, or `Meta.parse` inside a macro. One of the many reasons not to use `eval` in particular is that it causes your code to be run when the macro is _expanded_, which is almost never what you want:

```julia
julia> macro recur(map_name, iter_num, val_input)
               eval(Meta.parse(string(string(map_name, "(")^iter_num, val_input, ")"^iter_num)))
       end
@recur (macro with 1 method)

julia> f() = @recur g 10 1.001
ERROR: LoadError: UndefVarError: g not defined

```

This fails (in a new Julia session) because `eval` tries to call `g(...)` when you _define_ `f`, which is definitely wrong.

Fortunately, it’s easy to avoid strings, `eval` and `Meta.parse` because Julia’s built-in expression objects are much easier to work with. A macro similar to yours but with none of those red flags might be:

```julia
julia> macro recur(map_name, iter_num, val_input)
         expr = :($(esc(map_name))) # start with a single call
         for i in 2:iter_num
           expr = :($(esc(map_name)) ∘ $expr) # turn `f` into `f \circ f`
         end
         return quote # return an expression which computes the result
           $(expr)($(esc(val_input))) 
         end
       end
@recur (macro with 1 method)

```

However, I don’t really think there’s any need for metaprogamming here at all. Instead, I’d just write a function:

```julia
julia> function recur(f, iter_num, val)
         @assert iter_num >= 1
         output = f(val)
         for i in 2:iter_num
           output = f(output)
         end
         return output
       end
recur (generic function with 1 method)

julia> g(x) = x^2
g (generic function with 1 method)

julia> recur(g, 10, 1.001)
2.7828855056543795

```

Or, if you want something without a loop, then we can use, well, recursion…

```julia
julia> function recur(f, iter_num, val)
         @assert iter_num >= 1
         if iter_num == 1
           f(val)
         else
           f(recur(f, iter_num - 1, val))
         end
       end
recur (generic function with 1 method)

julia> g(x) = x^2
g (generic function with 1 method)

julia> recur(g, 10, 1.001)
2.7828855056543795

```

---

<div class="post-metadata">

**Author:** ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)\
**Post date:** [September 2, 2021, 11:00pm UTC](https://discourse.julialang.org/t/recursively-applied-1d-function/67602/3 "2021-09-02T23:00:09Z")

</div>

Note that `∘` accepts any number of arguments, so you can do this (even if you probably shouldn’t):

```julia
julia> Base.:^(f::Function, n::Int) = ∘(ntuple(_ -> f, n)...)

julia> sin^3
sin ∘ sin ∘ sin

julia> ((!)^17)(true)
false

```

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [September 2, 2021, 11:17pm UTC](https://discourse.julialang.org/t/recursively-applied-1d-function/67602/4 "2021-09-02T23:17:15Z")

</div>

[This great post](https://discourse.julialang.org/t/seven-lines-of-julia-examples-sought/50416/81) by @FedericoStra, might be of interest.  
Applying it to OP’s case:

```julia
g(x) = x^2
Gn(x, n) = foldl((y,_) -> g(y), 1:n; init=x)
Gn(1.001, 10)
2.7828855056543795

```
