DESIGN: substantive rationale for Term::ReuseAs wrapper form
The schema sketch in Decision 10 already committed to
Term::ReuseAs { source, body } as a wrapper, but did not record
WHY the wrapper form was chosen over a reuse_from: Option<String>
modifier on Term::Ctor. Adds the two substantive reasons:
- Compositional flexibility: wrapper generalises to record
literals, opaque box wrappers, capability cells — anything
future iters might add as an allocating construct. Modifier
would replicate per Term variant.
- Source-locality: (reuse-as SRC NEW-CTOR) reads as a sentence
with the source-binder at the head. Modifier scatters intent.
The trade-off accepted: schema permits Term::ReuseAs around a
non-allocating body. Caught at typecheck via
reuse-as-non-allocating-body diagnostic. Same shape as
Decision 7's Term::If composability accepts.
Recording before 18d.1 ships — per CLAUDE.md "design rationale
ne implementation effort", a schema choice has to name its
substantive reasons before code is written, not retroactively.
This commit is contained in:
@@ -964,6 +964,34 @@ Term::Clone { value: Box<Term> } ; `(clone X)` — explicit
|
||||
Term::ReuseAs { source: Box<Term>, body: Box<Term> } ; `(reuse-as SRC NEW-CTOR)`
|
||||
```
|
||||
|
||||
`Term::ReuseAs` is structured as a *wrapper* around a `body`
|
||||
term rather than as a `reuse_from: Option<String>` modifier on
|
||||
`Term::Ctor`. Two substantive reasons:
|
||||
|
||||
1. **Compositional flexibility.** Reuse-as is conceptually a
|
||||
wrapper that says "this expression's allocation comes from
|
||||
`<source>`'s slot". The wrapper form generalises naturally
|
||||
if future iters introduce other allocating constructs
|
||||
(record literals, opaque box wrappers, capability cells) —
|
||||
they all become valid `body` positions. A modifier on
|
||||
`Term::Ctor` would have to be replicated on every
|
||||
constructible Term variant the language grows.
|
||||
2. **Source-locality at the head.** `(reuse-as SRC NEW-CTOR)`
|
||||
reads as a single sentence with the source-binder named at
|
||||
the head. The modifier form would scatter the reuse intent
|
||||
across a child position of the constructor's argument
|
||||
syntax, separating the `source` from the rest of the
|
||||
reuse-as semantics.
|
||||
|
||||
The trade-off this accepts: the schema permits `Term::ReuseAs
|
||||
{ body }` where `body` is not an allocating form (e.g. a
|
||||
literal, a var). Such terms are caught at typecheck via a
|
||||
`reuse-as-non-allocating-body` diagnostic — structural rejection
|
||||
in the typechecker, not the schema. This is the same trade-off
|
||||
Decision 7 made for `Term::If`'s relationship to nested
|
||||
`Term::Match`: prefer composability over schema-level
|
||||
rejection where the typecheck rule is unambiguous.
|
||||
|
||||
**Iter 18e — `TypeDef` attribute.**
|
||||
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user