plan.org describes containers, pools and classes as they are after the repeal
This commit is contained in:
parent
cf71caefc2
commit
918edfb0b5
10
TODO.org
10
TODO.org
@ -1966,9 +1966,13 @@ CLOSED: [2026-09-25]
|
||||
The five predicates are the checker's five, with =integer?= in place of
|
||||
=copyable?=, and the section no longer names =(Handle $t)= or =pool-new=.
|
||||
|
||||
** TODO plan.org's Data model section still describes move-only containers
|
||||
"Owning containers move rather than copy on assignment" and "one =Vec= field
|
||||
makes it move-only" predate the repeal, under which everything copies.
|
||||
** DONE plan.org's Data model section still describes move-only containers
|
||||
CLOSED: [2026-09-25]
|
||||
The Data model section says assignment copies a container's header and the
|
||||
copies alias one buffer. The memory tiers and the classes section name the pool
|
||||
and generational handles as a library over a =Vec=, and the classes gate that
|
||||
named =Handle= is replaced by what classes are as built. The milestone record
|
||||
of what was frozen is left as history.
|
||||
|
||||
** DONE plan.org cites the wrong mechanism for jank's relinking bug
|
||||
CLOSED: [2026-09-25]
|
||||
|
||||
38
plan.org
38
plan.org
@ -5,7 +5,7 @@
|
||||
Two documents are normative and are settled ahead of implementation. Anything in
|
||||
this plan that contradicts them is out of date.
|
||||
- [[file:spec-memory.md][spec-memory.md]] — ownership, the four container types,
|
||||
copies and moves, assignable places, generics without type classes, function
|
||||
copies, assignable places, generics without type classes, function
|
||||
values.
|
||||
- [[file:spec-conditions.md][spec-conditions.md]] — the six hard cases of
|
||||
conditions/restarts: what ~signal~ returns, no-handler behaviour, restart
|
||||
@ -56,14 +56,15 @@ Allocators all the way down; ~malloc~ hidden behind them.
|
||||
| Tier | Strategy | Cost |
|
||||
|-----------+---------------------------------+----------------|
|
||||
| Frame | arena, bulk reset each frame | free |
|
||||
| Entities | pool + generational handles | free |
|
||||
| Entities | a pool over a ~Vec~, in a library | free |
|
||||
| Subsystem | region, freed wholesale | free |
|
||||
| Dev/REPL | leaks by design, reset on reload| dev only |
|
||||
|
||||
- Allocator is part of the calling convention, so a refcounted allocator can be
|
||||
added later without a language change.
|
||||
- Generational handles instead of pointers for cross-references: a stale
|
||||
reference is detectable, not undefined behaviour.
|
||||
- Generational handles instead of pointers for cross-references, written as a
|
||||
library over a ~Vec~ rather than provided by the language: a stale reference
|
||||
is detectable, not undefined behaviour.
|
||||
- Symbols and code live in a permanent arena that only grows.
|
||||
|
||||
** Why no persistent collections
|
||||
@ -93,8 +94,8 @@ world.
|
||||
|-------------+-----------------+------------------+------|
|
||||
| ~[n T]~ | inline, n items | copies | no |
|
||||
| ~[T]~ | ptr+len | copies the view | no |
|
||||
| ~(Vec T)~ | ptr+len+cap | *moves* | yes |
|
||||
| ~(Map K V)~ | open addressing | *moves* | yes |
|
||||
| ~(Vec T)~ | ptr+len+cap | copies the header | yes |
|
||||
| ~(Map K V)~ | open addressing | copies the header | yes |
|
||||
~Vec~ and ~Map~ are monomorphic on element type and record their allocator. Not
|
||||
a Lua-style array/hash hybrid — that is what makes Lua's layout and performance
|
||||
unpredictable.
|
||||
@ -105,17 +106,15 @@ world.
|
||||
returns ~(Option V)~; ~put~ is the ~()~-returning upsert. See
|
||||
spec-memory.md for the deferred move-aware operations.
|
||||
- Operations: ~get~, ~put~, ~remove~, ~push~, ~pop~, ~at~, ~length~, ~update~.
|
||||
Copying is explicit: ~(clone m)~, and owning containers move rather than copy on
|
||||
assignment. No ~!~ convention — nothing is immutable, so it
|
||||
An independent copy is explicit: ~(clone m)~. Assignment copies a container's
|
||||
header, and the two headers alias one buffer. No ~!~ convention — nothing is immutable, so it
|
||||
would carry no information. No ~assoc~; it only existed as the copy-returning form.
|
||||
- ~const~ qualifier on references and slices: compile-time contract that a
|
||||
callee will not mutate. Zero runtime cost.
|
||||
- Value structs copy on assignment — but only *value* structs. Ownership is
|
||||
structural: a struct is a value type iff every field is, so one ~Vec~ field
|
||||
makes it move-only. This is what keeps "copies on assignment" from meaning a
|
||||
shallow copy that aliases owned storage. Deep copies are always explicit:
|
||||
~(clone x)~. Value structs are the snapshot / undo / replay story; they need no
|
||||
separate type.
|
||||
- Structs copy on assignment. A struct with a ~Vec~ field copies the header, so
|
||||
the two copies alias one buffer, as in Odin. Deep copies are always explicit:
|
||||
~(clone x)~. Structs without owning fields are the snapshot / undo / replay
|
||||
story; they need no separate type.
|
||||
- Literals live in read-only memory.
|
||||
- *A global's initialiser may be computed.* A value the linker can write goes
|
||||
into the image and costs nothing to start; anything else is stored at
|
||||
@ -156,8 +155,8 @@ identity, extensibility, and live schema changes:
|
||||
|
||||
Classes require a managed allocation strategy and runtime class/shape metadata,
|
||||
but *not necessarily a tracing GC*. The initial likely choices are a world or
|
||||
session arena, pool allocation behind generational ~(Handle T)~ values, or an
|
||||
explicitly owned region. A small tracing GC confined to class instances remains
|
||||
session arena, a library pool behind generational handles, or an explicitly
|
||||
owned region. A small tracing GC confined to class instances remains
|
||||
an option if cyclic graphs prove burdensome; it never changes ~struct~ layout or
|
||||
the C ABI.
|
||||
|
||||
@ -187,8 +186,11 @@ surprising lazy mutation on field access:
|
||||
#+end_src
|
||||
|
||||
The precise class syntax, inheritance, storage strategy, and migration API are
|
||||
not frozen. Do not add classes until ordinary ~struct~, ~Handle~, and reload
|
||||
semantics are working.
|
||||
not frozen. What is built is narrower than this section: a ~defclass~ instance
|
||||
is a dyn map with its class in the object header, and a redefined class
|
||||
migrates each instance lazily at its next touch, so nothing enumerates live
|
||||
instances (TODO.org, "defclass is a named dyn map with a shape tag" and "A
|
||||
redefined defclass migrates its instances lazily").
|
||||
|
||||
Immutability also serves the optimiser: a value known never to be mutated can be
|
||||
copied into registers and stack-allocated freely. Mutability is what forces heap
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user