diff --git a/docs/blog/posts/2.3.0-released.md b/docs/blog/posts/2.3.0-released.md new file mode 100644 index 00000000..6afa9c50 --- /dev/null +++ b/docs/blog/posts/2.3.0-released.md @@ -0,0 +1,98 @@ +--- +draft: true +date: 2024-06-15 +authors: + - mpusz +categories: + - Releases +--- + +# mp-units 2.3.0 released! + +**A new product version can be obtained from +[GitHub](https://github.com/mpusz/mp-units/releases/tag/v2.3.0) and +[Conan](https://conan.io/center/recipes/mp-units?version=2.3.0).** + +This release fine-tunes many key features of the library. This post describes those and a few +other smaller interesting improvements, while a much longer list of the most significant changes +introduced by the new version can be found in our [Release Notes](../../release_notes.md#2.3.0). + + + +## Quantity reference specifiers + +The features described in this chapter directly solve an issue raised on +[std-proposals reflector](https://lists.isocpp.org/std-proposals/2024/06/10118.php). As it was +reported, the code below may look correct, but it provides an invalid result: + +```cpp +quantity Volume = 1.0 * m3; +quantity Temperature = 28.0 * deg_C; +quantity n_ = 0.04401 * kg / mol; +quantity R_boltzman = 8.314 * N * m / (K * mol); +quantity mass = 40.0 * kg; +quantity Pressure = R_boltzman * Temperature.in(K) * mass / n_ / Volume; +std::cout << Pressure << "\n"; +``` + +The problem is related to the accidental usage of a `quantity` rather than `quantity_point` for +`Temperature`. This means that after conversion to kelvins, we will get `28 K` instead of +the expected `301.15 K`, which will corrupt all further calculations. + +A correct code should use a `quantity_point`: + +```cpp +quantity_point Temperature(28.0 * deg_C); +``` + +This might be an obvious thing for domain experts, but new users of the library may not be aware +of the affine space abstractions and how they influence temperature handling. + +After a lengthy discussion on handling such scenarios, we decided to aid the `quantity` and +`quantity_point` construction with `absolute` and `delta` quantity reference +specifiers. This applies to: + +- the multiply syntax, +- 2-parameter `quantity` constructor. + +Here are the main points of this new design: + +1. All references/units that do not specify point origin (are not offset units) in their definition + are considered `delta` by default. This means that `42 * m` creates a `quantity` and is + the same as calling `42 * delta`. +2. Multiply syntax is extended to allow `quantity_point` creation with the `42 * absolute` + syntax. This will provide an implicit zeroth point origin. +3. For units that specify a point origin (`si::kelvin`, `si::degree_Celsius`, and +   `usc::degree_Fahrenheit`), the user always needs to specify a modifier. This means that: +    - `4 * deg_C` does not compile, +    - `4 * delta` creates a `quantity`. +    - `4 * absolute` creates a `quantity_point`. +4. The 2-parameter `quantity` constructor requires the same: + +```cpp +quantity q1(4, m); // OK +quantity q2(4, delta); // OK +quantity q3(4, absolute); // Compile-time error +quantity q4(4, deg_C); // Compile-time error +quantity q5(4, delta); // OK +quantity q6(4, absolute); // Compile-time error +``` + +The `delta` and `absolute` modifiers are stripped upon construction, so the resulting `quantity` +and `quantity_point` types use the underlying unit in its type. + +With such changes, the offending code will not compile, forcing the user to think more about what +is written. To enable the compilation, the user has to type one of the following: + +- `quantity_point Temperature(28.0 * delta);` +- `quantity_point Temperature = 28.0 * absolute;` + +If the user still insists on using `quantity` instead of a `quantity_point`, the code will +have to be written in the following way to compile successfully: + +```cpp +quantity Temperature = 28.0 * delta; +``` + +This will yield an invalid result, but now, hopefully, it is clearly readable in the code what is +wrong here.