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

    func TestWhatever(t *testing.T) {
        // ...lots of code

        _, _, _, _, _, _, _ = resp3, resp4, fooBefore, subFoo, bar2, barNew, zap2
    }
Like, I get it, it's a good feature, it caught quite a lot of typos in my code but can I please get an option to turn this checking off e.g. in unit tests? I just want to yank some APIs, look at their behaviour, and tinker a bit with the data.



This example isn't particularly good code. If you've got "lots of code" that names a bunch of variables (e.g. using ':=') that are never referenced AND you have a good reason not to do so (which I doubt: given this context it looks like an incomplete test), then predeclare these 'excess' variables:

   func TestWhatever(t *testing.T) {
        var resp3, resp4, fooBefore, subFoo, bar2, barNew, zap2 theirType

        // ...lots of code
   }
Alternatively, use '_' where they are being defined:

   // instead of
   resp2, err := doit()

   // use
   _, err := doit()
If, and given this context it's likely, you're checking these errors with asserts, then either change the name of the error variable, predeclare the err name (`var err error`), or split it into multiple tests instead of one giant spaghetti super test.

That said, in a code review, at a minimum, I would probably ask that these variables be checked for nil/default which would completely eliminate this problem.


This is not a piece of code I would commit, obviously! It's a piece of code in the middle of being written and re-written (and re-run, a la REPL), and constantly replacing "resp2" with "_" and back again with "resp2" is friction. Go doesn't have REPL but having a TestWhatever(t *testing.T) function is a mostly good enough replacement, except for this one small problem.


Whew, that's a relief! If I understand correctly, then I think you'll have a better experience if you practice doing something like this when writing tests:

  foo, fooErr := doit()
  require.NotNil(foo)
  require.NoError(fooErr)
  _, _ = foo, fooErr // alternative if you don't want the asserts for some reason, remember to come back later and delete though

  // ...repl churn code... 
Using the stretchr/testify/require package. This code defines both variables, gives the error a unique name in the scope, and then references the names in two asserts. You won't have to deal with unreferenced name errors in the "repl churn", so you can comment/uncomment code as you go.


The good news is if you use Nix or Guix it’s relatively easy to hack your local build of the compiler to demote the unused variables hard error to just a warning.


You know, for some weird reason, it never crossed my mind to hack the Go compiler to let me do things like that. And it's such a great idea.



Well, it's about as easy without neither Nix not Guix.


It's really not. Yes it's possible to figure out how to build and install the Go compiler, but then you have to repeat that process every time you want to upgrade to a new version. With Guix (I assume Nix is similar) you just save the patch somewhere and then run `guix install --with-patches=go=/path/to/patch go` and everything just works (including reapplying the patch on upgrade).


All of this could've been prevented if Go just had two ways to compile. Debug and release.

The go devs decided against this since they didn't want to build a highly optimizing (read: slow) compiler, but that is missing the point of developer ergonomics.


It could be prevented in an even simpler way: emitting warnings.

Most people nowadays ban building with warnings in CI and allow them during local development. But “CI” was barely a thing when go was developed so they just banned them completely. And now they are probably too stubborn to change.


The Go decision was explicitly to not have warnings, and the unused identifier thing complained about is merely a consequence of that.

https://go.dev/doc/faq#unused_variables_and_imports


As an outsider to Go, it feels to me like this basic pattern comes up over and over again in Go:

Q. Why can’t I have feature X?

A. We thought of that already, and your opinion is wrong.

Q. But basically every other language in existence supports this. And it makes development easier. We would really, really like it. Please?

A. Apparently you don’t get it. Here’s a pointer to a 15 year-old post on a mailing list where the first time someone asked for this, we said no. Your opinion is wrong.


> And now they are probably too stubborn to change.

Sounds like we agree!




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

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

Search: