cond: Flat Multi-Way Dispatch That Compiles to a Nested If

· 4 min read

Dispatching on one value across several cases is the most ordinary thing a program does. In Koru it had one honest spelling — a nested conditional, if in the else of the if before it, one indent deeper per case:

coin = if(k == 1)
| then -> 1
| else |> if(k == 2)
    | then -> 5
    | else |> if(k == 3)
        | then -> 10
        | else |> if(k == 4)
            | then -> 25
            | else -> 50

That is correct and it is fast, but it reads like a staircase — the fifth case sits four levels deep for no reason the problem asked for. The nesting is an artifact of the spelling, not the logic.

The flat form

cond takes the scrutinee once and lists the cases flat — each arm binds the value, guards it, and produces when the guard holds; a guardless | c _ arm is the default:

coin = cond(k)
| c k when k == 1 -> 1
| c k when k == 2 -> 5
| c k when k == 3 -> 10
| c k when k == 4 -> 25
| c _ -> 50

Same five cases, no staircase. First arm whose guard holds wins; the default catches the rest.

It matches nothing

The important part is what cond is not. It is not a match construct, and it does no comparison of its own. It sits on two primitives Koru already had — the when guard and the arm binding — and it lowers to a first-match if/else-if cascade: the exact staircase above, generated. It is a template in koru_std/control.kz, the same way ~if and ~for are templates, not built-in keywords. The language gained a spelling, not a mechanism.

The flat form is free

“Lowers to the cascade” is a claim about codegen, so we checked it the only way that settles a codegen claim — we compiled both forms of the same kernel and diffed the machine code. The cond version and the hand-nested if version produced byte-identical binaries: the same instructions, the same register allocation, the same everything. Not “about as fast” — the same code. There is nothing to measure because there is nothing different to run.

That is the whole point of a construct like this. You are not trading readability for a cost; the flat spelling and the nested spelling are two ways of writing one program, and the compiler collapses them to the same place before it ever reaches the optimizer. Write it the way that reads — cond — and pay exactly what the staircase paid, which is nothing extra at all.