5 ms·
> I loved playing with Go, but eventually it feels like you're conditioning yourself to be ok with a lot of "bad" code. Tons of repetition, tons of boilerplate
by blablabla123 6y ago
> I loved playing with Go, but eventually it feels like you're conditioning yourself to be ok with a lot of "bad" code. Tons of repetition, tons of boilerplate by other names.
Not well or hastily written Go is easily like that. I can only guess why you point out the repetition but when you look at well written Go code like in the Go std library, there isn't much repetition happening and it looks rather elegant. At the same time it can be quite some effort to create such code and might take several iterations. Documentation-wise I like the official documentation, it gives a lot of pointers why Go is how it is.
Also obviously it's not for every use-case. Where it works really well IMHO is where error handling is a vital part of the application. (And of course anything concurrent is quite a breeze)
- BoorishBears 6y agoNot having generics, by definition, invites a lot of repetition and boiler plate. I know generics are overrated and coming soon, but right off the bat that stuck out. I recall a point where I had written a function that needed to return a channel, but of course had to forgo types due to the lack of generics. The end result was having to wrap that channel in another channel that added typing at each call site. I asked around in go circles if that made sense, and called out how bad the felt but the answer was "no that's great! channels are cheap! the repetition is good because it's simple!" - The error handling has some sore points to that end too, and the implicit shadowing with shorthand assignments on one hand makes it easier to deal with multiple errors, but on the other hand introduced subtle logic bugs on one than more occasion where "err" was silently shadowed, which I greatly disliked. I'm actually suprised Go didn't forgo shadowing for the shorthand operator and force people to label their errors when dealing with multiple, it seems very "in brand", but I guess even Go draws the line somewhere lol - Then there's the whole stack trace situation. Which after plenty of reading still just wasn't making sense. I mean the idea of logging a stack of wrapped messages sounds very nice, but man proper stack traces not being the first class citizen of error handling just did not make sense to me in a language I hear referenced for systems work so much (and I realize they can be had) I saw proposals to rework Go's error handling, I don't know if any progress has been made to that end, but it's another example where simplicity can get in the way of itself - And I'll balance this all out by saying it was still fun to write, I don't want to seem like I'm just shitting on Go for existing. It's just these little warts that I kept getting over with just a little bit of "idiomatic Go" which I often found was just writing a little bit more code than you're used to, started to add up. And eventually I realized I was creating something that, while very easy to reason about, had a lot more to reason about than it needed to. That's where I kind of petered out in my personal usage.
- blablabla123 6y agoIt probably doesn't work to convince you, still I see that differently ;) About generics, it depends on the problem at hand. When writing a generic Matrix multiplication type that for instance should work both on real and complex numbers (or more obscure types) generics are a thing. On the other hand, when working for instance with golang.org/x/net/html, I really appreciate the interface definitions and the possibility to do type switches on those. The error handling problem can also be dealt with. I also prefer to not shadow variables, IMHO the ideal function has all its variables defined already in the signature. I mean there are stack traces when a panic is called, or something that wraps it like a log.Fatalf. I guess the idea is the author is giving much more thought to how errors are dealt with and how they are printed in a both useful (=greppable) and beautiful way. As an end user that doesn't want to dive into the code I probably always prefer to see a nicely formatted error message (or even a gracefully handled error) instead of a 100 line stack trace. Probably Go is not just the language spec but also how to use it. Therefore saying "Learning Go in 5 minutes" is probably a bit far-fetched ;-) (Probably for any language that would be true...)
- BoorishBears 6y agoI'm aware of stack traces on panics, but my understanding is you only get them if you let them bubble up and kill the application (so not really a "first class" option for errors in places like web handlers) Has that changed, or did I misunderstand? But I also think the stack trace message example is the perfect example of what I mean by "take the Go mentality with you" In a language like Kotlin for example, Go got my in the habit of attaching more information to exceptions as they bubble up. I was already generally in the habit of wrapping library exceptions, but I started religiously using a Result nomad implementation and wrapping errors with additional information so that my stack traces looked very "Go-like" in terms of human readability, but kept traditional stack trace information. It's small things that I think using Go makes you "re-appreciate" in other languages
- hcles 6y agoYou can get the full stack of the crash point (and a few extra frames that handles the stack generation) in a deferred recover, ie https://play.golang.org/p/XvZteY6Y6fh https://play.golang.org/p/XvZteY6Y6fh github.com/pkg/errors is a simple way to dump expensive stacktraces into each new/wrapped error. Or you can just panic and recover in your own app, it's possible though discouraged.