A tour through the beam ADT representation zoo
The Languages
Dynamically Typed
Statically Typed
Column meaning
- Record Type
-
named set of fields (key, value pairs), also refered as types, structs, records etc
- Union Type
-
like a record type but with more than one "shape", also refered as discriminated unions, variants etc
- Type Dispatch
-
a function that will have different implementations according to the type of one (or more) of its arguments, also refered as protocols or multi methods
TL;DR Table
Language |
Inspiration |
Record Type |
Union Type |
Type Dispatch |
---|---|---|---|---|
Dynamic |
||||
Clojerl |
Clojure |
Yes |
No |
Yes |
Efene |
Python/JS |
Yes* |
No* |
No |
Elixir |
Ruby |
Yes |
No* |
Yes |
Erlang |
Prolog |
Yes* |
No* |
No |
LFE |
Common Lisp |
Yes* |
No* |
No |
Static |
||||
Alpaca |
ML |
Yes |
Yes |
No* |
Fez |
F# |
Yes |
Yes |
Yes |
Gleam |
ML/Rust |
Yes |
Yes |
Not Yet? |
Hamler |
Purescript |
Yes |
Yes |
Yes |
PureErl |
Purescript |
Yes |
Yes |
Yes |
Groups
Languages that compile record types to erlang records
Gleam: generates hrl files
Fez
Erlang
Efene
LFE
Elixir: has support for erlang records, but for compatibility only
Languages that compile record types to erlang maps
Alpaca: __struct__ field for records, no extra field for anonymous records
Clojerl: __type__ field
Elixir: __struct__ field for structs
Purerl: no extra field for anonymous records
Hamler : no extra field for anonymous records
Languages with union types
Alpaca: tagged tuple if it has values, atom if not
Gleam: tagged tuple if it has values, atom if not
Fez: tagged tuple if it has values, atom if not
Purerl: tagged tuple (not sure about variants with no values, should be like Hamler)
Hanler: tagged tuple even with variant with no values
Languages that do type dispatch
Clojerl: Clojure Protocols
Elixir: Elixir Protocols
Purerl: Type Classes
Hamler: Type Classes
Notes
Alpaca
Records: "anonymous records".
Records are compiled as maps with the KV '__struct__' => 'record'. Because Alpaca doesn't provide any reflection facilities, more type information isn't propagated to the generated Core Erlang.
In the tag (in the case of variants/discriminated unions), it's just the atom representation of the tag name itself.
E.g. Some_tag 1 gets compiled to {'Some_tag', 1}
Tagged Unions: (variants in OCaml) get compiled as an atom if there's no associated value, and as a tuple if there is.
Type Dispatch: Author says: "Not currently. This sort of thing might get handled by type classes but I haven't gone too far down that line of thinking yet"
Clojerl
Records: (deftype) compiled to Erlang maps with a special __type__ field.
Tagged Unions: No
Type Dispatch: defprotocol and deftype, extend-type, extend-protocol work as in Clojure.
Protocols are not reified as in Clojure, there are no runtime protocol objects.
Elixir
Records: structs are compiled to Erlang maps with a special __struct__ field.
Tagged Unions: No (usually ad-hoc tagged tuples are used for this)
Type Dispatch: Protocols are collected and consolidated at compile time
Gleam
Records: Compiled to Erlang records (hrl files are generated)
Tagged Unions: Compiled to tagged tuples, they are just gleam custom types with multiple "constructors", if a variant has no values it gets compiled to an atom
Type Dispatch: Not Yet? Will Gleam have type classes?
Fez
Records: Compiled to Erlang records
Tagged Unions: Compiled to tagged tuples
Type Dispatch: Class method calls
LFE, Efene and Erlang
LFE and Efene are just "dialects" of Erlang, that's why they are covered together here.
Records: Erlang records, which are compiled to a tuple where the first value is an atom with the name of the record: LFE Records, Efene Records, Erlang Records
Tagged Unions: Since they are dynamically typed they can use tagged tuples for this, there's no need to declare them, examples are functions that return {ok, V} or {error, Reason}.
Type Dispatch: No
PureErl
Records: Compiled to Erlang maps (without an extra field), really similar to alpaca "anonymous records"
Tagged Unions: Compiled to tagged tuples
Type Dispatch: Type Classes
There are also newtype
Hamler
Records: Compiled to Erlang maps (without an extra field)
Tagged Unions: Compiled to tagged tuples
Type Dispatch: Type Classes