The hammer and the nail

black claw hammer on brown wooden plank

Quite possibly one of the most-quoted phrases in the software industry:

“If all you have is a hammer, everything looks like a nail.”

— Abraham Maslow, The Psychology of Science (1966)

This is often pulled out and dusted off when discussions of high-level architectural components, stacks, and programming languages begin to get a bit heated.  This post was inspired by a discussion with a budding computer scientist I know regarding why there are so many different programming languages, tools, and environments.

The discussion started off innocently enough.

“If I learn Python, how hard is it to learn a new language?”

Which led to:

“How many languages are there?”

Inevitably followed by:

“How many do you actually know?”

With this final doozie:

“Why are there so many different ones?”

That last one is the tough one – and the one I think most people tend to forget when they start digging their heels in on a preferred solution for a programming challenge.  Many junior devs (and to a lesser extent more senior ones) fight the good fight on learning a language, toolchain, stack or architecture to become proficient and productive; that tool of choice often becomes their hammer.  But the challenge they are tackling isn’t always a nail.  And here’s why.

A brief (and admittedly incomplete) history of programming languages

First there was the patch cable and the switch.  Early digital systems simply had basic connectors or physical switches to program them.  Higher level languages didn’t exist, and there was only one way to program the system.

Next up was assembly (and the human-friendlier assembler) languages.  These represented operations using mnemonics instead of raw bit-fiddling, and made code much more easy to build, reason through, and share.  LDA, LDX, LDY make a lot more sense than 0xA9, 0xA2, and 0xA0 respectively (from my 6502 assembler days).

In commercial use (as common as computer systems were in the day) the Formula Translation language (FORTRAN) was released in 1954 by IBM to tackle a very specific problem – mathematical modeling and engineering challenges.  While it could be used for other uses, it was not well-suited for the next big customers of computers – MegaCorp, Inc.

Big companies wanted to leverage the same technology that engineers and scientists were using, and thus FLOW-MATIC was developed by Grace Hopper and her team. FLOW-MATIC turned out to be the precursor for the Common Business Oriented Language (COBOL) which exploded in business mainframe centers around the world, specifically to solve business record keeping and accounting as well as codified business workflows.

The 1960’s and 1970’s spawned a great many application-specific high level languages like ALGOL (algorithm research), LISP (artificial intelligence), BASIC (entry-level general purpose language), and a myriad of others.  As computers became more powerful and more uses were found, the birth of high-level general purpose languages led to the rise of such beasts as C, PL/I, SNOBOL, and Smalltalk, to name a few.

The 1980’s saw a lot of consolidation in programming languages, where high-performance, (relatively) easily-learned, general-purpose languages took over, and programming approaches shifted from purely procedural to object-oriented and modular systems.  C/C++, Objective-C, Erlang, Perl and others filled  this niche nicely.

The 1990’s saw the birth of the modern internet as we know it.  As such, it was a veritable arms race to come up with the dominant technology, platform or stack to leverage the new medium.  We saw the birth of several languages geared towards rapid construction of server-side solutions such as Python, Ruby, Java, and PHP which quickly pushed out early approaches using C, C++ and Perl.  In the browser, Netscape rolled out JavaScript and Microsoft pushed a combination of DHTML, HTC and ActiveX during the early browser wars, which was ultimately won by JavaScript which is still used to this day, albeit in a far different form than in early browsers.

Not coincidentally, many of these languages launched around 1995 when the internet became publicly available.  While a general-purpose language was usable for these challenges, many internet-era-born languages had a specific strength not unlike the legacy FORTRAN, COBOL, and ALGOL days.  Some were more approachable, some had faster prototype times, some were better performing (in speed and/or memory), or worked best in a given operating system or corporate environment.

And here we are…

In consulting you offer hear, “You can have it quickly, cheaply, or complete – pick two of the three.”  In modern times, we have a plethora of languages, stacks, and toolchains that can achieve the 2-of-3 goal.  Some languages are still hell-bent on being performant (C/C++ come to mind) but have their risks.  Some are easier to use (Python, Ruby, NodeJS, PHP) and make for great prototyping and with the right architecture and datacenters can scale.

With Moore’s Law dissipating faster than the heatsink on a 30-core CPU, options like Elixir, Go, Rust, Scala and Clojure are starting to break out to support new paradigms of concurrency and distributed computing with first-class support to address those challenges.  Even in this day and age, there are “general purpose” high level programming languages that have niches that will also evolve over time, and I have no doubt will call for more specialized languages to tackle some new problem.

TL;DR

In essence, the reason there are so many programming languages out there, and operating systems, and toolchains, and stacks, and… is because there are so many things out there that are not nails.  Realizing this and not taking a position on your tool of choice – for no other reason than it is your tool of choice – can free you to not only pick the right tool for the job, but save the drill bit you were about to break the tip off of with that hammer.

And who knows – maybe learning how to use that new tool will open you up to a whole new arena of challenges, opportunities, and learning experiences that you might never have been exposed to if you only used your hammer.

Epilogue

I’m honestly not ranting above, it all comes from personal experience.  OK, so I didn’t work with FORTRAN I, but I did cut my teeth on 6502 assembler… And then moved on to C on an old MS-DOS machine, which led to C++ under Windows.  Interesting thing about knowing C/C++ at the time – it was one of a handful of languages in the 1980’s supported on a majority of high-end systems – which got me into cross-platform development where I learned about graphics processing, distributed systems, and Unix (and its many variants at the time).  Learning those other operating systems leveraged into a HPC project working with multiple database vendors, which dumped me into some serious backend work in a plethora of languages solving some tough engineering challenges on the internet.

If I’d never progressed from my original hammers, I would have missed out on a lot of very cool technology and learning opportunities.  🙂