Julia Union Splitting
Union splitting is the compiler making a separate fast path for each member type of a union type. Each path handles one member type directly.
One function accepts two kinds of numbers
The argument type lists both member types. Each call uses the matching member path.
doubleit(x::Union{Int, Float64}) = x * 2
println(doubleit(3))
println(doubleit(2.5))Each member follows its own branch
The branch test picks the member path. The integer branch and the decimal branch give different results.
bonus(x::Union{Int, Float64}) = x isa Int ? x + 100 : x + 0.5
println(bonus(3))
println(bonus(2.5))A mixed collection stays cheap to sum
Both collections hold the same values. The union collection needs fewer allocations than the general collection.
total_union(xs) = sum(xs)
total_any(xs) = sum(xs)
u = Union{Int, Float64}[1, 2.5, 3]
a = Any[1, 2.5, 3]
total_union(u)
total_any(a)
println(total_union(u))
println(@allocated total_union(u))
println(total_any(a))
println(@allocated total_any(a))Example
reward(x::Union{Int, Float64}) = x isa Int ? x * 10 : x * 2.0
values = Union{Int, Float64}[3, 2.5, 4]
println(reward(3))
println(reward(2.5))
println(sum(reward(v) for v in values))Key points
- Union type: a type that allows values from two or more member types.
- Member type: one of the types listed inside a union type.
- Fast path: one compiled path that handles a single member type.
- Use a union argument to let one function accept two kinds of values.
- Mixed collection: a collection whose elements come from the member types of a union type.
In this example, reward doubles a decimal value and multiplies an integer value by ten. The values collection holds integers and decimals together. The final line sums the reward for every value in the collection.
Note
Julia builds the member paths at compile time, so each call runs on its own path.
Try it Yourself
Edit the code, then press Run.
Running is simulated · JuliaHub
Exercise
What does union splitting give each member type of a union argument?