Skip to content

Commit 1c6fe8d

Browse files
MImmesbergerclaude
andcommitted
GEP 10: state the dimensionless blind spot and the equality carve-out (D2, D4)
Two scope caveats from @hmgaudecker's audit, both prose-only: - D2: the check is dimensional, not semantic. Anything reducing to the dimensionless dimension is indistinguishable to it — HOURS_FLOW is [time]/[time], so adding working hours to a share/count is not caught. Generalize the existing "result comes out dimensionless" bullet to state the principle, with HOURS_FLOW as the worked example. - D4: equality (==, !=) is deliberately not screened, so sentinel and exact-marker tests (p_id_empfänger == -1, kindersatz_m == 0.0) need not promote the literal to a parameter. Note the trade-off (a non-equivalent equality slips through) on the ordering-comparison bullet. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 7c3b078 commit 1c6fe8d

1 file changed

Lines changed: 16 additions & 3 deletions

File tree

docs/geps/gep-10.md

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,14 @@ a dimensionless result and falls back to the declaration, so the ubiquitous
477477
build-time auto-conversion of same-dimension operands paper over it;
478478
- an ordering comparison (`<`, `<=`, `>`, `>=`) of two non-equivalent quantities, or of
479479
a quantity against a bare non-zero literal — the literal silently carries the
480-
quantity's unit, so promote the bound to a parameter (only `0` is allowed inline);
480+
quantity's unit, so promote the bound to a parameter (only `0` is allowed inline).
481+
Equality (`==`, `!=`) is deliberately **not** screened: it is the operator for
482+
sentinel and exact-marker tests — a person-pointer's no-link marker
483+
(`p_id_empfänger == -1`) or an exact-zero guard (`kindersatz_m == 0.0`) — where the
484+
literal is a deliberate marker, not a hidden dimensioned bound to be promoted to a
485+
parameter. The trade-off is that an equality between two genuinely non-equivalent
486+
quantities is not caught, so `==`/`!=` are reserved for marker tests rather than for
487+
comparing computed amounts;
481488
- a logical operator (`&`, `|`, `~`) applied to a unit-carrying operand —
482489
`wealth & is_adult`, where `wealth` is a stock. Logical operators combine truth
483490
values, so an operand carrying a real unit is a bug the run-time arrays would silently
@@ -488,8 +495,14 @@ a dimensionless result and falls back to the declaration, so the ubiquitous
488495

489496
**What it cannot catch:**
490497

491-
- **a result that comes out dimensionless** — a body inferring a dimensionless value (an
492-
early `return 0.0`, or arithmetic that cancels) falls back to the declaration;
498+
- **anything that reduces to dimensionless.** The check is *dimensional*, not
499+
*semantic*: quantities that collapse to the dimensionless dimension are
500+
indistinguishable to it. A per-period count is `[time]/[time] = 1`, so `HOURS_FLOW`
501+
(working hours per period) reads as a plain number — adding working hours to a share
502+
or a head count is *not* caught. The same blind spot covers a body whose result
503+
*infers* dimensionless (an early `return 0.0`, or arithmetic that cancels): it falls
504+
back to the declaration rather than contradicting it. So the engine guarantees
505+
*dimensional* soundness, not that every quantity is the intended *kind*;
493506

494507
**A body the dry-run cannot evaluate must opt out explicitly.** The dry-run executes a
495508
*scalar* body symbolically, so a body it cannot trace must opt out: vectorized functions

0 commit comments

Comments
 (0)