Is it possible to dispatch on a trait inheritance hierarchy without invoking dynamic dispatch?
if dispatch can be determined at compile time it will be for example:
struct SomeType
x::Int
end
struct SomeTrait end
hasSomeTrait(::SomeType) = SomeTrait()
hasSomeTrait(::Any) = nothing
f(x) = f(x,hasSomeTrait(x))
f(x,::SomeTrait) = 3
f(x,::Any) = 4
If we look at the code produced we can see that the compiler used static dispatch. It can do this because of constant propagation.
julia> @code_llvm f(SomeType(2))
; @ REPL[5]:1 within `f'
define i64 @julia_f_12189({ i64 } addrspace(11)* nocapture nonnull readonly dereferenceable(8)) {
top:
ret i64 3
}
2 Likes
Thanks. Yes, but that’s only one level.
For example, what if I’d like to dispatch on an abstract trait type from which SomeTrait is a subtype?
so something more like the following?
abstract type AbstractSomeType end
struct SomeType <: AbstractSomeType
x::Int
end
abstract type AbstractSomeTrait end
struct SomeTrait <: AbstractSomeTrait end
hasSomeTrait(::AbstractSomeType) = SomeTrait()
hasSomeTrait(::Any) = nothing
f(x) = f(x,hasSomeTrait(x))
f(x,::AbstractSomeTrait) = 3
f(x,::Any) = 4
In this case we can see that it still uses static dispatch
julia> @code_llvm f(SomeType(2))
; @ REPL[7]:1 within `f'
define i64 @julia_f_12188({ i64 } addrspace(11)* nocapture nonnull readonly dereferenceable(8)) {
top:
ret i64 3
}
2 Likes
That looks great. Thanks!