How does the <? coalescing minimum operator work in EK9?
← Operators and Expressions · Ref: Q963
The <? operator is a COALESCING MINIMUM. It returns the smaller of two SET values. If either value is UNSET, the result depends on which is set:
- Both SET: returns the smaller value (like Math.min)
- Left SET, right UNSET: returns left (the SET one)
- Left UNSET, right SET: returns right (the SET one)
- Both UNSET: returns UNSET
This is unique to EK9 — no other language has coalescing comparators.
The >? operator is the coalescing MAXIMUM (same rules but returns the larger).
Bridge: There is no equivalent in Java, Python, Kotlin, or Rust. The closest analogy is a null-safe Math.min() that automatically handles missing values.
See Q899 for the full coalescing operator family. See Q24 for tri-state semantics.
Example
defines module qa.operators.coalescingmin defines function <?- Find the cheaper price using <? coalescing minimum. If either price is unset, returns the other. -?> bestDeal() as pure -> onlinePrice as Float storePrice as Float <- rtn as Float: onlinePrice <? storePrice <?- Find the closest deadline using <? coalescing minimum on dates. Works with any type that has the <=> comparison operator. -?> nearestDeadline() as pure -> deadlineA as Date deadlineB as Date <- rtn as Date: deadlineA <? deadlineB maxOf() as pure -> left as Integer right as Integer <- rtn as Integer: left >? right chainedMinFloat() as pure -> a as Float b as Float c as Float <- rtn as Float: a <? b <? c defines program CoalescingMinDemo() stdout <- Stdout() // Both values set — returns the smaller cheapest <- bestDeal(29.99, 19.99) stdout.println(`Cheapest: ${cheapest}`) // One value unset — returns the SET one knownPrice <- 25.0 unknownPrice <- Float() safePrice <- knownPrice <? unknownPrice stdout.println(`Safe price: ${safePrice}`) // Both unset — result is unset noPrice1 <- Float() noPrice2 <- Float() noResult <- noPrice1 <? noPrice2 if noResult? stdout.println("Should not reach here") else stdout.println("Both unset, result is unset") // >? coalescing maximum — returns the larger topScore <- maxOf(85, 92) stdout.println(`Top score: ${topScore}`) // Chaining: find minimum of three values lowest <- chainedMinFloat(30.0, 15.0, 22.0) stdout.println(`Lowest of three: ${lowest}`)
Common mistakes
E50001 — EK9 has no min() function so the call cannot be resolved — use the <? coalescing minimum operator instead. See ek9 -h E50001 for details.
Incorrect:
min(onlinePrice, storePrice)
Correct:
onlinePrice <? storePrice
Other ways to ask this
- What does <? do in EK9?
- How do I find the minimum of two values safely in EK9?
- What is EK9's safe minimum operator?
- How does coalescing less-than work?
Coming from another language?
Java: Math.min(a, b) requires null checks. Python: min(a, b) throws on None. Kotlin: minOf(a, b) requires ?: null handling. EK9's <? combines comparison + unset handling in one operator.
Keywords: unset handling, coalescing, safe comparison, less than, minimum