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
|
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=.
|
=copyable?=, and the section no longer names =(Handle $t)= or =pool-new=.
|
||||||
|
|
||||||
** TODO plan.org's Data model section still describes move-only containers
|
** DONE plan.org's Data model section still describes move-only containers
|
||||||
"Owning containers move rather than copy on assignment" and "one =Vec= field
|
CLOSED: [2026-09-25]
|
||||||
makes it move-only" predate the repeal, under which everything copies.
|
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
|
** DONE plan.org cites the wrong mechanism for jank's relinking bug
|
||||||
CLOSED: [2026-09-25]
|
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
|
Two documents are normative and are settled ahead of implementation. Anything in
|
||||||
this plan that contradicts them is out of date.
|
this plan that contradicts them is out of date.
|
||||||
- [[file:spec-memory.md][spec-memory.md]] — ownership, the four container types,
|
- [[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.
|
values.
|
||||||
- [[file:spec-conditions.md][spec-conditions.md]] — the six hard cases of
|
- [[file:spec-conditions.md][spec-conditions.md]] — the six hard cases of
|
||||||
conditions/restarts: what ~signal~ returns, no-handler behaviour, restart
|
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 |
|
| Tier | Strategy | Cost |
|
||||||
|-----------+---------------------------------+----------------|
|
|-----------+---------------------------------+----------------|
|
||||||
| Frame | arena, bulk reset each frame | free |
|
| 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 |
|
| Subsystem | region, freed wholesale | free |
|
||||||
| Dev/REPL | leaks by design, reset on reload| dev only |
|
| Dev/REPL | leaks by design, reset on reload| dev only |
|
||||||
|
|
||||||
- Allocator is part of the calling convention, so a refcounted allocator can be
|
- Allocator is part of the calling convention, so a refcounted allocator can be
|
||||||
added later without a language change.
|
added later without a language change.
|
||||||
- Generational handles instead of pointers for cross-references: a stale
|
- Generational handles instead of pointers for cross-references, written as a
|
||||||
reference is detectable, not undefined behaviour.
|
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.
|
- Symbols and code live in a permanent arena that only grows.
|
||||||
|
|
||||||
** Why no persistent collections
|
** Why no persistent collections
|
||||||
@ -93,8 +94,8 @@ world.
|
|||||||
|-------------+-----------------+------------------+------|
|
|-------------+-----------------+------------------+------|
|
||||||
| ~[n T]~ | inline, n items | copies | no |
|
| ~[n T]~ | inline, n items | copies | no |
|
||||||
| ~[T]~ | ptr+len | copies the view | no |
|
| ~[T]~ | ptr+len | copies the view | no |
|
||||||
| ~(Vec T)~ | ptr+len+cap | *moves* | yes |
|
| ~(Vec T)~ | ptr+len+cap | copies the header | yes |
|
||||||
| ~(Map K V)~ | open addressing | *moves* | yes |
|
| ~(Map K V)~ | open addressing | copies the header | yes |
|
||||||
~Vec~ and ~Map~ are monomorphic on element type and record their allocator. Not
|
~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
|
a Lua-style array/hash hybrid — that is what makes Lua's layout and performance
|
||||||
unpredictable.
|
unpredictable.
|
||||||
@ -105,17 +106,15 @@ world.
|
|||||||
returns ~(Option V)~; ~put~ is the ~()~-returning upsert. See
|
returns ~(Option V)~; ~put~ is the ~()~-returning upsert. See
|
||||||
spec-memory.md for the deferred move-aware operations.
|
spec-memory.md for the deferred move-aware operations.
|
||||||
- Operations: ~get~, ~put~, ~remove~, ~push~, ~pop~, ~at~, ~length~, ~update~.
|
- Operations: ~get~, ~put~, ~remove~, ~push~, ~pop~, ~at~, ~length~, ~update~.
|
||||||
Copying is explicit: ~(clone m)~, and owning containers move rather than copy on
|
An independent copy is explicit: ~(clone m)~. Assignment copies a container's
|
||||||
assignment. No ~!~ convention — nothing is immutable, so it
|
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.
|
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
|
- ~const~ qualifier on references and slices: compile-time contract that a
|
||||||
callee will not mutate. Zero runtime cost.
|
callee will not mutate. Zero runtime cost.
|
||||||
- Value structs copy on assignment — but only *value* structs. Ownership is
|
- Structs copy on assignment. A struct with a ~Vec~ field copies the header, so
|
||||||
structural: a struct is a value type iff every field is, so one ~Vec~ field
|
the two copies alias one buffer, as in Odin. Deep copies are always explicit:
|
||||||
makes it move-only. This is what keeps "copies on assignment" from meaning a
|
~(clone x)~. Structs without owning fields are the snapshot / undo / replay
|
||||||
shallow copy that aliases owned storage. Deep copies are always explicit:
|
story; they need no separate type.
|
||||||
~(clone x)~. Value structs are the snapshot / undo / replay story; they need no
|
|
||||||
separate type.
|
|
||||||
- Literals live in read-only memory.
|
- Literals live in read-only memory.
|
||||||
- *A global's initialiser may be computed.* A value the linker can write goes
|
- *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
|
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,
|
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
|
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
|
session arena, a library pool behind generational handles, or an explicitly
|
||||||
explicitly owned region. A small tracing GC confined to class instances remains
|
owned region. A small tracing GC confined to class instances remains
|
||||||
an option if cyclic graphs prove burdensome; it never changes ~struct~ layout or
|
an option if cyclic graphs prove burdensome; it never changes ~struct~ layout or
|
||||||
the C ABI.
|
the C ABI.
|
||||||
|
|
||||||
@ -187,8 +186,11 @@ surprising lazy mutation on field access:
|
|||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
The precise class syntax, inheritance, storage strategy, and migration API are
|
The precise class syntax, inheritance, storage strategy, and migration API are
|
||||||
not frozen. Do not add classes until ordinary ~struct~, ~Handle~, and reload
|
not frozen. What is built is narrower than this section: a ~defclass~ instance
|
||||||
semantics are working.
|
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
|
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
|
copied into registers and stack-allocated freely. Mutability is what forces heap
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user