I am wondering if there is a recommended way to deal with constants in generic code (ie supporting user types).
Example adding a rational f(x) = x+2/3
- Implementation 1:
f(x::T) where T = x + T(2)/T(3)
- Implementation 2:
f(x::T) where T = x .+ 2//3
- Implementation 3:
function f(x)
T = typeof(x)
x + T(2)/T(3)
end
AFAIK implementation 1 and 3 are equivalent.
Implementation 1 and 2 should have similar efficiency if the compiler can perform constant propagation.
I would say implementation 2 is better since it works with arrays whereas implementation 1 and 3 do not.
Also for irrational. eg adding 2pi f(x) = x+2pi
Implementation 1:
- Implementation 1:
f(x::T) where T = x + 2*T(pi)
- Implementation 2:
f(x::T) where T = x + 2*(pi*one(T))
This does not work with arrays.
- Implementation 3:
f(x::T) where T = (x .+ pi) .+ pi
works with array but not very nice to look at.
Those are the criterions I can think of to decide on best approach:
- precision should match user type (BigFloat, Float64,…)
- ability to support extended types such as DualNumbers, ForwardDiff, Vectors and Arrays…
- efficiency
- code readability
Thank you