* Bad abstractions which just stick around forever. There are some examples of this in UNIX which would never be invented in the way they are today but nonetheless aren't going anywhere (e.g. signal handling). This isn't good.
* Invent all of your own wheels. This isn't good either.
There's a balance that needs to be struck between all of these 3 extremes.
I know it's just an example, but if you're on linux there's signalfd() which makes signals into IO so you can handle it in an epoll()-loop or whatever way you like doing IO
We can't remove the old way of course, as that would break things, but that doesn't stop improvements
You have to start somewhere. Strongly specialized programs that f.ex. never access disk and only access network are a good candidate to be tested in either restricted containers or brand new OS-es that carry legacy baggage.
It's doable, but nobody wants to put in the money, time and energy into pioneering it.
* Bad abstractions which just stick around forever. There are some examples of this in UNIX which would never be invented in the way they are today but nonetheless aren't going anywhere (e.g. signal handling). This isn't good.
* Invent all of your own wheels. This isn't good either.
There's a balance that needs to be struck between all of these 3 extremes.