Rust · Design

Design

4.0.0-rc.1 · 3ee5e534

  • A thin layer over the C ABI. One private module per header, types, model, encode and train, re-exported flat; every public name is its C name without uform_ and _t in CamelCase, a verb’s argument struct becomes its *Config, and every wrapper’s documentation names the C symbol it calls. Enums mirror the C enums through the C name functions, never strings.
  • The receiver chooses, the verb stays. &Model runs a verb on the calling thread, on(&executor) blocks on an executor, and deferred(&executor) submits it, all with the same arguments.
  • Deferred calls use the language’s own idioms. status polls through uform_outcome_status, wait blocks through uform_outcome_wait, and a Deferred is IntoFuture, so .await polls the status word, since the library has no wake-up.
  • No life of its own. The binding starts no threads and keeps no queues or caches; releasing a Deferred rides Drop, which waits for the call first.
  • Arenas are lent and reused, never shared. Every output verb takes an arena and answers views borrowing it, so the borrow checker retires stale views at compile time.
  • Nothing costs anything until it is used. Blocking calls take no deferred-table entry and allocate no box, a surface Outputs leaves out is never computed, and an arena allocates only when a call writes into it.
  • A deferred receiver refuses borrowed inputs at compile time. The Accepts bound admits only owned inputs, so a borrow the library would read after the verb returns never compiles.
  • Suites run against the stub library, and against the real one with the tiny checkpoint.