Use concept naming to simplify and clarify your Javascript conditions

Concept naming comes naturally to most people but is still rarely seen in Javascript despite the benefits. In this post I’ll illustrate how a simple technique can make your Javascript code significantly more readable.

 
The benefits of writing simple, clear and human-readable Javascript code are well known if not always well practiced.  The other day, while skimming the source of some of the rules bundled with ESLint, I was pleasantly surprised to see many of them made use of “concept naming” for conditions. This is a practice common in many other programming languages but not something I see being used in Javascript very often, despite the benefits.

Let me illustrate the technique with a simple code snippet:


if (charsToMatch[line.charAt(cursorPos.ch)]) {
    // do something
} else {
    // do something else
}

The condition on line 1 is trivial but even something this simple can make us stop and pause as we try to work out what the test is doing, and why. If you’re new to the code or just haven’t worked on it for a while a lot of valuable time can be wasted trying to get an overview of the application flow. Each time we hit a condition we have to pause and ask “what are we trying to achieve here?”.

We could, of course, add a comment immediately before the condition but comments can quickly become out-of-date, incomplete or just plain wrong. For that reason there has been a general trend over the last few years to minimize or reduce the number of comments in source code, or even to abandon them altogether.

When it comes to conditions, there is a simple and reliable way of making your code more understandable – give a name to the concept that is expressed in the condition. In our simple example the intent of the condition might be to determine if the character at the cursor position is one that we don’t want to allow a user to enter. This is determined by checking if it appears in an array – charsToMatch.
We can rewrite our snippet to illustrate this concept:

var charAtCursorIsNotAllowedInInput 
       = charsToMatch[line.charAt(cursorPos.ch)];

if (charAtCursorIsNotAllowedInInput) { 
    // do something 
} else { 
    // do something else 
}

If I were to glance at the snippet above for the first time, I still wouldn’t necessarily know the specifics of the conditional test but I would immediately be able to glean the intent of the condition. It now more closely reflects how we think – in concepts rather than conditional statements – and is much more readable.

Of course, as conditions increase in complexity the benefits will become more apparent:

var charAtCursorIsNotAllowedInInput 
       = (charsToMatch[line.charAt(cursorPos.ch)])
         || (cursorPos.ch >= 0 
         && charsToMatch[line.charAt(cursorPos.ch - 1)]);

if (charAtCursorIsNotAllowedInInput) { 
    // do something 
} else { 
    // do something else 
}

In this snippet the test is more complex but the concept is unchanged and what is trying to be achieved is instantly understandable.

Am I suggesting you should always name your conditions? No. There is, of course, a slight overhead in the “noise” introduced by the extra variable (which I consider a small price worth paying) but, just as you wouldn’t find it necessary to comment every condition, you wouldn’t necessarily want to assign a name to every one either. As always, common sense and consideration for those that will come after you goes a long way.

I hope you can see from these simple examples that, like the judicious use of clearly named variables, applying concept naming to your conditions can make your Javascript code significantly more readable and easier to maintain.

Ternary Operators in Javascript aren’t just harmful, they’re selfish and evil

 
I recently spent many hours pouring over the CodeMirror source code in an attempt to track down a number of unpleasant bugs that turned what should have been a straightforward and quick update to my Brackets editor extension ‘Go To Matching Bracket‘ into a day-long slog.

The main reason for the wasted time? The unnecessary and excessive use of ternary operators (and ternary operators inside ternary operators inside ternary operators), whose soul intention seems to be nothing more than to obfuscate logic at every opportunity. Oh, and to save a few characters typing, because the web is short of characters and we don’t want to use them all up.

Apart from being ugly, confusing and error prone, ternary operators are a premature optimisation and usually turn simple refactoring into rewriting – they can rarely be sensibly expanded upon without reverting back to using a regular if/else statement (or heaping more stupid on top of the existing stupid).

So, next time you’re thinking about using a ternary operator, stop for a minute, read David Hayes excellent essay ‘Ternary Operators Considered Harmful‘ then… don’t. Just don’t.

Bonus:

If you’re using the excellent ESLint to improve the quality of your code then you can minimise the destruction that ternary operators wreak by enabling either the no-ternary or no-nested-ternary rule in your .eslintrc config file.


"no-nested-ternary": [2]

Add either of these rules, run ESLint in a Git pre-commit hook and you’ll never waste your colleagues time again (well, not with ternary operators anyway).

Why you can’t find that GitHub project page you’re looking for

GitHub Pages are a fantastic addition to the GitHub service. If you have already created a “read me” file for your project in Markdown format (and if not, you really should) then it takes all of 60 seconds to create a decent looking web page that is infinitely more welcoming to the less tech savvy than the ugly, cluttered mess that is the average GitHub project page. What’s more, the hosting of these pages, like the hosting of your project, is free.

A page I recently created for my Google Chrome Flashcards project illustrates what you can effortlessly create:

http://davidwaterston.github.com/GoogleChromeShortcuts

Unfortunately, there is one serious flaw in the GitHub implementation of pages – the URLs are case-sensitive.

This means that while my Chrome Flashcards page can be found at GoogleChromeShortcuts it won’t be found at GoogleChromeshortcuts (note the lower-case ‘s’ in ‘shortcuts’).

It might surprise you to hear that the W3C standard specifies that

URLs in general are case-sensitive (with the exception of machine names).
There may be URLs, or parts of URLs, where case doesn’t matter, but identifying these may not be easy. Users should always consider that URLs are case-sensitive.

Regardless, I can’t remember the last time I came across a case-sensitive URL in a public website.1 I’m very sure that most people would consider that particular “standard” absolute folly: a serious bug, a malfunction, something to be fixed and commercial suicide for most sites. With GitHub, this restriction is even more pointless as it’s not possible to create two project pages with the same name, even when the case-sensitivity is different i.e. now that I have created “GoogleChromeShortcuts” I can’t create a “googlechromeshortcuts” page. The case-sensitivity serves no purpose at all other than to frustrate users .

I wonder just how many of those 404 messages GitHub displays for pages that exist but which are hidden in the service of their adherence to a standard long since forgotten?

1 There is one notable exception – URL shorteners such as bitly.com and goo.gl rely on case-sensitive URLs to allow them to generate the greatest number of unique URLs with the least number of characters (though, notably, tinyurl.com links are not case-sensitive). For example this URL http://goo.gl/uQAJP is not the same as this http://goo.gl/UQAJP.
This is a very specific use case and doesn’t negate my original comments – GitHub Pages URLs are not the place for case-sensitivity.