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.