A great programming language is one that's loved by developers, has a lot of usage and fosters a healthy community - but what does it take for a language to get there? I'll try and outline what I think are the most important traits of a programming language and why I think this.
Developers no longer just expect a language to "work" - it also needs to provide a decent experience. This is a huge topic in itself, but to me the most important parts are: tooling, documentation, sharing and community.
Over time compilers have become far more user friendly than previous generations. Instead of just spitting out some incomprehensible error message, often unrelated to the problematic code, modern compilers offer hints about what could be wrong with the code and even offer suggestions on how to fix the problem. These days users expect that if they spell a variable name incorrectly that they'll be offered suggestions on variables in the same scope that have similar names, or that there's an extra bracket and precisely where it's missing. When compilers are helpful, users are more likely to stick with a language.
Being productive in a programming language is about more than just writing lines of code though. The majority of time spent programming is reading and discovering code, figuring out how the existing code works and reading its documentation. Discovering and navigating documentation is extremely important for developer productivity. One language that does this well is go: comments can be automatically converted into nice html documentation using the tools bundled with the language and godoc.org provides full access to this documentation. In their IDEs users are often presented with inline documentation as they hover over symbols, or clickable links that take them to the documentation hosted on godoc.org. This really increases productivity and improves the experience, especially for new developers.
Developers typically agree on nothing: bikeshedding is a term for development teams that spend a disproportionate amount of time discussing trivial details. Being able to collectively agree on what the goals of the language are is very important. Part of building a strong community is being very clear about what is in-scope for a language and what is out-of-scope. It's very beneficial for a community to know exactly what to expect from future versions of a language as picking up a new language can be a significant investment. If the goals of the language are made clear up-front and the team building the language sticks to it then that can relieve a lot of uncertainty around what the language will look like and whether it will be appropriate in the future. Often, saying no to new features is more beneficial than saying yes.
When you have a strong community the language ecosystem builds itself - users that love the language begin to promote it which in turn increases the community. This is also important in terms of getting a critical mass to pick up the language - if users feel empowered to create libraries and build the ecosystem then new users are more likely to find libraries that they need and are able and willing to build on that.
Do comment if you agree or disagree with anything here - I'd love to discuss it!