On this page
Versions What a minor version may do What a minor version may not do Deprecationnx fix
Not covered
The C toolchain
Platforms
Stability
What a version number promises, from 1.0 on. The short form: a program that builds with 1.x builds, and does the same thing, with every later 1.y.
Versions#
Nexium follows semantic versioning. MAJOR.MINOR.PATCH, and each release has a name from release-names.md.
- A patch (1.0.1) fixes bugs. It changes no program's meaning except where the old meaning was a bug listed in
KNOWN_ISSUES.mdor the changelog'sFixedsection. It may also add what changes no meaning (a tool, a command, a builtin, a field of anartifactblock, a way to install), as 1.0.1 to 1.0.3 did: the line between a patch and a minor is meaning, not size. - A minor (1.1.0) adds. Everything that was accepted is still accepted and means the same; what was rejected may become accepted.
- A major (2.0.0) may remove what a minor deprecated, after the cycle below, and never anything else.
The language changes only by addition after 1.0 (ROADMAP, "Past 1.0"). A change that would alter the meaning of an existing program waits for a major, however small.
What a minor version may do#
- Add syntax that was an error before (a new keyword only when it was reserved in
SPEC.md;KEYWORDSinself/lexer.nxis the list). - Add builtins, methods on builtin types, modules and functions to the standard library, effects only as reserved names becoming real, and fields to
artifactblocks. - Accept more programs: a stricter check may be relaxed, a limitation in
SPEC.mdmay be lifted. - Improve diagnostics, the generated C, the runtime, the tools' output. The text of a diagnostic is not stable; its presence is.
- Add a platform, a target, an editor integration.
What a minor version may not do#
- Remove or rename anything a program can name: syntax, a builtin, a standard-library function, a field, an effect, a command-line option.
- Change the effects a standard-library function has. A function that became impure would break every
pure fncalling it. - Change the output or exit code of a program in
examples/ortests/spec/, except a bug fix listed as such. - Change the shape of what
nx shipproduces for a given source: the C header's declarations, the Python and Rust signatures, the npm typings. New artifacts may appear next to them. - Change the on-disk formats a program reads:
nexium.toml,nexium.lock.
nx fmt may change its output in a minor: formatting is a tool, not a language feature. Such a change is listed in the changelog.
Undefined behaviour was never promised. A program that has it under SPEC.md (the view cases of 5.6, a value leaving its arena in 5.7) may become an error in a minor as the checker learns to see it; such a rule arrives as a warning in one release and an error in the next, so the program gets a release to run nx fix. 1.2 did this for the view rules V1 to V5 (SPEC.md 5.6 and 5.7): they warned, --strict or NX_STRICT=1 made them errors, and since 1.3 they are errors for everyone. --strict stays: it makes any warning an error, a deprecation's included.
Deprecation#
A feature that has to go is deprecated first:
- A minor version marks it:
nx checkwarns at every use, with the replacement named;SPEC.mdand the changelog say so. - It stays for at least two more minor versions and six months. Programs using it keep building and keep meaning the same.
- The next major removes it. Where the replacement is mechanical,
nx fixrewrites the program.
nx fix#
nx fix FILE... rewrites source in place and reports what it changed: the deprecations the running compiler knows how to migrate, and the edits the checker offers for its errors where the fix is mechanical: rule V4's .clone() where a value moves out from under a view of it, rule V5's @escape(...) around a value kept past its arena, _ = in front of a value nothing uses. Each edit is tried on the program first and kept only when the checker then reports fewer errors and none it did not report before; what it cannot fix mechanically it leaves, and says how many errors remain. --check reports without writing. It never changes what a correct program means, and it makes no edit that would decide what a program computes: where arithmetic may overflow in a !panics function, wrapping (+%) and saturating (+|) are the programmer's choice (decision 113). There are no deprecations yet.
Not covered#
- The generated C and
runtime/nx_rt.hare artifacts, not interfaces. Programs do not include the runtime header;nx shipgives them a header of their own. - The typed IR that
nx tirprints exists for the compiler's own tests. - The comptime interpreter's step budget, stack limits, and the exact bytes
nx sizeattributes to each declaration. - Behaviour that
SPEC.mdcalls undefined or unspecified.
The C toolchain#
nx is tested with the Zig version CI pins (ZIG_VERSION in .github/workflows/ci.yml, 0.14.1 today), which the Windows installer and the install script also install. Other Zig versions and other C compilers (--cc gcc, --cc clang) are expected to work: the C that nx emits is gnu11 with no compiler extensions beyond __attribute__ guards, and the runtime is one plain-C header. A bug that appears with one compiler and not another is a bug in nx; KNOWN_ISSUES.md lists any that are open. When the pinned Zig version moves, the changelog says so and nx doctor shows what an installation has.
Platforms#
Which operating systems and architectures are supported, and how far, is in platforms.md.