Live data from Hacker News

Ten years of “Go: The good, the bad, and the meh”

blog.carlmjohnson.net

131–140 of 305 posts

Re: Ten years of “Go: The good, the bad, and the meh”

#131
post #50

Earlier quoted context omitted.

I consider use of the "errcheck" linter mandatory for a professional Go programmer, and honestly even the hobbiest really ought to be using it. Yeah, it might be nice if it were integrated into the language but on the overall cost/benefits analysis of my actual costs & benefits rather than merely aesthetic ones, this one doesn't actually factor very high for me because using errcheck is easy. And I supplement all lan…

It still doesn't catch everything.

I am not aware of an option that "catches everything", in any langauge.

Re: Ten years of “Go: The good, the bad, and the meh”

#132
post #97

Earlier quoted context omitted.

> Working on a cross-platform project where in Go, I write code and it just builds I've worked on large golang code bases that had to build on bazel, and I had the same experience fighting it. It has nothing to do with the language. > In Java, I fight with Gradle. So gradle's issue, not Java's. See above.

Pretty much every golang project I've ever touched builds with `go build`. Most that have makefiles just call `go build`, and the makefile is more for building docker containers, or doing infra-related things. If a project is in go, 98% of the time `git clone XXX && cd XXX && go build` will work. That is absolutely not the case with C, C++, Java, python. > So gradle's issue, not Java's. See above. The issue exists wi…

> If a project is in go, 98% of the time `git clone XXX && cd XXX && go build` will work.

I can’t speak for the other languages but I reckon this is the case for Java projects. Git clone, cd XXX, mvn clean package.

Potentially messing about with whether you have Java 8, 11 or 17 installed which saddens me to mention. But if you are into Java, you have them all installed already, and just need to make sure the right one is activated when you do the above steps.

Re: Ten years of “Go: The good, the bad, and the meh”

#133

Earlier quoted context omitted.

Erlang had a better concurrency story than Go, and better error handling. But alas marketing wins.

Erlang is dynamically typed.

This doesn't say much because people generally throw interface{} everywhere.

Go is used because Google and that's it.

Re: Ten years of “Go: The good, the bad, and the meh”

#134
post #34

Earlier quoted context omitted.

I don't know C#, but I'll take a guess: I think it's exactly the same issue as null in Lisp and Lua — you sometimes want to differentiate between null as in "I returned no value", and null as in "I returned the fact that there is no value". Or null vs false vs empty list in the context of Lisp. This distinction becomes very clear (and sometimes very annoying) when you realize that in Lua, setting a table key to null…

There is no difference between "no value" and "the fact that there is no value". "The fact that" is just rhetorical verbiage. There is an ambiguity in a polymorphic container between a present entry indicating a null value, and a null return indicating there is no entry. E.g. hash table being used to represent global variables. We'd like to diagnose it when a nonexistent variable is accessed, while allowing access to…

This rhetorical verbiage matters a lot in a language like Lua where you can pack an array full of dbnull sentinel types but filling it with nil results in an empty array.

Re: Ten years of “Go: The good, the bad, and the meh”

#135

Earlier quoted context omitted.

Erlang had a better concurrency story than Go, and better error handling. But alas marketing wins.

Erlang is dynamically typed.

Erlang, frankly, has a lot of problems. The first major thing I used Go to do in the 1.4-1.6 era was to migrate my multi-year production Erlang system to Go, and I never looked back.

Somehow Erlang gets this special dispensation where people get to talk about it as if it's still 2005 and it's still this unique and interesting snowflake with virtually no competition. Which it was... back then. But having successfully convinced the world that there's an interesting space there, in 2023 there's a ton of options and the point in that space Erlang staked out isn't actually that interesting or unique when you measure it by 2023 instead of 2005.

Re: Ten years of “Go: The good, the bad, and the meh”

#136

Earlier quoted context omitted.

Erlang is dynamically typed.

This doesn't say much because people generally throw interface{} everywhere. Go is used because Google and that's it.

No, they don't. They didn't before generics and they do even less now.

You can tell this is an accusation thrown around by non-Go programmers because frankly, throwing around a lot of interface{} was always really inconvenient. It's not something the language trains you to do... it's something you get punished for, really quite hard.

Re: Ten years of “Go: The good, the bad, and the meh”

#137
post #124

The biggest go problem in practice is ironically omitted in both blog posts: Verbosity of error handling! There should be a shorthand for returning if last ret value is non-nil in one line. Otherwise all you code is littered with: if err != nil { return err } and it makes it four times as long and way less readable as a result. This needless verbosity really reminds me of Java. Also, go fmt is not opinionated enough!…

Your code shouldn't be littered with that though, those errors should be wrapped or have some kind of logging/handling associated with them. If you find yourself just returning err all the time, you're not doing it right, IMO.

In practice if you look into existing codebases, it is littered. defer is used for RAII-style clean up, so in 95% of the cases it's just return the error and that's it.

Re: Ten years of “Go: The good, the bad, and the meh”

#138

Earlier quoted context omitted.

For sure — a lot of language features need to be generic. But most people aren’t coding language features, and giving them the ability to do so can lead to, well, CodeFactoryFactoryMakerGenericMethodHelpersFactory, rather than good, clear, usable code.

There is no language feature for a tree map. Many problems require a tree map. Either inclusion of generics was a good thing, or it is worth sacrificing static typing or requiring codegen for these use cases. Repeat for numerous collections and APIs. Disallowing someone from using easy statically typed tree maps is not accomplishing any of the simplicity virtues people trumpet Go for having. While the much-warned-of…

This is a pretty arbitrary benchmark. I would guess, again, that 95% of programmers have never and will never need to create a tree map. Repeat for numerous collections and APIs that are totally irrelevant to most programmers' actual experience of programming.

Go is optimized for use, not computer science edge cases. And as a result it is widely used, and some of the most complicated and widely-used open-source projects out there are built in it, even before it had generics. For example, Kubernetes.

This is because of Go's simplicity, not in spite of it.

Re: Ten years of “Go: The good, the bad, and the meh”

#139

I am immensely thankful for Go. The simplicity of the language and the stdlib is shockingly well thought out -- things like io.Reader are so obvious and yet not part of many other languages. The language has made me a better programmer. And the cross-compilation story is chefs kiss . Working on a cross-platform project where in Go, I write code and it just builds. In Java, I fight with Gradle. In Swift, I fight the t…

> I wish the protobuf library wasn't awful I’m curious what you don’t like about it? I haven’t used Go in anger, but I love protobufs, and it’s shocking that Go, of all languages, would have a substandard implementation.

Been a few years since I’ve used Go protobuf library, but it left a sour taste. First memory allocations are awful and slow. At the time there was no way to reuse slices for serializer when serializing and deserializing. The library would often panic instead of returning an error (this basically why we switched to an alternative library).

Re: Ten years of “Go: The good, the bad, and the meh”

#140

Earlier quoted context omitted.

But you probably will have to differentiate at some point between what you're inserting. Why not just do that, instead of artificially combine it into one function? Nevertheless I feel like I'm getting lost in the weeds of this example. Obviously DRY and less duplication is good. However, you have to strike a balance between being clever and being clear. And frankly I would prefer 3 lines of clear code to 1 line of h…

> But you probably will have to differentiate at some point between what you're inserting. Why not just do that, instead of artificially combine it into one function? Why prematurely optimize for differences that may not (and in practice aren't really likely to) happen? Keep in mind that the tradeoff with generics is usually not 3 lines of clear or 1 line of hard to read, it's one line of clear code (T -> T), one lin…

I would say that a BulkInsert(Any) is a significant premature optimization over just inserting an object as would apply specifically to that object. Because it sounds like you'd have to do weird reflection stuff on the object to determine how and what to insert where.

If you are inserting an object, you should insert it, rather than create complicated generic insert methods that morph themselves based on the object being inserted. That is idiomatic Go.

Post reply on HN