back to posts

Flow-friendly tools

Mon Feb 26, 2018 · 1803 words · 10 min

Text editor learning curves Author unknown

The personal software stack

The term “software stack” almost universally means “the technologies that a complete piece of software utilizes to run”. It’s the frontend framework, the web server, the database, the programming language. They are selected based on “macro-scale” criteria - what the company already uses, what’s popular in the industry at the moment, what will fit the project best.

However, there’s also a second stack - the “personal” one. Every programmer has their own, tuned to fit their workflow best - it is the operating system, the editor, the version control system, the window manager, the shell… The software stack is decided in the planning phase of a project; the personal stack grows with the programmmer. As they learn and develop new and existing skills, software developers tune their personal software stacks to utilize them as efficiently as possible.


There is always a clear gap between an idea and its implementation, not only in programming. Chances are, if you were to stroll into a furniture store in a foreign country, where nobody speaks your language, it would be quite a challenge to ask if they have any chairs - even though you might know exactly what a chair looks like, you wouldn’t be able to translate your thoughts into words. The same goes for software development - computers don’t speak English, at least not yet.

It is the goal of every piece of software to minimize this mental gap. In psychology, if the barrier between ideas and their execution is almost non-existent, it is said that you’ve achieved “flow” - it is a state of complete focus on a task, when your efficiency and concentration are at their maximum. In the simplest definition, an ergonomic piece of software is one that doesn’t break the flow.

Challenge vs Skill Source: Wikipedia

Ultimately, flow is based on the balance between perceived skill and perceived challenge - as long as both are kept high, our software is “flow-friendly”. How can we then influence that?

The perceived challenge is particularly crucial to understand. Making software more complex for no valid reason does not increase the perceived challenge - it increases the actual challenge in using it, resulting in a relatively less powerful tool; a tool that makes it harder to achieve certain results than other, less complex alternatives; the tool should be kept simple. To increase the perceived challenge, we want the user to feel like they’re utilizing advanced skills and features - and to make skills and features seem advanced, we should make them powerful.

Building tools out of simple but powerful features is only one part of the solution, though. We also have to consider the perceived skill.

More often than not, flow gets broken every time you have to pause your task. If you’re typing out a complex program, or a blog post, or documentation, and need to look up the signature of a function, or use a feature of your editor that you don’t remember the keyboard shortcut for, you have to pause. Minimizing the number of those pauses is achieved through learning and better software ergonomy, and influences the user’s perceived skill - which is directly proportional to the number of features they have internalized.

The learning process and internalization

The learning process has three stages:

  1. Awareness

    The programmer is aware that there is a way to easily search-and-replace globally in Vim, but can’t remember the exact command; they write it down, or google it, and start using it in their workflow.

  2. Understanding

    The programmer understands why the command works the way it does. They know that :%s/foo/bar/g means “: enter command mode, then % for every line substitute foo with bar globally”. They don’t have to google it or consult their printed-out cheat sheet anymore, and consciously use it whenever they need it.

  3. Internalization

    The tool becomes so natural to use that utilizing it is no longer a conscious effort. It becomes pure muscle memory, and requires virtually no thinking on the programmer’s part. It never breaks the flow. The user starts learning new features.

Users very rarely, if ever, learn features one at a time. We are usually learning multiple skills simultaneously, at different rates and stages. Due to that, it’s important for the tool to reuse the fundamental skills for the more advanced techniques, thus both making them more approachable, and hastening the internalization of the basics.

A tool can only be as efficient as its user; someone with years of Haskell experience will write Haskell code better and faster in Nano than a Vim guru who never used the language. However, an user can also only be as efficient as the tools they use - consider an example of someone who always takes a minute to write a line of code. Regardless of what language or editor they use, they cannot write a 600 line program in less total time than 10 hours.

We cannot improve our users, but we can give them better tools with a higher skill ceiling and lower skill floor; that way, they’re useful regardless of how familiar the user is with them.

An example of a tool with a high skill ceiling could be C++ or Vim. They’re nearly limitless in their capabilities, but take a long time to be proficient with. The user can probably write a “Hello, World!” program in C++ or navigate their way around a text file in Vim without much googling, but they very quickly run into pointer arithmetic, the heap and the stack, or motions and the command mode.

Examples of tools with low skill floors are Notepad, or even Twitter - it takes only minimal, if any, effort, to understand and internalize all of their features.

The learning curve

We cannot evaluate only those two properties, though. There’s also the learning curve. “Skill floor” defines how easy it is to start using a tool. “Skill ceiling” defines how powerful the tool is, and how many features it has. The learning curve is what describes how much effort it takes to actually use all of them.

There is no clear answer to “which curve is the best”, as long as there is one. The best learning curve is the one that matches the learning rate of the user - as long as the user’s proficiency is constant with regard to the tool’s perceived complexity, they are in a state of flow.

The goals and the means

Assuming the user learns at a constant rate, the mythical perfect tool has a zero skill floor, an infinitely high skill ceiling, and a linear learning curve.

Software we strive to write should have a skill floor as low as possible, so that it’s easy to be introduced to. Some ways to lower the skill floor are:

Some ways to raise the skill ceiling are:

Some ways to smoothen the learning curve are:

It all seems intuitive and obvious, but it’s fun to actually spend a few hours considering the ergonomy of your software from time to time.

What sparked this post? Why, GNU Make usually screams about no defined rules and refuses to do anything if you don’t tell it how to make a file, but in some cases it actually works according to some obscure predefined behavior.

Which, sometimes, is worse than not working at all.


posts · github · twitter · music · home