System.Dim.Generic_Mks is not marked "Pure"

Is there any specific reason why in gnat 15 the package System.Dim.Generic_Mks is not marked Pure? This basically means my own Pure packages cannot use dimensionality analyis.

Hi @mstahl-iis and welcome to the forums!

You are right that just by looking at the documentation about the package in https://gcc.gnu.org/onlinedocs/gnat_ugn.pdf it does not seem like it cannot be Pure… However, if for whatever reason there are exception propagation, etc in the package, then it cannot be pure… In the docs it says that it raises a program error during compilation to indicate mismatching dimensions… So that could be the trigger…

@dkm are you the right person to ping here about this topic?

Best regards,
Fer

Edit: also, it is important to note that this package is not official, it is not part of Ada as defined by the standard. Therefore, GNAT could implement it however it sees fit…

There’s a fairly nice SI Units set of packages here.

IIRC, it is pure.

1 Like

There’s a fairly nice SI Units set of packages here.

That’s an old version. See here for the latest release of July 14 labeled 1.0.0 on GitHub:

1 Like

Note, that for practical purposes it cannot represent “class-wide” objects, e.g. it is impossible to create an I/O library, use it in a network protocol, write a dimensioned calculator. For this the dimension must be a constraint rather than a part of the type, but then it will not be static because Ada does not provide means to handle user-defined constraints as static when they become static. There is no static functions etc.

Then it is plain wrong with regard of shifted measurement units. Try this:

   X : Celsius_Temperature := dC;
   Y : Celsius_Temperature := dC;
   Z : Celsius_Temperature := X + Y;

Now, how about Image (Z, Exp => 0). The result is 546.29999 °C! :rofl:

In order to fix it, the aspect must include the offset. Furthermore 1K + 1°C must be illegal as well as 1°C * 1°C.

The solution is easy (think of Ada’s Time and Duration):

Celsius + Celsius illegal
Celsius - Celsius => Kelvin
Celsius + Kelvin => Celsius (where the Kelvin value must be a difference)

For the transformation of Kelvin to Celsius, you have take into account whether you have an absolute temperature or a temperature difference: for the latter you have

Clesius - Celsius equals Kelvin - Kelvin

In fact, you cannot transform a temp diff in Kelvin into Celsius.

I use a different approach. A shifted measurement unit (shift /= 0) forms an additive group with the shift removed. Only non-shifted ones do a multiplicative group. So:

   1°C + 1°C = 2°C
   1°C - 1°C = 0°C
   1°C * 1°C = illegal
   1°C + 1°K = illegal

To transform Celsius to Kelvin one simply gets a SI value of and multiplies it to K. The Si value of a measurement is

X * Gain + Offset

See Units of measurement for Ada.

The different to Time/Duration, Location/Distance etc is that Celsius is used in engineering as both an absolute value and a difference interchangeable. You would never sell illegal Celsius + Celsius to an engineer.

Thank you!

I’d come across the author’s homepage for it circa 2019/20, and couldn’t find it. I didn’t know about the github, so thank you.

Thanks @Irvise for your reply.

In the docs it says that it raises a program error during compilation to indicate mismatching dimensions… So that could be the trigger…

I thought “Pure” is only about elaboration time, not compile time…

Edit: also, it is important to note that this package is not official, it is not part of Ada as defined by the standard. Therefore, GNAT could implement it however it sees fit…

This is clear. My main motivation for using it is that it has no runtime overhead.