Programming Language

Nocter

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

/development/milestones/v0.10.0-phase-2.md

Nocter v0.10.0 Phase 2

Status: Completed on 2026-08-09.

Purpose

Phase 2 completes the directory-module model by separating a public callable contract in index.nct from its executable body in an explicitly imported implementation source. The public root remains the sole API authority without forcing growing standard-library implementations back into one large file.

This is a semantic declaration/body relationship. It is not a wrapper convention, textual inclusion, source-order rule, duplicate symbol exception, or separate-compilation boundary.

Source Contract

A public callable in a module root may omit its body:

// index.nct
use ./operations

pub func parse(text: &str): Value!

impl Value {
    pub method &self.render(): String
}

One private declaration with an exactly matching signature supplies each omitted body:

// operations.nct
func parse(text: &str): Value! {
    ...
}

impl Value {
    method &self.render(): String {
        ...
    }
}

Rules:

  • body omission is accepted only for a pub or pub(nocter) callable declared in index.nct
  • an omitted body requires exactly one body-bearing private implementation in a composed source of the same directory module
  • an implementation is not a second symbol and cannot be imported, exported, or selected by source path
  • callable kind, owner, generic parameters and bounds, receiver, parameter names and types, return type, and authored from clause must match exactly after canonical type resolution
  • inline public bodies remain valid for small declarations
  • implementation-only declarations without a root contract remain ordinary private callables
  • default belongs to the construction contract; its implementation does not repeat it
  • interface requirements retain their existing conformance model and cannot use module-body implementations; interface default bodies remain inline
  • interface implementation methods and drop members always require bodies

The model applies uniformly to top-level and associated functions, inherent methods, construction functions, typed literals, and coercion entries. No callable form gets a path-based or standard-library-only exception.

Compiler Identity

One compiler-owned CallableBodyIndex records the declaration-to-implementation relation for a complete directory module. Matching occurs after source composition and before symbol collection. It produces deterministic missing-body, signature-mismatch, and duplicate-body diagnostics.

  • exported symbol identity, visibility, hover notation, completion, and call resolution use the declaration span in index.nct
  • body resolution, type checking, ownership, buildability, lowering, and body diagnostics use the implementation AST and its physical spans
  • call targets and specialization identities use the declaration identity even when emitted from an implementation source
  • references and rename join declaration, implementation, and call occurrences
  • definition navigates to the public contract; implementation navigation uses the body location
  • source invalidation follows both the source-import edge and the explicit body relation

The index is shared semantic data. Individual compiler stages may not rematch callables by source text, basename, filesystem path, or presentation string.

Standard-Library Layout

After the semantic model is complete, Phase 2 normalizes the standard-library tree:

  • std/string_search and std/string_views become search.nct and views.nct sources of std/string
  • std/vec_into_iter becomes into_iter.nct in std/vec
  • std/io/core becomes core.nct in std/io
  • std/iter/core, ops, sources, chain, enumerate, and range become focused source files of std/iter; re-export-only adapter modules are removed
  • std/io_buffer becomes the genuine child module std/io/buffer
  • the internal target boundary moves from std/os to std/internal/os

std/error, std/fmt, std/io, std/iter, std/mem, std/num, std/path, std/prelude, std/process, std/ptr, std/sequence, std/slice, std/str, std/string, std/testing, and std/vec remain top-level conceptual modules.

Completion Gate

  • every supported callable kind parses, formats, and emits stable AST JSON with or without an inline body
  • declaration/body matching is source-order-independent and reports both physical locations
  • resolver, type checker, ownership, provenance, buildability, specialization, and native lowering consume the shared body index
  • LSP hover, completion, signature help, definition, implementation, references, rename, semantic tokens, and diagnostics preserve the two source-backed locations
  • the standard library uses the normalized module/source layout without compatibility re-exports from removed paths
  • std/vec/index.nct, std/string/index.nct, and std/io/index.nct present their public contracts without retaining private implementation bodies that belong in focused sources
  • public specification and compiler-development documentation identify one current source of truth
  • the complete compiler verification suite, documentation generation, public examples, formatting, warnings-denied Clippy, and git diff --check pass

Phase 2 does not add wildcard source discovery, overloads, separate compilation, header generation, dynamic linking, ABI-stable libraries, or new practical standard-library APIs.

Completion Record

  • One CallableBodyIndex matches bodyless root contracts to private bodies for functions, associated functions, inherent methods, construction functions, typed literals, and coercions. Stable E0250 through E0253 diagnostics cover missing, mismatched, duplicate, and invalid bodyless declarations.
  • The index owns callable and input identity. Receivers, parameters, and literal captures in a physical body map to the public contract before result-provenance and retained-mutation summaries cross a call boundary.
  • Resolver, type checking, recursive generic specialization, buildability, native lowering, drop discovery, and trusted declaration lookup consume the composed module and shared body relation. A regression test builds a source-backed generic body that reaches another generic call.
  • LSP definition, implementation, references, rename, hover, completion, signature help, semantic tokens, and diagnostics retain the public contract and physical body as two locations of one semantic callable.
  • Standard-library public contracts now live in their conceptual module roots. Focused sources are std/string/search.nct, std/string/views.nct, std/vec/into_iter.nct, std/io/core.nct, and std/iter/{core,ops,sources}.nct. std/io/buffer and std/internal/os are genuine child modules. Removed module paths have no compatibility re-export.
  • The complete library suite passed 2,370 tests with warnings-denied Clippy. The normalized installed-home suite passed all 225 tests, including native execution, ownership, region, provenance, LSP, and callable-contract audit coverage. Public examples, source corpus, CLI suites, formatting, documentation generation, and git diff --check complete the final gate.