C++ Logo

std-proposals

Advanced search

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

From: Lorand Szollosi <szollosi.lorand_at_[hidden]>
Date: Thu, 27 Jun 2024 22:56:55 +0200
Hi,

On Thu, Jun 27, 2024 at 10:03 PM Charles R Hogg via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> The way to achieve this with a units library is to make sure that every
> interface that *brings values into* a units library type, or *extracts
> values from* a units library type, forces the user to *name the unit* explicitly,
> *at the callsite*. Au was designed with this approach in mind from the
> ground up, and I was very heartened to see mp-units adopt it as well, to
> the point that mp-units is now every bit the equal of Au in unit safety.
> (Really, the whole 2.0 redesign for mp-units was a stunning leap forward in
> a lot of ways --- I was thrilled to see it.)
>

What you call unit safety, I'd argue, is a coding convention. You might
enforce it by power; you can't enforce it solely by c++ language features, *and
that's a good thing*. It's because it goes against composability. Think
about this code:

auto l = [](double d) constexpr { return d * km; };
static_assert(l(12) == 12 * km);

Full example: https://godbolt.org/z/PWocWYo6c

I'd argue that l(12) is *not* unit-safe: simply reading that line, you
cannot tell whether that static assert should succeed (i.e., I wrote d * km
in the lambda) or fail (i.e., if I were to write d * m, or even 2 * d *
km). I also didn't write return type in the lambda, as it's auto. Thus, no
matter what you ensure in the library, if a user would like a lambda
constructing a unit from a double, *they have it today*. Therefore, the
argument is, whether it's a *coding standard* we promote.


> Now to your question: if you have a typename that contains the unit name,
> isn't that enough? Say we had a *type* called `degrees_celsius`: why
> wouldn't it be OK to have a constructor from `double`, so you could simply
> write `degrees_celsius{42.0}`? (We would make it `explicit`, of course!)
>

There are units that you cannot construct as a + b * x, where an and b are
constants. A common example is date (based on some absolute time) of
countries: there are examples of days missing from calendars. Thus, in your
serialisation / deserialisation, you'll need a way to express
quantity_point constructions anyways. Users of the library could create
such a thing in non-standard ways; or, we can provide a standard function
to create it.

Units are still checked while compiling, so zero type safety is sacrificed.

Thanks,
-lorro

Received on 2024-06-27 20:57:08