`acosInHalfTurns`

```
sin(degrees: x) // or sin(deg:)
sin(radians: x) // or sin(rad:)
sin(pis: x) // or sin(pi:)
```

Do we currently have the last one in C, BTW?

```
asinInDegrees(y) // or asinDegrees, not too far from asinDeg
asinInRadians(y) // or asinRadians, not too far from asinRad
asinInPis(y) // or asinPis, not to far from asinPi
```

Yes, C23 has `sinpi`

(Apple's and a few other libcs have exposed it as an extension for a decade or so--we called it `__sinpi`

in Apple's libm since C hadn't standardized a name for it yet. I don't think any mainstream libcs have a sin-in-degrees).

+1. i reached the same conclusion after trying to “translate” countless MongoDB APIs as well.

A slight variation of the above:

```
enum TrigUnits {
case radians
case degrees
case pi
case arcminute
case arcsecond
case grad
case turn
case custom(Double)
}
func sin(_ v: Double, _ units: TrigUnits = .radians) -> Double
func asin(_ v: Double, _ units: TrigUnits = .radians) -> Double
```

usage:

```
sin(42) // same as sin(42, .radians)
asin(0.2) // same as asin(42, .radians)
sin(42, .degrees)
asin(0.2, .degrees)
sin(42, .pi) // sinpi
asin(0.2, .pi) // asinpi
```

This is heading quickly to being a full-fledged Angle type, which is interesting and worth doing well, but these are the implementation hooks that we use to build that, rather than the Angle type itself.

I see your point. However, if to have only "case pi" in the above enum and two separate (sets of) functions, one for "sin(x) asin(x)" (& co) and another for "sin(x, .pi), asin(x, .pi)" the resulting ASM is exactly the same as what it is in your proposal, so basically we are talking about the visual aesthetics of:

```
static func asinOverPi(_ x: Self) -> Self
static func sin(piTimes x: Self) -> Self
```

vs:

```
static func asin(_ x: Self, _ pi: Pi) -> Self
static func sin(_ x: Self, _ pi: Pi) -> Self
```

To get to the use sites:

```
asinOverPi(x) vs asin(x, .pi)
sin(piTimes: x) vs sin(x, .pi)
```

The trick is that API suggests to a user that they should also write:

```
func myFunction(_ x: Double, _ units: TrigUnits = .radians) -> Double {
return asin(/* some expression involving x */, units)
}
```

and then all of a sudden they're dynamically switching over `units`

unless everything gets inlined (which is also a problem, in a different way).

But that won't happen if we have "pi" in that enum as the only option (in which case it could be named "Pi"). To handle both cases users will have to write:

```
enum Pi { case pi }
...
func myFunction(_ x: Double, _ pi: Pi) -> Double {
asin(/* some expression involving x */, .pi)
}
func myFunction(_ x: Double) -> Double {
asin(/* some expression involving x */)
}
```

which is no different (†) compared to the "asinOverPi(x)" of your proposal other than the visual aesthetics.

(†) there could be a difference in compilation time though.

Ah, I was still thinking about your earlier units suggestion. I agree that there's no runtime cost here, but `asin(-1/3, .pi)`

has the wrong sense. It suggests (at least to me, if I don't stop and think about it) that we're computing `asin(-π/3)`

rather than `asin(-1/3)/π`

This is basically the right answer, but I'd take out the reference to π in the last one. `sin(cycle: x)`

or somesuch is perhaps more appropriate. It would be off by a factor of 2 from the π version, but it may be that it's closer to what most code is intending anyway. Having to think about how many πs you want is harder to quickly reason about than how many cycles you are intending. `cos(cycle: 1/2) // = -1`

. But I know many are perhaps more comfortable thinking in terms of half-cycles (π). Cycles may be friendlier to less mathy coders who just know they want some thing to twirl around 3 times. Just my 2¢.

(For most trig calculations, even though people like the number π, it is besides the point and need not be explicit if you have functions internally handling the scaling factor.)

I agree that `sin(piTimes x: Self) -> Self`

reads much nicer than the reverse `asinOverPi(_ x: Self) -> Self`

.

Perhaps `asinOverPi(of x: Self) -> Self`

adds that little bit of extra clarity. Makes it different enough to emphasise that it's `asin(x) / π`

and not `asin(x/π)`

.

Also thinking if this part of the function docstring is clear enough on that not so minor detail:

`/// The arcsine (inverse sine) of `

x`, scaled by 1/π.`

perhaps a little verbose but slightly more clear?

`/// The arcsine (inverse sine) of `

x`, the result of which is scaled by 1/π.`

Are the `atanOverPi`

family of methods necessary? `tan(piTimes:)`

et al make sense because they allow you to use “friendly” (and exact) numbers as the *argument*, and they can also provide more precision for pathological inputs (such as very large values). But the `over`

methods would be *returning* a value. Unless moving division by pi into the function allows for more precision, I'm not sure what the utility is versus just having the user divide the result by pi.