It's more like, "I don't see why a tastier dinner has to be more expensive". It's a tradeoff situation, and while I might be willing to buy a great $50+ meal from time to time instead of just a $20 one, I don't have any inclination to pay $1000 even if the meal is a tiny little bit better than the just-great one.
It's a matter of tradeoffs. Library design is a balancing act.
> We need generics because users have types that they need libraries to work with.
This is right where I become sceptical. Most libraries shouldn't care for the user's types at all. They should expose their own types so you can work the library - not the other way around.
Please provide an actual use case where the library has to "know" about the user's types (and please don't mention std::sort. It's as common an example as is "Dog :: Animal" examples to argue for class inheritance, and is just as irrelevant).
> Your own example, of an intrusively-linked list, illustrates this: without generics, you could not write a linked-list library component that would be usable for that.
As I mentioned, linked list can tangentially benefit from a very very thing generics layer on top of a fixed data structure implementation. The layer does nothing more than "instanciate" the types, but there is no code generated. But then again, the added convenience / safety is minimal, I once wrote a C++ implementation that I was quite happy with, and never used it.
> This is why C programs are crammed with so many custom one-off hash tables
There are probably not huge issues with a design like "HashTable ht = { .hash = &foo_key_hash, .equals = &foo_key_equals }" (if quick results are what you're after), but yes it is nice to have a few lines of type-safe wrap generated over some generic container interface.
An alternative reason why you'll find a good amount of custom hashtables in C code bases is, I suppose, that there are a lot of different ways to implement hash tables. Also writing a little code here might not be so bad. I've had 1 use case for a "hash" table in 2021 (glyph hash table for a new iteration of my font rendering code) and I've gotten away without even implementing it - the for-loop I've written has never shown up in any performance profile.
Considering that container data structures are probably the highest profile application for generics, I'm still not convinced that generics are needed in a systems programming language...