Closed lpil closed 5 years ago
Should still have a record type then though. The standard ML 'record' definition is often internally implemented near identically to how Erlang Records are (I.E. a tagged tuple), which has very nice performance benefits compared to Elixir structs (which are just maps internally). If anything a 'record' should be implemented as a tagged tuple and a row-typed record (known as an object
in OCaml) should be implemented internally as a map, same as Elixir Structs.
I do not like the name of 'struct' for that though, not even in Elixir, as struct implies something hardcoded in size, which Elixir structs are not, unlike tagged tuples.
I'm not a big fan of the name struct for the same reasons.
I'd like to use similar language to Elixir and Erlang where possible, and my records/structs/whatever are implemented using maps so we can have polymorphic functions that accept any with a field of name X with value type Y.
An enum with a single variant is effectively a record, though it doesn't have the nice named field access.
I don't like the name object so much as I think people might confuse it for objects that have classes in an OOP setting.
I don't like the name object so much as I think people might confuse it for objects that have classes in an OOP setting.
Ditto, a row-typed record 'is' still a record, just with named data instead of positional data, slightly slower but more flexible (like the record/struct distinction in elixir). But for OCaml it is what it is...
and my records/structs/whatever are implemented using maps so we can have polymorphic functions that accept any with a field of name X with value type Y.
So your records are already row-typed records? You really should support standard positional records as they do have a noticeable speed improvement in certain situations as well as are more reliably matched.
An enum with a single variant is effectively a record, though it doesn't have the nice named field access.
Except it also strongly types the data as well. This is a super common pattern in OCaml:
type stack_ptr = StackPtr of integer
type heap_ptr = HeapPtr of integer
And you don't have to worry about passing the wrong type to the wrong section, and yet it still internally compiles it to a raw integer, it effectively strongly types the wrapped type but still lowers it to that at compile time for efficiency reasons (OCaml is roughly C speed in execution, within a factor or so), it might even be a useful optimization on the beam.
a row-typed record 'is' still a record, just with named data instead of positional data
Agree, but I really want to avoid confusion with Erlang records. Besides the names listed above do we have any other options?
And you don't have to worry about passing the wrong type to the wrong section, and yet it still internally compiles it to a raw integer, it effectively strongly types the wrapped type but still lowers it to that at compile time for efficiency reasons (OCaml is roughly C speed in execution, within a factor or so), it might even be a useful optimization on the beam.
I think this optimisation is worth having, but I am planning to make it a different syntax than just an enum with a single variant, much like Haskell does with newtype
. My reasoning is that I want the runtime representation of data structures to be very predictable so that Erlang/Elixir users can call Gleam functions easily. I don't think having a special case for a single constructor fits well with this goal.
I don't think having a special case for a single constructor fits well with this goal.
I agree, OCaml only did it that way because it tries to minimize syntactical overhead, but sometimes adding in more is great for clarity. :-)
Just a passing idea, an unpacked strongly typed head:
type blah = Blah of int
Could compile down to just an integer, where:
type blah =
| Blah of int
(* or, same declaration *)
type blah = | Blah of int
Compile down to (in Elixir format) {:Blah, 42}
or so.
Easy disambiguation then.
I dig it! I think this is where we will go :)
It may be worth doing this to avoid confusion with Erlang records