# Constants in generic code

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

Thank you

I think either the first or the third implementation is fine. Also, broadcasting over arrays should be an orthogonal issue, and I would not define the same method to both broadcast and work on scalars, unless there is a compelling reason.

Also, for some scalars which are composed from integers via operations that propagate type, it may be enough to just convert the first element, eg

``````f(x::T) where T = x  + T(2)/3
``````

Similarly,

``````f(x::T) where T = x  + 2*T(pi)
``````

would be my choice.

2 Likes