C++ Logo

std-proposals

Advanced search

Re: [std-proposals] On the standardization of mp-units P3045R1

From: Mateusz Pusz <mateusz.pusz_at_[hidden]>
Date: Wed, 19 Jun 2024 18:55:09 +0200
Hi Arthur,

I would not like to start new discussions here until we address the issues
discussed before. However, I will briefly answer some of your concerns
here. If you would like to discuss this in more detail, could you please
open a new discussion thread on the reflector?

It is fine to decide that we do not want units in the Standard Library. But
please decide that now and not five years from now when all the
contributors to the proposals will spend hundreds of hours working on it.
This is what I asked a few meetings ago in LEWG, and the answer was to go
ahead, as it seems that we want it standardized. The authors spent a lot of
time writing proposals already since then.

I could argue that every measurement can (but does not have to) be modeled
as a quantity point, even for length and time. For length, you read the
value on the ruler or the odometer (notice that you do not have to zero the
ruler or the odometer to read the value). For time, you read the value of a
stopwatch. If you want to know how much time has passed or how long
something is, you subtract the read value from another value read in a
different measurement. However, it does not mean we do not need quantities.
If we want to find out how different readouts differ, we subtract them to
get a quantity.

> 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.

Sure! This is the solution with mp-units:

inline constexpr struct altitude_above_sea_level final :
quantity_spec<isq::altitude> {} altitude_above_sea_level;
inline constexpr struct altitude_above_terrain final :
quantity_spec<isq::altitude> {} altitude_above_terrain;
inline constexpr struct height_of_the_terrain_above_sea_level final :
quantity_spec<isq::height> {} height_of_the_terrain_above_sea_level;

QuantityOf<height_of_the_terrain_above_sea_level> auto
get_height_of_the_terrain_above_sea_level(QuantityOf<altitude_above_sea_level>
auto asl,

QuantityOf<altitude_above_terrain> auto aat)
{
  return height_of_the_terrain_above_sea_level(asl - aat);
}

int main()
{
  using namespace mp_units::si::unit_symbols;

  quantity asl = altitude_above_sea_level(1340 * m);
  quantity aat = altitude_above_terrain(340 * m);
  quantity res1 = get_height_of_the_terrain_above_sea_level(asl, aat);
  // quantity res2 = get_height_of_the_terrain_above_sea_level(aat, asl);
// Compile-time error
  std::cout << res1 << "\n";
}

https://godbolt.org/z/193afPe4K

śr., 19 cze 2024 o 18:13 Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
napisał(a):

> On Wed, Jun 19, 2024 at 11:29 AM Mateusz Pusz via Std-Proposals <
> std-proposals_at_[hidden]> 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 <https://abseil.io/docs/cpp/guides/time#time-durations>, 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
>

Received on 2024-06-19 16:55:27