Programming Language

Nocter

A self-contained systems language built around simplicity, encapsulation, and foolproof design.

/spec/language/ordering.md

Strict Ordering Operators

Nocter exposes one source-defined ordering primitive: strict less-than. A type declares the operation in an instance:

instance Rank {
    pub operator (&self < other: &Self): bool {
        return self.value < other.value
    }
}

The declaration has a readonly &self receiver, one named readonly &Self operand, a bool result, and a body. An owned or readwrite receiver, another right-operand type, another result type, an unnamed operand, or a bodyless declaration is invalid. Ordinary visibility, declaration type patterns, and declaration-wide where clauses apply.

The implementation promises a strict total order. It must be irreflexive, transitive, and consistent for every pair of values. These algebraic properties are an API contract; the compiler does not execute additional comparisons to verify them.

Derived Comparisons

One selected < operation defines every ordering token:

left <  right  =  less(left, right)
left >  right  =  less(right, left)
left <= right  =  !less(right, left)
left >= right  =  !less(left, right)

The operands are always evaluated exactly once from left to right as written. Reversing the strict-order call for > or <= does not reverse source evaluation. <= and >= negate one strict-order result; they do not call equality or execute ordering twice.

The selected call borrows its operands and does not consume their owners. Existing borrow and coercion syntax remains explicit at ordinary call boundaries. A caller may compare existing readonly borrows directly; a nominal type with a direct declaration may also be compared through the operator's implicit readonly operand adjustment.

Generic Requirement

Generic code requires the same structural operation:

func earlier<T>(left: &T, right: &T): bool where (&T < &T): bool {
    return left < right
}

The requirement proves strict ordering for that exact operand pair and a bool result. It adds no runtime witness or dispatch value. Concrete specialization must find primitive integer ordering, an accessible source declaration, or a declaration reached through one readonly coercion.

Selection

For the semantic left operand, selection uses this order:

  1. 1. matching integers use their primitive operation;
  2. an accessible declaration on the exact owner is selected;
  3. otherwise, one accessible readonly coercion may reach an owner with an applicable declaration.

The semantic left operand is the source left operand for < and >=; it is the source right operand for > and <=. The other operand must match the selected &Self input directly or through one readonly coercion. Coercions do not chain or receive implicit rankings. Multiple distinct viable targets are ambiguous and require an explicit as conversion.

> , <=, and >= cannot be declared independently. This prevents four definitions for one order from disagreeing.

Standard Types

Matching integer types retain primitive ordering. bool, payloadless enums, and arbitrary structs do not receive generated ordering.

Source-defined ordering for borrowed text and slices, including coercion from their owning containers, belongs to the compiler-checked std/str and std/slice contracts and their assigned behavior guides. Those declarations use the selector defined here. The < operator does not prescribe a sorting algorithm.

Tooling

Formatting preserves the authored < declaration and requirement forms. Hover presents the selected declaration with its concrete owner. Definition, references, and rename from any of <, >, <=, or >= use the identity of the selected < declaration. Semantic tokens classify the authored operator token as a method declaration and both operand bindings as readonly parameters. Compiler-private callable names are never public source or editor labels.

Non-goals

Strict ordering does not define partial ordering, three-way comparison values, floating-point behavior, comparator callbacks, hashing, or equality. Equality remains an independent operation. The existence of a standard sorting consumer does not make sorting part of operator selection.