C was unprincipled and pragmatic too, it was created with the goal of making UNIX portable. Still, C became one of the most popular and influential languages.
While I prefer ADTs/generics too, let's not forget that many people are less principled and pragmatic factors influence language choice as much (toolchain, ecosystem, popularity, familiarity).
That was a side effect of successful startups (Sun, SGI...) adopting UNIX as their OS.
Sun used Unix because Sun was co-founded by Bill Joy. By that time, Joy was already deeply involved in Unix (per BSD). If he didn't find Unix and C likeable and up to the task, they would have made different choices.
SGI and Sun were just one of many catalyzers, like a lot of programming languages have catalyzers.
The startups that have chosen UNIX, did so because the owners were part of the American UNIX university culture.
A different background would have mean a very different history in mainstream OSes and their respective system programming languages.
In Europe C had very little meaning until most enterprises started to replace their mainframes by UNIX servers from those companies.
I do think there's something intrinsically good about it compared to other contemporary systems languages - I don't think it's just that it tagged along with Unix.
It doesn't feels pragmatic at all. It relies on users to do the compiler's job(type assertions) , because "You dont need that with Go"TM ...
Right now the annoyance I hit more often is the inability to map a []Foo on an attribute .Name (string) to get a []string. I do that in ruby all the time, and with Golang it really sucks to do a for loop to collect stuff appending to a new array.
people.map(&:name) => ["Joe", "John"]
vs a := make([]string, 0)
for _, p := range people {
a = append(a, p.Name)
}When the problem is boring, use a fun & challenging language. When the problem is fun and challenging, use a boring language.