Browse the docs

silk.core.order.

The interface that gives user types the <, <=, >, and >= operators.

When to use#

Implement Order when values of a type have a total order. Add a T: Order bound when a generic algorithm compares its type parameter, as sorting and binary search do. The integer types, char, string, f32, and f64 already implement it, so List<string>.sort and List<f64>.sort work without more code.

Details#

&left < &right means Order.compare(&left, &right) == Ordering.Less for the conformance of the operand type (OP-009). The other operators use the same result:

  • <= tests != Ordering.Greater.

  • > tests == Ordering.Greater.

  • >= tests != Ordering.Less.

The program evaluates each operand one time, in written order. Concrete scalar operands always use the built-in comparison. The compiler selects the conformance during specialization. It adds no service requirement and no runtime dispatch.

string orders by its UTF-8 bytes, which is the order of the Unicode scalar values. It is case-sensitive and does not follow a locale, so "Zebra" comes before "apple", and a prefix comes before every longer text.

f32 and f64 use the IEEE 754 total order: negative NaNs, negative infinity, the negative numbers, -0.0, +0.0, the positive numbers, positive infinity, then positive NaNs.

Gotchas#

A conformance must define a total order. The compiler does not check this rule. If the order is not total, sorting and binary search give incorrect results.

On concrete floats, < and the other operators keep the built-in IEEE comparison, where -0.0 < 0.0 is false and every comparison with NaN is false. Only generic code with a T: Order bound and a direct Order.compare call use the total order, so a sort puts -0.0 before 0.0. A NaN that arithmetic produces, such as 0.0 / 0.0, can have its sign bit set and then sorts first.

Examples#

Order a user type#

silk
import silk.core.order { Order, Ordering }

struct Version {
  major: i32,
  minor: i32,
}

fn compareVersions(left: &Version, right: &Version) -> Ordering {
  if left.major != right.major {
    if left.major < right.major {
      return Ordering.Less
    }
    return Ordering.Greater
  }
  if left.minor < right.minor {
    return Ordering.Less
  }
  if left.minor > right.minor {
    return Ordering.Greater
  }
  return Ordering.Equal
}

impl Order for Version {
  compare: Version.compareVersions
}

pub fn main() -> i32 {
  let old = Version { major: 1, minor: 4 }
  let new = Version { major: 2, minor: 0 }
  if !(&old < &new) || &new <= &old {
    return 1
  }
  return 0
}

Import as Order with import silk.core.order { Order }.

Public declarations: 2.

Ordering#

silk
pub type Ordering = Intrinsic.Ordering

The result of comparing two values: Less, Equal, or Greater.

Details#

Less means that the left operand comes first. Order conformances return this type.

Order#

silk
pub type Order = Intrinsic.Order

The interface behind <, <=, >, and >=.

Details#

A conformance impl Order for T gives the member compare(left: &T, right: &T) -> Ordering. The operators borrow both operands, so a comparison does not consume a value.

The integer types, char, string, f32, and f64 implement it. string compares its UTF-8 bytes, so the order is case-sensitive and a prefix comes first. f32 and f64 use the IEEE 754 total order: negative NaNs first, then negative infinity up to -0.0, then +0.0 up to positive infinity, then positive NaNs. compare returns Equal for two floats only when their bits are the same.

Gotchas#

A conformance must define a total order. For each two values, exactly one result is correct, and the results must agree with each other. The compiler does not check this rule.

On concrete floats, < and the other operators keep the built-in IEEE comparison. Only generic code with a T: Order bound and a direct Order.compare call use the total order.

Category: Core.

Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, aarch64-unknown-linux-gnu-no-libc, x86_64-unknown-linux-gnu, x86_64-unknown-linux-gnu-no-libc, wasm32-unknown-unknown, wasm32-wasip1, wasm32-wasip2.

View the source of this page