A runnable introduction to the Nomi language.
Nomi is a statically typed, immutable language for writing expression-shaped programs that stay explicit as they grow. This site is both the language tour and the public reference: runnable examples execute in the browser, format themselves after valid edits, and show the same hovers as the editor.
Nomi at a glance
Section titled “Nomi at a glance”- Statically typed, with local inference — named functions spell out
parameters and every non-
Unitreturn type; bindings and lambdas infer. - Fully immutable — bindings, structs, and collections are all persistent; “modifying” returns a new value.
- Functional-first and pattern-matching — first-class functions, algebraic
data types, exhaustive
casedestructuring, and tail calls that run in constant stack space. - Clear local control flow —
return,break,continue, and prefixtryare available when they make a function easier to read. - Explicit interfaces — types implement interfaces with
impl Interface for Type { ... }, opt into generated implementations withderive, and call dispatch through qualified names. - Qualified calls, not value methods — behavior lives in the nearest API
container: usually a type owner, interface, or file API. Calls look like
User.rename(user),String.length(name), orDisplay.to_string(value), neveruser.rename(). - Pipe-oriented —
x |> f()keeps data flow reading top-to-bottom. - Structured concurrency —
concurrent { ... }blocks, tasks, channels, and context-style cancellation keep spawned work scoped. - Typed app fields — runtime context, configuration, and dependencies live
on a concrete app value; tests can swap
dependencies with scoped
with MyApp.field = mockoverrides. - Built-in tests — named
test/testsblocks, assertions, setup, and//!attached examples are ordinary Nomi code run bynomi test.
Where Go fits
Section titled “Where Go fits”Nomi is implemented in Go: the interpreter, analyzer, LSP, stdlib host functions, and current runtime are Go code. Today, Nomi programs run through that runtime rather than compiling to Go source; the same interpreter, built to wasm, powers the editable examples on this page.
Go is an implementation choice, not Nomi’s language identity, but Nomi does follow Go’s lead on some practical toolchain and runtime choices: garbage collection, cross-platform support, strong tooling, dependency mechanics, and host integration. Nomi keeps its own syntax and semantics, and it does not copy Go’s package concept: a directory of files that forms a visibility unit.
Most Nomi code does not touch Go. Go shows up when a Nomi module uses the
current dependency mechanics (go.mod next to nomi.toml) or when a module
wraps host functionality behind a typed Nomi API. In Nomi prose, “module” is
the Nomi unit rooted at nomi.toml; “Go package” means an importable Go package
used at an FFI boundary, not a Nomi concept.
Coming from another language
Section titled “Coming from another language”Elixir — Pipes, pattern matching, immutable data, and
transformation-heavy functions transfer well. Expect static types, declared
ADTs instead of atoms/tagged tuples, Iter pipelines instead of
Enum/Stream, and structured concurrent { } blocks plus supervisors
rather than actor mailboxes.
Gleam — ADTs, Result/Maybe, no null, local inference, and
expression-shaped code should feel familiar. Nomi adds bare bindings,
explicit impl Interface for Type blocks, derive, app fields, defer,
typed literals, and pragmatic local control flow.
Rust — Traits map to interfaces, conformances use
impl Interface for Type { ... }, where bounds are checked at call sites,
Result/Maybe use prefix try, and distinct types fill the newtype role.
There is no ownership system, no mut, no macros, no value-dot methods, and
inference stays local to function bodies.
Go — You will recognize go.mod, go get, strong formatting, explicit
imports, channels, and context-style cancellation. Nomi does not have Go’s
packages. The language model is not Go’s: values are immutable, errors are
Result/sum types, interface conformance is explicit, and concurrency is
structured.
Bindings & Expressions is the place to start; each chapter builds on the last.