Status: Accepted
Date: September 19, 2026
Related: ADR-278 (null and the T?), ADR-025 D2 (a failure leaves without a sigil), ADR-023 D1 (an error type is an enum), Part I 4.4, 6.6, 7.1 and 8, docs/language-review.md §3.5
language-review.md §3.5 lists nine things the specification writes that the
language does not have. They are not one kind of thing, and telling the two
kinds apart is the whole of this record.
Six are slips: a page reaching for a surface the language deliberately does not have, or writing a type by a name it does not carry. Each has a correct spelling that exists, so each is a page edit with no ruling behind it.
Three are constructs: a duration literal, a channel and a select block.
Each is a feature the language would gain and belongs to Part I chapter 8, and
none had a record. A page that writes one is not a slip — it is a page ahead
of a decision.
Changed by ADR-328: the call is supervisor::run, with restart: and policy: per child.
| written | is |
|---|---|
neg.is_some() (examples/1brc.nika) |
neg != null — there is no Some here (ADR-278) |
io::read_to_string("input.txt")? (Part III C.4) |
io::read_to_string("input.txt") — a failure leaves on its own (ADR-025 D2) |
List[Token], List[Row], List[Fortune] |
Vec[…] — Part I 2.2’s prose calls the concept List (Vector) and the type is Vec |
panic::on_panic fn(info) sync { … } |
the hook without the word: a lambda carries no promise (ADR-277 D6 puts it on the parameter’s type) |
supervisor::start_link(…; restart_policy: "always") |
an enum, which is what Part I 4.4 argues for where a string names one of a few things |
TimeoutError("Too slow!") |
an enum variant, because an error type is an enum (ADR-023 D1) |
The first three are wrong about a spelling; the last three are wrong about a shape, and each of those three is a page writing the thing the page next to it argues against.
Changed by ADR-150 D2, ADR-149 D1 and ADR-292 D12: each of the three is now decided by its own record, and its page carries that record’s rule rather than the mark.
A construct written on a page with no record behind it is marked
unspecified in place (D3), not removed and not decided in passing: removing
it loses the shape somebody wrote down and the argument it was making, and
deciding it in a footnote takes a language feature without a record’s worth of
question — what a duration is as a type, whether a channel is std’s or the
language’s, and what select does to sync.
Unspecified. This writes a construct the language does not have and no record decides. It is here for the shape of the example; the decision is named where it will be taken.
One paragraph in specification/README.md, beside the
Status note’s own definition, so that a reader who meets the mark knows
what it promises: nothing, yet, and where to look. The two marks differ: a
Status note stands under a decided rule the compiler has not caught up
with, the Unspecified mark under a construct nobody decided, and a page may
carry both, one under the other.
List[…] becomes Vec wherever a page writes it.select — decided by
ADR-150, ADR-149 and ADR-292, not
here.