What is the key to being an efficient programmer? Well, the answer is surprisingly simple. Having a setup where you can write and test your code over and over in an uninterrupted flow will dramatically increase your productivity.
The cost of doing just one more tweak to make the code perfect should be as close to zero as possible. The developer should not feel any drain when doing just one more test to ensure everything is absolutely correct. The experience should be fast and frictionless.
Instant run, change, re-run cycle
I always try to set up my development environment in a way that I can write code in one window, and immediately see the result in another. It does not matter if I am doing front-end or back-end development – I insist on having the code in one window and the result update in another window as soon as I press Ctrl+S or switch focus between windows.
I achieve this with a combination of two great developer tools:
The Entr command-line tool to restart programs automatically when files change.
find * | entr python3 demo.py
If you are working on a long-running process which does not exit on every run, such as a server app, you might want to use the
-z parameters to make Entr restart the program:
find * | entr -rz node server.js
Occasionally the workflow might need two commands, such as in this example compiling and running a demo program in C. That can be achieved with the
-s parameter along with the commands as one quoted string:
find * | entr -s "gcc demo.c -o demo; ./demo"
But what if the full development cycle includes uploading the files to a remote server? No problem, Entr and Rsync can handle that as well, and with the addition of ts you will also see the timestamps of when Rsync last ran.
find * | entr rsync -avz --delete-after * example.com:/path-to-target-dir/ | ts
Browser window auto-reload
The same principle applies to all development workflows, not just command-line stuff. For example this very blog is written in Markdown and is converted to static HTML pages with Hugo, which has a built-in command
hugo server that serves the pages locally and automatically reloads pages thanks to livereload.js.
Real-time feedback from code editor
While optimizing the code-change-compile-run cycle is the key to productivity, additional gains can also be achieved when the code editor gives real-time visual clues of what is going on and what might be an issue.
The screenshot below shows how the GCC linter in
Atom Pulsar adds a red dot to the line with an issue, and underlines the exact section on the line. A popup shows in-context information when the cursor is in the problematic function call.
In the same screenshot, note also how nicely
Atom Pulsar shows (with a yellow hint) the filename that has uncommitted changes, and inside the file we can see the lines that have changed. The dark grey communicates that a file is excluded from git tracking with
.gitignore (in this case the demo binary, as we only want to have source code in git).
What sets some programmers apart
During my career in software engineering, I’ve noticed that some coders simply have an instinct for what is too slow. While most people keep on grinding on the path they set on when trying to solve a problem, the more passionate programmers feel frustrated if their progress is too slow. An effective programmer will switch to optimize the speed of their progress – and only once they are happy with their velocity they will switch back to solve the original problem. This means they are eventually much faster at it and all future similar problems. Smart programmers have a great sense of when it is appropriate to stop the process, improve tooling, and then have the process run much faster.
Next time you catch yourself wasting time on doing something repetitive and slow, stop and ask yourself why you are doing it. A good programmer will always raise the bar for what they consider acceptable development velocity.