let and a for Head Take a Nested Tuple of Names — No VariantStatus: Accepted
Date: October 14, 2026
Answers: #611
(a for head and a let take only one level of tuple)
Related:
ADR-291 D1-D6 (the flat tuple this widens, its readers, NK1136, _);
ADR-291 D10 (match takes nested patterns);
Part I 2.1, 3.3; Part III C.1
How deep may a let and a for head take a tuple apart, and may either name a variant?
ADR-291 D1 let a let bind one name or a flat tuple of names, and D5 refused a
tuple inside the tuple with a sentence. A for head took the same flat list.
match takes nested patterns (ADR-291 D10), so the same tuple
(name, (line, col)) could be taken apart in an arm and not at a binding.
| Language | Its answer |
|---|---|
| Rust | Any irrefutable pattern at let and for, nested; a refutable one needs let … else or if let |
| Python | Nested tuple targets at assignment and for |
| Swift, Kotlin | Swift nests tuple patterns at let and for; Kotlin’s destructuring is one level |
| Option | Why it won or lost |
|---|---|
A1 — both sites take a nested tuple of names, _ and tuples, recursively |
Chosen: one pattern grammar for both binding sites, the one match already nests |
A2 — only the for head nests |
A let that stays flat would be the one binding site that takes a tuple apart differently from its neighbour |
| B — one level of nesting | An arbitrary depth: the second level is no different in kind from the first |
| A variant in the head | A variant can fail to match, and a binding has no branch to go to; that is match’s job |
ADR-291 D1’s reason was what the programs of the day needed. That is not how the language is decided: what it offers follows from what it is for and the coherence of its forms, and a tuple taken apart in one place and not in another is not coherent.
let and a for head take one irrefutable tuple pattern, nested as deep as it is written.let (a, (b, c)) = (1, (2, 3))
for (name, (line, col)) in places { … }
for (key, (_, count)) in totals { … }
The pattern is a name, _, or a parenthesised list of two or more patterns.
(p) is p. Each name takes the part at its position; a part whose type is not
known is ?, and a width is not compared where it is unknown (ADR-291 D3). _
binds nothing (ADR-291 D6). A written type on a destructuring let stays
NK1136 (ADR-291 D4). Every reader that declined several names (ADR-291 D2)
declines a nested pattern the same way. Changes ADR-291 D1 and D5.
let or a for head is refused, NK1259, naming match.let Some(x) = o and for Ok(v) in results can fail to match, and neither
site has another branch. The refusal says to take the value apart with a
match.