1. Indentation defines blocks
- Status: Accepted
- Date: 2026-09-02
Context
A block-structured language needs a way to mark where a block begins and ends.
The mainstream options are delimiter pairs ({ }, begin/end, do/end) or
significant indentation (Python, Haskell, F#, YAML).
Korrin's stated philosophy is minimal syntax and "one obvious way". Braces introduce a second, redundant signal: well-written code is already indented to show structure, and braces then have to agree with that indentation — when they disagree, the reader is misled and the compiler is not. Brace styles (same-line vs next-line, "cuddled" else) are also a perennial source of bikeshedding that a language can simply not have.
Decision
Indentation is the only thing that delimits a block. There are no { }, no
begin/end, no end keyword.
- A block is introduced by a header line ending in
:followed by a newline. - The block's body is the run of following lines indented further than the header.
- The body ends at the first line indented back to (or past, as a dedent) the header's level.
- An empty body is written with the
passkeyword on its own indented line.
The lexer turns this into explicit INDENT and DEDENT tokens; see
0007.
Consequences
- No brace-style debate, no missing-brace bugs, less visual noise.
- Copy-pasting code requires re-indenting — true of Python and broadly accepted.
- The lexer is more complex: it carries an indentation stack and emits synthetic tokens. This complexity is contained in one place (see 0007).
- Generated code and one-liners are not possible in the same way as a brace language. Korrin does not target code-generation-heavy use or shell one-liners, so this is acceptable.
- Tooling that manipulates Korrin source must be indentation-aware.
Alternatives considered
- Braces (
{ }). Familiar, editor-friendly, but redundant with indentation and stylistically contentious. Rejected as "bolted on because other languages have it". endkeyword (Ruby/Lua style). Still redundant with indentation, adds vertical noise, and creates its own "stack ofends" problem in deep code.- Offside rule with optional braces (Haskell, Scala 3). Two ways to do one thing — directly against the design goal.