News for hackers. Stuff that matters.
Re:I Love Go; I Hate Go by tptacek on Tuesday August 02, 2016 @02:40AM (#12208174)
I 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.

Re:I Love Go; I Hate Go by buro9 on Tuesday August 02, 2016 @02:57AM (#12208242)
> 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.

You haven't yet encountered clashing names?

https://golang.org/pkg/crypto/rand/

https://golang.org/pkg/math/rand/

Or?

https://golang.org/pkg/text/template/

https://golang.org/pkg/html/template/

goimports is wonderful, but some care is needed to make sure it has added the one you intended to add.

NB: Only an issue when new imports are added, not an issue if the correct package is already referenced.

Re:I Love Go; I Hate Go by zenlikethat on Tuesday August 02, 2016 @10:25AM (#12210151)
The minor inconvenience of occasionally having to fix a path when goimports picked the wrong one is far outweighed by the massive convenience it brings me every day.
Re:I Love Go; I Hate Go by donatj on Tuesday August 02, 2016 @10:08AM (#12210020)
I have been using it since I switched to VSCode about 4 months ago and thus far, knock on wood, it's always found the one I intend. I however do think it considers what public members/methods you are calling.
Re:I Love Go; I Hate Go by buro9 on Tuesday August 02, 2016 @10:29AM (#12210193)
"considers"?

It just finds a match and goes with it, and that does cause issue. Both of the above have potential security implications.

Filippo suggests preferring crypto/rand over math/rand as a softfix in this twitter conversation: https://twitter.com/filosottile/status/752210041709719552

I'd probably prefer html/template over text/template as it's better to have someone ask why their output was HTML escaped than to have someone render HTML in plain text without explicitly wanting to do so.

Re:I Love Go; I Hate Go by Someone on Tuesday August 02, 2016 @03:05AM (#12208267)
"But it […] 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 […] 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."

If you don't think of imports anymore, how can they save you from bugs?

(I do (somewhat) understand the "more importantly, the use requirement for variables" part, but also there, I think a warning should be sufficient. Your editor could/should color-code dead code, anyways, making it stand out before you compile)

Re:I Love Go; I Hate Go by jerf on Tuesday August 02, 2016 @09:24AM (#12209725)
The use requirement for variables saves him from bugs, goimports fixes the problem with required use of packages. It's separate.

The requirement that packages aren't used isn't to prevent bugs, it's to prevent packages from claiming spurious dependencies that you're then too afraid to remove. Or, in the case of a static language like Go, don't want to take the time to remove one-by-one and see if the compilation breaks. I deal with this problem in Perl where, basically, in a source code base that's been developed now for over a decade you have no idea whether a given module is actually used in the code, and it could be pulling in a whole bunch of other stuff very confusingly. The problem is less acute in Go to start with, but it's still nice to be able to rely on the imports being accurate.

Re:I Love Go; I Hate Go by Someone on Tuesday August 02, 2016 @03:47PM (#12212756)
"It's separate"

I don't think I misquoted the OP. He said "A and B help me with C" and I questioned how A could help with C, given the other claim that the OP doesn't pay any attention to A anymore.

"Or, in the case of a static language like Go, don't want to take the time to remove one-by-one and see if the compilation breaks"

That is a problem with perl, a language whose 'grammar' is about as free-form as it gets (aside: iOS is funny at autocorrecting programming language names: cobol => cool, perl => peril or pearl, depending on context), but not with go. The compiler can generate errors for unused imports; it easily could generate warnings instead.

I like clean code, but I also like it if a quick experiment doesn't require extra tooling to remove imports to make things compile, more so if it is not guaranteed that undoing such changes can be automated (adding imports isn't 100% reliable; if it were, why have import statements at all?)

In summary: Go is too opiniated here for me.

Also, this requirement effectively rules out ever using go in a repl. I think that is a minus for modern programming languages.

Re:I Love Go; I Hate Go by jerf on Wednesday August 03, 2016 @08:34AM (#12217439)
"I don't think I misquoted the OP."

I don't think so either. What he wrote was unclear (sorry, tptacek). I was clarifying what I'm pretty sure he meant. It's not like I've never done the same thing in writing myself.

"Also, this requirement effectively rules out ever using go in a repl. I think that is a minus for modern programming languages."

It's ruled out for a lot of other more fundamental reasons. Go is probably the most highly polished language from the 1980s.

This would be a much greater condemnation, except the sort of people who tend to frequent HN (including me!) tend to grotesquely overestimate how much most programmers are spending coming up to speed on the latest and greatest. In many contexts, a "really nicely polished 1980s language" is a step up in either reliability or speed. Perl is nominally a more advanced language, but on the whole, most programmers just use it as a sort of dynamically-typed C. I think the majority of programmers still aren't all that clear on what a "map" is. Arming my fellow programmers with more capabilities doesn't solve any problem either I or they have, but can make them worse.

Also, I'd observe that even for modern programming languages, "needs a REPL" is setting the bar high. Rust will probably never have a REPL. I see a couple of defunct projects trying and I haven't studied them, but at best Rust could have an all-in-unsafe REPL dialect, because who's going to be able to reliably type borrow-safe code into the REPL on the first try?

Re:I Love Go; I Hate Go by Someone on Wednesday August 03, 2016 @12:02PM (#12218914)
Rust and C++ came to mind when I wrote that. That's why I didn't write modern languages _must_, but only called it a minus if they didn't.

And thanks for the relativism in that remark about the most highly polished language from the 1980s. I fear you are right in that (example: today, a colleague said this was the first time he created a thread. He has had a job as a developer for a few years, and, given his age, likely never wrote for a CPU that isn't multi-core. Luckily, he isn't dumb, as he asked what would happen if that thread threw an exception)

Re:I Love Go; I Hate Go by pcwalton on Wednesday August 03, 2016 @03:31PM (#12220796)
> Go is probably the most highly polished language from the 1980s.

I think ML pretty objectively takes that crown, semantically speaking. For simplicity and elegance it's pretty difficult to beat.

Re:I Love Go; I Hate Go by jerf on Wednesday August 03, 2016 @04:33PM (#12221271)
I should have said mainstream 1980s. Obviously you can find any number of more sophisticated lanugages in the 1980s by features, give or take the multicore support which, depending on context, was less relevant back then, but not in the mainstream. By that metric ML is still probably "ahead of its time".
Re:I Love Go; I Hate Go by zenlikethat on Tuesday August 02, 2016 @10:27AM (#12210173)
goimports will remove imports when they are no longer referenced in the file. So, the otherwise manual step of removing them is automated for you.

Highlighting dead code is not a trivial matter, at least for anything that could be referenced external to the module.

Re:I Love Go; I Hate Go by unscaled on Tuesday August 02, 2016 @11:42AM (#12210739)
I'm using goimports too, and it works like magic 95% of the time, while I can manually take care of the rest.

But it only solves the unused imports issue. During development (especially when playing with code) I often need to temporarily comment out a section of code. I go build, and the situation usually unfolds like this: - ERROR! Yes, now, I have an unused variable dangling around, because this code was using it. - No problem, let's go on and comment out that variable as well. - Oh noes! That variable was defined using two other variables which are now unused! - The first one comes from a function result, but I still want to call that function, so I need to actually change (not comment out) the calling line to use an underscore. - The second is a global variable which using another variable? Where is it going to end?

At this point I end up following the FAQ's advice and just add the line "_ = unusedVariable". The only problem I have with that is that wasn't all this unused variables thing meant to keep us from shipping code with useless bits we don't need in production? Now I actually might end up not using this variable, but because I've ended up adding "_ = unusedVariable" during my debugging and left that on, I have no way of knowing that.

Re:I Love Go; I Hate Go by tptacek on Tuesday August 02, 2016 @01:08PM (#12211394)
The unused variables are the things that can really cause bugs in your code. It's annoying, and I share your annoyance, but I have also sighed to myself and said "shit, I'm glad Go caught that" after noticing really bad bugs that the error flagged.
Re:I Love Go; I Hate Go by junke on Tuesday August 02, 2016 @01:32PM (#12211554)
That's why unused variables should be reported.

What people are arguing about is errors vs. warnings.

> things that can really cause bugs

"can" means that they don't always cause bugs: other compilers treat such uncertainties as warnings because the human looking at the screen is the one who is in charge.

Go allows you to compile code which does not respect "go fmt", why? aren't you afraid of committing working code that does not abide to the proper style? Improper formatting can lead to confusion, bugs and maintenance problems too, after all.

Re:I Love Go; I Hate Go by tptacek on Tuesday August 02, 2016 @04:09PM (#12212953)
As someone else pointed across the thread, the error eliminates these bugs, not only in your code but, effectively, in all the libraries you import. It takes effort to retain those bugs.

That has significant value, and is why I've conclude Go's choice here was the right one, despite the annoyances it causes.

I like gofmt, but I don't really care whether the compiler enforces it. It's unlikely to catch bugs.

Re:I Love Go; I Hate Go by zzzcpan on Tuesday August 02, 2016 @04:16PM (#12213018)
Actually, that's a huge speculation. Breaking someone's train of thought with an error that needs fixing right that second could just as well cause some bugs.
Re:I Love Go; I Hate Go by junke on Wednesday August 03, 2016 @03:15PM (#12220656)
And so the compiler, who has no way to make informed decisions, is there to tell you which stylistic issues is more likely to introduce bugs or not, while being needlessly stubborn.

A sufficiently bureaucratic compiler.

Re:I Love Go; I Hate Go by bluecalm on Tuesday August 02, 2016 @02:50AM (#12208207)
>>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.

Re:I Love Go; I Hate Go by tptacek on Tuesday August 02, 2016 @02:51AM (#12208210)
You 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.
Re:I Love Go; I Hate Go by StavrosK on Tuesday August 02, 2016 @08:31AM (#12209412)
I prefer what I do with Python in this regard: The IDE shows me unused variables, I can run my code with them, but I can't commit since the linting hook will produce a hard error at commit-time if something's wrong.

It's not as easy to do with a compiled language, of course, but I don't think it would be over the top to have the compiler exit with a non-success code if there are warnings when building.

The "warning fatigue" you get from C is because the warnings are either about false positives or about things that are too trivial to bother with, not because of a property inherent in compiler warnings themselves.

Re:I Love Go; I Hate Go by wtbob on Tuesday August 02, 2016 @09:18AM (#12209685)
> I prefer what I do with Python in this regard: The IDE shows me unused variables, I can run my code with them, but I can't commit since the linting hook will produce a hard error at commit-time if something's wrong.

The problem is that while you do that, essentially no-one else on the planet does — and anyone who uses a library thus has to deal with the fact that that library has approximately a 100% chance of having nits like unused variables.

Re:I Love Go; I Hate Go by StavrosK on Tuesday August 02, 2016 @11:13PM (#12215313)
Yes, it's true that sane defaults are supremely important.
Re:I Love Go; I Hate Go by millstone on Tuesday August 02, 2016 @02:49AM (#12208206)
Oftentimes 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?

Re:I Love Go; I Hate Go by tptacek on Tuesday August 02, 2016 @02:52AM (#12208213)
It 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.
Re:I Love Go; I Hate Go by xyproto on Tuesday August 02, 2016 @05:05AM (#12208635)
This is a problem specifically about commenting in and out code. The IDE should comment in and out imports accordingly.
Re:I Love Go; I Hate Go by gnuvince on Tuesday August 02, 2016 @08:54AM (#12209550)
Rust warns you about those things; allows for quicker iteration in development, and gives you a list of things to address when you are ready to polish.
Re:I Love Go; I Hate Go by zaphar on Tuesday August 02, 2016 @09:05AM (#12209609)
There are a lot of languages that warn you about such things. There are also a lot of projects in those languages that spit out a hundreds of warnings when they compile. Are those warnings bugs? Were they examined by someone to make sure they are acceptable? The older the project the less likely the above is true.

Go eliminates an entire class of bugs with this feature. It doesn't just make them detectable and less likely. It eliminates them. If you don't care about eliminating them then Go's philosophy isn't for you.

But I for one am sold on that philosophy. I'm disciplined enough that in my rust code I ensure all warnings are fixed before I release. But I don't know if everyone else is just as disciplined. For Go code I do. Every library I use in Go has an entire class of bugs that are impossible. That's a useful guarantee in my book.

On a side note why do we as developers tend to prioritize making the act of writing code easier than the far more frequent act of maintaining that code? Optimizing writing you code over reading and maintaining that code long term seems like a case of premature optimization to me. Allowing something like warnings is one of those things that adds overhead to writing code but eliminates overhead over the life of maintaining that code. The gains are higher longer term at the expense of a shorter term pain. And a pain that tooling like goimports can almost completely eliminate in almost all cases.

Re:I Love Go; I Hate Go by gnuvince on Tuesday August 02, 2016 @09:52AM (#12209900)
> On a side note why do we as developers tend to prioritize making the act of writing code easier than the far more frequent act of maintaining that code?

Different phases of the development process call for different priorities: in early dev, you want reduced friction and quick turn-around time (something that the unsed imports and variables errors in Go infringe upon). Later on, you want maintainability and ensure that things don't randomly break (at this point, those errors become quite desirable). We shouldn't emphasize readers over writers all the time, we should emphasize them when it's the correct time to do so, which I'll admit is the majority of the time.

> Optimizing writing you code over reading and maintaining that code long term seems like a case of premature optimization to me.

That's actually something I've been thinking about quite a bit in the past few weeks :) I think if we were really concerned about readability of code, we would have much better literate programming tools (e.g., better integration with existing dev tools) and our programs would be written with the intent of being read by others. How many times have we felt lost in a foreign code base (or worse, a code base we wrote, but don't remember too well) trying to implement a change and not knowing or understanding some of the design decisions, being unaware of key assumptions, etc. There is a lot more to readability and understandability than having functions without unused locals. (By the way, why is it okay for a function to have unused input parameters?)

Re:I Love Go; I Hate Go by zaphar on Tuesday August 02, 2016 @10:32AM (#12210219)

    (By the way, why is it okay for a function to have 
     unused input parameters?)
That's caused by Go's interfaces and function type signatures. It may be necessary for a method or function to accept certain arguments to satisfy an interface or type signature even when those arguments don't get used. It's a bit of a wort I agree.
Re:I Love Go; I Hate Go by pcwalton on Wednesday August 03, 2016 @03:25PM (#12220737)
> There are also a lot of projects in those languages that spit out a hundreds of warnings when they compile. Are those warnings bugs? Were they examined by someone to make sure they are acceptable? The older the project the less likely the above is true.

The amount of development time I save by allowing warnings temporarily when testing easily outweighs any benefit to the ecosystem derived from making that warning abort compilation. I was partially responsible for making this a warning instead of a hard error in Rust and this wasn't even close to a tough call. I would be surprised if a single project in the ecosystem has ever benefited from this: projects that care about software quality pay attention to warnings, and those that don't care about this minimum standard of quality are going to be full of so many other bugs that the unused variable/import warning will make no difference.

> Go eliminates an entire class of bugs with this feature. It doesn't just make them detectable and less likely. It eliminates them. If you don't care about eliminating them then Go's philosophy isn't for you.

Go's philosophy is not about eliminating bugs above all else. If it were, then for example zero values wouldn't exist, reading from a nil map would panic, constants would have stronger types, all fields would have to be supplied when initializing structs, init ordering wouldn't be undefined, overflow would trap, errors would be required to be handled, and that's just off the top of my head.

Re:I Love Go; I Hate Go by rogerdpack on Tuesday August 02, 2016 @11:59AM (#12210863)
I thought it ironic that go also has a "go vet" which spits out "warnings" but...are those warnings bugs? Were they examined? etc. etc. :|
Re:I Love Go; I Hate Go by structorg on Tuesday August 02, 2016 @10:36AM (#12210243)
Fortunately, I don't see this as a big issue in Go so far because I have used it for small components connected by zeromq or http. In a way, Go is also enforcing distributed/microservice style of development since a huge monolithical/business-rules program with it seems like nightmare material.