Some comments.
This part:
c::Union{Integer, AbstractFloat} = nothing
will not compile, you would have to write c::Union{Nothing, Integer, AbstractFloat} = nothing.
In general the typeof(c) <: AbstractFloat should be optimized out by the compiler since the compiler knows the exact type of c you are passing, so this style should not impact the performance of your code.
However, there are two considerations:
- Using multiple methods would probably lead to a cleaner code.
- If you use
Union you have to be more careful when defining methods to avoid dispatch ambiguities. Here is an example:
julia> f(x::Int, y::Union{Int, Float64}) = "f1"
f (generic function with 1 method)
julia> f(x::Integer, y::Int) = "f2"
f (generic function with 2 methods)
julia> f(1, 1)
ERROR: MethodError: f(::Int64, ::Int64) is ambiguous.
which is sometimes considered as surprising (although it is a correct behavior technically)
EDIT. Here is an example when the compiler does not complain as it can always establish a more specific method:
julia> g(x::Int, y::Union{Int, Float64}) = "f1"
g (generic function with 1 method)
julia> g(x::Integer, y::Union{Int, Float64}) = "f2"
g (generic function with 2 methods)
julia> g(1, 1)
"f1"