Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Roadmap

Where Suji stands at 0.1.22, stated as current condition rather than as promises.

This page describes what works and what is missing. It deliberately contains no dates and no commitments. The honest summary is that Suji is a pre-1.0 language, built from source, whose surface is settled enough to write real scripts against and not settled enough to depend on.

Current Version

0.1.22, from the workspace Cargo.toml. There is no suji --version flag; the version lives in the source tree.

Suji is distributed only as a source build. There is no Homebrew formula, no apt package, no published crate, and no prebuilt binary. Building is make release, and the result is target/release/suji. See Installation.

Versions in the 0.1.x series have changed language syntax — 0.1.11 changed match arms from : to =>, and 0.1.22 changed slices from list[a:b] to list[a;b]. Treat a version bump as potentially source-breaking until 1.0. The full history is in Language Versions.

What Is Stable Today

These parts of the language are exercised by the full spec suite and are unlikely to move under you:

AreaState
Exact decimal numbers and arithmeticSettled since 0.1.9
Strings, interpolation, multiline stringsSettled
Lists, maps, tuples, and their methodsSettled
match in both formsSettled since 0.1.17
loop with through/with, labels, break/continueSettled
Lambdas, defaults, closures, multiple returnsSettled
Ranges, inclusive and descendingSettled since 0.1.18
Regex matching with ~ and !~Settled
Shell templates and | pipelinesSettled
|>, <|, >>, <<Settled since 0.1.12
Imports, exports, local file modulesSettled since 0.1.16
The standard library modules listed in the Standard Library OverviewSettled
Numeric error codes and framed diagnosticsSettled since 0.1.15

The AST-walking interpreter is the reference implementation, and it passes all 650 spec programs. suji --print-ast program.si dumps the parsed AST without running the program.

Known Limitations

These are the sharp edges as of 0.1.22. Each is a real constraint on what you can write today, and each is the obvious place for future work.

No error-handling construct

There is no try/catch, no throw, no Result or Option, and no defer. Any runtime error prints a diagnostic and terminates the process with exit status 1. The only available strategy is checking before acting: m::get(k, default), m::contains(k), xs::length() > 0. A script cannot be made to survive a single bad record. See Error Handling Deep Dive.

Regex is match-only

/pattern/ supports ~ and !~ and can be used as a match arm, and that is all. There are no capture groups, no ::match() or ::captures(), no regex-based replace, and no regex split. string::replace(old, new) takes strings only. Extracting a substring means combining split, index_of, and slicing, or shelling out to sed. Regex literals are also not interpolated, so a pattern cannot be built from a variable.

No tail-call optimisation

Recursion is bounded by the native stack; roughly 600–700 frames deep, a program aborts with a stack overflow. Deeply recursive algorithms need to be rewritten as loops. See Recursion.

A small collection API

Lists have map, filter, and fold but no any, all, find, unique, flatten, zip, enumerate, group_by, or sort_by. Maps have no set method — assign through m[k] = v. Strings have no slice, pad_start, capitalize, or lines. Most gaps can be closed with a fold or a loop, but they are gaps.

Decimal overflow aborts

Numbers are fixed-precision, maximum 79228162514264337593543950335. Exceeding it terminates the process rather than promoting to a wider type, so 2::pow(100) is not a large number — it is a crash. Division by zero is likewise fatal.

Everything is eager

Ranges materialise as full lists, so 0..1000000 allocates a million elements. map and filter allocate a new list per stage. There are no lazy sequences, no generators, and no parallelism. See Performance Considerations.

Other current gaps

GapDetail
No packagingSource builds only; nothing published to a package manager
No --version, --help, or -eThe only flag is --print-ast
No tuple indexingt[0] is a type error; destructure or use t::to_list()
No binding patterns in matchA bare identifier in a pattern is a string literal
No variadic or keyword argumentsUse a list or a map parameter
No break <value>Loops always evaluate to nil
Strings and streams are not iterableConvert with ::to_list() or ::read_lines() first
Minimal REPL:help, :quit, :exit only
No formatter or checkermake lint covers the Rust source, not .si files

Following Along

Progress is recorded in the repository rather than announced: the per-version implementation plans under internal_docs/, the growth of spec/, and the version history in Language Versions. The most reliable way to know whether something works is to write a spec file for it and run it.

See Also