Brooks, Wirth and Go.
It’s 1975.
The programmers have come back with the FORTRAN code, now in punch card form. The cards are taken back, with great consideration as to not to drop them, over to the mainframe. By the time they’ve been fed in, read, compiled, linked and executed by the computer, it has taken more than a week for the result to come back "[File name specification error]". At this stage, the code has touched the hands of a lot of people, consuming weeks of work hours.
Meanwhile, another engineer programming in Smalltalk and Interlisp is writing and running their implementation directly against a system console. After a few seconds, they have their result. “Ah” they go, fixing their mistake right then and there. Done.
The differences in turnaround time between these two approaches is on an order of three magnitudes.
Forget about a “10X programmer”, how about a “1000X programmer”?
As the hardware of modern computers has evolved to being hundreds of billions times faster than the ones that put humans on the moon, these type of discrepancies have shrunk drastically. Gone are the days of timesharing, of waiting hours for even simple computations to return a result. Even cellphones are powerful enough to calculate every computation humanity had computed by the 20th century put together.
Software, hasn’t perhaps moved forward as much. One could argue that not much have happened to solve the software crisis since ALGOL 68. Perhaps even worse is how little we have (collectively) learnt from the giants of that era. I want to exemplify two of these giants, and the lessons they can teach us.
Brooks.
It was the worlds first real programmable mainframe computer, opening up the notion that computers could be reprogrammed to suit new problems instead of being replaced by newer models. The architecture of the system introduced a lot of standards that we still use today, such as 8-bit bytes, 32-bit words and more.
What is perhaps even more interesting, was the project itself.
The project was … more expensive that what was first thought.
It blew the budget by a factor of 200; from $25 million to $5 billion.
For reference, the Manhattan Project
was budgeted for $2 billion.
Years after, Brooks decided that the best way to answer the question "why do software projects so often go awry?" would be to write a book about his experiences and lesson from IBM. That book was the now fabled The Mythical Man Month.
It's perhaps one of the best reads on software management there is.
One essay from it is ‘No Silver Bullet’, which states that:
Given how quickly a modern programmer could correct their mistakes compared to their punch-card predecessors, Brooks contended that the majority of remaining complexity was the problem itself, and that accidental complexity had mostly been solved.
That is not so say that productivity hasn’t increased since the 60s. On the contrary.
Take these examples:
- Free/open source software.
- Absurdly fast hardware.
- Generalized computers.
- Quick compilers.
- The Internet.
Together, they have pushed our overall productivity to great heights. They’ve also re-introduced a lot of the accidental complexity that our predecessors fought so hard to remove in the first place.
This notion of reducing accidental complexity to the bare minimum is the key to a lot of our problems, and there is no greater champion of this principle than Niklaus Wirth.
Wirth.
To say that Wirth accomplished a lot of great things in his career would be an understatement, and the examples given above are a fraction of his achievements.
He managed to execute on all these ideas by following a set of principles that can be summarized as follows:
You have to completely comprehend your idea in order to fully realize it.
The man concluded that Pascal was too complicated. Pascal.
With his newfound power, he built his operating system on top of his own hardware from scratch in 12K SLOC, with a footprint of 200 kilobytes. For comparison, OSX runs in on ~86M SLOC with a footprint of 3 gigabytes, built by one of the wealthiest companies in the world. Now, perhaps OSX is more feature complete than Oberon, but certainly not by a factor of ~40 000X. Something was lost along the way.
Where Brooks notion of ‘No Silver Bullet’ and the philosophy of Wirth intersects is here:
The greater the surface area of your language, the more gusts of sand there will be to hide its essence. At some point, the needle has moved forward to where the cycle starts over as a subset of the old becomes the new and the cycle starts over once again.
This notion of ‘less is more’ reminds me of a quote of the same nature, from another giant:
~ Tony Hoare
Rejecting Wirth’s premise in theory inevitably leads to Hoare’s second option [0].
What are the costs of taking this route?
The stones that bind us.
Training.
- Learning a new operating system bound to your tech.
- Learning a new IDE bound to your tech.
- Learning a new framework to replace the one that already works.
- Learning to use the new version of your old language.
All of your old skills benefit from your years of experience, and like the Ship of Theseus there comes a point where those skills account for less and less.Experience should add value, not subtract it.
Hamster wheeling.
- Previously working projects are broken after an update.
- Other peoples previously working projects that you depend on are broken after an update.
- Sifting through pages of documentation and StackOverflow posts that are no longer relevant.
- Having to keep up with the news in order to anticipate your next on-call headache.
Won't somebody please think of the juniors?
- The trade is exceedingly hard to learn even without yaks to shave.
- Everything but the kitchen sink is not a great way to introduce newcomers.
- Every moment spent learning tools could have been spent getting to know the project
or learning general skills that carry over to the next one.
Most juniors you run into are overwhelmed, confused and pressured to keep up with the constantly changing layers of clothes of the Emperor.
How do you teach .NET to beginners?
How it feels to learn JavaScript in 2016.'The tailor is canonized as the patron saint of all consultants, because in spite of the enormous fees he extracted, he was never able to convince his clients of his dawning realization that their clothes have no Emperor.'
~ Tony Hoare
Being forced to fix problems generated by external forces outside of your project, company, customer or continent is not helping anyone, especially not you.
The Mess We're In by Joe Armstrong.
Why Do We Have So Many Screwdrivers?
The Thirty Million Line Problem.
The Left Pad Story.
With the exception of the Gray Beards and perhaps kernel developers, the industry at large tends to be unaware, ignoring or rejecting this premise. Instead, each revolution of the wheel is spun until it arrives exactly where it started, with the promise of new beginnings.
Luckily, there are exceptions. Here’s one of them.
Go.
This wonderfully tiny, famously “stuck in the 70s” language, ticks all the necessary boxes to avoid most (if not all) of these issues, and draws inspiration from older languages but with a modern touch.
- Hit the ground running.
- Single install, no licenses/registration/sacrificial ceremony.
- Can run on anything, even if that thing is a dusty old laptop.
- Language is (comparatively) easy to pick up.
- Straight up procedural programming, with sprinkles of FP and OOP.
- No IDE coupling.
- No need to buy licences, no need to have engineers blocked by expired licenses.
- No need to re-train engineers to put text into a textfile. If they have decades of experience using one editor, they can use it.
- No solution files or complicated build systems that require IDE compilation in order to work.
- Instantly compile to a static binary.
- No need to sit around doing nothing whilst the project compiles.
- No need to cook yourself as all your cores spin to a 100% in order to compile one kind of text to another kind of text.
- Deploy by running a single executable.
- If it worked ten years ago, it works now.
- Being stuck in the 70s means no breaking changes since flared pants.
- Batteries-included standard library for everything under the sun.
- Every line of code is inspectable, no closed source libraries.
It was designed by Ken Thompson, Rob Pike and Robert Griesemer (a student of Wirth). The introductory book to the language was written by none other than Brian Kernighan. If it’s not already apparent, this language is the spiritual successor of C.
It’s been two years since I first picked up Go, and I can’t think of anything better for general[1] software development, especially when it comes to respecting the time of myself and others. It’s one of the few languages that allows me to program freely, without having to consult the internet or prod others who have more experience in it for things that should be self evident. There is less magic, less hiding, which yields much, much greater clarity. No surprises, ‘it just works’.
This isn’t to say that everyone feels this way, on the contrary. Critique is abundant. The discussions about Go’s missing features (say, lack of generics) have going on for years (more than a decade by now), which I can only assume will keep on going for the unforseeable future.
In the meantime, I urge you to give it a Go. Perhaps you’ll like it.
Fredrik Holmqvist
Tony Hoare's 1980 ACM Turing Award Lecture
[1] There are of course better languages for specific types of software.