I am lucky enough to have two very loving parents who occasionally take time out of their busy days to send me an email and let me know that they’re thinking of me. From my father, this is usually in the form of some interesting aviation video or a Fw:FW:Re: LOL series of comics about the foibles of senility. From my mother, adjurations regarding my education, social life, or other relevant deficiency are not uncommon.
Yesterday, amongst the usual maternal payload was attached an additional article of interest, entitled Which of these top 20 programming languages should your school teach?, with particular emphasis given to this list, which is described as the IEEE’s selection of top 20 languages to learn, but which is in fact a derivative of this list, which is the IEEE’s ranking of languages by popularity (where “popularity” is defined via a bunch of obscure SEO voodoo).
There are a number of things I don’t particularly care for in this article, but the one that really stood out to me was the prescribed methodology for finding your way through our really quite complex technological milieu. I wrote back a rather garrulous response, which I’ve reproduced here in two parts as pertains the two individual nits I felt I had to pick at the time:
Part 1: Java Sucks
I have a hard time believing that anyone advocating Java as a top 20 language to learn understands a whole lot about modern application development (by modern I mean the past five or so years). From the mid-90s onward, Java was heralded as the be-all and end-all of enterprise software development, and I suppose for a time it was probably the best solution available for cross-platform backend technologies.
The problem with Java (well, there are many problems with Java, but the main one in my opinion) is that when all you have is a hammer, everything starts to look like a nail. That is to say, the folly of many traditional ‘enterprise software architects’ is to try to obviate complexity by abstracting functionality to a “human-understandable” series of layered interfaces. What this means is that it becomes almost impossible to implement the solution to a problem given a reasonable level of systemic complexity, because you’re trading the unknown quantity that is the capacity for creative implementations for the known quantity that is language constraints.
Compare this “one-size-fits-all” approach with a polyglot development environment implementing, say, a high-level actor model via 0MQ or similar such language-agnostic messaging system (or Firebase, or a replicated no sql db, it doesn’t matter what the glue is). Text parsing is a pain to do with traditional statically-typed languages, so why not offload that part to Node or Ruby? Likewise, highly concurrent background functions suck to execute in Ruby because of the global interpreter lock (assuming you’re using the standard interpreter), so why not shunt those to Go or Erlang?
The point is, limiting yourself to one language that “does it all” is pretty much never a good idea, because the right solution is always to use the best tool for the job, and no sufficiently complex job can be accomplished with a single tool. To go back to the construction analogy, imagine trying to build a house if all you had were various kinds of screw drivers. It might start out well enough in the prototyping phase, but eventually you’d have to saw a board in half, or fit some plumbing, and you wouldn’t be having a very good time.
Part 2: An Alternative StrategyI realize that complaining about the list isn’t as constructive as suggesting an alternative, so here is my list of Top N “Programming Languages” to Learn Right Now (I put programming languages in quotes there because the original list enumerates several things that are not in fact programming languages, and also because I’m going to list several things that are more like domains or technologies than individual languages):
- Depending on what you found you liked or didn’t like about that experience, do one of the following:
- learn an interpreted back-end web technology (Node, Ruby)
- learn a compiled back-end web technology (Go, Java)
- Depending on what you found you liked or didn’t like about the preceding, do one of the following:
- double down on front-end tech and learn a modern web pipeline (SCSS/Gulp/Babel/etc.)
- double down on front-end tech and learn a mobile framework (Android/Java/Kotlin or iOS/Objective-C/Swift)
- double down on back-end tech and learn a functional environment (Erlang, Scala)
At that point you should have learned enough about yourself as an engineer that you can dispense with other people’s poorly-substantiated ideas of what’s popular/marketable/interesting and learn the things that will help you become the sort of person you want to be.