Skip to content
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

Should we allow deriving from system entities? #537

Open
mpusz opened this issue Dec 28, 2023 · 1 comment
Open

Should we allow deriving from system entities? #537

mpusz opened this issue Dec 28, 2023 · 1 comment
Labels
design Design-related discussion high priority EXTRA URGENT

Comments

@mpusz
Copy link
Owner

mpusz commented Dec 28, 2023

We allowed deriving from predefined quantity points to allow the users to provide a different name not only for a value but also for a type. This is also used in temperatures:

inline constexpr struct ice_point : relative_point_origin<quantity_point{273.15 * kelvin}> {} ice_point;
inline constexpr struct zeroth_degree_Celsius : decltype(ice_point) {} zeroth_degree_Celsius;
inline constexpr struct degree_Celsius : named_unit<basic_symbol_text{"°C", "`C"}, kelvin, zeroth_degree_Celsius> {} degree_Celsius;

We also benefit from something similar for units here:

inline constexpr struct gram : decltype(si::gram) {} gram;
inline constexpr struct second : decltype(si::second) {} second;

But it results in the #512 issue. The issue is that, as of now, different types (even meaning the same unit) are not simplified in expression templates.

I planned to fix it and extend the same support for dimensions, quantity specifications, and units so the user, for example, can type something like this:

struct SomeDevice {
  static constexpr struct spec : decltype(isq::speed) {} spec;
  static constexpr struct unit : decltype(si::kilo<si::metre> / non_si::hour) {} unit;
};

quantity q = 42 * SomeDevice::unit;

It seemed nice, but the deeper I am digging to make it work, the more complex it gets. Even the above example is invalid already (and should not compile) as we should never derive custom types from derived unnamed entities as strong types for them will not be decomposed during dimensional analysis. So we should not define a strongly typed unit for km / h.

Another issues are with the equality and other operations. For example, we have to enable isq::speed == SomeDevice::spec to be true. But if we do it then the question is what about isq::speed / isq::time == SomeDevice::spec / isq::time. This again should be equal. Also named quantities using such equations should be equivalent:

inline constexpr struct Spec1 : quantity_spec<isq::speed / isq::time> {} Spec1;
inline constexpr struct Spec2 : quantity_spec<SomeDevice::spec / isq::time> {} Spec2;

static_assert(Spec1 == Spec2);

Although, probably the above could be considered controversial.

As we can see the problem gets deeper and deeper and trying to address all of the cases would require a huge rewrite and complication of the design. Also, it will probably result in slower compile-times as much more logic will have to be done at every step (e.g., while simplifying equations).


Because of all the above I consider disallowing deriving from the predefined types (e.g., make them final). To be consistent we should do this as well for point rigins. But his would mean that zeroth_degree_Celsius would be of ice_point type. Also, cgs::second would be of si::second type. This makes systems not that nicely isolated as before.

Do you have any ideas how to deal with this issue?

@mpusz
Copy link
Owner Author

mpusz commented Jan 5, 2024

This also affects other definitions of popular unit systems. For example:

namespace si {
inline constexpr struct kilogram : decltype(kilo<gram>) {} kilogram;
}

namespace non_si {
inline constexpr struct hectare : decltype(si::hecto<are>) {} hectare;
}

namespace cgs {
inline constexpr struct centimetre : decltype(si::centi<si::metre>) {} centimetre;
}

namespace international {
inline constexpr struct kip : decltype(si::kilo<pound_force>) {} kip;
}

namespace natural {
inline constexpr struct gigaelectronvolt : decltype(si::giga<electronvolt>) {} gigaelectronvolt;
}

The above nice identifiers will currently not simplify with the units defined using prefixes 😢 If we do not find the solution for this issue, we will have to remove those helper types.

@mpusz mpusz added the design Design-related discussion label Feb 26, 2024
@mpusz mpusz added the high priority EXTRA URGENT label Feb 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
design Design-related discussion high priority EXTRA URGENT
Projects
None yet
Development

No branches or pull requests

1 participant