thoughts on replacement languages
Some idle thinking about what makes language succeed and replace their predecessors to go with the alpha release of rust. Mostly it comes down to not just being better, but solving a specific problem in a concrete way.
In the beginning, there was C and life was good. C identified a specific problem with its predecessor (assembly, ignoring some other predecessors) and nailed the solution. The portable assembler.
In time, the shortcomings of C for large scale development led to C++. C++ brings about a million new features to the language, but I’d say its success depends on better meta programming, mostly templates and to a lesser extent native support for class methods vs structs filled with function pointers. Cooking up generic collections in C can be done, but it involves a lot of CPP (ab)use and what I’ll call “void * decay”. Of course, these problems aren’t fatal for many applications, which explains why C continued on its own path.
The D language tried to address many of the complexities of C++, but didn’t quite catch on. It’s better than C++ in many ways, perhaps even every way, but it’s not enough to be better. Idiosyncratic syntax ambiguities are not a specific problem that is going to move programmers from one language to another. Adding first class support for looping over collections isn’t going to move programmers. Etc.
Java on the other hand identified two specific C++ problems. First, memory management and safety and solved it rather completely, top to bottom (perhaps even more than some would like: “Oh, it’s too bloated.“). Java also added a huge standard library. Writing C++ applications from scratch was still a major undertaking, and cross platform work was a bit perilous. Java’s
java.net.HttpURLConnection may not be the greatest, but it’s like standing on the shoulders of giants compared to building it up from
connect. C# deserves a mention. It’s a lot like Java, but won over still more Windows C++ developers by solving another specific problem: native system integration.
I think Go has succeeded because it has, from the start, been very clear about the specific problems it solves. It definitely doesn’t try to solve everything wrong with C or C++, but rather a short list. First and foremost, transparent concurrency support with solid runtime support. Definitely a specific problem that developers have and definitely a concrete solution to that problem. In addition, there are some operational improvements regarding compilation speed and modularity (and a large standard library), though I’m not sure those alone would have been enough.
Finally, there’s Rust. I have a harder time identifying exactly what Rust is for, because it’s been a moving target. Unlike Go, but more like D, the promise of Rust is not a specific solution, but simply betterness. Memory safety could qualify as a targeted problem, though historically that’s been a tough sell on its own.
Go has benefited from a slight head start over Rust, but also singularity of vision. Am I writing a server? Of course I’m going to use Go to handle concurrent clients! I could use Rust, but a glance at the concurrency documentation looks like I’ll be spending a lot of my time doing exactly the kind of thread management reference counting minutiae that Go does for me by providing channels. (Ah, so Rust does have channels. It’s just the 30 minute introduction that prefers to do things the hard way.)
What’s a concrete problem Rust could solve for me? How about first class support for writing a GUI application? I realize that’s probably well outside Rust’s current focus, but if the problem space for Rust is “application development” it makes a lot of sense. Notably, Java and C# both include their own GUI APIs, for better or worse. The current state of the art for Rust would appear to be a GTK binding. Or a Cocoa binding. Or maybe a QT binding or a Win32 GDI binding, etc. Whatever. Bindings never quite work the same way, and they suffer from a major documentation problem. I don’t want to be reading documentation about the GTK C API when I’m writing code in Rust.
All that said, I’d make the analogy that as Go is to C, Rust is to C++. I was able to pick Go by observing that it’s like C, but with some syntax changes and goroutines. I’m not sure I’ll pick up Rust in a similar fashion. There’s a lot going on here.
That was quick. A day after wondering what problem I’d use Rust to solve, I have the answer: creating 151 byte binaries. :)