Sort two Measurement records by value and pick the smaller using <? coalescing.
← Operators and Expressions · Ref: Q1230
Define a custom <=> operator that compares only the reading field. The <? coalescing operator then uses that ordering.
operator <=> as pure -> other as Measurement <- rtn as Integer: reading <=> other.reading
smallerReading() as pure -> left as Measurement, right as Measurement <- rtn as Measurement: left <? right
The custom <=> means <? compares by reading only, ignoring label. This is different from 'default operator' which would compare label first (alphabetically), then reading.
See Q1228 for default operator ordering. See Q1229 for priority-based custom ordering.
Example
defines module qa.operators.coalesce.customcmp defines record Measurement label as String: String() reading as Float: 0.0 Measurement() -> label as String reading as Float this.label: label this.reading: reading operator <=> as pure -> other as Measurement <- rtn as Integer: reading <=> other.reading default operator defines function smallerReading() as pure -> left as Measurement right as Measurement <- rtn as Measurement: left <? right defines program CoalesceCustomCmpDemo() stdout <- Stdout() // === BOTH SET — compares by reading only === sensorA <- Measurement("Station-North", 22.5) sensorB <- Measurement("Station-South", 18.3) smaller <- smallerReading(sensorA, sensorB) stdout.println(`Smaller reading: ${smaller}`) // === ONE UNSET — returns the set one === calibrated <- Measurement("Lab", 15.0) uncalibrated <- Measurement() usable <- smallerReading(calibrated, uncalibrated) stdout.println(`Usable reading: ${usable}`) // === BOTH UNSET — result is unset === offlineA <- Measurement() offlineB <- Measurement() noReading <- smallerReading(offlineA, offlineB) if noReading? stdout.println(`Reading: ${noReading}`) else stdout.println("No reading available") // === >? FOR LARGER READING === larger <- sensorA >? sensorB stdout.println(`Larger reading: ${larger}`)
Other ways to ask this
- How do I coalesce custom records that compare by a specific field?
- Given two sensor measurements, select the one with the lower reading.
- In Java I'd use Comparator.comparingDouble for a single field. What does EK9 offer?
- Migrating from Rust where I derive Ord on a struct — how does EK9 do custom ordering?
Coming from another language?
Java: Comparator.comparingDouble(Measurement::getReading). Python: min(a, b, key=lambda m: m.reading). Rust: impl Ord comparing self.reading. EK9: custom <=> on reading field, then left <? right.
Keywords: coalescing, <?, custom, record, minimum, measurement, reading, comparison