I am working with the DifferentialEquations package to play around some differential equations involving angles.

Instead of letting everything go on as a normal float and just afterwards reduce everything modulo 2pi for visualisation, i wanted to try to go the julian way and define a small wrapper for the Floag64 type

struct Angle <: Real
x::Float64
end
Angle(x::Real) = Angle(x % 2pi)

Unfortunately this is not enough to make for a smooth addition to my program as julia struggles to convert and does not know what to do with this new type.

I know that i can extend all the base operations by hand, but i was left wondering if there is a smoother and easier way to let a simple primitive Number type wrapper just automatically fall in place the rest of the Julia implementation.

More in general i tried to look for some quick guidelines when creating a new custom type but i could not find one. Are there any Best Practices ™ when it comes to seamlessly embed a new custom type in the language?

for single_param_function in (:(Base.sqrt), :(Base.sin))
eval(quote
function $(single_param_function)(a :: Angle)
return Angle($(single_param_function)(a.x))
end
end)
end

Someone with better knowledge of metaprogramming should check if this is reasonable (it works, but maybe is not ideal).

Note that you will get more accurate results by using mod2pi(x) instead of x % 2pi (since the latter uses 2pi, a Float64 approximation of the actual number 2π).

Is the sine of an angle another angle or just a number? If you don’t need it to be an angle, then simply defining Base.float for your type will work for a lot of functions that use this as their fallback.