> the entire language kind of feels slapped together to me

The slogan "avoid success at all costs" definitely is accurate for Haskell

I honestly don't think that that's why the language is annoying though.

"Avoid success at all costs" has always meant (in my mind) to mean "we will prioritize doing things the 'right' way instead of doing things to appeal to corporations". That's fine, I'm all for doing things correctly, but I think a lot of Haskell's bullshit isn't because of that.

It's a common complaint but it's common for a reason: the fact that records couldn't contain the same field names was really stupid. Apparently in the 90's the Haskell devs couldn't fathom two different types both having a field called "ID" or "name". How does allowing multiple objects to have an overlapping field name affect purity? Plenty of other languages, some of which are even more mathy than Haskell, have managed to pull this off (e.g. TLA+). Could it be because records/structs are really just a shitty hack around tuples tacked onto the language? Yes, Lens fixed hat particular problem with Template Haskell, and now there's yet another GHC extension to more or less work around it, but doesn't change the fact that I think it was something actively bad and it wasn't because of "purity" reasons.

It makes perfect sense when you think about the order of doing name lookup and type checking. In Haskell name lookup happens strictly before type checking. In more conventional 90s languages like C++ that’s obviously impossible because to compile `foo->bar()` the compiler must first know the type of `foo` before it can begin the name lookup for `bar` in the class hierarchy; in fact in C++ `bar(foo)` also requires knowing the type of `foo` before being able to look up `bar` due to the amazing feature of ADL. In Haskell the type checking was meant to be a research playground for new ideas, such as the idea of type classes, so naturally it was a bad idea to couple name lookup with type checking.

I’m not a historian but that’s just my thought.

> Apparently in the 90's the Haskell devs couldn't fathom two different types both having a field called "ID" or "name".

I think it's simply that making field names become functions that select from the record was a simple design that worked, and didn't require anything new to be added to the language.

My interpretation is more that changes solely for the purpose of wider adoption were explicitly "out of scope" for the language. Warts aren't undesirable, but in a certain sense actively embraced in my reading of the slogan.