.. as the Rest of Positional ValuesStatus: Accepted
Date: October 14, 2026
Answers: #618
Changes: ADR-349 D3 (a positional rest is decided here)
Related:
ADR-291 D10, D17 (the shapes of a pattern); ADR-293
D23 (ref Array[T] views); Part I 3.4; Part III 17.1
Can a match take a list apart by its shape? A list’s first element, its
last, or exactly two elements are today a len() check and indexes, each of
which can panic if the check and the index disagree. Every neighbouring
language with patterns (Rust, Swift’s arrays via case let, Python 3.10,
Haskell, OCaml, Elixir) matches a sequence by its elements.
[], [x], [a, b], [Op::Times, n] match a Vec[T], an Array[T] or a
view of either whose length is the number of parts, each part a pattern
against an element of type T. [first, .., last] and [h, ..] match any
length at least the number of named parts; the .. binds nothing.
Why. The shape is the length check, so no index is left to panic. It is the tuple pattern applied to a sequence, with the rest a tuple already has.
..rest binds the remaining elements as a view, ref Array[T].[h, ..rest] binds rest to the elements the other parts do not name. It is a
view of the list (ADR-293 D23) under the rules of every view: it may be read
and lent, and keeping it beyond the list is refused as for any view. A named
rest exists only in a list pattern.
Why. Recursion over a list’s tail is the use that makes list patterns
worth having; a copy of the tail would make every step cost the rest of the
list. The spelling is ..rest and not Rust’s rest @ ..: @ is not part of
Nikaia’s patterns, and ..rest reads as the rest, named.
.. in a tuple or a variant is the remaining values.(a, ..), (.., z) and E::V(a, ..) match as a list pattern does: the parts
before .. from the front, those after it from the back, the rest bound to
nothing. E::V(..) (ADR-349 D1) is the case with no named part. NK1255 stays
only for .. on a variant without values; naming more parts than the variant
carries is NK1253.
Why. One spelling, one meaning: .. is the rest in a struct, a list, a
tuple and a variant. Leaving the positional form refused would make a tuple the
one shape where the rest cannot be said.
.. per pattern: NK1258.[a, .., b, ..] does not say which elements each rest takes.
match with a list pattern needs else (NK1151).A list’s lengths are unbounded, so coverage is not computed: the rule for a
match over anything but an enum or bool applies. The lowering matches the
subject as a slice, match &(x)[..] { [a, .., z] => …, [h, rest @ ..] => … },
which leaves the list where it was.
len() and indexes, each index a panic away from a disagreeing check.[a, b], no ..). The first-and-rest and
first-and-last shapes are the common ones... without a named rest. Leaves recursion over the tail to index
arithmetic, which is what list patterns are meant to replace.rest @ ... @ is in no other Nikaia pattern; a second binding
form for one case is a spelling spent on nothing.