On Wed, Jun 19, 2024 at 11:29 AM Mateusz Pusz via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
I have an alternative proposal.

Let's consider adding `alternative(Reference)` and `relative(Reference)` modifiers that will influence how:

- multiply syntax works
- limit invalid use cases for quantity and quantity_point.

Here are the main points of this new design:
1. All references/units that do not specify point origin (are not offset units) would be considered `relative` by default. This means that `42 * m` will create a `quantity` and would be the same as calling `42 * relative(m)`. 
2. Multiply syntax could be extended to allow quantity_point creation with the `42 * absolute(m)` syntax. This will provide an implicit zeroth point origin.
3. For units that specify a point origin (kelvin, degree_Celsius, and degree_Fahrenheit), the user would always need to specify a modifier. This means that:
  - `4 * deg_C` does not compile
  - `4 * relative(deg_C)` creates a `quantity`
  - `4 * absolute(deg_C)` creates a `quantity_point`
4. Constrain constructors of quantity or quantity_point to require the same:

quantity q1(4, m);                      // OK
quantity q2(4, relative(m));            // OK
quantity q3(4, absolute(m));            // Compile-time error
quantity_point qp1(4, m);               // OK
quantity_point qp2(4, relative(m));     // Compile-time error
quantity_point qp3(4, absolute(m));     // OK

quantity q4(4, deg_C);                  // Compile-time error
quantity q5(4, relative(deg_C));        // OK
quantity q6(4, absolute(deg_C));        // Compile-time error
quantity_point qp4(4, deg_C);           // Compile-time error
quantity_point qp5(4, relative(deg_C)); // Compile-time error
quantity_point qp6(4, absolute(deg_C)); // OK

Please note the above would also apply to Kelvin and Fahrenheit.

Does it solve the issue discussed here?

FWIW, I think:
- The WG21 discussion process might be good for mp_units' health, but ultimately I don't think mp_units belongs in the STL.
- (As Mateusz knows,) personally I'm enamored of absl::Duration's minimalist design, where you have strong typing for the dimension algebra (which is irreducible complexity) but the library makes a sensible-in-context choice of units (e.g. seconds) and representation types (e.g. `double`) and your program is happy with that choice or else you pick a different library to use. As with type-erasure types, there are just too many "knobs" to make something that everyone will be happy with. (That's how we ended up with `std::function` and `std::copyable_function`, as well as another ~3 standard type-erasure types.)
- The idea of affine spaces is indeed key — it is indispensable. Almost all of the "new" ideas in this thread have been simply reinventing or renaming the two fundamentals `quantity` (delta, relative) and `quantity_point` (absolute).
- IMO, Mateusz' informally proposed names `relative` and `absolute` are not good, because they are exactly the opposite of how I'd explain them to a layman. A temperature delta of 4 degrees (C/K) is absolute; it has a physical meaning. Now, if you take that delta relative to some arbitrary origin — e.g. the freezing point of water — then you get the temperature reading on a human thermometer (the thing Mateusz informally proposed to call `absolute`, even though the way we got it was to add our delta relative to something else). Now, personally I wouldn't be opposed to calling deltas by the name `delta` somehow — e.g. `4 * delta_m` — but I don't think that buys any clarity.
- In fact, temperature (like calendar) seems to be special, in that we have several human-invented origin points (epochs) relative to which you might want to represent a temperature (date). We absolutely do not have that for e.g. meters, or (in the physical realm) seconds.
- But meters and seconds are special because they were invented specifically to measure deltas in spacetime. They're the only two units that work that way. Most other units seem to measure "quantity_points" by default: This object weighs absolutely 4kg, not "4kg more than a weightless object." I'm applying absolutely 4Nm of torque (or, hmm, is it really that I'm applying "a delta of 4Nm more than there would have been without my input"?)
- It's not intuitively 100% obvious to me whether we have a natural "origin" for kilograms (i.e. "this object's mass is absolutely 4kg") or whether that's just an abuse of notation (like saying "this event took absolutely 42 seconds" when what you mean was "the delta between this event's start and end was 42 seconds"). If we understood that point, it might be easier to talk about the whole system.

Finally, since I'm here, I'll mention my one big concern with mp_units' design even though it's new to the thread AFAIK:
- I think anyone converting units is already in a state of sin, so I'm not too worried about that part. And I like the (high-level) design for preventing accidental conversions of dimension. I'm very concerned, though, with the idea of managing what might be called "soft" dimensions: altitude-above-sea-level and altitude-above-terrain are measured in exactly the same dimension (length), the same units (meters), in the same direction (height), even with a very similar name (altitude), in fact we sometimes want to do mixed-mode math on them (the one minus the other equals the height of the terrain above sea level)... but still, it is catastrophic to confuse them. Can the type system actually help us solve this problem at all? My impression is that mp_units doesn't help us solve this problem. (Although it does help us with other problems, such as mixing up altitude with rate-of-descent, because the dimensions/units are different in that case.) It's not clear to me whether this indicates "we have half a solution, which indicates we should keep searching for the whole solution," or merely "that's a second problem entirely; the first solution is still worthwhile for the first problem."

But I don't think any of this is pro or con "should mp_units go into the STL?". I'm pretty firmly against its going into the STL either way. This designy stuff is all about "can we come up with a minorly tweaked design that improves mp_units?" and "can we come up with a majorly different design that is self-consistent at all, or does every alternative design run into serious problems?" (I suspect the answer to the former is "no, not really" and the answer to the latter is "yes, plausible alternative designs are a dime a dozen.")

my $.02,
–Arthur