Hi community!
Is it a radian? Is it a degree? Who cares! With Angles.jl
you’ll never again need to worry about using sin
or sind
.
I built the package we discussed in the previous discussion about a native angle type. The package is not registered yet because I’m hoping for a major breakthrough in how an Angle
could automatically inherit all of the functionalities a subtype of Number
has (see some details about that in this topic).
Please feel free to contribute, file issues, PR, etc. I’d appreciate any input you might have.
Cheers!
Yakir
2 Likes
You’re replacing methods defined in Base
(namely those of inverse trigonometric functions with Number
input), I think this configures as type piracy.
Oh… how? I didn’t (over)write a asin
function, I made a new arcsin
function. Not sure I understand how that is type piracy. Could you explain?
Oh, sorry, didn’t notice the names were different from those in Base
. However, the point of the package is to avoid confusion between sin
/sind
functions (and that’s fine), but now you’re introducing new inverse functions that does the practically same as functions in Base
. Isn’t this a contradiction?
Yea, you’re right, but hell if I know how to make asin
spit a (say) Radian
without committing type piracy. Let me know if you know how (seriously).
Probably I wouldn’t have defined methods for inverse functions Or, maybe, extend base methods with an extra argument specifying the return type, that relies, for example, on asin
/asind
?
asin(-0.5, Radian)
asin(sqrt(3)/2, Degree)
“The first argument can be omitted to get the default” is a pretty standard pattern too, eg
asin(Radian, 0.5)
I like that a lot! Here is the method with the two-argument version:
julia> using Angles
julia> import Base.asin
julia> asin(::Type{T}, x::Number) where {T <: Angle} = T(Radian(asin(x)))
asin (generic function with 11 methods)
julia> asin(Degree, 0.5)
Angles.Degree{Float64}(30.000000000000004)
But how would you define the method for when the first argument is omitted without committing type piracy on the normal version of asin
?
I wouldn’t. That’s the point — Base.asin
is defined, the fallback is radians, no existing code breaks.
Sorry, I thought you meant there would be a way to call asin(x)
and get Radian
back. But the only two options I have is either having a new function with just one argument (e.g. arcsin(x)
), or the good-old asin
with two arguments (i.e. asin(::Type{T}, x)
). Correct?
I was just suggesting that extending Base.asin
in with an extra parameter may be a good design choice.
I understand and agree. Doing it.
Ordinarily, I would expect that Angle
should be a subtype of Number
, in the same way that Unitful.Quantity
is. Also, I’m not sure why you aren’t building this package on top of Unitful
, which implements a lot of infrastructure to handle units and already has a degree type.
Agreed, I changed Angle to be a subtype of Number.
My motivations to not building this on top of Unitful
are:
- This is a learning process for me.
-
Unitful
is big, complete, and works really well in context of other units and dimensions. I love it! But this Angles
package is really small, doesn’t do much more than keeping the trig functions in check, and is more of a test to see if people would like to have an innate Angle
type in Julia.
- Are there other entities that are in
Unitful
and should/could get refractured into their own little packages? Are there things in Julia that should be in Unitful
? Hard to answer, but arguable for sure. I feel that Angles
falls into one of these grey zones: angles are more widely used than say volumes, and could benefit from their own smaller package.
Unless you want to give meaning to a complex angle, the angle should be a real quantity, so Angle
should be better a subtype of Real
, rather than Number
. You’d also replace all occurrences of Number
with Real
in the code.
Perfectly meaningful…what do you think asin(1.2+0im)
is?
The extension to complex plane of a well defined mathematical function. I mean, is there a physical meaning of “1.2 + 3.4im
radians/degrees”? deg2rad
and rad2deg
aren’t defined for complex input in Julia (for the record, they should be in Matlab). The package seems more oriented to handle conversion between physical angles with different units.
Or I could just keep it as a subtype of Number
, extending the functionality of the package to include angles with imaginary numbers and not losing any of its performance (I think…).
Sorry, I don’t get what you mean.
My point is that, as far as I know, there is no such thing like “complex angle”. There are complex numbers to which trigonometric functions can be applied, but I couldn’t find an interpretation of these numbers as geometrical or physical angles. I thought about solid angles, that are two-dimensional angles, but it doesn’t seem that complex numbers are used to represent in any way solid angles.
1 Like