7 ms·
Error handling isn't that verbose in Golang compared to other languages. Sure, in Python or Java(script) you can just throw an exception and handle that in a tr
by ThePhysicist 5y ago
Error handling isn't that verbose in Golang compared to other languages. Sure, in Python or Java(script) you can just throw an exception and handle that in a try/catch loop, but IMHO that's worse than explicit error handling, and I don't think that it produces more legible code in general. And error handling that's baked into the type system (as e.g. in Rust or Haskell) also requires pattern matching to handle errors, which really isn't that different from Golang's "if result, err := func(); err != nil { ...} else { ...}" pattern.
- samhw 5y agoYou mentioned Rust: well, Rust has the question mark operator for this case, so you can automatically unwrap a Result<T, E> and return the Err<E> with only one character of code. I worked with Go for years, and it's just not true to say that Go's error handling is not unusually verbose.
- lu4p 5y agoMaybe that's just me, but I find the explicit returns easier to read.
- brundolf 5y agoA thing that helps is that syntax highlighters normally color the question mark differently, helping it stand out
- ThePhysicist 5y agoPassing just the error up the stack is also quite easy in Golang, just use a named error return value and assign to it: func test() (result interface{}, err error) { _, err = someOtherFunction() } The thing is, you probably want to handle the error eventually, and that is just as verbose in Rust [1] as it is in Golang (IMHO). One can of course debate if it's more pleasing to use a "match" operator than an if/then/else loop to handle errors, but to me the difference is marginal. BTW one could even mimick Rust's type-based errors in Golang by returning a single interface{} type that's either a result or an error and then using a type switch, but that seems just silly and I have never seen that in the wild. 1: https://doc.rust-lang.org/rust-by-example/error/multiple_error_types/define_error_type.html https://doc.rust-lang.org/rust-by-example/error/multiple_err...
- simiones 5y agoThe difference is when a function has more than one line. In go, you constantly have to `if err != nil { return }` even with named return values. This is the part that breaks up the flow constantly and hurts readability. In Rust, the ? macro also handles this.
- samhw 5y agoPrecisely. As soon as you go beyond a ten-line toy program, you'll hit this problem, and in my experience it's almost universally acknowledged to be a problem with Go. Rust's '?' sugar effectively replaces the whole `if err != nil { ... }`, meaning it wasn't really honest to list Rust as another language that proves that error handling just has to be verbose and repetitive.
- ThePhysicist 5y agoSee my comment below. I never use this pattern personally, just wanted to point out that it exists. In general I think passing up errors through the call stack without adding context to them or handling them is a strong anti-pattern. I think many people in the Golang community see this similarly. And by passing an error up the stack with "?" you haven't magically "handled" it, so I don't think that's a fair point.
- erik_seaberg 5y agoA stack of ten functions wants to handle the error once. Returning it nine times is exactly the type of mind-numbing chore that computers do much more quickly and reliably than people, and I will never understand why so many want not to automate this.
- bregma 5y agoNow that computers are starting to write software it will eventually matter less. Until then, code is written by and for people, not computers.
- zohch 5y ago> Sure, in Python or Java(script) you can just throw an exception and handle that in a try/catch loop, but IMHO that's worse than explicit error handling Why?
- AnimalMuppet 5y agoI see a symmetry between return values that you are required to check, checked exceptions (that you therefore have to catch), and patterns that you have to match. In each case, the compiler forces you to handle your errors (or, more generously, the compiler helpfully points out where you failed to do so). But I think that pattern matching, and even checked exceptions, are much less verbose than constantly checking the return value. That doesn't mean that they're better, just less verbose. (Exceptions in particular - I can invisibly leave this function at points that are not specified. Does that leave everything in a clean state in all possible circumstances? Explicit error returns are much more verbose, but may be easier to reason about, because the information you need is all explicitly visible.)
- masklinn 5y ago> But I think that pattern matching, and even checked exceptions, are much less verbose than constantly checking the return value. That doesn't mean that they're better, just less verbose. I don’t see how you can say that monadic results aren’t strictly better: they’re safer, less verbose, and give the option of abstracting around. Odds are they’re even more efficient.