Interruptions and context switching are probably the two most costly things, directly impacting programmer's daily productivity. When there is no way to permanently avoid them, there are some interesting strategies to minimalize their impact.

The Cost of an Interruption

Based on different scientific studies, it takes at least 10-15 minutes to get back into the "zone" after an interruption (Parnin:10, vanSolingen:98). Depending on a task's complexity and your mental energy, definitely it can be more than only 15 minutes:

If an interrupt occurs when you have a lot of balls in the air - many pieces of unfinished code fitting together in a complex way - then returning to the flow state is harder. This concept is well known to every programmer, but probably only few heard about The Parable of the Two Watchmakers which perfectly captures all those details in writing, in an understandable form, even for non-programmers:

There once were two watchmakers, named Hora and Tempus, who made very fine watches. The phones in their workshops rang frequently and new customers were constantly calling them. However, Hora prospered while Tempus became poorer and poorer. In the end, Tempus lost his shop. What was the reason behind this?

The watches consisted of about 1000 parts each. The watches that Tempus made were designed such that, when he had to put down a partly assembled watch, it immediately fell into pieces and had to be reassembled from the basic elements. Hora had designed his watches so that he could put together sub-assemblies of about ten components each, and each sub-assembly could be put down without falling apart. Ten of these sub-assemblies could be put together to make a larger sub-assembly, and ten of the larger sub-assemblies constituted the whole watch.

The Cost of Context Switching

When context switching between complex programming tasks, it is usually more mentally challenging to return to the flow, than from a "simple" interruption. To fully switch to something else, you need to flush the cache (short-term memory) and load an entire new context. It takes time, effort and moreover, mental energy, which is finite and it's draining through the day. Those hard limitations are put in place by the human brain.

There is an exceptional book, written by David Rock - Your Brain at Work, which I highly recommend, if you are interested in improving how you spend your mental energy through the day. The gist is to treat your brain, during a deep work session, as a stage. As a session starts, you are slowly introducing essential actors (objects, tasks and pieces of information) into a scene (short-term memory aka cache). To properly light up a scene, you need to use some energy - mental energy.

Mind as a stage during deep work
Mind as a stage, during a long deep work session

When you get distracted, the entire stage collapses, and it takes some effort to rebuild it from the ground up. But there are some handy techniques to rebuild it faster.

Rebuilding The Context

For programmers, rebuilding the context after a task switch, usually means going back to an old code that was previously edited or debugged. Before editing starts, programmers navigate to several locations to rebuild the context (Parnin:10). But a task resumption can get much more painful, if an IDE doesn't remember the previous working state. That usually means:

  • last opened files,
  • cursor position (line & column) for every opened file,
  • breakpoints, watch variables and expressions,
  • bookmarks,
  • windows positions with the same layout (including tab's splits).

Rebuilding the last working state in IDE manually is usually a real pain and mentally challenging:

Losing this functionality interrupts my workflow beyond imagination. The opened documents represent a "bookmark" for me and I'm barely able to pick up work again without them.

Every time this happens (...) I am willing to put hours into finding a solution, because the thought of losing my opened document state once more after a work session is terrifying. But this time around (...) nothing of the usual remedies helps (...) This has added another 20 minutes and counting to my two hours put into solving this.

and programmers are perfectly aware of the problem:

This is a much bigger problem than it sounds as you then need to use other ways to remember what you were working on. This causes A LOT of lost time - source.

It’s so frustrating to have to keep pinning the same tabs over & over & over & over & over & over (I think you get the point). (...) My productivity goes down, and my stress level goes up! - source.

Which is why, the ability to save working state is a fundamental feature of every good IDE nowadays. But this was not always the case. Vim introduced :mksession command in the v5.2 around 1998:

A Session keeps the Views for all windows, plus the global settings. You can save a Session and when you restore it later the window layout looks the same. You can use a Session to quickly switch between different projects, automatically loading the files you were last working on in that project.

640 x 480 resolution was the standard from 1990 to around 1996. But you could get more screen real estate back then. There is a famous photo of John Carmack working on Quake using a 28-inch 1080p monitor in 1995.

John Carmack and 28-inch 1080p monitor
John Carmack and 28-inch 1080p monitor

Why did he choose 45 kg monitor for about $10k in 1995? Higher screen real estate = more code visible at once = more dense context. Productivity greatly increases when you have ability to store and access more detailed context. It is like a larger desk to hold documents when you are studying for an exam or doing any task that requires you to use using multiple sources of information from a common domain, like solving puzzles.

I still remember when I was working on my Amiga 1200 using HiRes resolution (640x256) in early 90's, coding in C using CygnusED editor.

CygnusEd on Amiga 2000
CygnusED on Amiga 2000

Only one file at a time, not so much real estate compared to my main 4K monitor these days. From a developer's point of view, the impact and progress of display resolutions on everyday productivity is huge. Let's try to define this observation:

The Law of Context Density

Larger context naturally emerges with bigger screen real estate.

The Role of Prospective Memory

Why is so important for programmers to have access to last working context? Let's start with prospective memory definition by John A. Meacham:

Prospective Memory - information with implications for actions to be performed in the future.

Prospective memory is like a sticky note posted on a fridge with reminder to buy a milk after work. Or an important document placed near an exit door, so when you will be leaving the next morning, you won't miss it.

A last working context is a form of prospective memory task, so a resumption failure is a prospective memory failure (Dodhia:05). Did you try to remember shopping list only by memorizing it? It is a nightmare, unless you know how do it properly (e. g. visualization technique). Even short list is hard to remember. We are constantly helping prospective memory by storing bits of information here and there. They act like anchors. When you are entering your (remote) office in the morning, there are visual anchors that will trigger automatically certain areas of prospective memory. Flowers waiting to be watered, a document lying on the desk that need to be processed today etc. Opening an IDE will allow another set of anchors to fire up prospective memory related tasks.

While modern IDEs can be fairly good in remembering last working state, they usually lack the ability to switch between them easily. There are few exceptions. Vim has :mksession, Emacs support sessions via different packages. Also, Qt Creator has similar functionality. IntelliJ based IDEs have task and contexts support.

Visual Studio lacks this crucial functionality, which is why I have built ContextKeeper extension. It lets you switch between working states, and also automatically switch between them, when changing git branches. Exporting contexts to different machines is fairly easy thanks to relative paths support.