Don't use my latest Emacs patches!

After years of waiting, Emacs 25 has finally been released. I was perusing the NEWS file this morning, and stumbled upon a few entries that I recognized… because I wrote them! My own features are now shipping to thousands of users.

Ironically, this release cycle has been so stretched, that I’ve already come to admonish those features.

js-indent-first-init

The first news item I found was:

New js.el option ‘js-indent-first-init’.

Ah, yes. I used to declare my JavaScript variables like this:

var a = 0,
    b = 1,
    c = 2;

I was under the impression this style was “safer” than separate var declarations, because the language’s hoisting rules were treacherous, and declaring all variables at the beginning of a function would clarify their scope.

var hoisting is still as nasty as it’s always been; but even back then, a static analysis tool could detect when variables were used before they were defined. I realized that, but always told myself, “Despite static analysis, this strategy is still ‘inherently safe.’ Why not be more safe?

First, my justification for a “single var declaration” was flawed. var typically needed to be at the beginning of a function, but one could still place code before it, and even (gasp!) reference the variables there!

function f () {
    a + b; // Uh-oh!
    var a = 0,
        b = 1;
}

Really, our rule should have been, “all variables should be declared at the beginning of their scope.” The “single var” was irrelevant. We could have used multiple var declarations at the beginning for the same effect.

Second, I failed to properly weigh the disadvantages of this style. At some point after questioning my sanity, I fatefully encountered Ben Alman’s article on the subject. Suddenly, the problems with this style became clear. It was a pain to maintain, and the tooling was proportionately difficult to write. The style’s risk of ASI was an “inherent weakness.” Alman’s “Multi-line expressions” and “Comments” sections reflected exactly the dilemmas I faced when implementing js-indent-first-init.

js-indent-first-init tries to support indenting code using this awful coding style. Please, just use separate var declarations and a linter.

var a = 0;
var b = 1;
var c = 2;

js-jsx-mode

I scrolled down further, and noticed:

‘js-jsx-mode’ (a minor variant of ‘js-mode’) provides indentation support for JSX, an XML-like syntax extension to ECMAScript.

At work, my team wanted to use React for our next project. I do like React’s declarative programming model.

That said, I am not a fan of JSX. I don’t like how JSX weighs down React users with transpilation baggage, or how its existence burdens tool authors with the task of supporting non-standard features. The rules for comments are different from that of JS. To pull off conditional rendering, you may need to embed JSX inside JS inside JSX! Really, after setting aside my familiarity with HTML, I find the structure of the JS API almost identical:

var ExampleComponent = React.createClass({
  render: function () {
    return (
      <div className="example">
        <h1>Example Component</h1>
        <ul>
          <li>One item</li>
          <li>Another item</li>
        </ul>
      </div>
    );
  }
});
var ExampleComponent = React.createClass({
  render: function () {
    var $ = React.createElement;
    return (
      $('div', {className: 'example'},
        $('h1', {}, 'Example Component'),
        $('ul', {},
          $('li', {}, 'One item'),
          $('li', {}, 'Another item')))
    );
  }
});

HTML may not even be the ideal language for user interfaces… but JSX celebrates it.

Overall, I find JSX unnecessary and detrimental. Despite this, my team still ended up using it. I was faced with writing and maintaining JSX. Finally succumbing to the hive mind for a moment, I compensated for the lack of JSX indentation support in Emacs by creating js-jsx-mode.

I regret it. I’ve created one less reason for developers to discard JSX, and helped set the stage for future non-standard syntax headaches. Before extending the language, consider the cost in complexity.

I wouldn’t shame anyone for using js-jsx-mode, if they didn’t have a choice. Eventually, I had the privilege to drop JSX, and I did. js-jsx-mode still proved useful when I prepared a patch for a React library written with JSX. Don’t rejoice for js-jsx-mode; consider it a safety net, if you cannot convince others to relieve themselves of this awful thing.

Moral

When you think you see some way to improve your performance, think about what problem you’re trying to solve.

In the case of var and js-indent-first-init, I thought I was reducing my error rate. I ended up improving the way I formatted code that I assumed would reduce my error rate. Big difference!

In the case of JSX and js-jsx-mode, I gave up for the sake of collaboration. I focused on improving the way I formatted syntax which my peers liked. Facebook’s justifications for JSX were “familiarity” and “readability.” The problem here was maintaining happiness. I don’t think JSX proponents realize that less is more. The addition of JSX seems to result in an overall increase of problems. I’d be happier if we could increase our productivity, release more quickly, and improve our users’ lives.

Programming blindly is hazardous. Make sure there’s a thinking person between your keyboard and chair.