Ternaries and cases
Choose values with branches, prepared trials, and ordered recovery.
Choose between two values
The decision markers read as condition ?: true-branch ?_ false-branch ?? undecided-branch. The false and undecided branches are optional; each branch can be an expression or a code block.
The result is odd. Change x to 8 and predict the other branch. Both branches produce values; neither changes a variable.
Choose among several answers
Case containers are useful when several guarded alternatives need to stay together.
The case returns negative. Try zero and a positive score. This is enough branching for most first programs. The sections below are deeper reading for uncertain values, recovery and validation; they are not prerequisites for Define and call.
Undecided is a third result (advanced)
An uncertain numeric comparison does not pretend that overlap means false. When the available enclosure supports both outcomes it returns standalone ?, and ?? selects the corresponding branch:
The undecided value is not simply contagious. Strong three-state logic still uses decisive later operands when possible: ? && _ is false, while ? || 1 is true. Otherwise uncertainty remains:
Predicates, cases, assertions, loops, and guards never accept ? as ordinary truth. They either expose an unresolved result or stop at a defined side-effect boundary.
Advanced: try a computed value
A prepared trial evaluates a candidate once, gives it a temporary name, and checks that name from left to right:
On success, the result is the original candidate. If candidate evaluation, binding, or a check fails decisively, soft ?- returns _. An undecided check returns ? instead. The temporary value binding does not escape the trial.
Prepared trials become ordered alternatives inside a case container. A soft failure advances to the next arm:
Use ?!- for a fact that must hold. Gates can be mixed on the same candidate; the first gate also decides what happens if evaluating the candidate throws:
Here a non-integer is a recoverable failure, while an integer that is not positive is an error. Destructuring patterns work too, and a structural mismatch follows the gate's soft or strict policy:
Assignments use the same expression directly. A soft failure assigns _; a strict failure throws before the assignment commits:
Two additional markers control undecided checks. ??- makes undecided a soft no-match, so an ordered case advances; ??!- requires a decided check and throws otherwise:
The first element is :fallback; the second remains ?. Replace ??- by ??!- to turn inadequate refinement into an error. This is especially useful with a halo guard such as value < {~ 0.55, 0.001, {= timeout=1 } }.
Before exploring prepared trials, test the simple parity and score examples at their boundary values.
Keep going
Continue with Functions for reusable rules or Multifunctions for guarded variants.