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.
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.
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.
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.