News for hackers. Stuff that matters.
Re:The unreasonable effectiveness of print debugging by dmitryminkovsky on Saturday April 24, 2021 @06:22PM (#26928696)
Whenever this comes up, I think of this quote from The Practice of Programming by Brian W. Kernighan and Rob Pike [0]:

> As personal choice, we tend not to use debuggers beyond getting a stack trace or the value of a variable or two. One reason is that it is easy to get lost in details of complicated data structures and control flow; we find stepping through a program less productive than thinking harder and adding output statements and self-checking code at critical places. Clicking over statements takes longer than scanning the output of judiciously-placed displays. It takes less time to decide where to put print statements than to single-step to the critical section of code, even assuming we know where that is. More important, debugging statements stay with the program; debugging sessions are transient.

I found this lines up with my personal experience. I used to lean on interactive debuggers a lot, and still enjoy using them. They're fun and make for good exploring. But the act of figuring out where you want to print really makes you think in ways that interactive debugging cannot. I find the two forms really complement each other.

[0] https://logging.apache.org/log4j/2.x/manual/index.html

Re:The unreasonable effectiveness of print debugging by mumblemumble on Saturday April 24, 2021 @07:06PM (#26928972)
There's a part of me that wants to say that that opinion has to be taken with a grain of salt and a lump of paying attention to who is offering it.

Circa 1999, one would assume that Brian Kernighan and Rob Pike are largely drawing experience from working with C, which is a relatively verbose language. Single stepping through C code in a debugger is indeed a laborious process.

If you read accounts from Smalltalk developers, on the other hand, it's clear that they very nearly live their entire lives inside the debugger, and consider it to be an enormous productivity booster.

I would guess that there are several effects going on there. One would be that, in terms of how much effective work it accomplishes, a line of Smalltalk code is generally not equivalent to a line of C code. That has a big impact on just how many steps are involved in single-stepping your way through a region. The other is the nature of the debugger itself. Gdb and Smalltalk debuggers are wildly different pieces of software.

Re:The unreasonable effectiveness of print debugging by xyzzy123 on Saturday April 24, 2021 @07:23PM (#26929064)
Linus used to be against kernel debugging for the longest time.

The core of his position (as I understand it) was that regularly needing a debugger is a sign that your software has "gotten away from you". You've let the software get to a state where it cannot easily be understood from the architecture and program text alone.

I do think debuggers can be useful when building up comprehension - particularly of other people's software.

It's very time consuming though, and at each "trace" you're only seeing one path through the program. Good architecture and documentation lets you understand all the possible paths at once.

Re:The unreasonable effectiveness of print debugging by aszen on Saturday April 24, 2021 @08:16PM (#26929308)
I hold the very same opinion, interactive debugging in general should be a rare need.

If it's being used too often then it points to the fact that the software has to be run in order to understand it. It's representation is not sufficient to convey it's run time behaviour.

Also would like to point that dynamic languages in general require more debugging than statically typed one's since one can't be certain of the data flow within functions.

Re:The unreasonable effectiveness of print debugging by lumost on Sunday April 25, 2021 @12:36AM (#26930374)
I usually find that debuggers are more useful in dynamic languages. As an example in python many bugs are due to an incorrect structure being passed into a method due to the method or input being underspecified/abused.

In such a case it's difficult to decide what to print or more particularly how to print it if it's type/shape is unknown.

Re:The unreasonable effectiveness of print debugging by mumblemumble on Sunday April 25, 2021 @12:16PM (#26933857)
I find that it's not specifically the kind of programming language, so much as the way the data is structured. Passing around big generic heterogeneous data structures makes it harder to just reason about state. That's a lot more common in dynamic languages, but I also see it happen plenty in, e.g., enterprise Java code.

In those situations, it's often just so much easier to set a breakpoint and take a peek than it is to waste brain cycles on thinking about what exactly you should even be printing in the first place.

Re:The unreasonable effectiveness of print debugging by zamfi on Saturday April 24, 2021 @08:29PM (#26929362)
I’ve felt the same way about IDEs in general.

We need more tooling to help people understand and mitigate necessary complexity, not tools that help one muddle through or — I shudder to think — extend complexity.

I’ve changed my mind on this recently only because some IDEs have indeed become good at the latter.

Re:The unreasonable effectiveness of print debugging by dnautics on Saturday April 24, 2021 @09:15PM (#26929546)
Once you traipse into concurrency land, too, debuggers get much more tricky. You now have to consider the state of the thread you are in, plus all the others.
Re:The unreasonable effectiveness of print debugging by mason55 on Saturday April 24, 2021 @09:19PM (#26929563)
And whether the act of debugging has changed how everything works
Re:The unreasonable effectiveness of print debugging by wrycoder on Saturday April 24, 2021 @08:44PM (#26929430)
Agreed. The only time I've found a debugger useful is when the print statements aren't immediately giving clarity, and cognitive dissonance is settling in.
Re:The unreasonable effectiveness of print debugging by porknubbins on Sunday April 25, 2021 @12:55AM (#26930423)
I think its the same as cognitive dissonance but I always find debuggers help when my code appears to be doing something impossible- like I’ll be thinking how could if(true) ever fail then remember oh this whole function isn’t even getting called and I had fixated on the wrong place. Debuggers will sort it out faster than a bunch of print statements.
Re:The unreasonable effectiveness of print debugging by socialdemocrat on Saturday April 24, 2021 @10:29PM (#26929885)
I guess you could view it that way although I prefer to think of what Smalltalk developers do as living inside a REPL. And that is indeed something I can relate to. I program Julia and I basically stay in a REPL all day. But I don't regard that as the same as using a debugger. Like a Smalltalk developer, I evaluate specific functions/methods with particular values. I don't step through code. I am pretty sure Smalltalk developers don't step through code a lot.

Rather they do live changes of their code, and then evaluate various objects to verify that things work as expected. That how I seem to remember working in Smalltalk many years ago.

I am not a fan of debuggers, although I do use the REPL a lot. I suppose like Rob Pike, I used them only for very limited tasks, such as getting a stack trace or getting some sense of control flow. But as soon as I have that, I spend more time looking at code and reasoning about it, than stepping in a debugger. With a REPL I can try out assumptions I make about the code, rather than being forced to step through it.

Re:The unreasonable effectiveness of print debugging by cle on Saturday April 24, 2021 @07:14PM (#26929020)
Perhaps it has to do with dynamism? I find myself "debugging" way more in dynamic languages that emphasize interactive development. At that point, the line between running code and debugging gets pretty blurry, since "stopping" execution at some arbitrary place is not very different from normal development anyway.
Re:The unreasonable effectiveness of print debugging by craftinator on Saturday April 24, 2021 @07:45PM (#26929183)
I think this is a really good split in methodology to identify. I've noticed the same in the way I debug static vs dynamic languages. It seems to reflect the nature of the language; dynamic languages are powerful because they are fuzzy, but that comes at the cost of comprehension, and static languages tend to be the opposite.
Re:The unreasonable effectiveness of print debugging by im3w1l on Saturday April 24, 2021 @11:21PM (#26930106)
It also matters which debugger you are using and which features it has. I personally find gdb to be completely awful, while some IDE debuggers are a delightful. With Java, you can hotswap code into a running program. And you could write the majority of your program like that. It becomes an interactive experience a little bit similar to using a jupyter notebook.

You can also make a weird sort of UI this way, where the way you interact with your program is by changing the code / and or state while it's running. Breakpoints prompt for input.

Re:The unreasonable effectiveness of print debugging by ReactiveJelly on Saturday April 24, 2021 @10:41PM (#26929938)
> we find stepping through a program less productive than thinking harder and adding output statements and self-checking code at critical places.

Uh, me too. That's why I don't single-step through huge chunks of a program.

I use code breakpoints.

Re:The unreasonable effectiveness of print debugging by bc4m on Sunday April 25, 2021 @12:56AM (#26930425)
I'm getting the impression a lot of people don't know basic debugger features like "continue" or setting breakpoints while paused at a breakpoint.
Re:The unreasonable effectiveness of print debugging by zoomablemind on Saturday April 24, 2021 @09:59PM (#26929740)
In a way, the print-debugging is a sign of 'owning' the code, when a developer is very much familiar with the structure and internal works of the project. This is akin to surgeon precisely pointing the scope and scalpel.

Add to this a need to build a debugging-enabled version of the project - an often long-running process, compared to a few edits to some 'release' build.

On the other hand, when dealing with an unfamiliar or complex and well-forgotten project, debuggers become that discovery and exploration tool that offers a wider context and potentially better situational awareness.

Of course, mix-in some concurrency and either debugging approach can equally become cumbersome without proper understanding of the project.

Re:The unreasonable effectiveness of print debugging by galangalalgol on Saturday April 24, 2021 @10:13PM (#26929808)
I still resort to gdb, but mostly when I need memory access breakpoints for when someone (occasionally me) stomped on memory.
Re:The unreasonable effectiveness of print debugging by ab111111111 on Saturday April 24, 2021 @11:59PM (#26930259)
I think the Key phrase from that quotation is "thinking harder". A debugger gives you all of the programme's state as a kind of vast animation, so it's easy to start working with one thinking "Something's going wrong here, so I'll just step through the whole programmme and see when things start looking like they're going wrong". It's then easy to miss the problem due to the vast quantity of data you have to parse. Using print statements, in contrast, forces you to formulate simple hypotheses and then verify or falsify them, e.g. "I think this variable in this function is causing the problem" or "I think everything's fine with the execution up to this point". I.e. the very fact that a debugger works so well at giving you an insight into how the programmes state can itself be part of the problem: it can be overwhelming.
Re:The unreasonable effectiveness of print debugging by bc4m on Sunday April 25, 2021 @12:53AM (#26930416)
Why would one step through the whole program? Use the approach you describe for print statements, but for breakpoints instead. Set them, inspect the relevant state when one is hit, then resume execution until the next is hit.
Re:The unreasonable effectiveness of print debugging by fauigerzigerk on Sunday April 25, 2021 @03:25AM (#26930971)
Why would I do this manually using some fiddly UI instead of automating it using the programming language I already have at my fingertips?

Using the programming language itself, I can extract exactly the information I need to see, transform it into exactly the shape that's easiest for me to inspect and combine output from different places in the code to create a compact list of state changes that's easy for my eyes to scan.

What I have found is that my debugging problems are either too simple to require anything more than thinking or too data dependent for a debugger to be the best tool for the job.

Re:The unreasonable effectiveness of print debugging by wonnage on Sunday April 25, 2021 @12:01AM (#26930264)
The Chrome devtools make adding a logpoint as easy as setting a breakpoint. So instead of adding your print statement, and rebuilding the app you can do it live. I think this is strictly better as you still get to enjoy the mental exercise of deciding where to put the logpoint. Even better, you can run anything you want in a logpoint, my favorite is console.profile/profileEnd() to get a cpu profile between two lines of code.
Re:The unreasonable effectiveness of print debugging by neonological on Sunday April 25, 2021 @03:02AM (#26930879)
There's another methodology that Brian and Rob Pike miss.

Rather then stepping through a program. Add breakpoints and just step from breakpoint to breakpoint.

With a good IDE, adding a breakpoint and hitting a shortcut key is faster than a print statement and on the GUI IDE your debugging sessions are not transient.

The only time their advice makes sense to me is when I'm in an environment without a gui. Even then jetbrains has a "ssh full remote mode." However at my company I have found that this feature doesn't work under Nix (nix-shell) so we all just use print statements.