Use A Modern Language Already

As I write this, it is July 2021.

Why are people still writing code like it's 1970???

Why is it that people make a virtue out of writing code in obsolescent languages?

People are writing code in C++ dialects that are older than they are. They gush on social media about how their code is header-only and compiles on bronze-age computers. They go to inordinate lengths to make their libraries Python 2-compliant. Besides being a waste of human effort, this sort of cargo-cult worship of backward-compatibility is stultifying to computing as a whole, holding the industry back from progress by pointlessly anchoring technologies in the past.

Don't do this.

That's it. That's the post. What follows is (really quite unnecessary) examples of the ridiculousness. You can avoid it all by using modern versions of modern languages. Now go forth, and be happier than I am.


PSA: C Isn't Modern

I count C, all versions of C, in this. C wasn't designed in the sense of the modern field of programming language design. C was first developed heroically, in pieces, in either PDP assembly or an extinct predecessor language—it's so old, no one actually even knows anymore.

I really like C in many ways, because it has a certain purity that demands focus and rewards elegance. It was one of the first languages I learned. But no one should be using in production today. C isn't merely simple, it is simple to the point of being pointlessly restrictive, inexpressive, and less safe.

For example, which code is clearer? Which one is less error-prone? The one in C:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
float sum_singles( float const xs[], size_t len )
{
	size_t k; float sum=0.0f;
	for ( k=0; k<len; ++k ) sum += xs[k];
	return sum;
}
double sum_doubles( double const xs[], size_t len )
{
	size_t i; double sum=0.0;
	for ( k=0; k<len; ++k ) sum += xs[i];
	return sum;
}
int sum_ints( int const xs[], size_t len )
{
	size_t i; int sum=0;
	for ( k=0; k<len; ++k ) sum += xs[k];
	return sum;
}
/* ... */

Or the one in C++:

1
2
3
4
5
6
7
template<class T>
[[nodiscard]] T sum_anything( std::vector<T> const& xs )
{
	T sum = T{0};
	for ( T const& x : xs ) sum += x;
	return sum;
}

In addition to collecting all the different implementations down into one, reducing the required maintenance, because the C++ version also uses an object that manages the lifetime, it is much safer from entire classes of memory bugs, and the compiler can even in some cases make the whole thing a constant-expression.

Or think about how C has no built-in containers? It's actually pretty hard to make a production-quality container, mainly because there are so many fiddly details in so many different edge-cases for so many different applications. The C++ standard library gives you all that for free, whereas in C you not only must DIY, you must DIY every time for every type. One can make various complaints about the abstraction C++ chose, but meanwhile it would have been literally impossible to do at all in C[1].

Or think about how C vs. C++ handle errors. In C, it is standard to use return codes, but this spreads out error logic, which makes coding at scale buggier and worse. Plus C++ exceptions are faster (supposedly one of the goals of C) because they are free on the the "happy path". They also describe the error semantically, which is theoretically possible with e.g. enumerations, but doesn't seem to be ever done.


PSA: Fortran Is Even Worse

Fortran (first seen in 1957) is probably the earliest computer language people still use unironically. If C is not a modern programming language, Fortran is begging to be made obsolete. Today, Fortran survives only in certain HPC circles and legacy codebases, and most of that is motivated by the vendor-lock-in influence of the copy-cat Matlab language, which today seems motivated by milking university students and scientist SMEs.

Everything Fortran can do, C can do better—and like I just said, we shouldn't even be using C.


Language Versions in Python and C++

People are writing new code in C++98! There is even a GitHub tag for C++98 projects to opt-into. GitHub was launched in 2008; how preposterous is it that there's a tag for writing in a language 3 decades old on a site that's only 2?

C++20 support[3] is mature and stable-enough for production right now, and even if it weren't, you could go back a few to C++11, which is rock-solid on every compiler I can even name. In fact, a properly standard-conforming C++98 modern compiler probably doesn't even exist anymore, because of the challenges with deliberately making a modern compiler's conception of the language worse.

Similarly, Python backward-compatibility is some kind of art form[4]. People clung to Python 2.* for more than a decade after 3.*, until finally the PSF had to kill it in 2020. Even then, transition was slow.


Consequences and Conclusion

While newer languages and language versions sometimes bring new APIs that aren't always necessary[5], they also usually bring refinements to the language grammar, keywords shown necessary by the test of time, and better tooling in the form of compiler fixes, compiler and library optimizations, and better cross-platform support—all of which lead, in general, to more productivity and clarity. The hard part of programming is understanding what you're doing, so using a language that is worse at that specifically is a form of self-harm.

This sort of willful stupidity isn't just degrading and pointless, it is also hazardous. New revisions of language standards regularly fix confusing language features that could lead to bugs in new code, or even the language itself. You know those folks bragging about how their code runs in old versions of Python 3? I sure hope no one actually does use an older version, because the 3.0 interpreter, for example, hasn't had any security patches for more than a decade!

No, bruh. Your code isn't "portable" or "robust" or "high-quality". Your code is a tangled nightmare of workarounds, polyfills, and cruft that could have been three times faster, a dozen times clearer, and thousand times more secure if it had been coded in a version of the language that wasn't written before you were born. Your code fights clarity—the single most important goal in all of software engineering—and you have the temerity to believe by that you're doing the world a favor. If you like the last millennium so much, then go the hell back. Leave the rest of us to writing quality code.


Notes


Return to the list of blog posts.