ADR-255: A Jump May Carry Its Condition After It

Status: Superseded by ADR-276 — its D1-D4 are D23-D26 there Date: September 29, 2026 Target Version: Nikaia 0.0.269 Related: Part I 3.2 (if), Part I 3.3 (break and continue), Part I 7.1 (throw is an expression of type never), ADR-135 D3 (a token that begins a line is read as the start of something new), Part I 3.4 (a match arm’s guard is written if)

1. Context

A function that leaves early says so first and gets on with its work after:

if speed > 250 {
    return 250
}

Three lines for one thought, and the thought reads backwards: the condition comes before what it guards. Swift answers with guard … else { return }, which negates the condition and adds a word. The owner asked for the shape the sentence has: return 250 if the speed is over 250.

2. Decisions

D1 — return, throw, break and continue may carry their condition after them

return 250 if speed > 250
throw TooFast(speed) if speed > 250
continue if n % 2 != 0
break if done

Each is if cond { jump } and nothing else: the tree the parser builds is that if, so every rule of if holds — the condition is a bool, the jump leaves where it always leaves, and a statement after it is reached when the condition is false.

D2 — Only after a jump

A condition after an assignment or a call would put the condition of any statement at its end, and a reader would have to read every line to its end to learn whether it runs. After a jump the line says where control goes, and the condition says when; nothing else is ever guarded this way.

return if c { a } else { b } is still a return of an if expression: where a block follows the condition, the if is the value. return if done, with nothing after the condition, is the bare return guarded.

D3 — The condition stands on the jump’s line

An if that begins a line is a statement of its own, as a [ that begins one is a list (ADR-135 D3):

return
if ready { start() }      // a statement after the `return`, never its condition

D4 — No new word

if is reserved and already guards a match arm (Part I 3.4); the word means only when in both places.

3. Consequences

4. What this does not decide

5. What is built

The grammar (exit_guard in crates/nikaia/src/parser/mod.rs), building the if D1 names; nothing after the parser changes. tests/jump_guards.rs holds all four jumps, D2’s return if … { … } else { … }, and D3’s next line.

This site is open source. Improve this page.