Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Yes indeed. Hatred of projects full of warnings is one of the hallmarks of a good programmer.

Except that it only happens in C and C++.

Why? Because C and C++ were designed to have sharp edges for you to cut yourself. The default behaviors are absolutely bizarre and stupid, and the breadth of things that are undefined behavior guarantees that any given program is non-conformant. Warnings and -Werr and linters were the only possible ways to keep any semblance of sanity and code quality.

But we're not talking about those dangerous languages and their sordid history. We're talking about the here and now and modern languages, where an unused import NEVER causes bugs, and where unused values aren't flagged as errors in any other language for good reason: we debug code far more often than we write it, and slowing the debug process for the sake of cleanliness is stupid.

And it still astonishes me how unused values are treated as errors in a language that happily allows variable shadowing that is literally one colon away (= vs :=), and doesn't allow file-level variable and function isolation. Those are FAR more dangerous and bug inducing.



Not sure, I mean there are clear workarounds for the debugging stage, before pushing into a public branch one would probably remove those the same way one would remove other ad hoc debugging code. Of course there are official reasons for this: https://golang.org/doc/faq#unused_variables_and_imports

Speaking of myself, in various programming languages both ancient and modern I've run into the situation where debugging is difficult because of hard to read code. Code written by others (or written by myself 6+ months ago) is always more difficult to read. Even more so when there are unused artefacts ("dead code").

So often it happens that people have to work under a lot of time pressure and write 300 lines for something that can be solved in 30 lines in the same language. It doesn't matter so much usually but when there is a difficult bug, sometimes the only way to solve it is to thoroughly understand the code. For me it's often easiest to just remove dead code/compactify existing code so there is less code I have to reason about.

Probably a lot of Go's design is about simplicity, its spec can be read in 1-2 afternoons if you're already familiar with the language.


Yes, the workaround for unused things is:

- comment out a line of code to check something.

- compile, get an error about unused variables because a variable is unused now that the line that used it is commented out.

- go back to the code and comment out that other line.

- compile, get another error because there's another two variables that are now unused.

- comment those lines out.

- compile, get another error because an import is now considered unused.

- repeat ad nauseum.

- Fix the bug.

- Uncomment everything you commented, and try to undo any changes you made to get around unused variables so that your code is mostly back to where it was, plus the bugfix.

- Last compile to make sure everything works.

--

I prefer this method:

- Install a custom go compiler from https://github.com/kstenerud/go

- comment out a line of code to check something.

- go test -gcflags=-warnunused

- fix the bug.

- uncomment the line.

- go test

--

This has nothing to do with the difficulty of debugging the code, or the complexity of the code you are debugging. This is about getting the compiler to stop fighting you.


I must admit it's not perfect. What I usually do is add

    _ = unusedVar
and then do the debugging stuff. Not sure why, but over time I ran into this procedure far less often but I do very pedantic error checking like

    return fmt.Errorf("foo(%v): %v", fn, err)
and putting in checks sometimes that can return custom errors. So in my log I often end up with messages like "bar: baz: foo(/data.txt): open: file not found". Debugging usually means for me replacing

    return err
with a more verbose

    return fmt.Errorf("...: %v", err)
and adding mentioned checks and/or additional log messages. Either with the log package or logrus. (And possibly adding unit tests/factoring out code into separate functions.) This gives me information content like in a full Java stack trace but in one line.

But YMMV, probably it also depends what kind of software one writes.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: