It's just baffling to me that tagged unions could be shunned in favour of the visitor pattern. How could that ever look like progress?
Being a millenial, I don't know what programming was like the 80's, but surely tagged unions must have been bread and butter for Pascal programmers?
struct my_tagged_union {
enum my_tag_enum tag;
union {
....
} payload;
};
That would be a pretty big break with "tradition" for the C language ;) (e.g. it would be similar to a "builtin string type")And of course tagged unions as "generic user-defined types" are much less convenient/useful than being directly integrated into the language syntax and type system.
Coincidentally, even padding bytes break things technically. Since they're undefined, you - in theory - can't ever calculate a bytewise hash value over a struct that has any padding bytes. It's still done frequently, it's just nulled out beforehand and copying is bytewise anyway. Doesn't change the fact that to the spec letter it's undefined behaviour. GCC also added __builtin_clear_padding() recently.
Hidden tags ... no. Just no.
In theory you can have both of course, and C++ now has support for variants (because we know C++ tries to be come a superset of all programming languages in existence). It's still a bit clunky to use though, especially because of the lack of "match" support in the language.
But I think a problem is that it's easy to mess up tagged union in low level, non-managed languages. Rust's enum work great, but that's thanks to the very strong type system and borrow checker which makes them effectively impossible to mess up in safe code.
In C or C++ it can become messy and hard to debug. In C you don't really have a choice, so you do it anyway but in C++ virtual methods and inheritance are usually a bit easier to manage.
From a modern perspective, it may be difficult to understand just how crushing the OO consensus was in the 1980s and 1990s. It still reverberates in our language design today. OO was good design was OO. If it didn't fit into OO, that was ipso facto proof that it was bad. Close the book. No further evidence required. Sum types? Kinda overlaps inheritance. Bad design. Not OO, therefore bad design. Why is Java a better language than C++? It's more OO, so QED.
OO here, by the way, is specifically that variant that emerged in the form of C++ and Java. Very important to have defined, enforced "private" keywords and deep hierarchies. Smalltalk by this definition is not an OO language. (And also, therefore, bad. Also possibly heretical for trying to steal the term OO... and I mean all the implications of the word "heretical".)
My "Software Engineering" course circa 1999 was basically "How to Design Software via OO". (It has the distinction of being the one course from my entire college career that I'm not sure I agree with a single thing I "learned" in that course. Even at the time I had done enough real work to be suspicious, and from here in 2021 I find the whole thing risible. But I got a 4.0, so....) Formal diagrams with strictly enforced diagram languages like UML, because OO was the future of Good Design and UML was how OO was going to help bring programming to the masses who would only have to draw Object Hierarchies and then {magic goes here that never was worked out} and perfect programs!
The internet hit programmers and programming earliest, and now there's only a remnant of the OO dogma just hanging on by its teeth in school curricula that haven't hardly been changed in 25 years, and it lacks the power to envelop the students the way it used to.
There was of course always a counterculture that didn't listen, which is where you get Smalltalk, Perl, Haskell and its ancestry, Python, etc. But you have to bear in mind that that was a counterculture...
... and you know, even today, Java and C++ are still pretty darned popular and it's not that hard to find people who still only know one of those (or maybe both) and still think OO ≡ good design ≡ OO, and the vast chaotic landscape of languages that don't even have "private" is just kid stuff for people who can't handle Real Design. Which is OO. Because OO is good, and good is OO.