Analysis of the proposed quantity handling changes in HL7/FHIRPath branch BP-2026-03-quantity-preview, from the perspective of our Rust FHIRPath engine.
The bulk of the proposal is long overdue and we support it:
- The
~vs=distinction being formally defined is a significant improvement 1 year = 1 'a'→ empty (calendar↔UCUM boundary for year/month is correct)1 week = 1 'wk'→ true (calendar↔UCUM equivalence for week and below is correct)- Left-unit rule for addition/subtraction (already our behavior; glad it's formalized)
- Quantity × Quantity with UCUM unit algebra (
12 'cm' * 3 'cm'→36 'cm2') — long overdue - No rounding on conversion itself — only during the equivalence comparison step
- Long type formalization
The proposed equivalence algorithm says: convert both to the least granular unit (year), producing 0.9166..., then round to 0 decimal places (the precision of 1 year) → 1 = 1 → true.
That means 11 months is equivalent to a year under this spec. The rounding rule exists to handle floating-point noise (e.g. 1.2/1.8 ~ 0.67), not to paper over genuinely different clinical durations. A rule that silently declares 11 months ≡ 1 year will cause real problems in healthcare contexts.
Suggested fix: Where either operand uses a calendar unit whose conversion factor is inherently approximate (month, year), equivalence should require explicit conversion via toQuantity() and return empty otherwise — consistent with how the spec already handles addition/subtraction of these units.
The spec says to convert to the unit with the "highest conversion factor" to avoid artificially increasing precision. That is clear for simple linear units like mm vs cm. It is not clear for:
'fl_oz'vs'mL'— which is "least granular"?- Composed units like
km/hvsm/s - A UCUM unit vs a calendar alias (
'd'vsdays) when they are numerically equal
Without a formal selection algorithm, engines will make different choices and produce different boolean results from the same equivalence expression.
Suggested fix: Either (a) always convert to the left operand's unit (simple, deterministic), or (b) define "least granular" formally in terms of the magnitude of the conversion factor relative to the UCUM base unit, with a defined tiebreaker.
The implicit conversion of 2 → 2 '1' combined with UCUM unit algebra for division means engines must produce and handle reciprocal units (/cm, /s, /kg) as valid Quantity values that can participate in further arithmetic. Almost no FHIRPath engine handles this today, and there are very few real FHIR use cases where a plain number divided by a quantity needs to produce a usable reciprocal unit result.
The Quantity / Quantity case (e.g. 120 'm' / 60 's' → 2 'm/s') is valuable and implementable. The Number / Quantity case producing reciprocal units is a much higher burden for proportionally little value.
Suggested fix: When the numerator is a plain numeric and the denominator is a Quantity, return empty rather than requiring reciprocal UCUM unit algebra. Engines that do support it can return the reciprocal as a conformance extension.
The spec says characters in the Unicode White_Space property are equivalent to each other but sequences are not collapsed. The implication (confirmed by the note) is that 'a b' ~ 'a b' → false.
That will surprise most implementers. Given that Brian's own test thread was explicitly probing this case, the spec should include a worked example table that explicitly states the true/false outcomes for double-space, tab, and leading/trailing whitespace — otherwise engines will diverge on this.
| Issue | Severity | Suggested Resolution |
|---|---|---|
1 year ~ 11 months → true |
High | Return empty for approximate calendar unit equivalence; require explicit conversion |
| Least-granular unit selection underspecified | High | Formalize the selection algorithm or default to left-operand unit |
Number / Quantity → reciprocal unit |
Medium | Return empty; make reciprocal unit support an optional extension |
| String equivalence whitespace not collapsed | Low | Add explicit worked examples in the spec |