5 ms·
Most perceived verboseness of Go comes not from the language or libraries but from the formater that does not allow to compress 3 lines of the error check down
by _0w8t 5y ago
Most perceived verboseness of Go comes not from the language or libraries but from the formater that does not allow to compress 3 lines of the error check down to single
if err != nil { return err }
- throwaway894345 5y agoIf this is the case, I think the fault here lies with flawed perception and not the formatter.
- _0w8t 5y agoThe formater in many cases essentially doubles the number of lines. That requires to scroll much more frequently than with more compact formatting.
- throwaway894345 5y agoI understand, but I take issue with the implication that compression makes code more readable.
- pxue 5y agoCompressing this into 1 line provides absolutely nothing for the reader, in fact, it absolutely takes away reability.
- The_Colonel 5y agoReadability absolutely suffers when almost everything you see on your screen is boilerplate.
- thatswrong0 5y agoSeriously. I see so many functions in my code see that consist of 1 line of thing I actually care about followed by 3 lines of boilerplate if err not nil… over and over again. IMO if Go didn’t have its tooling, no one would care about it.
- pxue 5y agoi have the completely opposite take. every if err != nil; return err let's me mentally draw a line in the sand and not worry about exception handling for code above that line. It lets me start fresh and restart my mental model with the line of codes below the error handling block. it doesn't take years of writing Go to understand this, all you need is a open mind to how Go does things.
- thatswrong0 5y ago> It lets me start fresh and restart my mental model with the line of codes below the error handling block. My code is almost exactly: err := doThing() if err != nil { return err } err = doAnotherThing() if err != nil { return err } etc. There's no need for me to "start fresh". Each line of actual stuff doing might return an error which needs to be returned. That's it. It's a complete waste of space and inhibits readability to absolutely no benefit. And this is extremely common across our code base.
- Zababa 5y ago> if err != nil { return err } I'm far from a Go expert, but I feel like this line is a bit pointless, especially if you write it a lot. At this point, why not just not handle the error, or panic?
- closeparen 5y agoThe community strongly discourages panic.
- Zababa 5y agoI think a panic is still better than a chain of if err != nil { return err } that bubbles up and does nothing. Of course the best solution would be proper error handling but not everyone does that (and it's not always obvious what to do).
- merb 5y agoand most of the time you can't handle it anyway. I mean consider you are having a database query and it fails because the connection error'd (network split). what to do know? restart the network switches and wait? of course not in http you will just print a 5xx err and hope it comes back. in go you need to bubble up these errors to your middleware and handle it there.
- sangnoir 5y agoAt the very least, you have to log that error.
- closeparen 5y agoOur coding convention (and I happen to agree) is that the outermost layer to touch the error is the one to log it. In this case the HTTP handler, or perhaps a gRPC middleware. You don't want to be logging errors as you propagate them, or the logs will show the same error at a bunch of different call sites vs. one complete picture of what happened.
- stouset 5y agoWorse, if res, err := actually_important_bits(...); err != nil { return nil, err } The actually important bits are hidden in the middle of line noise. In the "common case" where `actually_important_bits` is just a simple function call it's not necessarily as bad, but the problem is when you have ten successive instances of this and one is slightly different. It's impossible to notice the important difference at a glance. For an industry that is just starting to understand that code is read hundreds of times more often than it's written, golang fails at the few things we actually know for certain about what makes it easier to understand code at a glance.
- jrockway 5y agoIf you're using `res`, then you aren't going to scope it to the `if` statement. That is maybe another problem, sometimes you have to do this: res, err := actuallyImportantBits(...) if err != nil { return nil, fmt.Errorf("actually important bits: %w", err) } And other times you have to do this: if err := actuallyImportantBits(...); err != nil { return nil, fmt.Errorf("actually important bits: %w", err) } The problem here is that you really don't want "err" to leak to the outer scope, so the second case is preferable from an absolute reliability and least-surprise perspective... but you can only do that in certain arbitrary cases. I think it's a bit of a wart. You can certainly handle "res" in an else block, or even write "err == nil" and handle it there, but that is surprsing. I would say it's simply not done, ever, but the Go codebase itself does it (src/go/parser/interface.go.ParseDir was the first example I found; but my search returned many screenfuls of candidates so there are probably more cases lurking in there). The fact that you have a choice is not ideal, basically. But, having actually important bits in if err := ...; err != nil {} blocks is not detrimental to readability. You will know how to read that after 5 minutes of reading any Go program.
- jerf 5y agoI almost never use that in my code, I almost always use res, err := ... if err != nil { return nil, fmt.Errorf("...: %w", err) } for that exact reason. This doesn't scan any worse than any other text-based code. (Page in the people selling visual programming here.)