Live data from Hacker News

Problems with Go's design

medium.com

21–30 of 88 posts

Re: Problems with Go's design

#21

Earlier quoted context omitted.

Sorry to bring up this yet-another-generics-ranty-thing, but actually point 4 is a typical issue that can be nicely solved with generics, by defining a function that works on every type that implements Foo. In this way you can directly pass a slice of Foo to the function and achieve type safety at the same time. As stated by the author, there's a demand for manually constructing an interface-slice in Go, and this sho…

That's a different criticism. That's the "Go Needs Generics" issue. I don't disagree with it, but I also agree that there hasn't been any good solutions proposed for generics that meet the requirements that are at the core of Go: namely, performance of the compiled program, performance of the compiler, and performance of the developer.

The reason why I think generics are relevant to point 4 is that generics can be thought as "first-class interfaces" which seem to be wanted by the author. Yes, the author suggests a method that is not acceptable to my taste (implicitly converting []struct to []interface), but if Go had generics he might have not complained about the lack of "first-class interfaces", because generics are in some ways "interfaces on steroids".

As for the core features of Go you mentioned, sorry again for my cynical wording, but I think they are a bit dishonest.

They stress on the performance of the program, yet being slower than C/C++ due to the usage of GC and dynamic dispatch all the time. It was even regressed in Go 1.5[1], because the new GC prefers latency to performance. So, they traded performance for something considered more important.

How about the performance of the compiler? Well, the speed of the Go 1.5 compiler is ~10% worse than the previous one, because they rewrote the compiler in Go (it was previously in C, for those who didn't know yet). Why did they do so? Because it has advantages: reduces the barrier to contribute to the compiler, improves the code quality, etc.. Yet they traded performance for something they consider to be important.

And the performance of the developer... While Go is not very terrible at developer experiences, it isn't very good either. Embracing simplicity led to lack of expressiveness, a typical example being generics. While this isn't entirely a bad thing, it is, again, a trade-off.

So they make trade-offs all the time. Then why are generics not considered to be good enough to make a trade-off? Because they think so. It is their opinion, sure, but claiming generics are impossible because performance isn't very convincing to me.

[1] http://yokohummer7.github.io/blog/2015/09/01/go-1.5-regressi...

Re: Problems with Go's design

#22
post #14

We replaced the baity title with something more neutral, in keeping with the HN guidelines: https://news.ycombinator.com/newsguidelines.html

On a related note, unfortunately the system encourages attention grabbing headlines to make it to the first page. I think it's great that you then replace them, but without a penalty I don't think this will stop.

Would it be hard to deduct say min(5, upvotes)

Re: Problems with Go's design

#23
post #3

Nailed it. I love Go, but all of the things listed in this article (and more) make me bash my head against the wall more often than I'd like to admit. That said, there are some fantastic things about Go that aren't listed in the article (I feel like gofmt changed my life). Don't let this article discourage you from investigating Go as a tool to use!

Same here. Mark me down for loving the runtime/community and having issues with the language. Someone's going to target the Go runtime w/ a better language and zero-overhead and I'll be happy. I can't just switch to Nim or D because I still want the Go ecosystem (e.g. /x/crypto/ssh).

Re: Problems with Go's design

#24
post #7

Earlier quoted context omitted.

Point 4 makes sense though , it would really help with polymorphism in Go ,without generics. This is the kind of subtle behavior that is upsetting at times and I really think this is where the language could improve, definitely.

For every "quirk" mentioned in this article there are very good reasons for it, which the author lacks the imagination or patience to try and reason through. Point 4 is perhaps the best example. So given an interface Foo and a struct FooImpl which implements Foo, why can't we pass a slice of []FooImpls to []Foo? It's because the creators of Go are lazy and arrogant and incompetent and don't care right? No. Consider t…

I wouldn't put it quite so strongly, but yes; go makes design decisions that are addressing non-obvious problems that the designers encountered over several years of software development in other languages.

Consider the block against unused imports. Now consider an application made of hundreds of .go files, that relies on hundreds of libraries, each of which could itself be made of hundreds of .go files---all of which changes frequently enough that a total recompile may be necessary often (which might sound like a code-base you can imagine Mr. Pike would be familiar with). It's actually a non-trivial amount of work to churn through and ignore all the unneeded imports.

"But that's sacrificing developer prototyping velocity to solve a problem that most developers never see; at most, it should be a feature toggled by a compiler flag", one might argue. Well, sure... Now consider how many C / C++ libraries cannot be compiled with -Wall -Werror because the original developer had the option of building the library without those flags enabled and not enough people want to learn all the subtle details of the languages they use, they just want "the code to compile and be done with it." Now consider what that does to the problem of trying to build larger projects from these tiny pieces that were never actually sanitized for unneeded imports... Which will inevitably happen to code that works well enough, etc.

It's a line drawn in the sand, but it's a line drawn in the sand from hard-won experience with how little projects grow into big projects.

Besides, the language is so small that it's not very hard to write wrappers for IDEs that can quickly identify and kill unused imports automatically (probably also add them when needed, like the most common "oh GOD I need to put 'fmt' back in just because I'm pen-testing the outputs in this code I'm debugging").

Re: Problems with Go's design

#25
post #19

I actually had a subtle bug caused by variable shadowing. The current behaviour of := is error prone and IMO should be revisited. The situations where it cleans things up are offset by situations where it doesn't work (including in compound statements where it often ends up being I'd like to declare and check err but I also want to be able to use the other variable if err==nil). Another thing not mentioned is type sw…

Yes, the semantics of ":=" for the multiple-variable case are just weird. You can create one variable and assign another, and it's invisible what's happening. Not too good.

Variable shadowing is probably a misfeature anyway. If shadowing were an error, sometimes you'd have to change a local variable name. No big deal. An amusing alternative would be to require that any name imported into a block must be at least 3 or 4 characters long. You don't want short global variable names anyway; if "x" is a global variable, something is wrong. Then short local variable names could never clash.

Re: Problems with Go's design

#27
post #19

I actually had a subtle bug caused by variable shadowing. The current behaviour of := is error prone and IMO should be revisited. The situations where it cleans things up are offset by situations where it doesn't work (including in compound statements where it often ends up being I'd like to declare and check err but I also want to be able to use the other variable if err==nil). Another thing not mentioned is type sw…

The behaviour you are talking about isn't anything to do with :=. It's just how scoping works in Go. := is just syntactic sugar.

http://play.golang.org/p/bh6pm_8s9S

Re: Problems with Go's design

#28
post #6

While the title is linkbait-ish, the article makes interesting points with code examples, and the author is not 'religious' -- he concludes by saying he will continue to use Go. Like most other languages, Go is neither great nor bad; it's just another tool designed by people to solve a specific set of problems -- in Go's case, people who in the past have had to develop very, very large, complicated systems with lots…

> don't call Go or any other popular language "poorly designed" with a short blog post. Instead, say "it doesn't fit my current needs."

that's not what the author wanted to say though. very, very often someone says "this is bad" when they actually mean "this doesn't fit me". in this scenario, I think the author made a very good case for "it's poorly designed".

Re: Problems with Go's design

#29
Meh.

1. How often do you insert into a slice? You know that's a O(n) operation, right?

2. nil is typed, I'll grant that it's not the most obvious part of Go's type system.

3. Meh.

4. This is type covariance. It's complicated and hard to get right. The Java Generics FAQ looks like this: http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.ht...

5. I like by-value loops. Everything else in Go is by-value.

6. Yeah, fuck everything we know about parsing, let's make whitespace significant, then we can declare slices like:

    x := []int{
      1
      -2
      +3
    }
    len(x) == 3
    y := []int{1 -2 +3}
    len(y) == 1
7. Meh

Re: Problems with Go's design

#30
post #9

I think author of this article is strangely biased towards dynamic languages. Go is not about shortest programs in the worlds, yes sometimes code is longer than in python. But in Go I can manage code execution and predict memory easier better than in Python or other dynamic languages. Many things in Go were done on purpose. Learn to use Go and it's awesome tools, like gofmt, goimports and others.

I love Python, up until I remember that I can't make any guarantees of program correctness until I have 100% coverage tests on every line of code because the language is so flexible that it can't tell if a random identifier refers to a variable name that might exist at runtime (but is not determinable to exist at compile time), and therefore most of my variable-name typos that would be compile-time errors in another language are runtime errors in Python.

So great for prototyping, not so great for large projects and maintenance (as I've just put the floor of my unit test cost around a factor-of-2 more code).

Post reply on HN