Nocter
Nocter is a statically typed, value-centered systems language for building native executables from .nct source files.
Nocter v0.1.0 is the first narrow v0 release. The implementation target is arm64-darwin.
Why Nocter Exists
Nocter exists because trying a programming language should not require accepting a large toolchain, a package-manager commitment, or a pile of system-wide dependencies.
Normal Nocter builds should compile .nct source directly to native executable output without requiring LLVM, clang, as, ld, Xcode Command Line Tools, or an external runtime library from the user.
A language should be easy to try and easy to leave. The intended Nocter release shape is one .nocter/ directory containing the compiler, metadata, and the standard library. Installing Nocter should mean unpacking that directory and placing a nocter symlink in a directory already on PATH. Uninstalling Nocter should mean deleting the symlink and that one .nocter/ directory.
Nocter also comes from frustration with APIs that require users to inspect private implementation details before they can use the public surface safely. Public API should be explicit, narrow, and sufficient. Private details should stay private by default.
Nocter avoids adding many spellings for the same idea. Extra syntax can make a language feel convenient in isolation, but it increases what humans and AI assistants must remember. Nocter favors one clear form, source-backed diagnostics, and formatting rules over a wide menu of equivalent forms.
These motivations become three design pillars:
- Simplicity: small distribution shape, low toolchain dependency, and one canonical source style.
- Encapsulation: public API is the exception; private implementation is the default.
- Foolproof design: the language should guide ordinary code toward correct use and diagnose misuse before backend lowering or runtime execution.
The longer rationale lives in Design Principles.
Language Direction
Nocter is designed around values, modules, explicit contracts, and deterministic resource handling.
struct,enum,func,impl, andmethodform the value-oriented core.- Declarations are private unless marked
pub. interfaceis contract-only: it describes public capability without reusable code.- Future
embeddingis composition-only: it will own contained values and promote only their public contracts without exposing private internals. let,var,&T, and&+Tmake assignment and borrow capability visible.T!represents recoverable failure.T?represents absence.- postfix
?propagates bothT!andT?early. otherwiseis the single optional fallback form.ifandmatchare value-producing expressions.dropprovides deterministic cleanup instead of a runtime GC.
Nocter deliberately avoids class inheritance, trait-based code reuse, implicit interface conformance, and hidden runtime machinery in its core direction.
The normative language definition lives in spec/.
One Directory Install
Nocter release archives are designed to unpack to a single .nocter/ directory:
.nocter/
|-- nocter
|-- VERSION
|-- MANIFEST.json
|-- LICENSE
|-- NOTICE
`-- std/
Install by placing .nocter/ somewhere stable, for example under your home directory, then linking the compiler into a directory already on PATH:
tar -xzf nocter-v0.1.0-arm64-darwin.tar.gz -C "$HOME"
ln -s "$HOME/.nocter/nocter" /usr/local/bin/nocter
nocter doctor
If /usr/local/bin requires elevated permissions, use sudo ln -s ... or choose a user-owned directory that is already on PATH, such as ~/.local/bin when your shell already includes it.
Do not copy the nocter binary out of .nocter/; the compiler locates its standard library from the real installed binary path. If symlinks are not available in your environment, set NOCTER_HOME explicitly:
export NOCTER_HOME="$HOME/.nocter"
Uninstalling a .nocter/ installation is intentionally plain:
rm /usr/local/bin/nocter
rm -rf "$HOME/.nocter"
Release archives use the .nocter/ layout above. During repository-local development, source builds and the local release image remain the way to test changes before cutting an archive. Development setup lives in development/.
For repository-local release testing, the canonical standard-library source is tracked in development/std/ and release metadata lives in development/packaging/. Generate a local installation image under dist/.nocter/ plus the archive dist/nocter-v0.1.0-arm64-darwin.tar.gz with:
./development/compiler/scripts/package-local-release.sh
First Program
Create main.nct:
use std/io.print
func main(): i32! {
print("Hello from Nocter\n")?
return 0
}
Run it:
nocter run
nocter run, nocter build, and nocter check use main.nct when no file is specified. The entry function is the root-file function named main.
Build an executable:
nocter build -o hello
./hello
Check without building:
nocter check
Format a file:
nocter fmt main.nct
Current Status
The v0.1.0 compiler can parse, check, build, and run a meaningful v0 subset on arm64-darwin. It emits ARM64 Mach-O executables directly.
The buildable subset is intentionally narrower than the checkable language. Unsupported runtime forms are part of the v0.2.0+ roadmap unless promoted later; v0.1.0 should reject them with source-backed diagnostics before machine code is emitted. For the exact implementation boundary, see development/docs/implementation-status.md.
Learn More
- Language Specification: Nocter syntax, type system, ownership, standard library, CLI behavior, diagnostics, and tooling contract.
- Design Principles: the simplicity, encapsulation, and foolproof-design rules behind Nocter language decisions.
- Generics, Interfaces, Embedding, and Methods: the separation between explicit contracts and composition-based reuse.
- Nocter v0 Contract: user-facing v0 language boundary.
- Development: Rust bootstrap compiler, tracked standard library, release packaging inputs, implementation status, tests, and maintenance notes.
License
Nocter is licensed under the Apache License, Version 2.0.