# Angle package

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

Very convenient! Thanks!

1 Like

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