24 ms·
The most frustrating thing for me, by far, is that Go won't let you import unused packages. When you are commenting stuff out to debug a program, or adding debu
by twblalock 10y ago
The most frustrating thing for me, by far, is that Go won't let you import unused packages. When you are commenting stuff out to debug a program, or adding debug statements and removing them later, it constantly requires you to go back to the top of the file and comment out the unused libraries, only to uncomment them later when you've solved your problem.
The fact that there is not a compiler flag to disable this behavior, and that the core team is opposed to adding such a flag (https://golang.org/doc/faq#unused_variables_and_imports https://golang.org/doc/faq#unused_variables_and_imports), is simply ridiculous and makes programming in Go a real pain in the ass.
I can't think of any other language that does this.
- Sean1708 10y agoI think that's the thing that really gets me about Go. I really like that it's opinionated and forces you to write good code, but I just can't understand why they refuse to allow you to turn them off when you need it. Also doesn't that workaround completely nullify all the arguments they made in that section? And it puts the programmer in a worse position than if they could just turn it off temporarily.
- jerf 10y ago"I just can't understand why they refuse to allow you to turn them off when you need it." The answer to this and a lot of similar such questions about Go is "scale". Things that were sorta kinda convenient for you in a couple hundred lines become nightmares when several dozen developers on several hundred thousands lines of codes had differing ideas of what was convenient for them at the time. Just as you can't understand Erlang until you understand its emphasis on reliability, you can't understand Go until you understand its emphasis on coding at scale. Almost (but not quite) everything people can't understand about Go are things that people want to do because they work well locally, but things that have become serious problems in source code bases at scale. You also can't understand Go until you realize that the problems weren't merely hypothesized, but extracted from real already-existing source code bases. That said, I still feel they missed some steps. I'd like non-nil-able pointers. (Optional, like C#, because the way Go methods work means that if you're careful nil pointers of a certain type are perfectly legal and can have sensible methods on them, but that's not always the case.) Packaging is another obvious case where Google had an answer that worked for them so they didn't see a problem, though that's being worked on. (I'm struggling through this because I consider it a non-negotiable feature that my packaging solution allows me to locally mirror everything I use, which all packaging systems (not just Go!) seem to consider some bizarre use case. Strange, I consider it a basic requirement for truly professional development.) So bear in mind I don't mean this necessarily as a defense of Go, I'm talking about what it takes to understand it. (Edit: also, yes, I consider it a bit sad that Go doesn't have iterator support, per my comment at https://news.ycombinator.com/item?id=12210351 https://news.ycombinator.com/item?id=12210351 You can sort of bash some stuff together, and io.Writer and io.Reader cover a common case for Go programs and can be composed, but it's still a bummer.) It is completely the case that some people will come to a greater understanding of Go, and realize it's the wrong choice for their problems. But perhaps it will, at the very least, be less threatening that other people do consider it a good choice for their problems.
- andrewfromx 10y agoi was shocked by that at first too. Then I came to love it. It's sooooo go. Don't import stuff you aren't using. Don't declare a var and just leave it there un-used. When I go back to ruby and commit that crime, I see why golang did what it did. There's something magical about a golang program that will compile without error. It's worthy of checking in to git. And months later, there will be no unsed imports FOR SURE.
- greyskull 10y agoWhat about just really obnoxious compiler warnings that can't be disabled?
- wruza 10y agoStockholm syndrome in action. There are two phases: active development and release engineering. -Wall for former, -Wextra -Werror for latter. If someone is not disciplined enough to throw out unused variables/imports/whatever from release, Go will not save him from hell.
- sagichmal 10y ago> There are two phases: active development and release > engineering. For you, perhaps. Go encourages you to think about your problem and develop it in the "release engineering" style from the very beginning. This is a virtue of the language, in my view.
- kennymeyers 10y agoCan't you just also comment out the package import declaration?
- aleksi 10y agoYou may want to configure your editor to use goimports: https://godoc.org/golang.org/x/tools/cmd/goimports https://godoc.org/golang.org/x/tools/cmd/goimports
- dmoy 10y agoI think it depends on what you're using it for. On my day-to-day I'm working with absolutely massive pieces of software that have dependency trees that would literally make me cry if I stopped and thought about it too hard. In that world, this sort of thing enforced strongly makes me much happier. For random one-off hacking, yea, it'd be a pain. Differing use cases lend cause to different tooling.
- junke 10y agoPeople are ok with compilers telling them what is wrong, they complain that Go wants to control when you fix the problem: "fix that import NOW, bad developer" is not opinionated, it is stupid. > Differing use cases lend cause to different tooling. What?
- dmoy 10y agoBy differing use cases: If you're messing around with your own test code, it's fine if your compiles get slower, etc. On the other hand, if you're writing code that thousands of other engineers are immediately going to depend on, it's better if you're not allowed at all to make things slower via unused imports. True, if you could globally mandate the use of a lint/presubmit rule disallowing unused imports, that would also work. But, that's a harder swing.
- junke 10y agoMy reaction to "differing use cases lend to different tools" was that tools and especially languages often accommodate multiple, sometimes contradictory use cases. I am not writing code that thousands of other engineers are going to depend on. A company that requires this can enforce methodological rules. Go is supposed to be used in different contexts, not just Google, right?
- AnimalMuppet 10y ago> > Differing use cases lend cause to different tooling. > What? Different needs, different languages. I write 100-line scripts in Perl that rip apart text files and extract the bits I want. I don't write 100,000 line embedded systems in Perl.
- JonnieCache 10y agoI use an editor plugin that adds and removes imports automatically. It works very well. https://github.com/DisposaBoy/GoSublime https://github.com/DisposaBoy/GoSublime
- aleksi 10y agoIt uses goimports for that.
- treigerm 10y agoI use an Atom extension called "gofmt" which automatically calls goimports[1] every time I save. So any unused imports will be removed and if I start to use new imports that are in my GOPATH or the standard library then it automatically adds them. [1] https://godoc.org/golang.org/x/tools/cmd/goimports https://godoc.org/golang.org/x/tools/cmd/goimports
- millstone 10y agoHow does that work with undo?
- buro9 10y agogoimports guesses the one you want and adds it back.
- millstone 10y agoMy question was, since goimports modifies your document (and gofmt even more so), is your undo stack preserved across saves? If so, how?
- buro9 10y agoThat's a question for your text editor. I use Sublime Text 3 with GoSublime and have noticed that the undo stack is just my changes (makes sense, the goimports is an external process), but that's cool because any CTRL+S is going to trigger goimports and so the correction of the imports is invisible and always there.
- _asummers 10y agoIn Eclipse, this is true. The import was considered an "action" that got put into your undo stack. It was just triggered by the editor, not you.
- Leon 10y agoI believe it has worked well for me for undo. However some other Atom formatters have broken my undo in weird ways, namely the formatter for Node JS I had turned on to auto format on saves. I had to turn it off.
- mseepgood 10y agoI use goimports.
- tptacek 10y agoI used to feel this way. It was my top complaint about the language. But it, and, more importantly, the use requirement for variables, has saved me from bugs repeatedly; I more and more notice the bugs it's protecting me from as I keep coding in the language. I am rapidly coming to the conclusion that this was very, very much the right call. I get the sense that most Go programmers use "goimports" to work around the annoyance. I have my Emacs configured to use it automatically. I never even think about imports anymore.
- millstone 10y agoOftentimes when I write in Go, I'll produce an unused variable as a side effect of commenting out code as a debugging experiment. What would you think about Go issuing a warning instead of an error in this case? Also, if goimports solves import issues, why isn't it just built into the compiler?
- tptacek 10y agoIt doesn't work as a language feature, because it's not precise or perfect. Package references can be ambiguous, and need to be overridden. It works extremely well as a tool though.
- xyproto 10y agoThis is a problem specifically about commenting in and out code. The IDE should comment in and out imports accordingly.
- bluecalm 10y ago>>But it, and, more importantly, the use requirement for variables, has saved me from bugs repeatedly; So how is it better than C where you get a warning (at least from GCC) that you have unused variables? You can quickly test things and you are coming back to fix all the warnings later anyway.
- tptacek 10y agoYou get warnings for lots of things in C. There's no getting around the use requirement in Go, at least not without crudding up your code.
- eloff 10y agoBikeshedding much? I can't see this being a real problem. There are a lot of other decision that the Go team made, for better or for worse that have much greater effects on real code. Unused imports is a joke. var _ = unusedImport Or use goimports. Then you don't even have to think about it.
- oolongCat 10y ago>Then you don't even have to think about it. Can't agree with that. We once had an issue with our code because someone had made a copy of his code base and goimports was importing an older version of a library. Yes definitely this is something the programmer could have prevented. BUT! "not think about it" is not really true.
- eloff 10y agoOk. Effectively don't have to think about it 95% of the time then. Close enough.
- philh 10y ago(I've never used Go, so please correct any errors.) > var _ = unusedImport This is what the devs suggest as an alternative to having a compiler flag to turn off the check. But with a compiler flag, I can easily discover the unused import when I build for production, simply by turning that flag off. By using the variable in a dummy way, I need to remember to go back and check for such things. Presenting this as a way to address the problem feels like it's missing the point.
- themihai 10y agoIn practice you don't really have this problem. It's a beginners issue thst's not worth "fixing" because there are tools that can help(goimports). I'm glad there are not such compiler flags.
- hueving 10y agoGoimports doesn't help when the name is ambiguous. >I'm glad there are not such compiler flags. Because if they were there people would force you to use them? Or are you just unhappy that people could have a different debugging workflow than you?
- gkya 10y agoI really would like to see what happens when somebody forks go to create a sort of Go++ (tm) which, while still compiling code written for actual Go, didn't strictly prohibit unused variables and imports but only issued warnings and, added function templating as a means of generics. Regardless of whether these are good ideas or not to have in Golang, it'd be interesting to follow how the community orientates itself in time.
- mulltiq 10y agoWell, there's Oden experimental language that compiles to Go, but it's Haskell inspired (even written in Haskell itself) https://oden-lang.org https://oden-lang.org
- m_sahaf 10y agoEveryone else is suggesting goimports, but here's another trick: import _ "unused/package" This is usually used to benefit from the packages' side-effects (e.g. trigger init() - mostly used in SQL drivers to register the driver).
- aleksi 10y agoBut then you have to remove blank identifier to actually use package.
- _ak 10y ago> The most frustrating thing for me, by far, is that Go won't let you import unused packages. If you want to explicitly import unused packages, you just prefix it with `_`, like this: https://play.golang.org/p/ltfQgco22t https://play.golang.org/p/ltfQgco22t Remove the `_` in the import of `crypto/rand`, and the program won't compile anymore.
- wtbob 10y agoMeh, I just have emacs configured to run goimports on save, right along with gofmt. I never even worry about, unless I have to resolve which of two packages with the same final name component I'm using. That can be a bit annoying, but it's not terrible. Back when Go had insanely great compile times, it was worth it. Now that compile times are … okay … it's — okay.
- kmiroslav 10y agoIt's a simple reflection of the fact that the Go creators have never used a modern IDE. Anyone using a modern IDE pretty much never even thinks about imports, which are (and should be) automatically managed by the tool, not by the programmer.
- fishnchips 10y agoThis statement is probably true but that's kind of irrelevant. IMO it is actually a virtue of the language if it is perfectly usable without a modern IDE. Contrast that with Java and you'll see what I mean. Go follows the Unix philosophy where things like imports or formatting can be supplied by any external tool. If you wish to bundle all these small tools into a single IDE you can do it, too.
- kmiroslav 10y agoEverything is perfectly usable without an IDE, you are just more productive with one than without one. Regardless of the language. In this particular case, the IDE could automatically remove the imports when you remove the corresponding symbol from your source, or automatically add the import when you introduce a new symbol. The "can be supplied by any external tool" is a cop out that was acceptable in the 20th century but this is 2016, we have a higher bar for developer productivity.
- fishnchips 10y agoNothing about the language or its tooling prevents you from building such an IDE or a plugin to one of the existing IDEs. And there is absolutely nothing in Java that makes IntelliJ so awesome. These things are totally orthogonal. What I like about Go's tooling is that it allows good plugins for various text editors (eg. Sublime or Atom) to be implemented with relatively little effort.
- kmiroslav 10y ago> Nothing about the language or its tooling prevents you from building such an IDE or a plugin to one of the existing IDEs. And there is absolutely nothing in Java that makes IntelliJ so awesome. These things are totally orthogonal. No, they're not. There are a few necessary conditions for this kind of symbiosis to work well: - The language has to be statically typed. Without type information, the IDE is completely blind and can barely help you at all without human supervision. - The IDE has to be written on top of the same runtime as the language it's editing. This is what makes Eclipse/IDEA and Visual Studio so spectacular: they understand the bytecode they are working with. These are necessary conditions but they're not sufficient. You can still write crappy IDE's if these conditions are met, but thankfully, IDEA/Eclipse/Visual Studio are technical wonders that multiply the productivity of their users. For example, in Go, the simple action of selecting the the surrounding expression simply doesn't exist anywhere. It's the most basic automatic action that's trivial to do with the proper language and IDE, and yet nonexistent in Go. Along with tens of others. That's the price to pay when a language is designed without any consideration for its tooling nor basic things we learned about language design these past twenty years.
- scott_s 10y agoNot allowing the import of unused packages was an explicit design goal intended to reduce compile times. Cribbing from a comment I made years ago: Take a look at this adaptation of a keynote talk on the design of Go, with the title "Language Design in the Service of Software Engineering": http://talks.golang.org/2012/splash.article http://talks.golang.org/2012/splash.article Section 7, "Dependencies in Go" addresses this issue: http://talks.golang.org/2012/splash.article#TOC_7 http://talks.golang.org/2012/splash.article#TOC_7. The relevant paragraph states, The first step to making Go scale, dependency-wise, is that the language defines that unused dependencies are a compile-time error (not a warning, an error). If the source file imports a package it does not use, the program will not compile. This guarantees by construction that the dependency tree for any Go program is precise, that it has no extraneous edges. That, in turn, guarantees that no extra code will be compiled when building the program, which minimizes compilation time. Further, the talk justifies this approach through their analysis of how their C++ codebase was compiled: The construction of a single C++ binary at Google can open and read hundreds of individual header files tens of thousands of times. In 2007, build engineers at Google instrumented the compilation of a major Google binary. The file contained about two thousand files that, if simply concatenated together, totaled 4.2 megabytes. By the time the #includes had been expanded, over 8 gigabytes were being delivered to the input of the compiler, a blow-up of 2000 bytes for every C++ source byte. As another data point, in 2003 Google's build system was moved from a single Makefile to a per-directory design with better-managed, more explicit dependencies. A typical binary shrank about 40% in file size, just from having more accurate dependencies recorded. Even so, the properties of C++ (or C for that matter) make it impractical to verify those dependencies automatically, and today we still do not have an accurate understanding of the dependency requirements of large Google C++ binaries.
- PopsiclePete 10y agoThere's at least one tool to help with that, maybe even more. I have never, not once, manually removed an unused import in the last year of Go programming. Basically, as soon as I save my file, it gets formatted, linted, unused imports are removed, the project is then compiled and unit tests are ran. I couldn't be happier.
- tekknik 10y agoThis also infuriates me (more-so the "know-it-all" attitudes of the devs). What's even more infuriating is how simple of a change this is. It took me about 15 mins to change the compiler, adding compiler warnings and producing a warning instead of an error on unused imports and vars.