# Union splitting over abstract types

**URL:** <https://discourse.julialang.org/t/union-splitting-over-abstract-types/45568>\
**Category:** General Usage\
**Tags:** performance\
**Created:** [August 26, 2020, 11:00am UTC](https://discourse.julialang.org/t/union-splitting-over-abstract-types/45568 "2020-08-26T11:00:25Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [August 26, 2020, 11:00am UTC](https://discourse.julialang.org/t/union-splitting-over-abstract-types/45568/1 "2020-08-26T11:00:25Z")

</div>

If I have an abstract type `X` whose only subtypes are `A` and `B`, will union-splitting kick in and make dispatching over an object inferred as `X` as efficient as dispatching over one inferred as `Union{A, B}`?

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [August 26, 2020, 11:04am UTC](https://discourse.julialang.org/t/union-splitting-over-abstract-types/45568/2 "2020-08-26T11:04:37Z")

</div>

I am not 100% sure, but from my earlier testing, I don’t think it happens.

---

<div class="post-metadata">

**Author:** ![Keno](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/keno/32/285_2.png) [@Keno](https://discourse.julialang.org/u/Keno)\
**Post date:** [August 26, 2020, 11:35am UTC](https://discourse.julialang.org/t/union-splitting-over-abstract-types/45568/3 "2020-08-26T11:35:49Z")

</div>

No, it doesn’t. The reason is that we would then have to invalidate code when you add another subtype of `X`, which is not something we can currently track in the system (nor is it clear that it’s desirable).

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [August 26, 2020, 2:06pm UTC](https://discourse.julialang.org/t/union-splitting-over-abstract-types/45568/4 "2020-08-26T14:06:53Z")

</div>

I’m biased, but I really like the approach described in  
[https://timholy.github.io/SnoopCompile.jl/stable/snoopr/#Inferrable-field-access-for-abstract-types-1](https://timholy.github.io/SnoopCompile.jl/stable/snoopr/#Inferrable-field-access-for-abstract-types-1)

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [August 26, 2020, 2:37pm UTC](https://discourse.julialang.org/t/union-splitting-over-abstract-types/45568/5 "2020-08-26T14:37:12Z")

</div>

I don’t understand how that would help. My concern is mainly with

```julia
struct ClassRoom
    people::Vector{Union{Student, Teacher}}
end

```

having better runtime performance than

```julia
struct ClassRoom
    people::Vector{AbstractClassMember}
end

```

On a side note, it’s cool that

```julia
struct ClassRoom
    people::Vector{subtypes(AbstractClassMember)...}
end

```

works. With the caveat that it doesn’t support new types of course.

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [August 26, 2020, 2:59pm UTC](https://discourse.julialang.org/t/union-splitting-over-abstract-types/45568/6 "2020-08-26T14:59:18Z")

</div>

Yeah, it depends on what you’re doing. Basically what it helps with is if `people` has fields and you write code that accesses those fields: even if it has no idea what kind of object `people` is, inference now knows what types of objects you’re pulling out of its fields.

I’ve been using this trick in quite a few places in Base and the stdlibs (for `LibuvStream`, `LibuvServer`, `AbstractPipe`, `LibGit2.AbstractGitObject`, and `LibGit2.GitObject`) and it’s really cleaned up a lot of inference problems. But these are all cases where the ~~abstract~~ type is essentially a field-container and you don’t do a ton of stuff with the container itself.
