I’m writing a numerical code that is parametrized by T, which is typically T=Float64 but could be one of the other number types. It’s a PDE solver so I’ve got a bunch of other types I call “geometries”, say A{T}, B{T}, etc…, to represent various finite element spaces in various dimensions on various domains.
Right now I’ve got functions that look like f(::Type{T},geometry::G) where {T,G} but I’d like to get rid of the redundant ::Type{T} parameter of f.
Should I just do get_T(A{T}) where {T} = T and then f(geometry::G) = (T = get_T(G); ...)? Will that get compiled down to equally as efficient code as if I specify T explicitly as a parameter of f?
Yeah, that’s perfect. Except that your get_T definition is missing a ::, it should look like:
get_T(::A{T}) where {T} = T
Then you call it like get_T(geometry), and you do not need G as a method static parameter of the f method.
If you really need to define get_T on the types, instead of on values, you can do it like so:
get_T(::Type{<:A{T}}) where {T} = T
If the geometries all have a field of type T, you can even do fieldtype(typeof(geometry), :field_name) instead of get_T(geometry). Then you do not need get_T.
In general, always avoid unnecessary method static parameters (where at the end of the definition of a method). Except as noted here, in the Performance tips:
Actually, what I ended up doing is something like f(geometry,::Type{T}=get_T(geometry);...) where {T} so that I can use the type T in subsequent keyword arguments, is this kosher for performance?