HN
Today

Nominal Types in WebAssembly

This technical deep dive explores the nuanced world of type equality in WebAssembly, contrasting its default structural typing with the desire for nominal types. It highlights how Wasm's recursive type groups offer an approximation, but true inter-module nominality has been elusive. The author then cleverly reveals how the recent exception handling proposal, with its tag keyword and exception mechanics, inadvertently provides a mechanism for nominal types, framed as a "troll post" on the committee's slow progress.

11
Score
1
Comments
#13
Highest Rank
5h
on Front Page
First Seen
Mar 14, 3:00 PM
Last Seen
Mar 14, 7:00 PM
Rank Over Time
1613191924

The Lowdown

WebAssembly's type system primarily employs structural type equality, where two types are considered equivalent if they have the same structure, even if declared separately. This can be problematic when distinct types are desired, especially for security or capability management. The article delves into this challenge and proposes an unexpected solution.

  • Initially, WebAssembly types like (type $t (struct i32)) and (type $u (struct i32)) are structurally equivalent, handled by the Wasm implementation partitioning types into equivalence classes.
  • Recursive type groups (rec) offer a way to create an approximation of nominal typing within a single module, as types within the same rec group are considered distinct from those outside or in other groups.
  • However, rec groups don't prevent other modules from forging types with identical structures, undermining strict nominality across module boundaries.
  • The author then unveils a "troll post" revelation: the recently adopted WebAssembly exception handling proposal introduces the tag keyword, which can be repurposed to create nominal types.
  • These tag-defined types use param instead of field and lack features like subtyping and mutability directly, but mutable fields can be wrapped in mutable structs.
  • Constructing such a nominal type involves using throw, and instances are returned as the exn (exception) type, requiring specific code to check their identity and access their "fields" via catch handlers.
  • The mechanism, while syntactically unconventional, ensures type safety: if a value isn't the expected nominal type, an exception is thrown upon access.
  • For principled composition, the tag can be exported and imported by other modules, similar to the proposed type imports, allowing strict nominal identities across modules.

Ultimately, the post serves as a clever demonstration that the Wasm committee's exception handling proposal, perhaps unintentionally, provides a pathway to implement nominal types, highlighting the sometimes circuitous routes technical specifications take.