In Go, a feature needs to have an extremely good reason to be added, and even then it's only added with care and caution.
In other languages, pointless features are added because maintainers are afraid, or not empowered to say... "yeah, we get it, but no, we will not add cruft to the language because you can't write your own 2 line function to achieve the same, no matter how hard you dunk on us on Twitter, it's take it or leave it, but you won't tell us how to run this project"
I wouldn't have described language designers' feelings that way, but you're absolutely right. For example, witness the recent features added to Python with little more justification than "other languages have it". It's pure FOMO - fear of missing out.
`match` also breaks fundamental Python principles [2] and interacts badly with the language's lack of block scope:
>>> a, b = 1, 2
>>> match a:
... case b: pass
...
>>> a, b
(1, 1)
Not to mention that it also required large changes to the CPython implementation, including an entirely new parser(!) - which means other implementations may never support it [3]. Clearly `match` doesn't fill a gap in a coherent design for Python. It seems to have been added due to a combination of FOMO and/or resume-driven development.Another example is async-await - while the concept is fine (although I think stackful coroutines are a better fit for a high-level language), the syntax is just copy-pasted from other languages [4]. There seems to have been little thought as to why C# etc chose that syntax (to allow `async` and `await` to be contextual keywords), nor how `async def` contradicts existing Python syntax for generators.
[0] https://peps.python.org/pep-0635/#motivation
[1] http://canonical.org/%7Ekragen/isinstance/
[2] https://x.com/brandon_rhodes/status/1360226108399099909
[3] https://github.com/micropython/micropython/issues/8507
[4] https://peps.python.org/pep-0492/#why-async-and-await-keywor...
I mean granted, Java needed some tweaks for developer ergonomics, and I'm glad they finally introduced value types for example, but I now find that adding entire paradigms to a language is a bad idea.
In the case of Go, yes it needed generics, but in practice people don't use generics that often, so thankfully it won't affect most people's codebases that much. But there's people advocating for adding more functional programming paradigms and syntax like a function shorthand, which is really frowned upon by others, because new syntax and paradigms adding to the things you need to know and understand when reading Go.
Plus at the moment / the way the language is designed, FP constructs do not have mechanical sympathy and are far slower than their iterative counterparts.
Go is almost an anti-language in that sense, reluctantly accepting shiny lang features only after they’ve been proven to address major pain points. It’s almost more an “infrastructure deployment toolkit” than a language. Which strangely makes it extremely pleasurable to work with, at least for network-centric applications.