mp-units icon indicating copy to clipboard operation
mp-units copied to clipboard

Prime numbers (unit magnitude) unfit for standardization

Open JohelEGP opened this issue 8 months ago • 13 comments

Prime numbers (unit magnitude) unfit for standardization

The current mp-units library (v2.0), since #300, implements the amount of an unit, its magnitude, as a sum of prime numbers. [ Note: 10 km = 10⋅10³ m = 10 000 m. In code, 10 km is 10⋅10³ m, a quantity with runtime value 10 and compile-time values 10³ m. 10³ is the magnitude of the unit m. -- end note ]

P2980 R0 and R1 mention, in "Plan for standardization" (§8 and §9, respectively),

2024.1 (Tokyo) | Paper on prime numbers to SG6

What follows are my opinions, previously voiced and still unchanged. What's changed since then is the appearance of P2980 with the quote above. The exchanges sparked by my opinions gained me some insights. This issue themes my insights around the expectation of std::quantity.

The implementation uses known_first_factor. It is to be specialized for prime numbers it can't compute due to limits. Before v2.0, it was exercised at https://github.com/mpusz/mp-units/blob/5cc7fb1f0bd9a4a77e3f4e36f86cdf6e840e5e70/test/unit_test/static/magnitude_test.cpp#L30-L31 https://github.com/mpusz/mp-units/blob/5cc7fb1f0bd9a4a77e3f4e36f86cdf6e840e5e70/test/unit_test/static/magnitude_test.cpp#L181-L193

I have argued that such an interface is unfit for standardization. I suggested that the unit magnitude should be implementation-defined (with minimal requirements, e.g., at least as much support as std::chrono::duration with std::ratio; possibly with implementation-defined limits https://wg21.link/implimits). My intent was to allow for better implementations to emerge. @mpusz rightly argued that it would make for less portable code as the limits of implementations diverge.

Considering this, for standardization, I think we're left with a single option. Standardize the current implementation as-is. Code will be portable, with the limits of the unit magnitude fixed (and with known_first_factor for working around those limits).

The intent of the "Paper on prime numbers to SG6" is to make the would-be implementation-defined interfaces std::quantity uses for unit magnitudes just another library part of the C++ standard library. But I think those prime number interfaces are unfit for standardization.

And so, I have thought, can't we use expression templates instead of prime numbers? There remains the need to simplify (which #300 achieved by definition). There remains the need to tell whether two magnitudes are equal. Or maybe we could fall back to using expression templates when specializing known_first_factor would be needed.

I'm not sure what we would lose by foregoing #300 for expression templates on the unit magnitudes. Would we have to use more explicit casts? How would it affect what can be done by the library? I'd like to know that in terms of possibility, simplicity, and safety. Would it make existing use cases impossible to express, or would it actually permit more without going through known_first_factor? For certain, if we had to use more explicit casts, it wouldn't be simpler. And if we had to use more casts, we'd shadow the casts with actual safety concerns.

JohelEGP avatar Oct 24 '23 21:10 JohelEGP