OxL Reference

4.6 Interfaces

oxl
pub(api) interface Storage {
  fn get(k: str) -> bytes?  io
  var fn put(k: str, v: bytes)  io
  fn has(k: str) -> bool  io => get(k) != none     // a default method
}

interface ReadWrite { embed Reader; embed Writer }
interface Container<T> { type Item = T; fn items() -> iter<T> }

@explicit interface Persistent { fn key() -> str }

assert FileStorage: Storage                      // static check
  • Interfaces are structural: a type T satisfies I if for every method of I without a default implementation T has a method with the same name, a compatible receiver (&self ⊂ &var self), the same parameter types, the same or a narrower return type and effects that are included in the effects of the interface method.
  • Default methods are added to a type when it is used through the interface; the type's own method takes priority.
  • An @explicit interface is satisfied only by an explicit impl I for T or @derive(I).
  • Use: as a generic constraint (T: Storage, static dispatch) or as the type dyn Storage (dynamic, via a vtable).

Standard interfaces:

InterfaceExplicitPurposederive
Copyyescopying instead of moving (§3.9)yes
Clonenoclone()yes
Dropyesdestructorno
Eqno==, !=yes
Ordno<=> and comparisonsyes
Hashnokeys of Map/Setyes
Shownointerpolation, logsyes
DefaultnoT.default()yes
Serializableyesserialisation (§9)automatic for data/enum
Iterable<T>nosource for for—
Streamable<T>nosource for for await—
Middlewareyeshandler of rpc attributes (§10.2)—

explicit-interface, interface-not-satisfied

See also

Source: docs/spec/oxl-standard.en.md