4 ms·
I feel like we're talking past each other or the goal posts are moving or something. > If we had reasonable types, sin could define the type it wants to do wha
by munificent 4y ago
I feel like we're talking past each other or the goal posts are moving or something.
> If we had reasonable types, sin could define the type it wants to do what it does efficiently (turns, or radians if the platform has an efficient instruction, or a lookup table index into some division of a quadrant, or whatever). That representation matters to the sin author, but not the user. All the user cares about is, then, how many times do I have to pay some conversion cost? And if I'm using the type the sin author provided, the answer is zero (or maybe like one, at initial load). But that relies on the sin author using such a newtype.
Everything here is equally true if you take types entirely out. sin() will ultimately be doing math on floating point values. The sin() function expects angles according to a specified scale. Some scales (turns, according to the author) require one less multiplication in the function prelude. Therefore, sin() is faster if it specifies that as the input scale.
That benefit is negated if angles are stored in another scale and rescaled every time sin() is called. That's just hoisting the multiplication out to every callsite.
So what you need is to store angles in the numeric scale that is fastest for the implementation of sin().
Whether those floating point angles are wrapped in a newtype is completely orthogonal. What matters is that the numeric scale you use to store and represent angles is the one that requires the least arithmetic in the underlying implementation of the trig functions.
Unit types are great, but they solve different problems than the article is talking about.