News for hackers. Stuff that matters.
Re:Algebraic Data Types: Things I wish someone had explained... by LessDmesg on Tuesday November 19, 2019 @10:42AM (#21574040)
Even Haskell doesn't get it right: there are no exhaustiveness checks on pattern matches (something OCaml has), and while sum types provide closed unions, getting open unions is clunky (have to use typeclasses). OOP languages are imperfect in the opposite direction: open unions out of the box (inheritance) but no closed unions and no pattern matching. Seems language authors on the whole are bad thinking design spaces through. "The user might want any of three simple things X, Y, or Z, so let's choose the one that our language will support well, the one it will kind of support, and the one it won't support whatsoever just for the hell of it".
Re:Algebraic Data Types: Things I wish someone had explained... by sjakobi on Tuesday November 19, 2019 @01:40PM (#21576556)
> Even Haskell doesn't get it right: there are no exhaustiveness checks on pattern matches

Just enable -Wincomplete-patterns or -Wall!

Re:Algebraic Data Types: Things I wish someone had explained... by fauigerzigerk on Tuesday November 19, 2019 @03:23PM (#21577856)
It's just a warning, and it's opt-in. I would say that counts as not getting it right.
Re:Algebraic Data Types: Things I wish someone had explained... by whb07 on Tuesday November 19, 2019 @01:35PM (#21576472)
Haskell does have exhaustive checks. Its just a compiler flag which isn't default turned on (this kills me).
Re:Algebraic Data Types: Things I wish someone had explained... by hcarvalhoalves on Tuesday November 19, 2019 @04:30PM (#21578519)
Can you please elaborate with some examples what you mean by "closed unions" and "open unions" here? I would appreciate a lot.
Re:Algebraic Data Types: Things I wish someone had explained... by kccqzy on Tuesday November 19, 2019 @07:14PM (#21579871)
We say a sum type is "open" is more alternatives can be added later (or some alternatives can be removed later), perhaps in a different translation unit or a different library. We say it is "closed" if all alternatives must be specified at the definition, no alteration allowed.

For example if you write this in Haskell

    data PrimaryColor = Red | Green | Blue

    colorToInt Red = 1
    colorToInt Green = 2
    colorToInt Blue = 3
it is closed because future code can't add more alternatives. Instead you must simulate it using type classes, with a wildly different syntax, and (some would say) a hack. Or define a different sum type that wraps the above.

OCaml on the other hand supports the above perfectly with a slightly different syntax, but it also supports polymorphic variants (not to be confused with a Haskell sum type that's polymorphic because of a type variable like Maybe) which are lighter weight. For example you can write a function that takes different "constructors" without necessarily giving a definition for the type or listing all alternatives:

    let color_to_int = function
      | `Red -> 1 | `Green -> 2 | `Blue -> 3
Notice I never defined any type for the three colors! If you wish, you can mention the type:

    [< `Red | `Green | `Blue ]
or give it an alias to make it look more normal. But you can add (with some limitations) or remove more things to this variant later on.

To me, though, the most intuitive way of understanding this is to think of the first as nominal typing, whereas the second is structural typing.