au
au copied to clipboard
Support constants
In some sense, we can already do this.
constexpr auto RAD = radians(1);
However, this brings int into the equation, via the 1. This could affect the arithmetic of the underlying Reps in some equations where it gets used. It could also run afoul of our guards against integer division.
It would be nice if we could express constants solely in the realm of dimensions and magnitudes. We might need to make a new type template, such as Constant. It would probably be a "monovalue type" (in the nomenclature introduced in #88). Perhaps something like this:
constexpr auto RAD = make_constant(Radians{});
Alternatively: maybe a "constant" is just an instance of a unit? We would need to enable multiplying and dividing a quantity by a unit, if so. Then we would write:
constexpr auto RAD = Radians{};
It's interesting to imagine how this would look with other constants. Consider something like $E = mc^2$. We might write kilo(grams)(10.0) * squared(C)... and the result might be labeled as 10 kg * c^2. Of course we could also apply .as(joules) to the result to get a more familiar unit.
This is an intriguing idea worth exploring more later.
Having thought more about this: no, a constant should not just be an instance of a unit. A "unit" could be basically any type, so we'd need SFINAE, which would be expensive. This argues in favor of using a Constant template.
It's probably still good to keep this template as a monovalue type, and use a labeled unit.
Here's a running checklist for what it would take to call this feature "done". (I'll check things off as they're implemented locally in my client, rather than on remote.)
- [x] Multiplication and division
- [x] Regular numbers
- [x]
Quantity - [x]
Magnitude - [x] Other
Constant - [x]
QuantityMaker - [x]
SingularNameFor - [x]
QuantityPoint(= delete) - [x]
QuantityPointMaker(= delete)
- [x] Explicit conversions to
Quantity- [x]
.as<T>(): initialize withT{1}in units of the constant - [x]
.as<T>(unit): choose unit-and-rep- [x] Exact representability checks (no "safety surface" heuristics)
- [x]
.coerce_as<T>(unit): choose unit-and-rep, ignore safety checks
- [x]
- [x] Explicit unit conversions to raw number
- [x]
.in<T>(unit): choose unit-and-rep- [x] Exact representability checks (no "safety surface" heuristics)
- [x]
.coerce_in<T>(unit): choose unit-and-rep, ignore safety checks
- [x]
- [x] Implicit conversions to
Quantity - [x]
make_constant(...) - [ ] Math functions
- [ ]
min - [ ]
max - [ ]
clamp - [ ]
fmod? - [ ]
% - (Skip rounding functions because rep is undetermined, and people can use
.as<T>()to get this)
- [ ]
- [x]
AssociatedUnitTsupport (sov.in(m / s)would work) - [ ] Presentation
- [ ] How to name constants?
cvs.Cvs.SPEED_OF_LIGHT;h(orh_bar) vs.H(orH_BAR) vs.PLANCK_CONSTANT; etc. - [ ] Use
constantssub-namespace? - [ ] Update single-file script to include constants
- [ ] How to name constants?
- [ ] Documentation
- [x] Reference page
- [ ] Update single-file section of installation docs
- [ ] Alternatives page
- [ ] If we have a list of common monovalue types, add this to the list
We may want to add some documentation for how to add a new constant, after we settle on the presentation.