JavaScript is widely used these days. But there are still many people who dislike it, which is why Dart and – to a lesser degree – CoffeeScript have passionate fans. Recently, Crockford, who has done much to establish JavaScript as a credible general-purpose programming language, called it “
tragically important”. In this blog post, I argue that we should see JavaScript’s glass (cup?) as half full and not as half empty.
Four factors
Whenever I look at a programming language, I consider four factors:
- Is it freely available?
- Is it an elegant programming language?
- Is it useful in practice? That is: Can I write cross-platform GUI applications? Does it have enough libraries?
- Does it have good tools, especially a good Integrated Development Environment (IDE)?
You’ll notice that I haven’t mentioned execution speed. That’s because it rarely matters to me. However, it has been great to see that JavaScript’s speed has increased considerably in recent years. It is now fast enough for all but the most extreme use cases.
Is JavaScript freely available?
JavaScript is arguably the most open programming language there is:
ECMA-262, its specification, is an ISO standard. That specification is closely followed by several implementations from independent parties. Some of those implementations are open source. Furthermore, the evolution of the language is handled by TC39
[1], a committee comprising several companies – companies that are normally competitors.
Is JavaScript elegant?
Yes and no. I’ve written fair amounts of code in
C++, Haskell, HyperTalk, Java, Pascal, Prolog, Python, Scheme and 6502 assembler.
I’m also loosely familiar with Smalltalk, Common Lisp, Self and others. So I’m well aware that JavaScript isn’t the pinnacle of elegance. There are two kinds of things that tend to confuse newcomers: On one hand, there are true quirks, such as function-scoped variables (instead of block-scoped ones), limited loops and complicated constructor subtyping. But even in elegant languages, you have to get the hang of the style. In JavaScript that includes learning the quirks. On the other hand, there are unorthodox mechanisms, such as object-based, prototypal inheritance. Those are mainly a hurdle for people coming from other programming languages.
But JavaScript has also many elegant parts. Brendan Eich’s favorites are:
- First-class functions
- Closures
- Prototypes
- Object initialisers and array initialisers
(4) let you start with objects and introduce abstractions (such as constructors, JavaScript’s class analog) later. They also enable JSON. The elegant parts also help with working around the quirks. For example, they allow you to implement block scoping
[2], better loops
[3] and inheritance APIs
[4] – all
within the language.
Language compatibility between JavaScript engines used to be a problem, but isn’t, any more, partly thanks to the test262 suite that tests engines for ECMAScript conformance. In contrast, browser and DOM differences still are a challenge. That’s why it is normally best to rely on frameworks for hiding those differences.
Whether or not you accept CoffeeScript as a way of increasing JavaScript’s elegance is a matter of taste. For me, JavaScript is not broken enough to warrant a different syntax and an intermediate compilation step. ECMAScript.next might eventually play a role that is similar to CoffeeScript: It will fix most quirks and provide more syntactic convenience. Classes [5] are one example – a feature that has been field-tested via CoffeeScript. But ECMAScript.next will be a true superset of JavaScript and there will be no need for compilation on modern browsers.
Is JavaScript useful?
If I program in a language, I want to be able to write cross-platform GUI applications. Doing so is always a compromise: you give up some quality in exchange for not being limited to a single operating system. In the past one targeted the major desktop operating systems: Windows, Mac OS and Linux. But we now have two additional interactive platforms: web and mobile. JavaScript is a great choice for the web and a good choice for mobile. For the desktop, free solutions are being developed (examples:
AppJS,
node-webkit), but they are not as mature as, say,
PhoneGap.
When it comes to libraries, there is still an unfortunate schism between client-side JavaScript and server-side JavaScript. On the server side, things are already close to ideal: The Node.js package manager (npm) offers both ease of use and a tremendous selection of useful libraries. I’m hoping that we’ll ultimately have an npm-like solution that works for both client and server. But for that to happen, client and server must share more system APIs.
JavaScript’s usefulness is helped by two recent technologies: Both JSON and NoSQL databases (such as MongoDB and CouchDB). Those databases usually tightly integrate JavaScript and JSON.
Lastly, there is shell scripting, which is practically its own platform. It solves problems that typically involve reading, creating and/or transforming files. Shell scripts are often throw-away code. It helps if you are fluent in the language that you write them in. Therefore, Bash and similar languages are not a good option for most people. It also helps if the language has many libraries (parsing file formats, manipulating images, etc.). JavaScript has become viable in this area, thanks to Node.js [6].
Does JavaScript have good tools?
JavaScript is getting better build tools (example: Grunt) and test tools (example: mocha). Node.js makes it possible to run this kind of tool via a shell (and not only in the browser). One risk in this area is fragmentation: we are in the process of getting too many of these tools. The Java community benefits from having few tools that are used by everyone.
In the IDE space, JavaScript still has catching up to do. The gold standard for free IDEs is the Java-centric Eclipse. JavaScript being more dynamic than Java, more work and a different mindset are necessary to create an IDE. One promising new attempt is Adobe Brackets. For me, a good IDE is essential for using a language to its fullest potential. After having gotten used to the comforts of Eclipse, I found it difficult to leave Java behind, even though it is not a very succinct language.
The future
The next version of the JavaScript language standard is code-named ECMAScript.next. It will be finished by the end of 2013 and its final name will probably be ECMAScript 6. ECMAScript.next is an important next step to keep JavaScript relevant. It fixes many quirks and makes features part of the language that were previously implemented by libraries (examples: modules
[7], classes
[5]). Doing so is challenging, because ECMAScript.next must not break existing code, as it will be a silent upgrade for most users.
Given that it will be years until we can rely on ECMAScript.next being there in browsers, I expect people to develop in ECMAScript.next on a modern browser, but to deploy two versions: An ECMAScript.next version for modern browsers and a version compiled to ECMAScript 3 for older browsers. For simplicity’s sake, one could even deploy only the ECMAScript 3 version. The similarities to CoffeeScript are obvious, especially in the latter case. Hence, some of its techniques and work flows can probably be adopted.
Conclusion
Considering the four factors free availability, elegance, usefulness and tools, JavaScript is doing remarkably well. It certainly is not perfect, but right now (as opposed to in some hypothetical future), it is hard to beat. Thus, JavaScript can be described similarly to how Churchill
described democracy: the worst programming language except for all the others. I see JavaScript’s glass as half full. You get something versatile, but have to put up with a few quirks. In the future, there will be fewer quirks. And its elegance, its usefulness and the number of its tools will all increase.
References
- ECMAScript: ES.next versus ES 6 versus ES Harmony
- JavaScript variable scoping and its pitfalls
- Iterating over arrays and objects in JavaScript
- Lightweight JavaScript inheritance APIs
- ECMAScript.next: classes
- Write your shell scripts in JavaScript, via Node.js
- Harmony proposal: modules