Programming Language

Nocter

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

/development/packaging/v0.4.0-release-notes.md

Nocter v0.4.0 Release Notes

Nocter v0.4.0 makes one source-owned package graph the shared unit of command-line compilation and editor analysis. Package declarations, executable targets, dependency requests, exact locks, and root-module code live together in nocter.nct. The compiler and language server resolve the same typed package, module, and executable identities instead of reconstructing project structure from entry-file paths.

Highlights

  • A package root is exactly a directory containing nocter.nct. The file has a parsed manifest section and an ordinary root module; index.nct remains only a directory module.
  • #executable declarations replace implicit main.nct discovery. An omitted entry selects the code in nocter.nct, entry: "." selects the root index.nct, and an explicit logical path selects a file or directory module without a .nct suffix.
  • Imports are classified before filesystem discovery. ./ and ../ are module-relative, / is package-relative, declared aliases enter exact dependencies, and std enters the compiler-matched standard library. The compiler performs no ambient package-name search.
  • #dependencies accepts path, Git, and archive sources. Generated format-1 #lock data records exact Git commits and archive SHA-256 identities in the same nocter.nct; there is no separate lockfile.
  • nocter fetch, --locked, and --offline provide explicit dependency resolution policy. Lock updates are failure-atomic, package caches are keyed by content-derived PackageId, and nested packages keep independent alias scopes.
  • Git and archive installation validates package boundaries, canonical paths, archive entries, symbolic links, and executable/module escapes before a package enters analysis.
  • The language server owns immutable, generation-numbered package snapshots. Diagnostics, hover, completion, signature help, definition, references, symbols, and semantic tokens observe one document/graph generation per request.
  • Dependency traces survive failed frontend and package-graph loads. Creating a missing import, repairing malformed source or manifests, deleting a symbolic-link target, and fixing transitive package metadata deterministically invalidate affected analyses without discarding unrelated snapshots.
  • The server supports versioned diagnostics, generation-backed semantic-token result identifiers, saved-text synchronization, dynamic **/*.nct file watching, nested package ownership, and an explicit initialize/shutdown lifecycle.
  • Native lowering now requires complete planned-call signatures. It no longer treats unknown call arguments as legacy i32 values, eliminating a test-only path that could conceal an invalid lowering plan.

Package Example

//! JSON command-line tool.

#name: "json-tool"
#version: "0.1.0"
#executable: {
    name: "json-tool",
}

#dependencies: {
    json: {
        git: "https://github.com/example/json.git",
        revision: "main",
    },
}

#lock: {
    format: 1,
    dependencies: {
        json: "git:7db21c1000000000000000000000000000000000",
    },
}

use std/io.print

func main(): i32! {
    print("json-tool\n")?
    0
}

Migration from v0.3.0

  • Create nocter.nct at the package root and declare each executable with #executable. Package build, run, and check no longer infer main.nct.
  • Put the customary main function directly in nocter.nct, or set entry to another logical module path. Use entry: "." only when the intended entry is the package-root index.nct.
  • Declare every non-standard-library package alias in #dependencies. An installed directory with a matching name does not create an importable dependency.
  • Run nocter fetch to resolve missing exact Git/archive locks and install package data. Commit the generated #lock change in nocter.nct; use --locked in verification and --offline when network access must be prohibited.
  • Keep script-style compilation explicit with nocter run app.nct, nocter build app.nct, or --file. Single-file mode has no package directives or dependency namespace.
  • v0.3.0 remains a historical release record. v0.4.0 is still pre-1.0 and does not promise source, package-manifest, or binary compatibility with later releases.

Distribution and Verification

The release asset contains one .nocter/ directory with the compiler, version and manifest metadata, license files, and standard library. The supported host and native target are arm64-darwin. Normal builds require no LLVM, external assembler, linker, SDK tool, or runtime library.

Release qualification covers 2,204 compiler-library tests; all CLI build, run, package, formatter, LSP, distributed-home, and example-corpus integration suites; formatting; warnings-denied Clippy; public documentation generation; optimized local packaging; installed-home doctor; packaged check/build/run and JSON-RPC acceptance; generated native execution; and archive inspection. The installed compiler reports Nocter 0.4.0, and repository and packaged homes use the same release metadata.

See the v0.4.0 release record for architecture, completed gates, qualification boundaries, and non-goals.

Explicit Limits

  • The only supported native host and target are arm64-darwin.
  • Package dependencies use exact source identities; registries, semantic-version resolution, and multi-package workspace membership are not included.
  • Package test targets and a package test runner are not included.
  • The language server does not scan every unopened module into an ambient symbol index. Rename, code actions, inlay hints, persistent semantic caches, and concurrent request scheduling remain future work.
  • No source-level lifetime parameters, runtime interface dispatch, async execution, concurrency, or stable cross-version ABI is included.