Structural identity is not implicit conversion, and writability decides the layout question
This commit is contained in:
parent
95b4f1173b
commit
c49286ca01
25
DISCUSS.md
25
DISCUSS.md
@ -128,15 +128,28 @@ front-end question, not a data-model change.
|
||||
|
||||
**Two costs, and the second is the real work:**
|
||||
|
||||
- **It cuts against the project's standing instinct.** This language has repeatedly chosen explicit over convenient: no
|
||||
implicit numeric conversions, a bare integer cannot become an enum, `:spcae` must fail at the call site. Structural
|
||||
typing says things are compatible when they happen to line up, which is the opposite reflex. Worth deciding
|
||||
deliberately rather than drifting into — and worth asking whether structural compatibility should be *written* at the
|
||||
site that relies on it, the way `(GamepadAxis n)` made an enum conversion explicit without making it implicit.
|
||||
- **Not an "explicit over convenient" question — that framing was wrong and is recorded so it is not repeated.** The
|
||||
standing rules about implicit numeric conversion and about a bare integer not becoming an enum are about *lossy*
|
||||
things happening silently. A structural match is not lossy; it is a different notion of type *identity*. The two were
|
||||
lumped together in conversation and the author rejected the pairing, correctly. Strong typing and nominal typing are
|
||||
separate choices and this only touches the second.
|
||||
- **Field order is layout, and that is the hard part.** `{x f32, y f32}` and `{y f32, x f32}` have the same fields and
|
||||
different memory. So either field order becomes significant — surprising, since nothing else about a structural type
|
||||
should be — or matching a differently-ordered type requires a copy, which breaks the zero-cost property the whole data
|
||||
model rests on. This is the question to settle first; the type checking is comparatively easy.
|
||||
model rests on. Accepted in conversation as a limitation to respect rather than fight.
|
||||
|
||||
**Writability is what decides whether the copy escape exists.** Fields would be writable on the same terms as any struct:
|
||||
by value you get a copy and writes are local; through a `(Ptr T)` they reach the original. But that settles the layout
|
||||
question rather than sitting beside it. *Read-only* structural access has an out — the compiler could gather the
|
||||
requested fields into a temporary, and then field order would not matter at all. *Writable* structural access cannot:
|
||||
it has to alias the real storage, so the layout must genuinely line up. Decide writability first; the layout answer
|
||||
follows from it.
|
||||
|
||||
**`defclass` may solve this, for the cases that can afford it.** A class has an implementation-defined representation, so
|
||||
the compiler owns the layout and access goes through metadata rather than a fixed offset — field order stops being a
|
||||
user-visible fact. The limit is that a class carries identity and metadata, and a `Vector2` should not pay for either.
|
||||
So plain structs still need their own answer and classes only cover the cases where the overhead was already accepted.
|
||||
See item 7.
|
||||
|
||||
Also unresolved: the shim generates a C typedef per *named* struct, and an anonymous struct has no name to generate one
|
||||
from. Either anonymous structs cannot cross the FFI, or the generator learns to name them.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user