# Type instability with Union or heterogenous array/tuple

**URL:** <https://discourse.julialang.org/t/type-instability-with-union-or-heterogenous-array-tuple/78122>\
**Category:** General Usage\
**Tags:** type-stability\
**Created:** [March 19, 2022, 7:35am UTC](https://discourse.julialang.org/t/type-instability-with-union-or-heterogenous-array-tuple/78122 "2022-03-19T07:35:54Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Marcell\_Havlik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcell_havlik/32/37424_2.png) [@Marcell\_Havlik](https://discourse.julialang.org/u/Marcell_Havlik)\
**Post date:** [March 19, 2022, 7:35am UTC](https://discourse.julialang.org/t/type-instability-with-union-or-heterogenous-array-tuple/78122/1 "2022-03-19T07:35:54Z")

</div>

Hey Julianners,

I just cannot figure out how to make type stable code in case when we have a “sort of” heterogeneous array or tuple and we randomly pick an element.  
I did this minimal example.

```julia
hn(qq) = begin
	local r
	q=qq[rand([1,3])]
	if isa(q, Int)
		r=4
	elseif isa(q,Float32)
		r=3f0
	else
		r=1e0
	end
	return r
end
@code_warntype hn((3,3f0,2))
hn((3,3f0,2))

```

Is this something that isn’t possible to resolve in any certain way in Julia?

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [March 19, 2022, 8:19am UTC](https://discourse.julialang.org/t/type-instability-with-union-or-heterogenous-array-tuple/78122/2 "2022-03-19T08:19:06Z")

</div>

Your function is fundamentally unstable, it literally draws a random type at runtime. Your type assertions only make individual branches type stable, but the return value of the function is still unknown to the compiler.

---

<div class="post-metadata">

**Author:** ![Marcell\_Havlik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcell_havlik/32/37424_2.png) [@Marcell\_Havlik](https://discourse.julialang.org/u/Marcell_Havlik)\
**Post date:** [March 19, 2022, 8:20am UTC](https://discourse.julialang.org/t/type-instability-with-union-or-heterogenous-array-tuple/78122/3 "2022-03-19T08:20:16Z")

</div>

Yeah, you are right… I just want this to be type stable… 😃  
I guess you basically proved it isn’t possible.

So:

```julia
fn(arr::heterogenous type) =
  x=arr[pick random] # only available in run time
  return x # cannot be deferred or fixed any certain way?
end

```

But then how to handle the heterogeneous types in Julia? ☹

---

<div class="post-metadata">

**Author:** ![Marcell\_Havlik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcell_havlik/32/37424_2.png) [@Marcell\_Havlik](https://discourse.julialang.org/u/Marcell_Havlik)\
**Post date:** [March 19, 2022, 8:25am UTC](https://discourse.julialang.org/t/type-instability-with-union-or-heterogenous-array-tuple/78122/4 "2022-03-19T08:25:41Z")

</div>

In C++ we could write a very performant code with virtual functions I think. Does this something that cannot be accomplised with Julia?

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [March 19, 2022, 8:31am UTC](https://discourse.julialang.org/t/type-instability-with-union-or-heterogenous-array-tuple/78122/5 "2022-03-19T08:31:38Z")

</div>

You can use the trick with type assertions like you did, but inside the branches you should call a function that performs the work. You want to avoid the instability propagating to the compute heavy parts of your code.

---

<div class="post-metadata">

**Author:** ![simsurace](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simsurace/32/30216_2.png) [@simsurace](https://discourse.julialang.org/u/simsurace)\
**Post date:** [March 19, 2022, 12:09pm UTC](https://discourse.julialang.org/t/type-instability-with-union-or-heterogenous-array-tuple/78122/6 "2022-03-19T12:09:35Z")

</div>

When you have heterogeneous data whose elements are accessed based on runtime information, try to minimize the code that runs in the uninferred state, i.e. wrap subsequent code in a function that can be specialized to the different types. Using the profiler, you can then check that often the run-time dispatch overhead is negligible. That is, the fact that the top function call is type-unstable is not actually detrimental to performance.

---

<div class="post-metadata">

**Author:** ![Marcell\_Havlik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcell_havlik/32/37424_2.png) [@Marcell\_Havlik](https://discourse.julialang.org/u/Marcell_Havlik)\
**Post date:** [March 19, 2022, 12:43pm UTC](https://discourse.julialang.org/t/type-instability-with-union-or-heterogenous-array-tuple/78122/7 "2022-03-19T12:43:46Z")

</div>

So basically I could write something like this and it is optimal:

```julia
calc(a::Vector{Float32}) = a.+=1f0
calc(a::Vector{Float64}) = a.+=1e0
qn(hetarrs) = begin
  arr = hetarrs[rand([1,2])]
  calc(arr)
end

vv = (
randn(Float32,10000),
randn(Float64,10000),
)
# @code_warntype qn(vv)
qn(vv)

```

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [March 19, 2022, 2:21pm UTC](https://discourse.julialang.org/t/type-instability-with-union-or-heterogenous-array-tuple/78122/8 "2022-03-19T14:21:12Z")

</div>

Yes, the advantage of doing it this way is that you pay the cost of the type instability a single time, at the call for `calc`.

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [March 19, 2022, 3:23pm UTC](https://discourse.julialang.org/t/type-instability-with-union-or-heterogenous-array-tuple/78122/9 "2022-03-19T15:23:31Z")

</div>

This approach is called a “function barrier” where `qn` is unstable, but the `calc` function serves as a barrier for the instability beyond which the types are known. The call to `calc` incurs dynamic dispatch, but `calc` itself is not affected.
