On 2015-01-09 10:06, Antony Polukhin wrote:
I like the idea of `overload` more than the `match` idea.
I see many people prefer going through apply_visitor() with overload(). Coming from a functional programming perspective, this is kinda backwards. What we need is sum types. C++ unions are sort of sum types, but they're crap, so variant<> is our C++ workaround. However, somewhere along the line it was decided that variant<> was to be accessed /by type/ (either through get<T>() or apply_visitor()), which means that variant<T, T> does not work well at all. This means variant<> fails to be the building block that sum types can/should be, because you cannot use a variant<A, B> in a generic context the way you use, say, Either, in Haskell, because while Either A B works just fine when A and B might end up being the same type (because you can still distinguish the Left and Right constructors just fine), variant<A, B> with its type-based access breaks down when A and B end up being the same type. Really, variant<> should have been index-based all along, so that you can just do get<0> and get<1> on a variant<T, T> (or a variant<A, B> where A might be B) without losing information. Analogously, match(v, [](T){}, [](T){}) on such a variant would Just Work (again, without losing information), while apply_visitor() with overload() breaks down. There might be legit uses for a type-indexed variant, but really, proper sums should have been the #1 priority, and it's a damn shame that variant<> didn't get it right. </2cents>