if/else
Syntax
Semantics
The if / else construct evaluates one of two blocks based on a boolean condition.
- cond must have type Bool
- Exactly one branch is executed
- Both branches are type-checked independently
- Only variables defined in both branches are visible after the if
Katon uses structural merging of branch environments rather than implicit mutation.
Variable Visibility and Merging
After an if / else:
- A variable is available only if it is defined in both branches
- The variable must have the same type in both branches
- Otherwise, the program is rejected
This ensures deterministic SSA and simplifies verification.
Example
Valid because x is defined in both branches with the same type.
Invalid Example
if b {
let x = 10;
} else {
// x not defined
}
assert x > 0; // error: x not defined in all branches
Type Consistency
If a variable is defined in both branches but with incompatible types, the program is rejected.
Borrowing and Updates Across Branches
- Borrowed variables remain read-only within each branch
- Functional updates produce branch-local values
- No mutable aliasing is introduced
Valid: y is borrowed consistently in both branches.
Verification Semantics
- Each branch is verified independently
- Post-condition is checked against the merged environment
- Control flow introduces no implicit side effects