-
Notifications
You must be signed in to change notification settings - Fork 87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Determining the best way to create a quantity #413
Comments
If you prefer |
If you prefer |
Please share your comments below. |
Greetings! I haven't followed this discussion, but if I had to pick a syntax, it would definitely be (2). I wrote most of P2128's discussion about preferring to reserve |
@mhoemmen, whichever syntax we choose here the quantity<isq::speed[m / s], int> speed{42};
auto distance = quantity_cast<isq::distance[km]>(isq::length(42, m));
quantity_of<isq::altitude[m]> auto alt = get_alt(); Additionally, it seems that even if we choose option 2, the following will be valid: auto speed = isq::speed[km / h](42); After the discussion in #391 (comment) we consider the above to be the primary syntax for now and then possibly add a "comma syntax" as a shorthand wrapper to do the same in one step. |
I guess I dislike both variants of creating quantities through the combination of a Reference with a Number (that is, both |
I see your point. We can discuss some other syntaxes as well here if someone has some ideas... At this point, we can still change everything, and we are still looking for the best way to define and construct a quantity and to specify other related properties ( |
As you write in the glossary, a unit can be a reference. So what if we restore the unit references that we have in the library now, such that It would have the effect that the following two would be equivalent ways to specify a radioactivity: |
That is an interesting idea, but there are still some issues to be solved here. For example, what should
Another issue is that A lot of the derived quantities are not created in terms of base quantities but in terms of specific kinds, so it might look nice in the case of Another case here is the natural units system. In such case |
Given a hierarchy of quantity types as currently under discussion in #405, Then, by our tentative conclusion that As one of the more special cases, the expression As for the natural units system, the machinery works equally well. What do you think? |
That is an interesting idea. However we have to think what it means from the interface point of view. I think that it makes quite a lot of mess here. But let's start from the beginning.
If I understand correctly you suggest
It depends how would you like to define a natural unit system. Even though the speed is dimensionless and expressed in unit Now let's try to think how we can define a quantity type. To be consistent with proposed behavior should Next one is |
If we like the above idea, I have the following proposal. This new syntax will deduce a Additionally, Last but not least, this means that we will not be able to simplify units definitions from: inline constexpr struct hour : named_unit<"h", mag<60> * minute> {} hour; to inline constexpr struct hour : named_unit<"h", 60 * minute> {} hour; if the latter will start to be allowed by the C++ language. How do you like such an approach? |
Some code examples: quantity_of<isq::energy> auto q1 = 42 * isq::energy[J];
weak_quantity_of<isq::energy> auto q2 = 42 * J;
quantity_of<isq::energy> auto q3 = 42 * J + 42 * isq::energy[J];
quantity<isq::energy[J], int> q4 = 42 * J + 123 * (kg * m2 / s2);
quantity<isq::energy[J], int> q5 = 40 * N * (20 * m) + 123 * (kg * m2 / s2); |
Also, as @JohelEGP correctly noticed in #391 (comment), the multiply syntax has some issues. So we have to choose the best compromise here. |
That is exactly what I am proposing.
I believe we have some freedom here. After all, we have already established that
Sounds reasonable. Could we still have the
Why is that? By definition above,
I don't feel that these issues are all that relevant with this shorter form. If you still support |
The SI brochure says
ISO 80000-1, 3.9 unit of measurement, note 2 includes
|
I am not sure if we will be able to implement that in a generic way that will not look like a workaround.
The former just scales a unit providing another unit. It does not know anything about the dimension or a reference type.
This and also the number of additional parentheses needed in the short form. For example: |
As long as I can see that we can limit |
I am not sure. To simplify, we could remove |
I don't share your concerns regarding the implementation: With the proposed syntax, Once
The two remaining syntaxes are:
|
Indeed. The definition of quantity contains
But in So in |
I imagine some quantities could also be shared between different system of units. So if |
I understood that a reference is really just a If we indeed need to specify an explicit relation to a "system of units", and do not want to include that relation in the Then, w have two options: The first option is indeed, we require the user to always provide create a reference through one of the syntaxes that were under discussion initially. Or we could provide real Given that both options seem suboptimal to me, let me ask why we even need that "system of units" information, beyond what is already encoded (perhaps implicitly) in the base dimensions of the units we use? Unless my initial understanding was correct all along, and there is no such separate information in current V2 at all. |
Just to make it clear, systems of units are built on top of systems of quantities, and those are built by manipulating base dimensions. As @JohelEGP mentioned some time ago, there is no such thing that would be named as a dimension of
No. As I mentioned by definition
In V2 only base units get information about the base dimensions they are used to measure. This is done to be able to verify if a provided unit is compatible with the current quantity but yes it could work as well as some kind of a reference if we would redesing the framework a bit.
It is a bit different from what we have right now but I can image it to work like that. I am only afraid that with such a logic people will be too eager to just pass units everywhere which will end up in hard to understand (read long) error messages as we will always talk in terms of derived quantities equations rather their names. So we are trading compile time error readability for quantity construction helper robustness here.
This was the case in V1. In V2 I didn't find a different way then to define a unit in terms of a system of quantities, to be able verify the correctness of the assigned unit to a specific quantity
Yes, this is the main idea of V2. Many systems of units (even natural units system) (for example SI, CGS, FPS) should be able to reuse the same definition of a system of quantities (ISQ).
That is the main intent here. As stated above
This is what I was initially afraid of.
This was the case for V1 refrences. |
This is what I meant by trading compile-time errors for quantity construction helpers' robustness: static_assert(is_of_type<60 * (m / s), quantity<reference<derived_quantity_spec<isq::length, per<isq::time>>, derived_unit<si::metre, per<si::second>>>{}, int>>);
static_assert(is_of_type<60 * isq::speed[m / s], quantity<reference<isq::speed, derived_unit<si::metre, per<si::second>>>{}, int>>);
static_assert(is_of_type<42 * J, quantity<reference<derived_quantity_spec<isq::mass, power<isq::length, 2>, per<power<isq::time, 2>>>{}, si::joule>{}, int>>);
static_assert(is_of_type<42 * isq::energy[J], quantity<reference<isq::energy, si::joule>{}, int>>); I am worried that people will end up with the first types way too often if we provide such a "lazy" feature. |
We can also discuss if |
If we agree on the above, then how does it relate to #405? The above simplifies the library to the maximum. The #405, on the other hand, wants to add a lot of additional information. The biggest problem with the latter is the fact that we do not know what to do about that additional data. As we discussed, quantity character types are controversial, and we do not know how to enforce quantity kinds in an efficient way. |
How does that formulation handle the following?
In one extreme: Nothing is allowed. Everything is in the user's hands, including making sure not to mix quantities of the same dimension in ways that shouldn't be mixed due to properties not expressible by the library. There's no one other extreme, as evidence by the necessity of making tradeoffs. |
Playing on the interpretation of a
In this design, the quantity type-safety is enforced by the C++ type system to a user-selectable level: The user chooses how narrow/"far down the tree" they want to specify their quantities; since quantities don't implicitly widen, the user is softly "locked-in" unless overridden with explicit widening. The preferred way to "start-off" is by constructing quantities using an instant narrowing of pure units-based quantities: |
The problem I see here is a question if anyone will be using I think that the problem here is that we already know how to specify a hierarchy of quantities or specify their character, but we really do not know how to benefit from that information in an efficient way in the C++ language. The only thing we agreed on so far in #405 is that we should probably not allow two quantities of parallel kinds to be compatible with each other. Other than that, there are still controversies if we should somehow enforce the characteristics of a quantity or limit conversions to vertical kinds.
I am against mixing or cross-referencing systems of quantities with systems of units. ISQ should not use or specify any units (just quantity types/specs). SI, CGS, and other systems if units should build on top of ISQ to assign units to quantities. We had quantities redefined for systems of units (i.e. SI) in V1, and it was too expensive from the definition and standardization point of view.
This is what we agreed on but even though I really do not like it, ISO 80000-1:2022 says explicitly:
|
Depends on what the library would allow. If nothing else, it allows expression of intent. For example, there are pairs of quantities of equal dimension where one is a factor of 2∏ of the other. So if it wasn't possible to express different quantities of the same dimension, and you chose to stick to what the library allows, you could accidentally mix those without taking into account the factor of 2∏. If it was possible to express different quantities of the same dimension, accidental conversion could be avoided. Furthermore, it opens the path to easing the burden of conversion and book-keeping of the factor of 2∏ required on the part of the user.
As you mention, it's a matter of safety and ease of use. Comparisons between quantities of the same kind that are not in the same vertical hierarchy of kind could be allowed if there are no safety concerns. If comparing diameter and height should consider the length, what of the following should be
Also remember that there's a relation between comparison and conversion required by the |
I believe we are in agreement. The example I showed for
Yeah, from examples like these, (or wavelength and diameter), I gather that ISO 80000 indicates that there are not too many kinds in actual use beyond the base dimensions. To me, that is not necessarily unreasonable. |
Energy does have many, as I alluded to at #405 (comment). Most |
The radius of an object is half the diameter of that same object. That doesn't mean that comparing this object's radius to something else always has to give the same result as comparing it's diameter to that same third thing. Assume you have a publication that uses mathematical notation, and describes an object A, whose radius
This is not an issue with the hierarchical behaviour I have described; comparisons behave like additions regarding dimensional analysis and compatibility. We already have rules how additions behave, and those explicitly mention a common type.
That is fine with me. All I'm suggesting is that we should try to model kinds so they match general use. The better the references, the easier it is for us to explain that behaviour. |
Yes, but it occupies an identifier and does not add any type safety. For example, right now, I have
Well, I still can mix them as they are interconvertible :-(
I had some strong opinions about that before but now I really do not know how to progress here 😢
This is exactly my point. There is no such thing as SI dimension. SI (being a system of units and not quantities) specifies units for ISQ quantities. Dimension is a property of a quantity, not a unit. Unit can only be defined for a specific quantity/dimension, and this is why in V2, base units take base quantities so I can check in
I am not so sure about it. ISO 80000 never stated it explicitly, and if it did, I suppose it would say that all The more we dig into this subject, I feel that we learn that we can do less and less here in terms of C++ type safety. On the one hand, it heavily simplifies the entire library. On the other hand, it removes all of the things that we hoped to be able to model, which is quite frustrating 😢 |
I wasn't aware of that, but you are right of course. In some way, that makes the design even more elegant, as base units are specified in terms of base quantities, and
I believe the machinery we are discussing can model this. It may not match common use of ISQ quantities, where many lengths are comparable, but the user of the library may take those exact same concepts from the standard, and define "stronger" quantities that are not comparable. That is, |
I think I see a reasonable solution providing support for that and most parts of #405 as well. Unfortunately, right now, I provide a week-long training for a customer, so I have limited bandwidth, and after that, I have another week of family vacation. I will be working on it in the background and checking if my assumptions are correct. |
@burnpanck, please check #426 if that is what you meant? Also, I need help with #427. |
Done in V2. |
Today, after a code review comment, I added a second syntax that creates a quantity in V2 design:
You can find diff with more examples here: 858cbb4.
For now, we have two of those, but I would like to decide which one is better ASAP and remove the other one. Please review the above commit and share your opinion.
The text was updated successfully, but these errors were encountered: