Atom

While I'm a big fan of Emacs as a general purpose text editor, there are a few things it just doesn't handle very well. Among its major weaknesses is that it largely lacks graphical interface APIs, a holdover from its origins as a terminal editor where text was the only medium. There are features for viewing images and PDFs in Emacs, but not for drawing them; and the APIs these features depend on are built in at the native level and are not accessible via Emacs Lisp. This means that if you want to show something to the user, you need to do it as text.

However, there are other editors out there - even ones that offer similar degrees of customizability to Emacs - and one that I've been watching with particular interest is GitHub's Atom. They packaged a slimmed down version of Chromium, including its V8 Javascript engine, with a JS-based editor. By doing so they enabled Atom to leverage all of the goodness of web technologies, including HTML5 and CSS3 and dynamic extension via Javascript packages, providing a similar level of extensibility to Emacs with some additional capabilities.

Unfortunately, Javascript kind of sucks. It's really not a very good language for building complex applications due to the way the language grew
(organically and haphazardly) and the resulting lack of coherence. To address these shortcomings there is a menagerie of compile-to-Javascript languages such as CoffeeScript (Atom's preferred language), TypeScript, Dart, GWT, and so on. Among them are a number of functional languages, including PureScript, ClojureScript, and Elm. I find that functional programming tends to make my life a lot more pleasant, so when I decided to start work on an Atom extension for one of my side projects I decided to break the mold somewhat and use Elm.

Elm is a Haskell-inspired language that focuses on avoiding unmanaged state and providing a strong guarantee: the complete absence of runtime errors. To do that, it requires the programmer to strictly isolate Elm from Javascript, passing data through only via guarded "ports". This makes interoperating with Javascript a bit roundabout, but it does provide a nice clean line between the "safe" Elm code and the "who knows what the heck will happen, really" outside world.

Fortunately, getting an Elm view set up in Atom is really not particularly difficult: you just need to bind to an HTML element in Atom like you would any other web page, and you're off to the races.

    var Elm = require('../build/my-elm-app.js');
    var app = Elm.MyApp.embed(this.myView.getElement());
    this.setupPorts(app.ports);

Once you have the two environments playing together, you can take advantage of Elm's features for most of the heavy lifting and punt out work to Atom via ports where needed. I particularly wanted to be able to use Elm's parser combinator libraries for building a small Domain Specific Language (DSL) for my project, and it was a breeze once I got the plumbing set up - parsers written any other way quickly turn in to a hairball-y mess of calls and state. While I have my own gripes with Elm, it was worlds better than Javascript for this project.

While I happened to choose Elm, this kind of approach is nothing special and I expect that anyone can use it to write Atom packages in another compile-to-JS language. If that language has some sort of self-hosting interpreter *cough*Clojurescriptcough you may even be able to get an eval-able environment within the editor itself, a la Emacs. So, if you share my views on Javascript ("I'd rather not") but want a flexible editing environment with good tooling and powerful APIs, you might want to give Atom a try with your preferred language.

If you like what I write, you can subscribe to my mailing list to get new posts in your inbox: