Hacker News new | ask | show | jobs
by ShabbyDoo 4617 days ago
What's notable is that no one has yet posted here saying, "Go stunk for me. Perf and reliability were both awful. I went back to blahblah and threw away all my Go code." It's usually easy to find detractors of any technology.
5 comments

I actually have seen complaints about Go's performance relative to other compiled languages, like C++, D and Java. I don't think it's coincidental that most of the Go converts come from a dynamic-language background. If you're porting from Ruby, 2-3x slower than Java still seems blazing fast.

For me, Go misses the sweet spot entirely. A year ago I was curious about both Go and Clojure, my interest piqued by the strong concurrency support each has. I picked Clojure and have grown more and more confident in that choice.

Why not Go? In a language with nil pointers (Tony Hoare's "billion-dollar mistake"), no generics, and sub-JVM performance, static typing just doesn't seem worth it. Also, poor interop with other languages means Go can only draw from its own small community for libraries (contrast Clojure which makes using mature, well-tested Java libs trivial).

When Rust is more mature, it may be what I hoped Go would be: the safe language, with lightweight threads, that makes me never have to write C or C++ again.

Go didn't stick for me either.

Go is interesting and I really enjoyed channels, but no generic programming really disappointed me. I guess supporting the generic paradigm is pretty tricky (C++/Java templates/generics aren't dear to my heart), but not being able to implement map/filter/reduce functions...

I just did a prototype in Go. Python is my normal go-to language for prototyping. I concluded that for prototyping, I'm going back to Python.

My main objections were neither performance nor reliability (I don't care about either while prototyping), but developer productivity. I find there are just so many programming conveniences in Python that I wish I had in Go - list comprehensions, negative slice indexes, for- and with-statements over user-defined data types, heterogenous dictionaries, easy duck-typing. When I just want to get some ideas working to prove a concept, it's really annoying to flesh out all your types and error handling in full detail.

I do think Go would probably make a pretty nice production language, but I'm not at liberty to convert the large C++ and Java systems I work with to Go. Even if I were, I think I would prefer C or C++ because of its easy Python bindings.

for- and with-statements over user-defined data types

Any reason why doing this with channels and goroutines doesn't fulfill your requirements?

I don't need concurrency, and my app (which is a fairly simple "munge some data from backends, apply some algorithms, and template it" webapp) seems easier to reason about without introducing them.
I don't need concurrency

Except that you do. You've just said it yourself! What the for command does in Python is essentially running two communicating coroutines, passing control between them. Yield-using generators actually make it very explicit, by creating special resumable stack frames. The only difference is that in Go, you're not limited to a single stack frame in the producer, nor do you have to use a loop or the new PEP-380 "yield from" syntax (for example, if you're iterating over a tree). The blocking channel takes care of the execution sequencing. (Also, in Go, the channel makes it possible for the consumer to use multiple stack frames, if you're re-building another data structure instead with the data you receive from the producer, but that seems to be a rarer case. It's a nice symmetry, though.)

The Python equivalent of two communicating goroutines is a bidirectional generator (PEP 342), not a for-loop. I try to use the language construct with the least power.

Basically what I wanted this for is that I have a user-defined type that is basically a list of some other user-defined type, plus some extra stuff. In Python it's trivially easy to implement __iter__ and delegate, and then I could manipulate these objects the way I thought of them, as containers for other objects. In Go...I wonder if I could've used type embedding (making the first member of A be []B), but I don't think the built-in language constructs respect embedding when figuring out what's a legal expression. I ended up biting the bullet and explicitly looping over the slice member, but the point of prototyping is being able to think of your code in the terms of your problem domain.

> "Go stunk for me. Perf and reliability were both awful. I went back to blahblah and threw away all my Go code."

I played with Go in the beginning, mainly due to the Pascal and Oberon feeling the language has. Even tried to submit some code back to the project.

Went back to C++, .NET and Java, with an eye on D and Rust, because:

- Most Go features are actually not that new, if you happen to have a good CS background with lots of experience in many programming languages

- The community attitude "our way or the highway" regarding generics, error handling, dynamic libraries and package management

I think that's because Go is reasonably good for, say, 90% of situations, and if you're in the 10% where it is not a good fit then you already know that and you know better than to try using Go in that situation, and thus few people find Go stinking.

On the other side is things like Python, which are reasonably good for a much lower fraction of things (e.g. 30%), but if you're in the 70% you very well might not realise it does not suit your situation and thus experience Python stinking.

The thing is, it is not a bad language. It's also written by great engineers, who deserve their place in history. My problem with it (and this is the critique you see very much outside the HN circles, where Go is not a bit of a hype), is that it doesn't offer much over the state of the art of twenty years ago (Java), which wasn't exactly state of the art either ;).