Wednesday, 18 May 2011

Emacs or Vi? Why the answer is neither.

Any programmer worth his salt should, at the very least, have heard of the perennial Emacs vs Vi editor war. And in some likelihood, especially if you are a veteran developer, have a preference, and expertise, in one of these editors. Perhaps you even participated sometimes (or often) in editor discussions, and defended your choice.
And while it is clear there is not going to be a definite favorite in this issue, there is at least the consensus (well, in most of the Linux community at least), that the choice should be between one of these two - Emacs or Vi/Vim - and any other choice is inferior. In practice many people may be doing things differently, they may be using different tools and editors, but the prevailing mindset is still this one. It is however a mindset I strongly disagree with, and this post is a challenge to that. (Brand me a heretic if you wish, but at least bear with me until the end of this post.)

First, some background: I am a very productivity-minded person, in particular a proponent of tools mastery, and therefore, of spending some time to learn and master tools used frequently, to increase one's productivity in the medium and long term. So the issue of which tools are better does matters to me a lot.
When I first started learning and experimenting with Linux, back in 2000, that's when I first heard of these two editors, and how beneficial it was considered to master one of them. I first learned the very basics, so I could get a feeling for both. I quickly took some preference for Emacs, but never went much further than the basics, since most of what I did at the time was small editing of Linux config files. It was later when I was in college, that I started to develop much more. It would then have been the time to master one of these editors and use it for actual coding. But I never did. I used other editors and IDEs (mostly IDEs) and never looked back, I didn't even consider the possibility of making such IDE's editing work like Vi or Emacs. I always felt disregarding Vi/Emacs was the right choice, that they were not good approaches, although I never thought or verbalized much about why that was the case, until recently. Until I became more involved in the D programming language community  (which attracts programmers from all sorts of different backgrounds and languages, not just C/C++ but from Java to Ruby, to Python, Perl, etc.), and related discussions popped here and there, especially as I started to do IDE development.

So what is the reasoning then? Before we discuss the answer, we need to clarify what the question is. That may well be the most important consideration. You see, I think the important question is not "What is the best editor?", but rather, "What is the best development tool for writing software?", where best means, roughly speaking, the most productive. These two propositions are not exactly the same. I don't care much about which tool I use to edit config files, write emails, write notes, articles, etc. . I don't do that often enough to care about being super productive in them, I just need the basics. What I *do* often do is write software and code, so that's what I really care about. And here is where I think that Vi and Emacs are inferior tools. They have two fundamental problems:

First, they are both essentially textual interface tools (as opposed to graphical interface tools), and this is an inescapable shortcoming. Because anything a text UI can do, a graphical UI can do just as well, but the opposite is not true. A graphical UI is simply strictly better, kind of like a Paretto improvement, or an algorithm that dominates another one in all cases and input. Note that I'm not talking about using the mouse vs. using the keyboard here. That aspect is completely unrelated (especially since you can use a mouse just as well in a textual interface). My point is that a graphical interface offers a much greater and better potential to *display and convey information to the user*. For example: font styles, squiggly lines, decorations and other editor markers, images, icons, etc..
Now, yes, both Emacs and Vi have graphical frontends, I haven't missed that. But the thing with those is that they are essentially still a text based UI (see picture example: vi, emacs). Their graphical frontends add something like a menubar, a toolbar with icons, and a mouse interface, but the core editor (and thus the gist of the product) is still text-based. It is far from a full, proper graphical interface, it is still very much constrained in the way I described above.
Another alternative is to modify existing graphical tools (like proper IDEs) to work like Vi and Emacs in their editing mode. But the problem with this approach is that these are extensions, afterthoughts, to the nature of Vi/Emacs. They are not part of the core Vi/Emacs product, yet the extensions will be bound to their paradigm and thus - because these two UI paradigms (text and graphical) will be competing with each the other - the product will never be of a wholesome, integrated design. Well, not unless the extensions breaks compatibility with the standard Vi/Emacs interface, but then it's hardly Vi/Emacs anymore. In other words, if you are designing a tool that is going to be used in a graphical interface, you should design it from the start with that in consideration. Designing it as a text tool, and then have someone else design an extension or additions for graphical interface usage will be suboptimal, inferior.

Now, some people may think the above argument is somewhat moot, or of little value, because they think graphical interfaces do not add that much useful functionality to the development tool. If you convinced of that, you should consider whether that isn't just because you typically work in a environment, an ecosystem, where it is hard (and therefore infrequent) for such advanced functionality to exist in the development tools. On some ecosystems, such as with older languages, that might be common. But more on that later, let's look at the second point.

What is the second reason I think Vi/Emacs are not the best approach? Well, because they are primarily text editors, that is, editors of textual content (note that this is related, but different, to the previous point of whether they have a textual or graphical User Interface). The issue here is that they mostly "see" text content, and their editing operations are textual ones. This is great if what you are editing is indeed little more than plain text (emails, notes, config files). But, if like I said above, what you are doing is writing code, developing software, then it is not that great. Because source code and the underlying languages of that code have a great degree of semantics, and thus, the potential for lots of different semantic operations. Semantic operations that can be just as common, if not more, than textual ones. And as such, since they can be common, they need to be considered with importance in the interface design, for example, in the way they will compete for the shortcut real estate with other operations. If all the best shortcuts are taken for text operations, and little is left for semantic operations, or for that matter, for other language toolchain functionality (like building, debugging), that is clearly suboptimal.
At this point some people may think: 'but really, what other significant "semantic operations" are there other than open declaration or autocomplete?' Well a lot more than you think, if you are asking that question. You probably just don't know it, because your editor doesn't support it. Note that it is not just about operations that modify the source, but also even just the navigation and the display of information. Having more semantics opens the possibility of more functionality for all these aspects (for example, an outline view that displays the top-level declarations of the current file, or icons and decorations for the different kinds of elements your language supports).
But that is an interesting question nonetheless, because it brings us to a secondary point: the truth of "source code and languages have lots of semantics, and thus, the potential for lots of different semantic operations." actually depends a lot on which language and software one is developing with. There is likely a big gap between statically and dynamically typed languages, for example. But even with languages of the same general category, the potential may still be much harder to realize in one compared to another. So if you are working in a terribly broken or convoluted language as say, C/C++ or Perl, don't be surprised if their tools generally don't have much semantic functionality. And the little functionality they have may work poorly, thus reducing its usefulness, desirability and frequency of use. This is what I meant when I mentioned programmers working only in certain ecosystems not valuing graphical interfaces: if all you work with is with such languages and tools, you may never realize the extra potential there is.
For example, for Java the tools are of great quality, like the excellent Eclipse JDT, the Java IDE. I use semantic operations so often in JDT: Content Assist (Ctrl-Space); Open Declaration (F3), quick Type Hierarchy (Ctrl-T), quick Outline (Ctrl-O), Refactor: Rename (Alt-Shift-R or F2 in some other contexts), Refactor: Extract Method (Alt-Shift-M), Refactor: Change Parameters (Alt-Shift-C) Refactor: Introduce parameter (Alt-Shift-T, P), navigate to member/element above/below - Ctrl-Shift-Up/Down), word navigate (Ctrl-Left/Right), and others. Nowadays, I probably use them more often than textual operations - like cut/copy,paste, textual find/replace, etc. (but excluding actual typing of course!). That is why the generality of Java developers (even the good/smart ones - in case you're one of those people who think Java is just for dummy programmers) do not give a rats ass about Vi/Emacs, and rightly so. But my point is that even for other languages, the same holds true: that a better development tool, a graphical one, a proper *Integrated Development Environment* will always be superior in potential to a mere text editor, even a very extensible one like Emacs. And this "superiority" is not an distant theoretical thing, it is something that in practice I would say has been reached for many languages already (although it is a very subjective thing to judge). It certainly has for Java, and even for C/C++ I think it has. So for example, if all I coded was C/C++ I would still not be using Vi/Emacs, but would much rather be using Eclipse CDT, or even Netbeans, Visual Studio, XCode, or KDevelop. This would be true even half a decade ago (perhaps even a full decade ago), despite the semantic functionality and external tool integration of these IDEs not being as rich and featured as it is now. But it still would be better than standard Vi/Emacs, I believe.

This is not to say that there are not good lessons and ideas to consider from Vi/Emacs... surely there are. But it is a very different thing to take and adapt some ideas from a tool, versus actually using the whole tool. (Much like LISP sucks, but it is still good to learn and experiment with :P )
So people, time to move to the new century. We can have a similar discussion again in a few decades, when people start using Kinect-like devices to control their tools, or better yet, Graphical Interfaces get superseded by Neural Interfaces. :)