Good way to parametrize over type parameter?

Hi,

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?

1 Like

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:

1 Like

OK thanks for the information!

1 Like

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?

It is kosher for performance, but it does not seem like a nice style IMO.