4. Missing and entered values
This chapter evaluates the strength three times: with every measurement taken, with one side of the specimen never measured, and with the strength typed in by hand. It shows what a missing measurement makes of a result, and how a result records where its number came from.
The program is chapter 3's, with whole-number measurements, without the
printed area, the rounding for reading and the 0.1 + 0.2 line, and with
two more environments.
Every measurement taken
The specimen measures 150 mm by 150 mm and carried 675 kN:
auto const specimen = formula::environment(
formula::Measured<SideA> { 150 }, formula::Measured<SideB> { 150 }, formula::Measured<Load> { 675 });
auto const result = formula::checked_evaluate(strength, specimen);
if (!result)
{
std::println("cannot calculate the strength: {}", result.error());
return 1;
}
std::println("measured: {} = {} ({})", formula::symbol_of<Strength>(), *result, result->source());
675 kN over 22500 mm² is exactly 30 MPa. The library calculated it, so its
source is derived.
A measurement nobody took
Side b was never measured. formula::Measured<SideB>::absent() says so:
auto const sideBMissing = formula::environment(
formula::Measured<SideA> { 150 }, formula::Measured<SideB>::absent(), formula::Measured<Load> { 675 });
auto const withoutB = formula::checked_evaluate(strength, sideBMissing);
if (!withoutB)
{
std::println("cannot calculate the strength: {}", withoutB.error());
return 1;
}
if (formula::number_of(*withoutB).has_value())
{
std::println("a strength was calculated without side b: {}", *withoutB);
return 1;
}
std::println("b not measured: {} = {}", formula::symbol_of<Strength>(), withoutB->kind());
The evaluation still succeeds: nothing went wrong in the arithmetic, so the
std::expected holds an outcome, not an error. That outcome holds no number.
An absent input makes the result of every operator it reaches absent, so the
area is absent, and with it the strength. formula::number_of returns the
number an outcome holds as a std::optional, here an empty one, and the
outcome's kind() prints as empty.
Empty is not zero. Zero is a measurement, and a side of zero millimetres would make the strength a division by zero, or, in another formula, a confident wrong number. An empty result says that the number cannot be known from the measurements given.
A value entered by hand
Sometimes a person states a result instead of letting the formula calculate
it: a value taken from an earlier report, say. formula::entered marks a
measurement as typed in, and the environment carries it next to the
measurements:
auto const typedIn = formula::environment(formula::Measured<SideA> { 150 },
formula::Measured<SideB> { 150 },
formula::Measured<Load> { 675 },
formula::entered(formula::Measured<Strength> { 31 }));
auto const asEntered = formula::checked_evaluate(strength, typedIn);
if (!asEntered)
{
std::println("cannot calculate the strength: {}", asEntered.error());
return 1;
}
if (!asEntered->is_overridden())
{
std::println("the strength entered by hand was not used: {}", *asEntered);
return 1;
}
std::println("entered by hand: {} = {} ({})", formula::symbol_of<Strength>(), *asEntered, asEntered->source());
The sides and the load would give 30 MPa, but the strength entered by hand,
31 MPa, overrides the formula, and the result is 31 MPa. Its source() is
formula::ValueSource::ManuallyEntered, printed as manually entered, and
is_overridden() is true. A report can therefore show which numbers the
library derived and which a person asserted.
Output
measured: f_c = 30 MPa (derived)
b not measured: f_c = empty
entered by hand: f_c = 31 MPa (manually entered)
Summary
formula::Measured<Q>::absent()-- a measurement that was not taken; every result that needs it is empty, never zero.formula::entered(measurement)-- marks a value as typed in by a person; it overrides the formula that would calculate it.formula::number_of(outcome)-- the number an outcome holds, as astd::optional; empty when it holds none.formula::ValueSource-- where a result's number came from:Derived,MeasuredorManuallyEntered.is_overridden()-- true when the result is a value entered by hand.