Problems with Go's design
51–60 of 88 posts
Re: Problems with Go's design
#52Nailed 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!
Re: Problems with Go's design
#53I'm surprised to see the author mention not being able to compile when there are unused imports. Editor plugins that call goimports have solved this problem for a long time now. For example, I use vim-go ( https://github.com/fatih/vim-go ), and if I remove the only line of code that references the "fmt" package, the "fmt" import line at the top of the file will automatically be removed. Edit: Here is the reasoning on…
Re: Problems with Go's design
#54Earlier quoted context omitted.
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 st…
Sure, there's lots of trade-offs - you can't build anything significant without trade-offs. Also, you can still say performance is a value and trade it away for other things, eg GC. It's a bit silly to say that if something isn't as fast as C++/C right away then it doesn't take performance seriously. I don't think anyone's being dishonest in making such trade-offs - if you have multiple competing values then you need…
Actually, I think GC is inherent to the language, and that's why I listed it as one of the trade-offs that Go made (not the Go implementation made). Almost every language construct depends on GC, e.g. append(), make(), and more. Even the following innocent-looking code:
func f() *int {
a := 1
return &a
}
is GC-dependent, because it would result in a dangling pointer in non-GC languages. But the code is perfectly fine in Go because GC is inherent to the language. It is not possible to make GC optional in Go, so the performance penalty will stay there forever, only alleviated as the implementation matures (or sometimes regressed, as Go 1.5 shows), unless you use only unsafe.Pointer all the time.Re: Problems with Go's design
#55Meh. 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,…
That's not type covariance. Variance only comes up when you have generics, which Go doesn't, and subtyping, which Go doesn't really have. It's the lack of a coercion/conversion between slice-of-T to slice-of-interface. The correct language-level solution to #4 is to introduce generics and to allow generic type parameters to have interface bounds. That would solve the problem without having to introduce variance.
Go's slices are generic to the extent needed, and the subtyping of Go's interfaces fits the requirements for ordering of types well enough.
Re: Problems with Go's design
#56While 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".
Language design decisions by superstars like Robert Griesemer, Rob Pike, and Ken Thompson (the creators of Go) that may seem inconvenient or annoying when working on small to mid-size projects could very well make life much easier when working on giant projects which take years and do not fit on any single person's head.
I'm reminded of this insight by Lawrence Kesteloot of Dreamworks: "What’s particularly hard is having technical discussions with someone who hasn’t broken through as many walls as you have. Breaking through these walls means making different trade-offs, and specifically it means making a decision that seems to make less sense in the short term but will help later. This is a hard argument to make—the short term advantages are immediately demonstrable, but I can’t convince anyone that a year from now someone may make an innocent change that breaks this code."[1]
Unless you personally have led Internet-scale mission-critical software projects at a place like Google, as the authors of Go have, I don't think you're in a position to judge their decisions too harshly. Neither am I, BTW.
--
[1] http://www.teamten.com/lawrence/writings/norris-numbers.html
Re: Problems with Go's design
#57Earlier quoted context omitted.
That's not type covariance. Variance only comes up when you have generics, which Go doesn't, and subtyping, which Go doesn't really have. It's the lack of a coercion/conversion between slice-of-T to slice-of-interface. The correct language-level solution to #4 is to introduce generics and to allow generic type parameters to have interface bounds. That would solve the problem without having to introduce variance.
I don't see how it's not type covariance. Go's slices are generic to the extent needed, and the subtyping of Go's interfaces fits the requirements for ordering of types well enough.
Re: Problems with Go's design
#58Nailed 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!
I've never understood this, every Go user swears on gofmt for some reason that I just dont get. Can you elaborate how gofmt changed your life? Its a really simple tool and lots of languages have those...
* It's highly opinionated. It's not cluttered with customization options. This means your Go program and my Go program are formatted exactly the same. Period. I don't have to choose between spaces or tabs or get annoyed that you chose spaces when tabs are clearly superior. * By being highly opinionated, Gofmt just takes care of those decisions. You focus 100% on coding -- not on stylistic decisions. * It's practically built in and maintained by the core team. The "other tools" out there are usually open-source. You have to go hunting for them. Gofmt ships right with Go. Then you have to figure out how to run them. With go, it's just a simple `gofmt `. Boom. Done. No NPM dependencies, no Ruby gems to install. Just run it and move on.
I don't write Go full-time, but I've started adopting similar tools for my primary languages. My editor at my current job runs a similar tool for Node. I don't have to think about style any more. It's just taken care of for me. And all of my team have reached the same conclusion. Peace of mind and focus on what really matters is invaluable.
Re: Problems with Go's design
#59Meh. 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,…
> • an identifier
> • an integer, floating-point, imaginary, rune, or string literal
> • one of the keywords break, continue, fallthrough, or return
> • one of the operators and delimiters ++, --, ), ], or }
The things you can put as elements of a slice, values of a map, or values in a struct literal are Expressions nonterminal symbols (https://golang.org/ref/spec#Expression). As far as I can tell, the tokens that can end an Expression are a subset of those after which semicolons can be automatically inserted.
Re: Problems with Go's design
#60Earlier quoted context omitted.
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
Probably the root of the issue is that it's slightly more complicated than syntactic sugar: "Unlike regular variable declarations, a short variable declaration may redeclare variables provided they were originally declared earlier in the same block (or the parameter lists if the block is the function body) with the same type, and at least one of the non-blank variables is new. As a consequence, redeclaration can only…
Without the mixed declaration/redeclaration you'd have to either declare a different error variable every time in the block, or explicitly declare your result variable:
foo1, err1 := DoSomething()
foo2, err2 := DoSomething2()
// or
var Foo foo
var err error
foo, err = DoSomething()
foo, err = DoSomething2()