Files
AILang/design/contracts/language-constraints.md
T
Brummel bcd41810f4 design/ + source rustdoc: replace opaque shorthand with content phrases + links
Reader-facing prose and rustdoc carried opaque shorthand like
"Decision 10", "clause-5", "mq.1", "ct.1", "eob.1", "rpe.1",
"post-mq.3", and "Iter 22b.1:" with no in-repo definition the reader
could follow. This commit replaces every such occurrence in the
durable tier the reader is most likely to land on (design/ ledger +
source //! module headers + the central /// public-item rustdoc) with
an inline content phrase plus, where applicable, a Markdown link to
the file that defines the referenced concept.

design/ ledger — 16 files:
  Definition-site headings demoted from "Decision N: <title>" to
  "<title>": authoring-surface, tail-calls, memory-model section in
  rc-uniqueness.md, dual-allocator section, typeclass design,
  effects "pure core + algebraic effects".
  Cross-reference sites: "Decision 1" -> canonical-schema principle
  (data-model); "Decision 3/4" -> effects + scope-boundaries; "Decision
  6" -> authoring-surface; "Decision 8" -> tail-calls; "Decision 9" ->
  rc-uniqueness (dual-allocator); "Decision 10" -> memory-model;
  "Decision 11" -> typeclasses (model). "clause-5" -> body-link
  durability gate. "clause-3" (in language-constraints) ->
  bug-class-reintroduction discriminator. "mq.1/2/3", "ct.1/4",
  "eob.1", "rpe.1" -> the canonical-form rule / the type-driven
  dispatch / the Str carve-out / etc. "post-mq.3" -> "type-driven".

design/contracts/feature-acceptance.md: file-local "clauses 1/2/3"
-> "criteria 1/2/3" (sprachliche Kohärenz mit der File-Überschrift
"Feature-acceptance criterion"); "the clause-3 mechanism" -> "the
bug-class-reintroduction discriminator".

Source //! module headers — 24 files:
  Stripped "Iter X.Y:" prefixes and "(Decision N)" / "(mq.X)" tags
  from spec_drift, uniqueness, reuse_shape, migrate_canonical_types,
  typeclass_22b{2,3,c}, suppress_filter, lift, mono, linearity,
  diagnostic, method_dispatch_pin, method_collision_pin,
  no_per_type_print_ops, mq3_multi_class_e2e, print_mono_body_shape,
  print_no_leak_pin, cli_diag_human_workspace_load_error,
  ct1_check_cli, prose snapshot, unbound_in_instance_method_pin,
  mono_xmod_ctor_pattern, desugar.

Central /// public-item rustdoc:
  ast.rs (full sweep — every "Iter X" + "Decision N" prefix
  reformulated; mode/Type::Fn rustdoc now points at memory-model.md;
  Constraint / SuperclassRef / InstanceDef / ClassDef rustdoc points
  at typeclasses contract).
  diagnostic.rs (all "(Iter X)" / "(mq.X)" tags on diagnostic codes
  removed).
  lib.rs (FORM_A_SPEC rustdoc points at authoring-surface.md
  instead of "Decision 6").
  canonical.rs (type_hash + Float-literal rustdoc).

Still outstanding (for a follow-up commit): ~500 inline `//`
code-body comments with `Iter X.Y` markers across the workspace, and
a handful of `///` rustdoc items in hash_pin / workspace_pin / lift /
mono / suppress_filter test-pin and internal-function bodies. Code
identifiers (test filenames like `mq3_multi_class_e2e.rs`, function
names like `iter18e_drop_iterative_default_preserves_hashes`) stay
verbatim per the user's "code identifiers stay verbatim" rule.

Tests: design_index_pin 5/5 + docs_honesty_pin 5/5; workspace builds
clean; full `cargo test --workspace` previously green (every
`test result: ok` line, no FAILED line).
2026-05-20 09:47:33 +02:00

1.9 KiB
Raw Blame History

Language-design constraints (binding)

Language-design constraints (binding)

The four constraints below are necessary preconditions for RC to be sound and complete without a cycle-collector backstop. They are not new — AILang already satisfies all four — but the memory model makes them load-bearing rather than incidental:

  1. Strict evaluation. Every Term::App (see Data model) argument is fully evaluated before the call. No laziness, no thunks. (Already true.)
  2. No recursive value bindings. (let x EXPR ...) evaluates EXPR in a scope where x is not bound. Recursion is exclusively via Term::LetRec (which binds a fn, not a value) and module-level fn defs. (Already true.)
  3. No shared mutable refs. Values are immutable once constructed. There is no ref, IORef, Mutex, or any primitive that allows a value to be mutated from a position outside its allocation. (Already true.)
  4. ADTs are acyclic by construction. Strict evaluation + no-recursive-value-bindings + no-shared-mutable-refs together guarantee that any value graph reachable from a binding is a DAG. The reference graph has no cycles. (Follows from 13.)

Laziness, recursive value bindings, shared mutable state, or any feature that creates cycles is rejected at design time unless the proposal proves the cycle is collectible by an extension (e.g. linear ownership).

These constraints are the precondition for the memory model: a sound RC implementation without a cycle-collector backstop requires the reference graph to be a DAG, which constraint 4 establishes from 13. They are also the load-bearing structural reason behind several rejections under the feature-acceptance bug-class-reintroduction discriminator (notably iterated-mutable-state reasoning).

Ratified by: crates/ailang-check/src/uniqueness.rs (in-source mod tests).