So, because the Julia compiler infers return type of a function given the input types. All DispatchDoctor does is, for a function f1
:
- Puts
f1
’s body into a separate function definition, with an identical signature, but a different name. Let’s call itf2
. - From the original function
f1
, it removes the original body, and inserts code that will checks the compiler-inferred type off2
given the types ofargs
. f1
runsBase.isconcretetype
on that inferred type, and if false, throws an error.- Otherwise,
f1
callsf2(args…)
, and returns the result.
So because the inference of f2
and isconcretetype
are in “type space”, it can do that at compile time. Thus, if things are type stable, Julia should just remove the error message from the code altogether.
Basically this if-statement’s first term only depends on input types:
And if type_instability(T)
evaluates to false
, it should compile to
if false && ...
error()
end
f2(args...)
and then we assume LLVM will remove that if statement.
Well, I don’t want to say 100%. I haven’t found an example otherwise but with the Julia compiler and LLVM I never really feel 100% confident about an optimization taking place or not. It “should” compile away that if statement, but people should share examples otherwise.
I guess we could make ourselves 100% confident if we turn the checker function into a @generated
function, so that we can explicitly remove the if statement from the code. But I’m assuming the Julia compiler will do that for us.