# How to make type-stable: passing an element of a vector of functions

**URL:** <https://discourse.julialang.org/t/how-to-make-type-stable-passing-an-element-of-a-vector-of-functions/60068>\
**Category:** Performance\
**Tags:** question\
**Created:** [April 26, 2021, 10:27pm UTC](https://discourse.julialang.org/t/how-to-make-type-stable-passing-an-element-of-a-vector-of-functions/60068 "2021-04-26T22:27:25Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![sofiablopez](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sofiablopez/32/20488_2.png) [@sofiablopez](https://discourse.julialang.org/u/sofiablopez)\
**Post date:** [April 26, 2021, 10:27pm UTC](https://discourse.julialang.org/t/how-to-make-type-stable-passing-an-element-of-a-vector-of-functions/60068/1 "2021-04-26T22:27:25Z")

</div>

I have an array of functions, and I need to iterate it and pass each element of the array to another function. How can I make it type-stable?

This code illustrates my problem:

```julia
function f(g::Function, x::Int64)
     return g(x)
end

g1(x) = x^2
g2(x) = (1 - x)^2
garr = [g1, g2]

function test()
    for k = 1 : 2
           f(garr[k], 20)
    end
end

```

```julia
julia> @code_warntype test()
Variables
  #self#::Core.Const(test)
  @_2::Union{Nothing, Tuple{Int64, Int64}}
  k::Int64

Body::Nothing
1 ─ %1 = (1:2)::Core.Const(1:2)
│ (@_2 = Base.iterate(%1))
│ %3 = (@_2::Core.Const((1, 1)) === nothing)::Core.Const(false)
│ %4 = Base.not_int(%3)::Core.Const(true)
└── goto #4 if not %4
2 ┄ %6 = @_2::Tuple{Int64, Int64}::Tuple{Int64, Int64}
│ (k = Core.getfield(%6, 1))
│ %8 = Core.getfield(%6, 2)::Int64
│ %9 = Base.getindex(Main.garr, k)::Any
│ Main.f(%9, 20)
│ (@_2 = Base.iterate(%1, %8))
│ %12 = (@_2 === nothing)::Bool
│ %13 = Base.not_int(%12)::Bool
└── goto #4 if not %13
3 ─ goto #2
4 ┄ return nothing

```

However, when I run this, this issue doesn’t happen:

```julia
function test1()
        f(g1, 20)
end

```

```julia
julia> @code_warntype test1()
Variables
  #self#::Core.Const(test1)

Body::Int64
1 ─ %1 = Main.f(Main.g1, 20)::Core.Const(400)
└── return %1

```

---

<div class="post-metadata">

**Author:** ![ggggggggg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ggggggggg/32/265_2.png) [@ggggggggg](https://discourse.julialang.org/u/ggggggggg)\
**Post date:** [April 26, 2021, 10:31pm UTC](https://discourse.julialang.org/t/how-to-make-type-stable-passing-an-element-of-a-vector-of-functions/60068/2 "2021-04-26T22:31:57Z")

</div>

Use a tuple?

---

<div class="post-metadata">

**Author:** ![sofiablopez](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sofiablopez/32/20488_2.png) [@sofiablopez](https://discourse.julialang.org/u/sofiablopez)\
**Post date:** [April 26, 2021, 10:40pm UTC](https://discourse.julialang.org/t/how-to-make-type-stable-passing-an-element-of-a-vector-of-functions/60068/3 "2021-04-26T22:40:10Z")

</div>

Keep getting the same problem:

```julia
garr = (g1, g2)

```

```julia
julia> @code_warntype test()
Variables
  #self#::Core.Const(test)
  @_2::Union{Nothing, Tuple{Int64, Int64}}
  k::Int64

Body::Nothing
1 ─ %1 = (1:2)::Core.Const(1:2)
│ (@_2 = Base.iterate(%1))
│ %3 = (@_2::Core.Const((1, 1)) === nothing)::Core.Const(false)
│ %4 = Base.not_int(%3)::Core.Const(true)
└── goto #4 if not %4
2 ┄ %6 = @_2::Tuple{Int64, Int64}::Tuple{Int64, Int64}
│ (k = Core.getfield(%6, 1))
│ %8 = Core.getfield(%6, 2)::Int64
│ %9 = Base.getindex(Main.garr, k)::Any
│ Main.f(%9, 20)
│ (@_2 = Base.iterate(%1, %8))
│ %12 = (@_2 === nothing)::Bool
│ %13 = Base.not_int(%12)::Bool
└── goto #4 if not %13
3 ─ goto #2
4 ┄ return nothing

```

---

<div class="post-metadata">

**Author:** ![AndiMD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/andimd/32/6531_2.png) [@AndiMD](https://discourse.julialang.org/u/AndiMD)\
**Post date:** [April 26, 2021, 11:02pm UTC](https://discourse.julialang.org/t/how-to-make-type-stable-passing-an-element-of-a-vector-of-functions/60068/4 "2021-04-26T23:02:01Z")

</div>

The problem is that `garr` is a global variable that can change. You could pass it as an argument, or make it `const garr = (g1, g2)`.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [April 26, 2021, 11:31pm UTC](https://discourse.julialang.org/t/how-to-make-type-stable-passing-an-element-of-a-vector-of-functions/60068/5 "2021-04-26T23:31:44Z")

</div>

Each function has its own type, so I do not think that is possible in general. You will be in better shape if you can assert the return type of `f`, something like:

```julia
julia> function test2(garr)
           s = 0
           for i in eachindex(garr)
               s += f(garr[i],20)::Int
           end
           s
       end

julia> garr = [g1, g2];

julia> @btime test2($garr)
  29.114 ns (0 allocations: 0 bytes)
761

```

But if `garr` has more than a few types, that performance will probably break.
