CLAUDE/DESIGN/JOURNAL: design rationale ≠ implementation effort
User correction during the post-RC-overnight check-in: the 18a "Type::Fn metadata vs. new Type variant" call was justified across DESIGN.md, JOURNAL, and the commit message primarily by "avoids ~250 match-arm sites". That is an observation about the current state of the code, not a design rationale. CLAUDE.md gains two binding rules: - Design rationale ≠ implementation effort. Effort is at most a tiebreaker; a choice whose only stated reason is effort is suspect. The rule names the 18a misstep as the canonical anti-example so future sessions catch it earlier. - Direction freedom + bounce-back conditions inlined (was previously a cross-reference to a private auto-memory file outside the repo, which the user couldn't see). DESIGN.md Decision 10's Schema-additions block now leads with the substantive reasons for per-position metadata: semantic locality (modes belong to fn-parameter positions, not to types in general — Decision 1 line); compositional clarity (type identity vs. calling convention factor apart); future-proofing (per-position metadata generalises; Type-variant approach combinatoric blows up). The match-arm count remains parenthetical, explicitly named a tiebreaker. JOURNAL records the correction itself — the mistake stays as a data point because how design discipline corrupts is informative.
This commit is contained in:
@@ -6098,3 +6098,46 @@ explicit modes) becomes the first program subject to the check;
|
||||
its current shape (borrow-then-own on `xs`) is exactly what the
|
||||
check should accept, so 18c.2 starts as a "green for the
|
||||
existing test" iter.
|
||||
|
||||
## 2026-05-08 — Correction: 18a Schema-choice rationale
|
||||
|
||||
User flagged that the 18a "per-position metadata vs. `Type`
|
||||
variants" decision was justified in the JOURNAL / DESIGN.md /
|
||||
commit message primarily by implementation effort ("avoids
|
||||
~250 match-arm sites"). That is not a design rationale. The
|
||||
choice may still be right (it is), but the *reasons* it is
|
||||
right have to come from the language, not from the cost of an
|
||||
alternative. New CLAUDE.md section "Design rationale ≠
|
||||
implementation effort" makes this a binding orchestrator rule.
|
||||
|
||||
The substantive justification, retroactively recorded in
|
||||
`docs/DESIGN.md` Decision 10's Schema-additions block:
|
||||
|
||||
1. **Semantic locality.** Modes are properties of fn-signature
|
||||
parameter positions, not of types in general. Embedding modes
|
||||
in `Type` would let the schema permit forms like
|
||||
`(con List (borrow Int))` — syntactically possible but
|
||||
semantically meaningless. Decision 1's "schema permits
|
||||
exactly what is meaningful" argues against the Type-variant
|
||||
approach.
|
||||
2. **Compositional clarity.** A `Type` value's identity should
|
||||
depend only on the type. Calling-convention information
|
||||
(own/borrow) is orthogonal to type identity; mixing them
|
||||
conflates two axes that should be factored apart.
|
||||
3. **Future-proof against more position metadata.** Per-position
|
||||
metadata generalises naturally to additional dimensions
|
||||
(streaming, captured, lifetime witness). The Type-variant
|
||||
approach would force every new dimension into its own
|
||||
`Type::*` variant and produce combinatoric ordering questions
|
||||
(`Borrow(Streamed(T))` vs `Streamed(Borrow(T))`) that don't
|
||||
arise when modes live in a flat metadata vector.
|
||||
|
||||
The match-arm count remains true as an observation but appears
|
||||
in DESIGN.md only parenthetically, marked explicitly as a
|
||||
tiebreaker rather than a rationale.
|
||||
|
||||
This entry stays as a record because the original mistake is
|
||||
informative — design discipline corrupts faster than I notice
|
||||
when I let "implementer-friendly" creep into the slot reserved
|
||||
for "language-honest". The CLAUDE.md rule exists so the next
|
||||
session catches this earlier.
|
||||
|
||||
Reference in New Issue
Block a user