Canonical Flow
Compared to v0.40.0, Neva v0.41.0 establishes one canonical, zero-config format for Neva source, exposes that formatter both through the CLI and a public Go package, adds a portable type-description substrate for future runtime tooling, and hardens several runtime and installation paths.
Highlights
neva fmtis now built into the Neva CLI. It formats valid Neva source with one fixed, syntax-only style and is available for stdin, files, and recursively scanned directories.- The public Go package
pkg/formatterprovides the same formatter to tools and integrations. It parses and renders standalone Neva source without module resolution, analysis, desugaring, or code generation. - The formatter canonicalizes import blocks and composite literals, wraps breakable layouts at 80 columns, and is checked against the repository source corpus in CI.
std/reflect.TypeandTypeNodeexpose a portable finite, indexed description of a Neva type. Recursive edges are represented as indexes into the same descriptor.Turn,Match, andSelectnow receive independent inputs concurrently, eliminating the sequential-receive deadlock risk when senders arrive in a different order.- The Unix installer no longer requires
sudo; setNEVA_INSTALL_DIRto choose an explicit destination.
A first-party, zero-config formatter
Use neva fmt before committing, or make it a repository gate:
neva fmt -w .
neva fmt --check .neva fmt is deliberately opinionated and has zero configuration: each valid source file has exactly one canonical layout. It is syntax-preserving, so semantic style rules and automated refactorings remain separate tooling concerns.
The design drew on gofmt, rustfmt, Prettier, Kotlin, Swift, Zig, and Odin formatters, while settling on Neva's own canon: compact layouts where they remain readable, vertical sequences when they do not, and no ambiguous alternatives for imports, indentation, or spacing.
For example, it sorts imports into their canonical groups and normalizes indentation:
Before
import {
@:zeta
third:omega
fmt
@:alpha
third:alpha
reflect
third:zeta
@:omega
runtime
}
After
import {
fmt
reflect
runtime
third:alpha
third:omega
third:zeta
@:alpha
@:omega
@:zeta
}
It also makes a single deterministic choice when a breakable sequence crosses 80 columns:
Before
type ExtremelyLongAlias very_long_package.SomeVeryLongGeneric<first_type, second_type, third_type>
interface VeryLongInterfaceName<first_very_long_type_parameter, second_very_long_type_parameter, third_very_long_type_parameter> () ()
After
type ExtremelyLongAlias very_long_package.SomeVeryLongGeneric<
first_type,
second_type,
third_type,
>
interface VeryLongInterfaceName<
first_very_long_type_parameter,
second_very_long_type_parameter,
third_very_long_type_parameter,
>() ()
For scripting and editor integration, the command supports standard output, in-place writes, diffs, file listing, parse-error continuation, and deterministic directory traversal:
neva fmt -d path/to/file.neva
neva fmt -l .Go-based tools can import the same public package used by the CLI:
import "github.com/nevalang/neva/pkg/formatter"
formatted, err := formatter.Format(source)Portable type descriptors: a foundation for future tooling
std/reflect.Type is a compact graph representation for carrying a resolved Neva type as data. Its public shape is a list of TypeNode values; the relevant node forms include scalar values and indexes to composite children:
pub type Type list<TypeNode>
pub type TypeNode union {
String
List int
Struct list<StructField>
Union list<UnionCase>
}
The root is node 0; composite relationships point to other nodes by index. For example, the Neva type list<string> is carried at runtime as:
const list_of_strings reflect.Type = [
reflect.TypeNode::List(1),
reflect.TypeNode::String,
]
This makes recursive types representable without a global registry or per-message metadata.
This release deliberately provides the descriptor substrate only: it is a foundation for future reflection-aware tooling. It does not add TypeOf, #bind_type, JSON conversion, or a global type registry.
Reliability and developer experience
Turn,Match, andSelectpreserve their existing behavior while accepting independent inputs in either sender order.- The installer uses a user-writable location by default and reports release-discovery and download failures correctly.
- Node and declaration syntax, documentation, and the checked-in source corpus were aligned with the new canonical formatter output.
Included PRs
- #1166 Install Neva without
sudo - #1169 Remove comma-separated node and import declarations
- #1173 Structure compiler directives in the AST
- #1175 Add the portable
std/reflecttype descriptor - #1180 Receive runtime inputs concurrently
- #1172, #1174, #1177, #1178, #1181, #1183, #1184, #1185, #1186, and #1188 First-party formatter and its canonical CI baseline
- #1189, #1190, and #1191 Documentation, CI, and release maintenance