swift-numerics icon indicating copy to clipboard operation
swift-numerics copied to clipboard

Angle type

Open karwa opened this issue 6 years ago • 5 comments

I wonder if we might rather define our trig functions in terms of an Angle type:

public struct Angle<T: Real> {
  public var radians: T
  public init(radians: T) { self.radians = radians }
  public static func radians(_ val: T) -> Angle<T> { .init(radians: val) }
  
  public var degrees: T { radians * 180 / .pi }
  public init(degrees: T) { self.init(radians: degrees * .pi / 180) }
  public static func degrees(_ val: T) -> Angle<T> { .init(degrees: val) }
}

Browsing SE-0246, this alternative design doesn't seem to have been considered, but I think it would help to make our functions more useful and self-documenting. Depending on what you're doing, it can be more natural to think in terms of degrees rather than radians. In C, people tend to bring these utility functions/macros by themselves, whereas other languages like Java include them as part of the standard library.

The design of the type given above means that creating and consuming an Angle in radians in essentially free.

Clearly, we cannot make this change to the ElementaryFunctions protocol requirements, as we need the conforming type to provide those implementations. However, we can do this for the free functions - either in addition to, or in place of the regular functions which take a <T:ElementaryFunctions> argument.

karwa avatar Dec 27 '19 21:12 karwa

I've thought about this design in the past (and did an implementation back in Swift 2 that I never published); it would be as-well-as, rather than instead-of, but it's not actually a bad idea. You start to get into weird typing questions if you aggressively go down this path with the trig functions (by analogy, exp should produce a result type that differs from its argument, with log having the reverse signature, and we need to make the types relate to the angle type when we move to complex operations), but for simpler use cases it can be pretty nice.

stephentyrone avatar Dec 28 '19 14:12 stephentyrone

Random thought...

Having Angle<T: Real> be a struct is good, because it makes it easy to add different representations of the underlying angle. You could easily add a public var turns: T, a public var gons: T, etc.

davedelong avatar Jan 20 '20 01:01 davedelong

I'm also in favor of the Angle type. In my code base I constantly have to keep in mind if the angle in a given block of code is in radians or degrees (hint: it's always the Angle type).

I'd be more than happy to help here if needed. Forgive me for asking, but what is the consensus: is the issue still relevant (PR/implementation needed) or is there more discussion required?

jkalias avatar Dec 07 '20 00:12 jkalias

No, not really. I am not aware of any uses of Gradians, that’s probably the reason.

On 29 May 2022, at 21:31, mgriebling @.***> wrote:

Is there a reason to ignore Gradians (one hundredth of a right angle)?

— Reply to this email directly, view it on GitHub https://github.com/apple/swift-numerics/issues/88#issuecomment-1140510376, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAHGFVAJWSVTH23OLT535WTVMPAZXANCNFSM4KACTVOQ. You are receiving this because you commented.

jkalias avatar May 29 '22 21:05 jkalias

Gradians are a metric version of radians. Probably not used much but handheld calculators always had a "DRG" key which supported degrees, radians, and gradians. Noticed, that Apple's calculator does not support it.

mgriebling avatar May 30 '22 11:05 mgriebling