Skip to content

lexer/typecheck: String < String not built-in for lex comparison #458

@hyperpolymath

Description

@hyperpolymath

Surfaced by

hyperpolymath/standards#284 — AffineScript port of `check-ts-allowlist.ts` (TS->AS migration STEP 2 tail-batch-1, hyperpolymath/standards#239 umbrella).

Behaviour

```affine
let a: String = "abc"
let b: String = "abd"
if a < b { ... } // ERROR: TypeMismatch (String, Int)
```

`<` / `>` / `<=` / `>=` work for `Int` and `Float` (unified per the no-OCaml-float-ops convention) but do not have a `String` overload for lexicographic comparison.

Why this hurts

Several scripts in the estate sort string lists or compare path prefixes byte-by-byte. The standards#284 port had to inline a manual `str_lt` helper using `char_to_int(string_get(...))` for every `<` use site. Every future TS->AS port that touches sort/order will hit the same wall.

Proposed fix

Add String overloads for `< > <= >=` that lower to byte-wise lex compare. Pattern follows the existing `String ==` / `!=` overloads. Should resolve in `Typecheck.binop_resolve` (or wherever the existing integer-comparison handler lives).

Alternative: ship a `String.lt` / `String.compare` stdlib function in `stdlib/String.affine`. Worse ergonomics (`String.lt a b` vs `a < b`) but smaller compiler change.

Acceptance

  • `let _ = "a" < "b"` type-checks and emits a working comparison
  • Tests cover empty-string, equal-prefix, and non-ASCII edge cases
  • One of: typecheck overload OR `String.compare` stdlib (owner choice)

Refs

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions