Hacker News new | ask | show | jobs
by nicoburns 2187 days ago
That's not a language feature though, right? It's just a struct containing a union and a discriminant. That means:

- No pattern matching means your stuck with the awkward if-elseif-else

- It doesn't check that you've accounted for every possible variant.

- You can only hold one variant of each type: you can't have two variants that both contain a string.

- The specific instance isn't it's own type, so you can't implement methods on it.

3 comments

A language that I am working on has those things "built-in" (it still generates compilable C++ in the backend). I did recently add pattern matching (and not just on variants) where the above would be equivalent to:

  $v:|[:int, :bool, :double] = 5;

  $vi: = v.[:int];
  $holds_int: = v.?[:int];

  switch v {
    .[:int]$i { /std cout << "got int:" << i };
    .[:bool] { /std cout << "got bool" };      
    .[:double]$d { /std cout << "got double: " << d };
  };
If a type repeats in the same variant, you would match by index to tell them apart:

  $v:|[:int, :int]<(.[0] = 5);

  switch v {
    .[0]$i0 { /std cout << "got first int:" << i0 };
    .[1]$i1 { /std cout << "got second int: " << i1 };
  };
(I have some ideas to allow named labels instead of numerical indices but that is not yet implemented)

It is, in spirit, an implementation of the inspect proposal [1], but with a (subjectively) much simpler and more powerful syntax (the grammar of the entire language is fully LALR(1) without ambiguities).

[1] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p137...

Take a look at my reply above. Your right it isn't built into the language, but it does come with a helper method, std::visit, which does take into account that you've accounted for all possible variant types, and will throw a compile error if you didn't. You also aren't stuck with if, else-if style syntax.
You can use std::visit() for the time being, and pattern matching is being discussed.