hanki

ord

stdlib/ord.hk: the Ord trait and Ordering, a total ordering.

a.cmp(b) returns Less, Equal, or Greater. It is the single ordering primitive: List.sort and the canonical (sorted-key) Map encoding are both built on it, and a user type gets a total order by implementing cmp.

The primitive impls compare with the bare operators, which the type-aware lowering routes to the right opcode per width. < on int is arbitrary-precision (Op::LtBigInt), on u64 it is unsigned (Op::LtUint), on the signed fixed-width ints it is signed. bool orders false < true. string and bytes (lexicographic, via the bytes.compare intrinsic) live alongside in eq/bytes order.

Ordering

type Ordering
  Less
  Equal
  Greater
end

impl Eq<Ordering>

Hand-written (not @derive) so it sits in the baked stdlib prefix: stdlib bodies compare Ordering (cmp(..) == Less), and a stale-blob chunked lower must resolve Eq<Ordering> from the prefix, and never from an impl synthesised after the user items. Mirrors the @derive(Eq) generator's shape; the build_stdlib_bytecode self-containment assert guards that.

eq?

def eq?(self, other: Self) -> bool

Equal when both are the same ordering variant.

Less.eq?(Less)    => true
Greater.eq?(Less) => false

Ord

trait Ord

cmp

def cmp(self, other: Self) -> Ordering

Total order. a.cmp(b) is Less when a sorts before b, Equal when they tie, Greater when a sorts after b.

1i32.cmp(2i32)  => Less
2i32.cmp(2i32)  => Equal
3i32.cmp(2i32)  => Greater

min

def min(self, other: Self) -> Self

The smaller of self and other by cmp, returning self on a tie. A default method over cmp: every Ord type gets it without repeating the body, and a type may still override it.

3i32.min(7i32) => 3i32
7i32.min(3i32) => 3i32

max

def max(self, other: Self) -> Self

The larger of self and other by cmp, returning self on a tie.

3i32.max(7i32) => 7i32
7i32.max(3i32) => 7i32

clamp

def clamp(self, low: Self, high: Self) -> Self

self limited to the closed range from low to high: low when self sorts below it, high when self sorts above it, self otherwise. A default method over min/max as they are over cmp, so every Ord type gets it and may still override it. Crossed bounds (low sorting above high) answer high - the bounds apply in order and the last one wins; the answer is total because a default method that crashed would bar every pure caller of the trait.

1i32.clamp(3i32, 7i32) => 3i32
5i32.clamp(3i32, 7i32) => 5i32
9i32.clamp(3i32, 7i32) => 7i32
3i32.clamp(3i32, 7i32) => 3i32
7i32.clamp(3i32, 7i32) => 7i32
5i32.clamp(7i32, 3i32) => 3i32

impl Ord<int>

cmp

def cmp(self, other: Self) -> Ordering

int is arbitrary precision; < lowers to Op::LtBigInt.

0.cmp(0)                              => Equal
9223372036854775808.cmp(1)            => Greater

impl Ord<decimal>

cmp

def cmp(self, other: Self) -> Ordering

decimal shares int's total order, in-band infinities included (-inf < finite < +inf < undefined, HANKI.md §3); < lowers to Op::LtBigDecimal.

1.5.cmp(2.5) => Less
2.5.cmp(2.5) => Equal

impl Ord<rational>

cmp

def cmp(self, other: Self) -> Ordering

Same total order as int/decimal; < lowers to Op::LtRational.

(1 / 3).cmp(1 / 2) => Less

impl Ord<i8>

cmp

def cmp(self, other: Self) -> Ordering

Total numeric order on i8.

(-1i8).cmp(0i8) => Less

impl Ord<i16>

cmp

def cmp(self, other: Self) -> Ordering

Total numeric order on i16.

5i16.cmp(5i16) => Equal

impl Ord<i32>

cmp

def cmp(self, other: Self) -> Ordering

Total numeric order on i32.

1i32.cmp(2i32) => Less

impl Ord<i64>

cmp

def cmp(self, other: Self) -> Ordering

Total numeric order on i64.

2i64.cmp(1i64) => Greater

impl Ord<u8>

cmp

def cmp(self, other: Self) -> Ordering

Total numeric order on u8.

0u8.cmp(255u8) => Less

impl Ord<u16>

cmp

def cmp(self, other: Self) -> Ordering

Total numeric order on u16.

1u16.cmp(1u16) => Equal

impl Ord<u32>

cmp

def cmp(self, other: Self) -> Ordering

Total numeric order on u32.

7u32.cmp(3u32) => Greater

impl Ord<u64>

cmp

def cmp(self, other: Self) -> Ordering

Unsigned: a high-bit-set u64 orders above i64::MAX and never below 0 (< lowers to Op::LtUint).

0u64.cmp(18446744073709551615u64) => Less

impl Ord<bool>

cmp

def cmp(self, other: Self) -> Ordering

false < true.

false.cmp(true) => Less
true.cmp(true)  => Equal
true.cmp(false) => Greater

impl Ord<bytes>

cmp

def cmp(self, other: Self) -> Ordering

Lexicographic byte order, via the cross-tier bytes.compare intrinsic (so both tiers agree); shorter is Less when it is a prefix of the longer.

"a".to_bytes().cmp("b".to_bytes())  => Less
"ab".to_bytes().cmp("a".to_bytes()) => Greater

impl Ord<string>

cmp

def cmp(self, other: Self) -> Ordering

Lexicographic by UTF-8 bytes (rides on Ord<bytes>).

"apple".cmp("banana") => Less
"banana".cmp("apple") => Greater