Integrated Development Environments: Debunking the Myth

Updated 2016-12-30

IDEs provide the user with a lot of neat features beside pure text editing capabilities: auto-completion, refactoring, project management, etc. What are the key features that are really needed? More generally speaking, what makes a good IDE? Some fancy IDE features are rarely used. Let’s tackle a few examples.

Refactoring (renaming symbols) is convenient but in practice should happen as less often as possible. Avoid the issue altogether by thinking twice before naming a symbol instead.

Auto-completion certainly stands among the most famous features. But is it essential? If we know in advance what we want to write, good touch-typing skills will often be faster than the time needed for selecting the right item from the auto-completion list. (Unless the name is long and cumbersome to write, in which case auto-completion proves helpful.)

The thinking process “list first, then think about what you want, then select” is a bad habit: it is slower than “think what you want and write it down”. More on that later.

Completion comes in handy, so we think, when listing members of a class. But if the class is documented, the list of members should be obvious. Going to the definition will provide more documentation than the auto-completion list. This falls short in the event of inherited members, or worse, diamond inheritance, in which case it becomes really hard for a human being to describe an object mentally or by going to the definition of both its parents and descendants. Then a completion framework becomes essential to describe an object.

This solution only applies to ill-designed languages however: a better, more permanent solution resides in avoiding the use of diamond inheritance in the first place. Nothing good can result from not knowing the objects you manipulate.

The myth of the too-good-an-editor

Emacs and Vim have the reputation of the being the geek’s best friends, the tools to rule them all. And yet many professional programmers discard them from their toolbox to fallback to the “reputable corporate programs.” Why is that so?

To quote Paul Graham:

“Lisp is worth learning for the profound enlightenment experience you will have when you finally get it; that experience will make you a better programmer for the rest of your days, even if you never actually use Lisp itself a lot.”

This is the same argument you tend to hear for learning Latin. It won’t get you a job, except perhaps as a classics professor, but it will improve your mind, and make you a better writer in languages you do want to use, like English.

But wait a minute. This metaphor doesn’t stretch that far. The reason Latin won’t get you a job is that no one speaks it. If you write in Latin, no one can understand you. But Lisp is a computer language, and computers speak whatever language you, the programmer, tell them to.

So if Lisp makes you a better programmer, like he says, why wouldn’t you want to use it? If a painter were offered a brush that would make him a better painter, it seems to me that he would want to use it in all his paintings, wouldn’t he? I’m not trying to make fun of Eric Raymond here. On the whole, his advice is good. What he says about Lisp is pretty much the conventional wisdom. But there is a contradiction in the conventional wisdom: Lisp will make you a better programmer, and yet you won’t use it.

Questions:

Answers:

I can recall the times when I was studying, our dean would say (and write in the syllabus):

Fundamental editing

What is the one feature we need from a text editor?

Have you ever faced a one-time situation where you wished that the editor could automatically do this and that? Something specific enough that you know nobody will ever be in such a situation again. Like remove all the roman numerals at the beginning of every two paragraphs, or remove the XML tags while keeping a subset of it?

No editor developer can predict what use the user will make of it. Boosting the user’s productivity by implementing every single corner case of editing capabilities is not possible.

As such, an editor needs just one core feature to boost the productivity of every user:

Be an extensible editor.

That’s it. Well, let’s add some frivolities to the list:

Touch-typing is what will make you write code fast, not fancy IDE features. Mouse actions will disrupt the flow which is why a keyboard-oriented editor will allow for a faster flow. See Mastering the keyboard.

Text mode is not strictly required, but as of 2016 it is still prevalent in many contexts in which you really want to keep your favorite tool at hand.

Extensibility alone implies many features commonly found in other editors. For instance:

Text editors that are extensible, keyboard controlled and work in text mode are not legions. The most popular are, by far, the ancient, legendary Emacs and Vim. TextAdept is another one that offers some interesting feats.

Vim inherits from vi, a historical text editor that is very minimalist. Both editors are sometimes mixed up, in so far as some systems actually symlink vi to Vim. This is dangerous so let’s stress this out: if you find yourself wondering why so many people follow the Cult of Vim while it seems to be the most limited editor you’ve ever encountered, you might be using the wrong piece of software.

The war between Emacs and Vim is, in my opinion, futile. To the point that Emacs has a mode to emulate Vim. Both editors have all the fundamental features: a Turing-complete configuration that allows for binding any action to keyboard shortcuts. (Plus they run in text mode.)

Maybe the only significant difference between the two is that Emacs uses Emacs Lisp as a configuration language while Vim uses Vimscript.

Another difference is that Emacs has a greedy tendency for bundling its community extensions (for the sake of GPL3 protection?) while Vim keeps it slightly lighter.

Learning curve

An editor is not the easiest tool to master. It takes time getting used to the bindings. It will only start proving efficient once the bindings have been hard-wired to your brain.

But this is not what matters most. The hardest part will be to become comfortable at customizing the editor, that is, learning the scripting language and the editor API to make it fit all your needs. And your needs will become legions over the years.

Bindings

The venerable vi has left its mark in computer history: its modal approach has inspired many unrelated programs to use its bindings. Getting familiar with the basics of vi will help using many programs smoothly.

Emacs has generated a similar phenomenon, maybe a tad more limited. Some tools (shells, Matlab) also offer Emacs key bindings.

This had become prevalent to the point that bindings can be classified into families:

CUA are the bindings that IBM had laid down in the 1980 and that are now (2016) considered “standard”: Ctrl-c, Ctrl-v and the like. If you think that Emacs and vi go “against the rule”, note that they were first…

Switching from a keybinding family to another can be disturbing: I personally try to stick to one as much as possible. Which also means that it might be a good idea not to change the default bindings of the most common actions within Emacs and Vim. That is more a matter of personal taste though.

Versionable configuration

Last but not least, an extensible text editor means you will want to save and sync your configuration across machines. If the configuration is not saved in a versionable format, the editor is not an acceptable tool for the purpose…

Project editing

Using a text editor a programmer is often bound to managing big sets of files for each projects. This has set the need for IDEs. But not so fast. What is most needed?

Building the project? A console to run the build command will do. (Calling it from the text editor can be a plus if the error output can direct to the spurious files and lines.)

Versioning? Use your favorite interface to the VCS, there is little need for interfacing it from the text editor.

File browsing? There are efficient ways for doing that (better than just a file tree) within or outside a text editor. More on that later.

What you will need most in big projects:

Surfing the whole code base as fast as possible.

It is not only about finding files, it is about finding chunks of code. With little typing and little cognitive effort. When you write code, you actually spend a lot of time reading the existing code:

Incremental narrowing search

Above we mentioned the following thinking process: “list first, then think about what you want, then select”. This is counter-productive since you should know what you are looking for beforehand. I advocate for the following, more productive mindset: “think what you want and write it down”. This allows for a different UI approach.

The “classic” UI design bound the the former thinking process is made of lists of objects the user is looking for: file lists, buffer lists, text search lists, etc. The user browses them and picks the desired items.

Incremental narrowing search is a much more productive design reflecting the latter mindset: the list of results is filtered as you type while it is ordered by best match. The typed text needs only be approximate. Which makes it very fast to look for anything, should you know the exact name, remember part of it, or just be looking for some keywords.

Implementations of such UI designs include fzf and Emacs Helm. fzf runs from the shell, it will let you search files, shell history and so on. Emacs Helm is similar but runs for any lookup action within Emacs.

The strong point of this design is its universality: it is not specific to one action, it can be used pretty much anywhere the user can make a request with words:

Linus Torvalds on git:

It’s the content that matter, it’s not actually the files.

It is most important to be able to browse your project by content as it should not matter if a portion of code got moved to another file.

It is also a cheap way to find references: forcing exact matches with a regexp like \<name\> will make it reasonably accurate.

It is an inefficient go to definition however, which only proves useful if you don’t have any semantic analysis at hand for your programming language.

Go to definition

I used to work for a company that was working on a massive code base. On my first day I was told “disable auto-completion and all those cumbersome, slow features, then activate go to definition.” As a matter of fact, all programmers in the company were using and abusing of this one feature, almost exclusively. Since the code base was immense and the documentation somewhat lacking (don’t be surprised…), contributing to the code-base implied reading big portions of the existing code and thus going down the huge hierarchy of structures and functions.

Go to definition proved to be by far the most useful navigation function. If the code base is well written, a glimpse at the definition will give you a full understanding of the functions you are calling and the data structures you are manipulating, both from comments and code. When badly written (lacking in clarity or comments…), you can jump straight to the code to decrypt what it truly does!