Language Pessimism and Optimism
Let’s talk languages. Not languages like Swahili or Latin, but languages like C or Java. Programming languages. I would argue that the programming language you use day to day is the most important tool you use in programming – if you use a modern language, it offers a lot of punch compared to something like assembly. The programming languages of today are cross platform, which gives you compatibility, meaning you don’t have to worry about writing your code for every platform or architecture, because your language takes care of it for you. It gives you abstraction, because you can write code that takes a different shape than the way the machine sees it. Machines can’t understand for loops or if statements, or even really anything more than 0s and 1s. We made up things like functions and classes and interfaces and stuff like that. And these abstractions are really good. I’ve never wondered when a for loop or if statement didn’t work as intended in the language. Programming languages also give you safety – they prevent you from doing bad things with your program. If I try to cast to a non-compatible type, my compiler might catch that – if I try to write to some memory I don’t own, my language or Operating system will stop that. And that’s just scratching the surface – there’s plenty more to love about languages. Higher order functions! Algebraic Data Types! Optimizations! Syntactic Sugar! It’s a joyride all the way down. But we’re not going to talk about the nitty-gritty type theory of languages, no, today we’re going to be talking about how people view languages in programming, by doing everybody’s favorite thing – dividing people into two kinds of people, the x’s and the y’s, or the pessimists and optimists.
The Pessimists
The pessimists tend to say something along these lines quite often: “Good code can be written in any language, and bad code can be written in any language. It’s all about discipline when writing code.” COBOL is as good as Java. People made great systems in COBOL, just like they made great systems in Java. And it’s true. Much underpinning financial systems were written in COBOL. Many COBOL systems are still out in the wild running, decades after they were written. And to the pessimists’ credit, they work just fine. After all, if a language is Turing complete, it is as powerful as any other language. Basically all popular languages are Turing complete, so they’re theoretically equivalent in power. Some languages are just better at certain things, but they can all express the same things.
The Optimists
The optimists might say that languages are different. An optimist might say that they prefer C++ to C because it has collections and Object Orientation. An optimist might enjoy using smart pointers to aid in memory management. An optimist might like the way that python handles iterable collections. These all aid in code readability, because the abstraction is easy to understand and encapsulates more functionality in fewer lines. Maybe an optimist likes static types, because they make it explicit what types of data a function or method might return, or make it easier to understand the way data transforms throughout its lifecycle. In the optimists’ eyes, there are abstractions which aid in the expression of code, and since different languages choose different abstractions to make the expression of some types of programs harder and some easier, there are some differences between languages. You can program in an object oriented style in C. You can program in a generic style in C. These are all far less compact than their equivalent C++. There is an aesthetic difference, if not theoretical difference.
A Twist
If you follow my points up above, I’m promoting the idea that language optimists prefer the aesthetics of a language, whereas the language pessimists prefer the theoretical power of a language. Theoretical power of a language is not bounded by expressiveness, however. If it took you 100 lines of code to read from a file in a toy language (let’s call this language Airplane), but 1 line of code to read from a file in another language (let’s call this language Ship), Ship and Airplane would be theoretically equal in power. But in practice, most people would prefer to use Ship for reading files. 1 line of code is 100x less than 100. If this was the case for everything (let’s say it took 100x more lines to write any possible program in Airplane than in Ship), you would probably prefer Ship. In terms of expressiveness, Ship is better than airplane.
Ship is still not more powerful than Airplane; it is simply more expressive.
But that’s still just aesthetics; what if there was a class of problems that Ship did not suffer from that airplane suffered from. Let’s say that Airplane and Ship are both Web programming languages, and if you fail to write “safe” Airplane code, you might allow some users to read information that belongs to another user’s. Let’s say in Ship, this problem doesn’t exist – Ship wouldn’t let our code compile if it could detect the possibility of this bug.
Even with this added on, Ship is still not theoretically more safe than Airplane; a correctly written Airplane program is as safe as a Ship program that compiles. But I would say in this case, most programmers would prefer Ship. Even though Airplane is theoretically as safe as Ship, a language that provably lacks a class of errors is at least marginally better than a language that may probabilistically have a class of errors.
Now the twist is, is Ship in a different class of language compared to Airplane? Does safety matter?
Choose your own adventure
It’s up to you. Theoretically safety doesn’t play a part in programming. God awful safety vulnerabilities and memory leaks don’t matter because, while they cause us and our users to be sad, and might even cause us to go to jail, they don’t make our program any less powerful. A program doesn’t care if you go to jail or not, actually, and neither does math. If you are concerned with this definition of power, then Airplane and Ship are indeed equivalent. But maybe you have a more practical bent. If so, Ship is probably the better language – hey, you can express yourself with 100x less code and it has more safety built in that Airplane.
Is Safety Preference?
That leads me to my last point. Is Safety Preference? Is a safer language a categorically different language than one that an unsafe language? I would argue so. Most programmers these days will probably never touch a memory unsafe language (C and C++ being the most popular of these). There’s a whole extra class of errors to account for in these two languages, and when you choose a garbage collected language, most of the time you don’t have to worry about memory. That helps you out with delivering better safe software. And that’s great. It makes you more productive. But maybe you need to have performance instead of safety, and this is where most people go for performance. Safety comes at some cost, and you can’t always have safety. But if you can have safety, you might as well buy into it, since it lessens your cognitive load.