Your parametric methods don’t use the parameter T . If you don’t need to use a parameter, you don’t need to write a parametric method e.g. fun_Bar(::Bar) ; the only reason I can think of for writing an unused parameter is to nudge the compiler to specialize over subtypes of Type , Function , and Vararg , which is only something you should try if you prove that specialization isn’t happening and specializing improves performance without excessively increasing compilation in your program.
I agree that the method doesn’t need to use the parameter in the example, and I was just trying to illustrate what seemed like the main problem in a minimal way. In the actual use case I have additional arguments that are also parametric, and I want everything that is of parametric type to be consistent.
Maybe it is helpful to explain the actual use case. I want to write a MathOptInterface wrapper for some solver, where the solver works for different data types as long as all data is of a common type. So I define my optimizer this way:
mutable struct Optimizer{T} <: MOI.AbstractOptimizer
<whatever>
end
Now I want to declare which constraint types I can support. Some of those types are non-parametric (MOI.Zeros for example) but others have data attached and so are parametric (MOI.PowerCone{T} for example). Now I want to collect all of the types I support in a Union:
const MySupportedCones{T <: Real} = Union{
MOI.Zeros,
MOI.PowerCone{T} #<--- removal causes errors
}
If I have MOI.PowerCone{T} in this Union, I get the Foo situation above. If I comment it out, I get the Bar situation. At the moment it is out because the solver does not yet support that type, but I want to leave open the possibility that it will in some future version.
This matters because now I want to declare support for these cones, but I want (in the case of MOI.PowerCone{T}) for the type to match that of the Optimizer. So I do something like this:
MOI.supports_constraint(
::Optimizer{T},
::Type{<:MOI.VectorOfVariables},
::Type{<:MySupportedCones{T}}
) where {T} = true
This fails if I don’t include MOI.PowerCone{T} in the union, because then the T is ignored in the union definition. However, I can’t just put Type{<:MySupportedCones} as an argument in supports_constraint because I want to return false if I get a MOI.PowerCone{Float64} but the optimizer is an Optimizer{Float32} or whatever.
As I said in the first message, I can get around this by just declaring a fake type parametric on T to include in the Union. It’s harmless because I know that MOI will never ask me about it anyway, so the question is mostly trying to understand what is going on.