Hacker News new | ask | show | jobs
by sgreben 4074 days ago
Sum types + exhaustiveness checking already do this, right? For this example:

  type animal = Cat | Dog
  type action = Sound | Eat | Attack

  let cat_sound () = printf "meow"
  let cat_attack () = printf "scratch"
  let dog_sound () = printf "woof"

  let act animal action = match animal,action with
  | Cat, Sound  -> cat_sound ()
  | Cat, Attack -> cat_attack ()
  | Dog, Sound  -> dog_sound ()
Compiling this yields:

  Warning 8: this pattern-matching is not exhaustive.
  Here is an example of a value that is not matched:
  (Dog, (Eat|Attack))
just as we'd like.
3 comments

Adding new animals or actions requires access to and recompiling this code. The expression problem attempts to find a way around that.
I'm not proposing this as a solution to the expression problem (which has actual solutions, as noted in the other comments [0] and elsewhere [1]).

It is, however, an extremely simple way of implementing the table-style dispatch outlined in the post, with a reasonable layout and compile-time completeness checks.

It's not open to extension outside the compilation unit, but in exchange it is dead simple and you still only ever need to change exactly two places in the code if you want to extend along either axis. Sometimes you just don't need polymorphism when a switch statement will do.

[0] https://news.ycombinator.com/item?id=9409779 [1] (PDF) http://www.math.nagoya-u.ac.jp/~garrigue/papers/variant-reus...

The problem is not so much if the compiler will catch it, but how to lay out the new code/types in an editor, hopefully all in one place or accessible from one place.

C++ will catch a missing combination at compile time as well.

Note that the given example has only one place where all combinations are defined. Not sure if this could be done in C++.