Algebraic Data Types
The builtin types are all well and good, but Erie isn’t much without a few additions: maps/dictionaries, structs, and especially alegbraic data types (ADT). Erie will eventually support all of these, but I focused on implementing ADTs first. I refer to them as “union” types throughout the compiler, but they are one in the same.
I want all Erie types to be declared with deftype
, regardless of the ultimate shape of the type (i.e. ADT, struct, or type alias). By making the signature of deftype
look like a function, it makes adding type parameters straight forward for supporting polymorphic types.
(deftype Maybe [a]
(union [a 'nil]))
One big difference between Erie’s ADTs and those of other langauges that I’m familiar with is Erie doesn’t required “tags” for each option. For example, in Elm, representing Maybe
looks like:
type Maybe a
= Just a
| Nothing
Note how the non-Nothing
case requires the Just
tag. This means a value of type String
does not conform to the Maybe String
type in Elm. In Erie, String
will conform to (Maybe String)
because of the lack of tags. I’m not aware (at least not yet) of why tags are necessary. I may run into the reason later in development, but for now, it seems to be working. If you, as a developer, like the tagged approach you can mimic it with tuples in the definition.
(deftype Result [error value]
(union [{'ok value} {'error error}]))
Erie treats a quoted symbol as a type with a single value of itself. It allows for the above which will integrate nicely with Erlang and Elixir.
In the future I want deftype
to be a macro that generates useful functions regarding that type. Specifically allowing matching in a case
expression. For now deftype
is treated as a special form by the compiler. As I continue to expand the functionality of macros, a large amount of that work should shift out of the compiler and into Erie macros.