leviathan-lang.com / docs / reference
Language Reference
The language as it is implemented today, one entry per concept, grouped by chapter. Every entry carries runnable examples.
Lexical
- Array and range literals — Array literals in square brackets, inclusive ranges with
.., and range spreading inside an array literal. - Char literals — A single-quoted literal becomes a
charwhen the context expects one and it holds exactly one Unicode scalar. - Comments — Line comments, block comments, and the
///doc comment that documents the declaration below it. - Identifiers — The characters a name may use, the camelCase house style, and the reserved name
System. - Keywords — The reserved words, the contextual words that are ordinary identifiers elsewhere, and the keywords that may still name members.
- Literals at a glance — Every literal form of the language and the type each one has.
- Numeric literals — Decimal, hexadecimal and binary integers, floats, and the
_digit separator. - Punctuation, operators and template literals — The punctuation and operator tokens, and the backtick-delimited template literal passed to macros and rules.
- String literals — Quoted strings, escapes,
${}interpolation, rawr"..."strings and triple-quoted multiline strings.
Types
- Generics — Generic classes and functions, how type arguments are inferred or given explicitly with
::<T>, invariance,T::memberand type constructors. - Numeric conversions and working types — How operands of different numeric types combine, and when a value is converted on its way into a typed variable, field, parameter or return.
- Primitives (the object mask) — The built-in value types, their default values, the methods they carry, and the
voidunit rules. - Reference vs value semantics — Which types are shared when assigned or passed (class instances) and which are copied (primitives, structs, arrays).
- Sized floats: float8, float16, float32 — The narrow floating-point formats, how every operation re-rounds, and where they overflow or throw.
- Sized integers: byte, int8, int16, int32, uint — The fixed-width integer types, how arithmetic wraps, how mixed widths combine, and when conversions throw.
- Type expressions — How a type is written: names, qualified names, generic instantiations, unions, optionals and function types.
- Unions and optionals — Closed unions
T | U, the optionalT?, narrowing with!= Noneandis, and the??and?.operators.
Expressions
- Calls — Calling functions and methods, with positional and named arguments, explicit type arguments, and the rules that decide which callable a name refers to.
- Construction — Creating objects by naming the type, choosing a constructor by label, supplying type arguments, and building a class that declares no constructor.
- Indexing — The square-bracket operator reads and writes elements through an indexer accessor, and rebinds the variable when the target is an array.
- Integer operators — Shifts, xor, remainder and complement on every integer width, the width at which they compute, and the exception thrown by an out-of-range shift.
- match — type, value and range dispatch — Select the first arm whose pattern matches a value, a type or a range, either as an expression that yields a value or as a statement.
- Member access and qualification — The dot for instances, the double colon for base, static and namespace names, optional chaining, and the explicit-type marker.
- Method dispatch — An instance method call runs the override of the receiver's actual class, whatever static type names the receiver.
- Method references — Naming a function, method or labeled constructor without calling it yields an ordinary function value.
- Operators on objects — A class defines the meaning of an operator by declaring a member with a symbolic selector; the equality operator derives its negation automatically.
- Operator precedence — The binding strength and associativity of every operator, from loosest to tightest.
- Prefix operators — The operand types accepted by the unary operators !, - and ~, and the results they produce.
- Primary expressions — Literals, names, this, parentheses, array and range literals, lambdas and string interpolation, the building blocks of every other expression.
- Strictness — What the compiler rejects instead of guessing, and which failures are left to run time as catchable exceptions.
Declarations
- Accessors — Replace how a field is read or written with get and set, and define computed values and indexers.
- Argument binding — How a call's arguments are matched to parameters, filled by defaults or injection, and how overloads are ranked.
- Activating a namespace's bind with use — Importing a type with use also installs the binding its namespace exports for that type.
- Classes — Declare reference types with fields, methods, constructors and accessors, with generics and inheritance from one or more base classes.
- const declarations — Fix a local, field, global, parameter or loop binding after its initializer, with the exact rules for each kind of slot.
- Constructors — Declare constructors with new, select among them by label and argument types, call base constructors, and construct classes that declare none.
- Dependency injection: bind and inject — Declare lexically scoped factory bindings that fill unbound parameters automatically, and select a binding explicitly with inject.
- distinct fields — Keep same-named fields of different bases in separate slots, reached by qualification.
- Enums — Declare a closed set of named integer-backed values, convert to and from their codes, and match on them exhaustively.
- Fields — Declare the data a class or struct holds, with optional initializers, and how a field without an initializer gets its default value.
- Imports — uses and use — Bring a namespace's names into scope in bulk with
uses, or one name at a time withuse ... as .... - Interfaces — Declare the members a class must provide, including fields, and let any class satisfy them by declaring those members.
- Methods and functions — Declare callables with block or single-statement bodies, overloads, default parameters, named arguments and type parameters.
- Multiple inheritance — Combine several base classes, how same-named fields and methods collapse or stay separate, and how to reach one base's member by qualification.
- Namespaces — Group declarations under a name, reopen a namespace to add to it, nest namespaces, and reach members with
::. - Operator declarations — Define operators on a class or struct by declaring a member with a symbolic selector such as (+), (==) or ([]).
- override — Mark a member that must replace an inherited member or satisfy an interface requirement, and the warning for a member that almost does.
- readonly fields — Fix an instance field once, either in its initializer or in every constructor, and keep it read-only afterwards.
- Value structs — Declare value types that are copied on every assignment, pass and return, with derived equality and explicit mutating methods.
- weak fields — Hold a non-owning reference to an object that reads as None once the object is gone.
Statements
- Exceptions: throw, try and catch — Throwing a value that implements IException, catching it by type, and the standard exception hierarchy.
- Labeled loops — Naming a loop so that break and continue can leave or restart an outer loop from any depth.
- break and continue — Leaving a loop early or skipping to its next iteration, and what counts as a loop for these statements.
- Statements — Declarations, blocks, conditionals, the four loop forms, return, and the order in which a script's top-level statements run.
- using — deterministic cleanup — A using declaration owns a resource and closes it exactly once on every way out of its block, in reverse order of declaration.
Library
- await — waiting for a promise —
awaitunwraps a promise to its value, suspending only the current task while other work keeps running. - Cancellation, timeouts and structured concurrency — Cancellation is an exception delivered at the next await; awaitTimeout turns a timeout into a None result; TaskGroup keeps tasks inside their scope.
- Capability interfaces — IEnv, IConsole, IClock, IFileSystem and INet: injectable stand-ins for the ambient environment, console, clock, files and network.
- Collections are values — Array, Map and Set never change in place; every changing method returns a new collection, and the idiom for change is to rebind.
- The event loop and program lifetime — When a program is finished, what keeps it alive after the last statement, and how callbacks are dispatched.
- Exit codes — env::exit and env::setExitCode — How a program chooses its exit status, and what an uncaught exception does.
- The GUI floor — The native windowing layer that the Dagon GUI framework is built on; a capability floor, not a public API.
- The iterator protocol — IIterable and IIterator — Two interfaces that make any type usable in a
for-inloop, and the rules for which loop path the compiler picks. - Networking — sockets and HTTP — TCP streams, listeners and the in-language HTTP request and response model, all driven by the event loop.
- The standard library — The prelude that ships with the compiler, written in the language itself and in scope in every program.
- Streams — the system boundary — Everything that crosses the program boundary (timers, sockets, signals, child processes) is a stream with one consumer; this entry defines the shared model.
- The native floor — std::sys* — What the
sys*functions instdare, why compile-time code cannot call them, and which two are public. - Tasks — suspension and interleaving — What a task is, what runs while one is suspended, and in what order suspended tasks resume.
- Threads, workers and message passing — Run work in parallel with std::spawn; values cross between threads by copy, and Channel is the way to talk to a running worker.
- TLS and cryptography — Secure connections wrap the existing socket in place, so TcpStream, HttpClient and HttpServer gain TLS without any API change.
Metaprogramming
- Attributes — inert, typed annotations — Declare an attribute with
attribute Name { fields }, attach it with@Name(args), and let rules read it. - comptime — run the language at compile time —
comptimevariables, expressions andifstatements evaluate ordinary code during compilation and fold the result into the program. - import() — comptime file inclusion —
std::import(path)reads a project file at compile time and folds to its contents as acomptimestring. - Expression reification — lambdas as data — A lambda literal in a position typed expr::Expr<F> compiles to an ordinary closure plus a walkable tree of its checked body, which is what query builders translate to other languages.
- Body-generating rules — generates and replace — A
generates body ofrule replaces a method's body outright and discards the original, for stubs whose body is machine-filled. - Compile-time metaprogramming — A map of the four compile-time layers, procedural macros, and the
--expandflag that shows what a rule produced. - Procedural macros — comptime code returns code —
macro name(string payload) comptime { … }runs at compile time, receives a string, and returns the code that replaces the call. - Quasiquote templates and holes — Backtick-delimited templates hold the code a rule injects, and
$holes fill them from the match. - The reifiable subset — The expressions that may appear in a reified lambda and the tree node each one becomes.
- Captured values and the binds array — How a reified lambda records the outside values it uses, once and in order, in the binds array, and what that guarantees.
- Where a lambda literal is reified — A lambda literal becomes an expr::Expr<F> in any position whose expected type is expr::Expr<F>: a call argument, a declared variable, a return value or a field initializer.
- Reification errors — The compile errors a reified lambda can produce, what each means, and how to fix it.
- Reification in --expand output — How the compiler's --expand view shows a reified lambda as an explicit expr::Expr construction, and what it guarantees about the checked tree.
- siteId — identifying a lambda in the source — Every reified lambda literal gets a number that is fixed at compile time, distinct for each lambda in the source, and the same on every run.
- Method calls in a reified lambda, and like / ilike — The six method calls that may appear in a reified lambda, and the exact matching rules of string.like and string.ilike.
- Body-replacing rules — rewrites, replace and $body — A
rewrites body ofrule replaces a method's body with a template that splices the original back in with$body. - Rules — match a shape, inject code — A rule matches declarations by shape and injects quasiquoted code at a named anchor, with
match,where, andinject … at. - Splices — $for, $if, $ident and friends — Repeat, choose and name pieces of a template at expansion time with
$for,$if,$ident(...), composite identifiers and$_params. - target:: — the compilation-target constants —
target::os,target::archandtarget::tripleare compile-time strings that describe the platform being compiled for.
Compiler
- Columnar storage of struct arrays — How native builds lay out an array of simple structs column by column, when that applies, and how to turn it off.
- The leviathan command line — Every option of the
leviathancompiler, grouped by what it does, with the exit statuses and how arguments reach your program. - Cross-compilation: --target and per-target runtimes — Building executables for another operating system or processor, what the build needs for each target, and what a target can reject.
- The execution engines — The four ways the compiler runs a program, why they always agree, and the few places where one of them has to refuse a program.
- Implementation status and execution modes — What the reference promises, what
unreleasedmeans on a page, and the four ways to run a Leviathan program. - Native backends: LLVM and C++ — The two ways to turn a program into a native executable, what each one covers, and the runtime limits of natively built programs.
- Ownership analysis and memory verification — How the compiler decides which allocations die with their function, and the options that report and verify that analysis.
- The WebAssembly (browser) target — Building a program as a WebAssembly module for the browser, what it can use, what it cannot, and how it reaches the page.
Trident
- The trident commands — Every
tridentsubcommand with its arguments, grouped into building, managing dependencies, and publishing and auditing. - Dependencies — Declaring local and repository dependencies, renaming a dependency's namespace with
as, development-only dependencies, and the rule that you may only use what you declared. - The manifest: trident.toml — Every key of
trident.toml, how sources and assets are listed, and the three ways a project can choose its entry point. - Two tools: trident and leviathan — How the package manager and the compiler divide the work, what the build plan between them is, and the commands that build and run a project.
- Publishing, yanking, and auditing packages — Releasing a version of a package, withdrawing it without breaking existing users, and requiring human review and signed provenance for the dependencies a project uses.
- Versions, the lock file, and integrity — How trident picks versions of repository dependencies, what
trident.lockand the checksum record guarantee, and how to build without the network.