Hacker News new | ask | show | jobs
by Sharlin 810 days ago
`std::variant` is very awkward to use, and has design compromises because it doesn't have language support. Besides, the ability to write something like `std::variant` as a pure library type first requires you to have a very complex type system, more complex than Rust's, and certainly more complex than a "simple" language such as C or Go would ever consider adopting.

C++ is going to have pattern matching "any year now", and it's going to make `std::variant` more ergonomic to use, but on the other hand any pattern matching feature will have to make design compromises in order to support `std::variant` and other mutually-incompatible variant-like library types of which C++ has a bunch of (pointers, unions, `std::optional`, `std::any`, `std::expected`, did I miss any?) Add to that all the zillions of third-party variant-like types (including boost::variant) that exist in the wild because the code base predates C++17 and/or doesn't want to use C++17 features for whatever reason. All this complexity could've been avoided had the language just supported real sum types from the start. Or at least from C++11 up or whatever.

As a sibling commenter noted, algebraic data types and pattern matching with compile-time exhaustiveness checking go hand in hand; I meant to mention the latter in my original comment, but left it out because I consider the latter almost implied by the former.

1 comments

Right, I'm not trying to argue that std::variant is better than native language support. By definition, a language construct will always be easier to write and read.

All I'm saying is that the current state of std::variant makes it okay enough to use type safe discriminated unions.

Visit + overload is not that far away from pattern matching in terms of readability, clang does warn on non exhaustive switch cases, etc.

You did ask more generally:

> Does that really need to be part of the language though, or as long as you can code it, or have it in the standard library, it's fine?

And my answer is, yes. I don't consider `std::variant` a proper replacement, more like a crutch that may even be worse than not having anything at all, because its existence can be used as an argument against introducing language-level sum types in the future.