Comments like this are not the problem with HN.
The fact that they get voted, literally, to the top, is.
Comments like this are not the problem with HN.
The fact that they get voted, literally, to the top, is.
And it'd often be quite a simple logic bug that I could see straight away.
Regularly using logging for debugging is often an inexperienced developer's crutch. It's a red flag, the sign of the desperate, that they can't comprehend their own code or don't seem to understand the business logic.
It can be a bad substitute for replicating the problem, reading the code + using a debugger.
Sometimes it really is justified. The author seems to have relied on it a lot though.
Like in the situations in the article. That's why the comment in question is not just blunt. It's a bad comment.
A good comment would take a specific instance of using logging and said why setting a breakpoint / using a debugger would have solved that particular mystery faster.
NaN bug doesn't sound like it needed logging
Mutability bug doesn't sound like it needed logging
Dependencies and versions bug doesn't sound like it needed logging
The Documentation and versions bug doesn't sound like it needed logging
Obviously we're not seeing the whole picture or the whole bug. But that's 4/5. Most of those sound like they needed a simple step-through.For example, in the documentation and versions async.js bug, he added "extremely verbose" logging where it appears that a simple step-through would have immediately revealed to him the passed arguments were wrong and the signature of the method didn't match the documentation. Which would have made him realize he had the wrong version.
The only one where I would expect to have to use logging is the tests bug.
Even after you've read the code and think you've spotted the problem, you should step through to 100% confirm you've understood the problem.
It's simply confirming the bug and the solution, it's good science, it's good practice. It's empirical.
Even in those scenarios, I rarely have to look at live data, reading the code is often enough to identify it or playing around a little bit. The patience to replicate a bug before trying to fix it.
This is the essence that sets apart a good debugger from a bad one. A bad one resorts to littering the code with print/log statements because either they can't replicate the problem or they simply can't run the code in their head.
I'm being unfair, it's not even that, they simply need more experience. When I was younger I remember complaining that exception stacks were utter gobbledigook, utterly useless. Now, I read one and often know exactly what the bug is. I was completely and utterly wrong, impatient and unwilling to admit my ignorance. At the time I thought I was wise and knowing. They're very useful, I simply didn't understand them.
My "simply" from above belies the years of experience I have.
I have had times when I used a debugger and then realized I was never going to find the problem that way; I needed a larger amount of information that only logging could provide.
I've only been programming about 30 years so I probably haven't hit my peak yet, but my guess is that even with more experience I'll still want to use both tools.
Debug logging doesn't have to be litter either. Instead of commenting out use log levels like with https://www.npmjs.com/package/debug-logger
Because 17 years ago, I had this same naive development workflow. With PHP, exactly as OP mentioned.
Whenever someone mentions static typing, the canned response from JS developers is "Oh, haha, we actually have unit tests for this" (usually accompanied with a patronizing smile for the obsolete waterfall programmer). Yet when dealing with a real world dynamically typed application from some mediocre company, there are (surprise) no unit tests at all.
I think the best compromise is optional typing. The language should encourage it by default, but allow some variables to be declared as dynamic/untyped. This greatly simplifies things like parsing of JSON data, which should essentially all be considered a string until there's some reason to consider it something else, but enforces consistency and safety through most of the application. Haxe does a pretty OK job with that.
Like C#'s dynamic keyword (not to be confused with its var keyword, which just does type inference).