Programming Language

Nocter

A self-contained systems language built around simplicity, encapsulation, and foolproof design.

/development/reviews/v0.19.0-phase-2.md

v0.19.0 Phase 2 Collection Ordering Review

Result: passed (2026-08-28). This review covers the public readwrite-slice sort contract, strict-order selection, in-place movement of move-only values, destruction, Vec coercion reuse, complexity and allocation bounds, module responsibility, native behavior, and editor behavior introduced by v0.19.0 Phase 2.

Review Criteria

The review traced:

  • every comparison from the generic (&T < &T): bool requirement to the concrete selected operation;
  • every owner moved out of and back into a slice slot, including duplicate-key and early-return paths;
  • arithmetic used for heap children and element byte offsets;
  • the public declaration selected for explicit slice views and coerced Vec receivers;
  • all new standard-library source and module dependencies;
  • public contract and implementation-source hover, member completion, and navigation;
  • duplicate algorithms, Vec forwarding methods, unnecessary private wrappers, allocation, compatibility behavior, new compiler primitives, and editor-only reconstruction.

Findings and Remediation

Stability would conflict with the bounded-storage goal

A stable general-purpose sort either needs additional owned storage or a substantially more complex in-place merge algorithm. Neither cost should be hidden behind a first practical ordering API. The accepted contract explicitly permits equivalent elements to move, guarantees constant auxiliary storage and O(n log n) worst-case work, and leaves a future stable operation as a separate contract. The method name remains sort; instability is a documented semantic property, not an implementation accident.

Ordering initially entered the slice observation source

The first body was added to slice/views.nct, which would have made borrowed observation and owner-moving mutation share one source responsibility. The completed structure places all heap ordering and raw movement in slice/ordering.nct. slice/views.nct retains only length, pointer, borrowed search, equality, and lexicographic comparison.

The first completed method retained a redundant private forwarding function

An intermediate implementation placed the heap loops in a private free sort function and made the method body forward to it. Since no second consumer existed, that wrapper added another name without defining a boundary. The loops now live directly in the contract-completing method body; only sift_down and swap_elements, which each isolate reused invariants, remain helpers.

Fixed-array unsizing is an independent language capability

Nocter currently has no public fixed-array-to-slice conversion. Adding one would affect coercion, provenance, method selection, and the language specification beyond collection ordering. Phase 2 does not add an implicit conversion merely to broaden a test. Direct slice behavior is exercised through an explicit Vec readwrite view, while ordinary Vec method syntax separately proves the existing receiver coercion. Fixed-array unsizing can be designed independently if a practical consumer requires it.

The native fixture obscured its orchestration function

Embedding the complete Nocter acceptance package inside the Rust test function crossed the workspace line-count guard. The source is now an immutable file-scope fixture, while the test function owns only temporary package creation, discovery, compilation, and execution. No lint exception was added.

Final Boundary Assessment

  • spec/21-practical-standard-library.md exclusively owns ascending result, instability, complexity, failure, allocation, and ownership behavior.
  • std/slice/index.nct owns the sole public declaration. std/slice/ordering.nct owns the sole algorithm and raw movement; std/vec contains no sort declaration or wrapper.
  • strict-order selection remains the existing compiler-checked generic operation. The algorithm calls < directly and does not reconstruct dispatch, call equality, or accept a parallel comparator abstraction.
  • every comparison runs while the complete slice is initialized. swap_elements performs no user call or fallible operation after opening its first slot and fills both slots before returning.
  • valid slice layout makes element offsets representable. The root < end / 2 condition makes root * 2 + 1 representable and within the active heap.
  • the algorithm allocates no storage and introduces no recoverable failure. Two moved locals are its only element-sized auxiliary owners.
  • native acceptance proves reverse and mixed integer order, empty and one-element inputs, already ordered input, duplicate keys, String ordering through coercion, move-only values, and exactly one destruction per original owner.
  • LSP completion exposes sort on Vec, and definition navigation reaches the slice contract rather than an invented Vec declaration. Contract and body hover use the same checked program as native compilation.
  • no compiler source, primitive registry, compatibility path, or reviewed module dependency set changed.

No unresolved correctness or responsibility-boundary finding remains in Phase 2 scope.

Verification

The completed tree passed with /private/tmp/nocter-v019-phase2 as the external Cargo target:

cargo test --locked --manifest-path development/compiler/Cargo.toml --workspace
cargo clippy --locked --manifest-path development/compiler/Cargo.toml \
  --workspace --all-targets -- -D warnings
cargo fmt --manifest-path development/compiler/Cargo.toml --all -- --check
node docs/build-docs.js
git diff --check