In a 2019 blog post, which I found today on the front page of /r/programming, Michael Orlitzky complains that modern languages have too many breaking changes. He contrasts "grownup" languages like C and Ada, which have remained stable and largely backwards compatible for decades, with languages like Rust, which regularly breaks compatibility despite having promised otherwise in its 1.0 release.
This is a reasonable criticism, and yet what strikes me most about it is how seemingly irrelevant it ultimately is. Rust handily outranks Ada on any measure of language popularity you care to name (TIOBE Index, Stack Overflow Survey, Github statistics), and its adoption is still trending upward. Clearly, there is a sizeable contingent of programmers who do not view its breaking changes as deal-breakers.
Why might that be? Glancing over some of the Rust release notes myself, I notice a couple of trends.
- Many of the changes are low-impact and provide a clear migration path for existing code.
- Many of the changes involve fixing holes in Rust's memory-safety checks.
For breaking changes that fall under (1), it's easy to understand why Rust programmers put up with them. Switching languages is a much bigger hassle than doing a simple find-and-replace to update a renamed library function.
For breaking changes that fall under (2), it's a little less obvious. If your code has unknowingly been taking advantage of a safety hole, it can often require a fair amount of work to fix (as any D programmer who's tried to test their code with -preview=dip1000
can attest). Why are Rust programmers willing to subject themselves to that kind of aggravation?
The answer is: because that's the reason they chose Rust in the first place! Rust's memory-safety checks are its biggest value-add compared to other languages, and the main driver of its adoption. Making those checks more accurate and effective is giving Rust programmers more of something that they've already demonstrated they want.
It is worth noting that the vast majority of these breaking changes occurred within a single language edition. For example, Rust 1.5.0, which has thirteen breaking changes listed in its release notes, was an update to the 2015 edition that started with Rust 1.0.0 and continued until Rust 1.30.0. Again, this fact does not seem to have had any serious impact on Rust's adoption.
Are there languages where breaking changes have hurt adoption? The most notable example I can think of is Python 3, which has struggled for years to win over Python 2 programmers. And if we look at the changes introduced in Python 3, we can see that they follow very different trends than the Rust changes discussed above:
- Many of the changes are high-impact, requiring widespread changes to existing code, and lack a clear migration path.
- Many of the changes are focused on performance, correctness, and type safety.
Trend (1) is straightforwardly bad because it increases the cost of migration. Trend (2) may at first seem like a good thing, but the problem is that these qualities are not what most programmers chose Python 2 for. They chose it because it was easy to learn, convenient, and fun, and forcing them to rewrite all of their code to handle Unicode correctly or use generators instead of lists is the exact opposite of that.
What can we learn from this for D?
First, that the success and popularity of a programming language is mostly determined by factors other than stability and backward compatibility (or lack thereof).
Second, that even without an edition bump, small-scale breaking changes with easy migration paths aren't a big deal.
Third, that even with an edition bump, large-scale breaking changes that make migration difficult should probably be avoided.
Fourth, that breaking changes should be used to give D programmers more of what they already like about D, not to take the D language in new directions.
To Walter, Atila, and the rest of D's leadership, I hope this post provides some helpful data points for you to take into account when designing D's language editions and planning future language changes.
To everyone else reading this, I'd like to leave you with one last question: what do you like about D? What strengths does D have, as a language, that you'd like to see become even stronger?