The values behind the choices
Sisu's goal is that people are productive in it because things work. Four values serve that goal, and a choice that trades one for another follows this order.
- Correctness
The language makes wrong programs hard to write. Mistakes are caught early, at compile time where possible.
- Simplicity
Few concepts, rules without special cases, every effect visible where it happens.
- Readability
Code that reads top to bottom. Errors in plain words.
- Performance
Native code with predictable memory. Optimizations never change what a program means.
Simplicity ranks above readability because agents now write and read much of the code. Special cases and two ways to do one thing cause their mistakes, and slow a human reviewing their work.
Principles
Some records settle features that are still planned, such as interfaces. The status page shows what works today.
- 0004Python syntax, Rust semantics, Swift memory modelSurface syntax follows Python, semantics follow Rust, and memory management and everyday ergonomics follow Swift.
- 0027What Sisu is forproposedFast, small, reliable command-line tools, scripts and server-side software, with code that is fast and easy to verify; three acceptance programs define 1.0.
- 0006Correctness, then simplicity, then readability, then performanceA design choice that trades one value for another follows this order.
Syntax and names
- 0001Statements end at newlines, not semicolonsA line break ends a statement, except inside parentheses. No statement needs a
;. - 0028A
;stands in for a line breakTwo statements, fields, variants or arms can share a line with a;between them; an unnecessary;is a warning. - 0015The prelude holds only what almost every program usesA name is visible in every file without an import only if almost every program uses it, or the language depends on it.
- 0019Enums are values named through their enumamended by 0025 and 0030An enum is an inline value built as
Expr.Num(2); a pattern can use the bare name, andmatchmust cover every variant. - 0020Labels belong to the declarationA variant labels every field or none, and is built with its labels in declared order.
- 0035A file is a module, and its names are private unless
pubnot built yetThe path of a file names its module, a folder's front door ispkg.sisu, an import binds only what it shows, and each item, field and method needs its ownpub.
Values and change
- 0002Bindings are immutable by defaultsuperseded by 0011
letmade a binding that cannot change andvarone that can; immutable by default still holds. - 0011
let mutmarks what can changeOne word,mut, marks every binding, field and method receiver that can change. - 0007Arrays are values, shared until writtenBinding, passing or storing an array behaves as a copy, made only when a shared array is written.
- 0022Classes compare by identity plannedA class has no
==unless it conforms toEqby hand;isasks whether two references are the same object.
Memory
- 0005Memory is managed by reference countingamended by 0031Every heap object carries a count of its references and is freed when the count reaches 0.
- 0008Weak references break cyclesA
weak mutfield does not keep its object alive, and reads asNoneonce the object is gone. - 0012Methods borrow
selfsuperseded by 0029A method receivesselfwithout changing its count, and the caller keeps it alive for the call. - 0021A loop makes its written arrays unique before it startsamended by 0025A loop that writes a local array makes it unique once, before the first iteration, so its writes skip the count check.
- 0025mir holds every countCopies and releases are explicit statements in a mid-level IR, moves are consuming operands, and a debug-build check certifies each function.
- 0029Parameters are borrowed unless the function consumes themA function that only reads a counted parameter borrows it: the caller keeps its reference, and neither side counts it.
- 0030
matchtakes its scrutinee apartAn arm moves the parts it binds out of an owned scrutinee, and a box it held alone becomes a block the arm builds the next box into. - 0031Compiled programs allocate with mimallocPrograms link mimalloc v3 by default, and
--allocator systemlinks the System allocator for Valgrind and ASan.
Types
- 0014Strings are UTF-8 valuesamended by 0016 and 0018A
stringis always valid UTF-8 and behaves as a value, andlen()counts bytes. - 0017Floats follow IEEE 754
f64arithmetic never panics: division by zero gives infinity or NaN. - 0018A conversion that can fail returns an optional
u8(n),char(n)andi64(x)of anf64return an optional, and no conversion panics. - 0023Generics are monomorphized and checked at the definitionEach list of type arguments gets its own compiled copy, and a generic body is checked once, against its bounds.
- 0024Optionals nest
i64??is its own type, and??andif letpeel one layer. - 0032
while truewith nobreakisneveramended by 0034A function can return from inside an endless loop with no dead tail after it, and code after the loop warns as unreachable. - 0034
loop,breakwith a value, and loop labelsAloopgives the value of itsbreak,outer: for ...letsbreak outerleave an outer loop, andwhile truewarns and points atloop.
Errors and diagnostics
- 0003Integer overflow panics instead of wrappingOverflow, division by zero and dividing the smallest
i64by -1 stop the program with a panic that names the source location. - 0013Diagnostics have stable codesEvery error and warning has a code that is never reused, one wording, and an explanation that a test compiles.
Runtime, I/O and concurrency
- 0009The runtime owns I/O; Sisu builds its own objectsOnly the runtime calls the operating system, and text crosses the boundary as a pointer and a length.
- 0016The word functions trust the UTF-8 invariantIn a release build, the runtime functions behind
words()skip the UTF-8 check that a debug build still makes. - 0010Tasks share no objectsproposedA value that crosses into another task is copied; only channel and task handles are shared.
The compiler
- 0026The compiler stays one crateA split before LLVM was measured against a rule set in advance: an edit already rebuilds the tests in about 2 s, so a split cannot pay for itself.
- 0033Every language feature has a generator ruleA feature is done only when the program fuzzer generates it, and a unit test fails when a variant has no generated program.
What Sisu deliberately avoids
These come from the roadmap's Deliberately avoided list.
- Lifetimes and a borrow checker. Reference counting keeps Sisu in Swift's ergonomic camp. Inferring lifetimes without annotations only moves the cost into the compiler.
- Header files.
- Unrestricted operator overloading.
- Inheritance. A
classis a reference type, not a hierarchy; composition, enums and interfaces cover polymorphism, as in Rust and Go. - Macros. They hide code from error messages, the formatter and the language server. Generated conformances,
constinitializers, attributes and committed generated files do their jobs. - Variadic parameters. An array costs two characters,
sum([1, 2, 3]), and uses a type that already exists. - Pointers in Sisu code. A class is already a reference, and arrays are values.
- Formatter options. One style ends style debates.
- A separate linter. Lints are compiler warnings.
import *. A reader must always see where a name comes from.- A pipe operator
|>and function captures. Method chains and continuation lines already do this, and two ways to write one call break "one obvious way". - Gleam's
use. Gleam needs it because it has no early return; Sisu hasreturn. - A
returnthat names a function further up the call stack. The functions in between would end early with nothing in their signatures to show it;Resultand?pass a failure up one visible step at a time. - Separate float operators such as
+.. The checker knows each operand's type, so+serves both. - Integers without a size limit, or division by zero that gives 0. Sisu's fixed-size integers panic on overflow and on a zero divisor.
- Mutable memory shared between tasks. Tasks share no objects, so counts stay non-atomic and Sisu code cannot have a data race (ADR 0010, proposed).
- A package registry, for a long time. A registry means hosting, security and name squatting.
Interfaces are planned. Planned work has no promised date and may change.
Compile-time evaluation and reflection are left open, to decide once Sisu has grown; the roadmap's Open decisions lists what has to be settled first.
Proposing a change
Open a GitHub issue that names the record and the change you propose. A change that is accepted becomes a new record that supersedes the old one. See how to contribute.
Sisu