Good, sharp tools (programming toolbox — part 2)
Recently, I got myself safety razor. I've been eyeing those ever since I found out that they are not patented (and thus free from monopoly pricing), so when a friend pointed me to a store that sells them, I had to get one. (For the uninitiated, safety razors are shaving tools that hold a super sharp razor blade securely, and have a metal plate that helps hold the blade at the correct angle for shaving.)
And, I must say... compared to the electric shaver I've been using for the past few years... there can be no contest. The safety razor is so much better. Not only am I getting a cleaner shave for less time spent, I also get no surprises due to tools running out of battery, and end up paying a lower price overall (even when considering shaving cream).
The only downside is that I need to stay focused while shaving, to not accidentally cut myself.

And that experience got me thinking again about tools and toolboxes again.
I like my toolbox to have sharp tools.
And that's normal. As common counter-intuitive wisdom goes, a sharp blade is often much safer than a blunt blade. The sharp blade directs force precisely where you want it, rather than redirecting in all directions, and thus is less likely to slip out.
And safety razors, like a lot of my programming tools, have really sharp edges.
Yet, I also like my sharp tools to be safety-conscious. I want to be able to use them safely with a bit of caution, even if they are not "idiot-proof".
That's similar to how the safety razor's head protect you from the sharp blade during normal usage, even though it's likely you would get a mild cut if you as much as hold a the tool wrong. And likewise, other sharp tools have extra buffering of protection around them; sharp kitchen knifes have cutting boards, with many tools you aim to cut away from yourself, there are no-cut gloves, and so on.
In that sense, what I would term a good sharp tool isn't glamorous—it might be shiny, but that's the edge, not extra fluff around it. Good sharp tools aren't necessarily intuitive, and they won't act on guesses. Instead, they are precise, doing exactly what you direct them, even if it's wrong.
Yet, good sharp tools aren't footguns. They don't randomly cause a lot of damage far away from where you use them—that's not what precise means.
For my own programming toolbox, I have a few tools that are rather sharp. Yet, I leave the unsafe, sharp ones out.
Here are a few examples:
ImageMagick
ImageMagick is an extremely versatile suite for modifying, converting, resizing, combining, and otherwise manipulating images from the command line. Especially converting.
And I love using it; it is a good sharp tool.
It doesn't come with extra safety features. A bad command line will happily clobber existing files, possibly even the files it's currently reading. However, it doesn't touch files you haven't told it about, so it safety-conscious. As long as you back up yous files, it won't damage them.
The habit I have when working with ImageMagick (and similar tools like FFmpeg) is that if I'm unsure about what a command line would do, I run it in a empty folder, into which I've copied all the needed files.
That way, if something is wrong and I do overwrite a file, I still have the copy elsewhere—and there are no extra files for a runaway *
wildcard to chew up.
And that habit helps a lot. I've yet to lose a file to ImageMagick or FFmpeg.
sed
sed
is a file/stream editor based around regular expressions and short scripts. It is also one of my most-used commands—I find it extremely useful for turning outputs from one command into inputs for another, since it provides many ways to adapt one stream of text into a slightly different format, or to extract pieces of text as needed.
It is also rather sharp. Documentation is terse, tutorials hardly better, and you end up learning most of the features while you use them. Intuition doesn't always work, so double-checking helps a lot.
sed
can be made to overwrite files if you use the -i
(in-place) option, but even that comes with an built-in safety mechanism, that lets it create backup files with e.g. -i.bak
. Yet, I usually don't use that.
Instead, most of times, I end up using sed
with xargs
, since the latter lets me reuse the lines produced by sed
as arguments for the next command.
For example, if I wanted to copy a bunch of files into a subfolder (e.g. to use them with ImageMagick), I might do something like the following:
mkdir _/
# Safety: run and inspect the copy commands generated:
ls ./*/*.png | sed -E -n 'p;s|^./|_/|p' | xargs -n 2 -- echo cp
# outputs, e.g.: cp ./aaa/bbb.png _/aaa/bbb.png
# cp ./aaa/bbb2.png _/aaa/bbb2.png
# Actually run it if it looks good:
ls ./*/*.png | sed -E -n 'p;s|^./|_/|p' | xargs -n 2 -- cp
# Note: pass -d '\n' to xargs if you have filenames with whitespaces
In this case, the safety does not come from something special sed
does, but from the echo
I pass to xargs
, which ensures that I see all of the commands that I'm about to run before I actually decide to run them. (echo
is just a command that prints everything that comes after it).
dd—not in my toolbox
dd
is a command for copying data between files, with many options for copying only a certain number of bytes, skipping parts of files, or truncating files.
The reason I don't want it in my toolbox is that it is a really sharp, with nearly no safety features.
It comes with an unfamiliar command line that doesn't match anything that other commands use, so I can't inspect it. Crucially, the difference between the input file and the output file, if=
vs of=
, is easy to miss.
It is sometimes given as an example for writing blocks of data to the raw hard disk itself, and that just cements it as a scary tool to use, given the risk of messing up the filesystem.
And finally, there are a lot of other, less-scary, tools I can use to copy parts of files as need, such as cat
, head
, and tail
.
Rust—in my toolbox
Rust is a recently-developed systems programming language, that takes a lot of inspiration from functional programming languages, yet sticks to an imperative structure. It is currently in the process of rapidly taking over the industry due to all its safety guarantees.
And I absolutely enjoy using it. Even when I end up fighting with the compiler, once the code compiles, Rust gives me a peace of mind that I won't get any major crashes from my code.
Compared to the most-popular systems programming language out there, C, Rust is just as "sharp" in terms of features and speed. Yet, C is notoriously unsafe, and it is very easy to accidentally cause the whole system to malfunction because of a small mistake when freeing/allocating/reusing memory. Meanwhile, Rust forces you to carefully describe which parts of the code are responsible for which parts of computer memory.
And that makes Rust a good sharp tool to include in my toolbox.
Conclusion
Through the examples in this article, I hope I've introduced what I would consider a good sharp tool—a tool that is:
- Precise, doing exactly what has been requested of it
- Capable, being able to deliver in a wide variety of circumstances
- Safe, not putting the user at unnecessary risk during normal operations
- Professional, designed for use not as much for first-time users, but for people who take the time to master it,
- Yet, sharp, a tool that doesn't go out of it's way protect the user from all possible harm, just from the most obvious one.
Without getting much into politics, it feels like companies keep marketing a lot of bad, blunt tools. Supposedly, such tools are "easy to use", "feature-packed", "smart", "beginner-friendly", "idiot-proof", "intuitive", and the like, you name it. But often, such tools make for great demos, yet fall apart the moment you use them for a real project. The "easy to use" tool is easy only when you follow the steps exactly as written, the "feature-packed" app lacks features that let you connect it to other apps outside of a narrow pre-designed set, "smart" features are smart only inasmuch as you use them to solve easy problems. "Beginner-friendly" ends up not equipping you to solve non-beginner problems, but leaves you stuck in the basics; "idiot-proof" means you don't get to understand how it works and thus remain ignorant, "intuitive" blames you for failing.
Supposedly, those bad, blunt tools are a way through which everyone can become a craftsman. (And when everyone is a superhero... 😅)
But, I personally prefer having good, sharp tools in my toolbox instead. With them, I can do anything, if I take the time to master the skills. And as I master my tools, I know I am becoming an even better craftsman—because they encourage me to grow closer to the craft.
This has been my 8th post of #100DaysToOffload. Given the date, I should be on my 11th post already, so I am running a bit behind... but I have been stocking up on drafts that just need a bit of editing to publish. Stay tuned! 😁