Records
A record such as %{name: String, age: Integer} needs no declaration. It
emits a BEAM map with atom keys. The field set is exact: extra fields are a
different record type. A record is accepted as Map<K, V> when its atom keys
and field values fit K and V. Build a smaller record by writing the fields
you want.
mod records
pub fn birthday(user: %{name: String, age: Integer}) -> %{name: String, age: Integer} { %{user | age: user.age + 1}}
pub fn origin() -> %{x: Integer, y: Integer} { %{x: 0, y: 0}}
pub fn name_of(user: %{name: String, age: Integer}) -> %{name: String} { %{name: user.name}}There is no implicit width subtyping. A literal with an extra field is a different type, and a missing field is a type error:
pub fn extra() -> %{name: String, age: Integer} { %{name: "ada", age: 36, admin: true}}