In Defense of Print()
Software developers love to rag on each other for not doing things properly and not getting things done right. This might make sense when we want our codebase to be adequately tested, but it might also degenerate into a game of one-upmanship where we try to make others feel inferior. A great example of this is bashing on those using light mode, and another is using print logging as a debugging tool.
Except in the case of print debugging, it’s actually one of the most effective tools in your software engineering toolkit.
Premature Optimization?
I get it.
As software engineers we are used to judging others in our field, and we look at the tools developers use as a simple yardstick to measure their skills.
Yet when we look at the tools for debugging available to us, we might pick “time-travel debugging”. Yet the last thing you need when you’re trying to solve a *complex* problem in development is setup time for your debugging sessions.
You might simply need immediate feedback in order to perform a sanity check on that bug. A simple print log can quickly provide an answer to a question you have about your code, while avoiding the overhead of fancy tools.
Keep It Simple Stupid (KISS). Use the simplest tool that will get you the answer you need rather than complicating your software engineer life.
I don’t care how powerful your debugger is when all you need to know is Did this function get called, according to these conditions or what is the value of this variable, when this other variable is set? The overhead of configuring breakpoints can (if you’re me) provide an obstacle to getting to a solution (and force you to forget what you were doing in the meantime).
The Stigma
KISS is a well-known principle in software engineering. So why is there a strong stigma around using print debugging to solve your production defects?
It’s simple, and that’s because the problem with print debugging is exactly the same reasoning as to why I use it. Print debugging is universally available and straightforward. No configuration, IDE plugin or pair programming required. It’s just a developer, their code and the output.
I’d argue that the strongest developer knows the tools available and when to use them. The print statement is one of them, and there are plenty of situations where using print is the right thing to use to solve a particular problem.
When to Use Print Debugging
Print debugging isn’t just about throwing random output into your console and hoping that it works. This is actually an art form if you do things right.
Here is a collection of times when using print debugging is the right move in order to solve a problem.
Quick sanity checks
If you’re unsure whether a block of code is being executed, adding a simple print (“Reached here”) can immediately confirm it.
Simple value tracking
Need to know what a variable’s value is at a specific point in the code? Throw in a print(variable) and you’re done. No need to inspect watches or set conditional breakpoints.
Debugging in restrictive environments
When working in minimal environments — think Docker containers, remote VMs, or embedded systems — your fancy tools may not be an option. But print()? It’s always there for you.
Production fixes
Sometimes you have a bug in production, and you can’t attach a debugger. A strategically placed log or print() can help you diagnose the problem in real time without disrupting the system.
Complex debuggers are too slow
When you just need to make a quick check without navigating all the steps to attach a debugger.
Conclusion
Working as a software engineer should mean we choose the right solution for any given problem. It’s not a sign of weakness to use a tool available to you.
Going simple isn’t the right solution for absolutely every problem. Equally fancy over-engineered solutions are not right for every problem. The best tool for any particular job is the one that gets the job done quickly and efficiently, and sometimes that tool happens to be print.
So, feel free to print log test and take down that bug. You have my permission.