In Defense of JavaScript (the Hard Way)

JavaScript can teach you programming as well as most any other language, but be wary.

Thanks to some thoughtful reader feedback, I've realized that my piece a couple of weeks ago about learning code "the hard way" is missing something important: why JavaScript doesn't fit among "hard way" languages like C and Java in the first place.

I wrote that picking up an popular coding class, which these days tends to mean intro to JavaScript, is the wrong way to start a coding education. Instead, I argued that it's better to learn to code "the hard way," which means learning the fundamentals of programming: what code even is in the first place.

So, let's back up. There is a good case to be made that JavaScript qualifies as much as any other high-level programming language as a starting point.

"I am a programmer with two decades worth of experience," writes William Cotton in an email. "I started tinkering with C and Perl, moved on to C++ in AP Comp Sci in HS and Java in some introductory CS classes in college, but I dropped out and spent the early part of my professional career working with Ruby and Javascript. I've built a few iOS applications written in Objective-C."

"These days I'm writing 100 percent Javascript," Cotton continues, "be it for front-end web development, back-end web services, or making desktop or smartphone applications. Javascript has become the kind of general purpose programming language that you use to support your argument for learning Python or Java."

He's right, but we first need to understand what makes JavaScript different from other general-purpose languages. At first glance, it would seem to be "not much." There are variables, control structures, functions, loops, and most everything else. The syntax mirrors that of C by design, and in a JavaScript program you'll find a similar mess of curly braces, semicolons, and return statements.

How JavaScript works

JavaScript in its original form was meant to be interpreted by a JavaScript engine built into a web browser. As such, the browser functions as a sort of virtual machine, providing JS web applications with resources (like memory) and an execution environment. The browser itself may be implemented in C and other languages, and it may execute via resources provided by the operating system, but it also provides this bonus level of abstraction to JavaScript programs.

A key word in the paragraph above is "interpreted." This is an important distinction in programming languages. An interpreted language is one that does stuff by way of interacting with another program, such as a browser, that has a whole bunch of machine language instructions just hanging around ready to be directly executed. The interpreter will receive a wad of code and its job is to then piece together a bunch of ready-to-go commands to represent that code at a lower-level of abstraction (closer to the machine).

This is in contrast to what's known as a compiled language. Here, code is received by a compiler program instead of a browser or virtual machine and is converted into machine-level instructions. It's sort of the difference between cooking from scratch and cooking from a recipe kit.

JavaScript in 2016 is actually both a compiled language and an interpreted language, depending on how it's being used. In particular, Chrome's V8 JavaScript engine takes JS code and compiles it to machine code rather than merely interpreting it as above. Node.js, meanwhile, is a powerful and popular library that enables JavaScript to be run within an operating system environment like Windows or OSX in addition to being interpreted conventionally by a browser.

That's a huge capability and is allowing for the usage of JS as a "full-stack" language, e.g. one that can be employed from client-side web applications running in a browser all the way back to the server, where it can be used to manage and interact with databases in a role similar to PHP. JS can even be used to build regular old desktop applications via libraries like JW.js, though this is relatively uncharted territory. The Spotify desktop app is often held up as an example of this capability.

JavaScript is the language of the web—even if not all of the web realizes it yet—and it's popular enough that extensions like Node.js will continue to emerge and thrive.

So, then why shouldn't it be a programmer's first language if the future so clearly seems to be converging on JavaScript?

Framework fatigue

The point I never really got around to making in my earlier piece is that JavaScript is in itself a fine general-purpose programming language to learn, even if it skips over some key things like variable types and memory pointers, but it's also become the nexus of a roiling sea of shortcuts and pre-defined patterns in the form of frameworks.

Frameworks aren't necessarily evil. The basic idea is that a framework provides a bonus level of abstraction to a programming language. It may not extend the language's capabilities, but it will focus and standardize certain capabilities. jQuery, for example, takes the different elements of a webpage's structure (the document-object model or DOM) and allows them to be neatly packaged up into abstractions called objects, which can then be operated on using a standardized set of functions.

There are a lot of JavaScript frameworks and new ones are constantly being popularized. Every programming language has frameworks, usually a much smaller set of them that come and go usually much more slowly, but, it can seem like JavaScript is frameworks.

There's a language down there, but surrounding it is a buzzing cycle of new abstractions. The site ToDoMVC offers a comparison of some 64 different JS frameworks by way of a sample project (a ToDo list) implemented using each one. Judging by the thousand-something pull requests visible at the project's GitHub page, ToDoMVC is regularly besieged by requests to add still newer frameworks.

"How can we feel like craftsmen when we're scrabbling in the dark with unfamiliar tech?"

"A world dominated by endless tiny frameworks actually works okay for JavaScript experts and consultants," writes developer Allen Pike in a post about JavaScript "framework fatigue." "We become skilled at mixing and matching components, are able to spend time keeping up to date on the latest options and their relative strengths, and gain a lot of fodder for our conference talks. Yet for those who are new to JavaScript or who aren't full-time client-side developers, any given tiny framework can't possibly solve the wide range of problems that JavaScript developers struggle with."

This is what constitutes a JavaScript introduction in many cases: an introduction by way of some framework. These extra and often redundant frameworks are unavoidable in JS. I have a difficult time imagining basic programming skills within all of that noise and, daresay, temptation.

It's a weird thing: frameworks provide ready-made entry points into code, but their popularity and flux mean that a JavaScript developer is always in a position of having to learn the next thing (and guess the next thing) to stay above water. Guessing wrong could mean not having a job.

Programmer/blogger Jimmy Breck-McKye writes that we've entered "a crisis of churn rate." "Programmers want to program," Breck-McKye laments, "they want to build things, and be masters of their craft. But how can we get anything done when we're spending most of our time learning? How can we feel like craftsmen when we're scrabbling in the dark with unfamiliar tech?"

Go forth

So, you can learn fundamental programming via JavaScript, but be aware that it's a holy fucking mess out there. If it does wind up being your first language, I'd recommend Marijn Haverbeke's short-ish Eloquent JavaScript for its focus on teaching programming principles by way of JavaScript minus most of the clutter. Actually, the first person to tweet at me a cool thing they did in JS gets their very own copy (that was once my copy). No ringers.

Learning to code the "hard way" means to learn the fundamentals and to be aware of the noise that obscures the underlying reality. Programming right now is full of a lot of noise and it's hardly exclusive to JavaScript frameworks. This is a good thing because it means that programming is evolving quickly, but the flipside is that it's going to be a lot harder to keep up with. Good luck!