4 ms·
That sounds incredibly ignorant to me. If this is the first language you've used where you give that sort of attention to errors, you must not have used and le
by TheDong 12y ago
That sounds incredibly ignorant to me.
If this is the first language you've used where you give that sort of attention to errors, you must not have used and learned from the terrible mistakes of C, which constantly returns errors which are not required to be handled, just like go.
Heck, you must not have learned from bash where every second line is "if [[ $? != 0 ]]" or you just did set -e and fail hard.
For me, the problem with Go's errors isn't even the lines they take up, but the fact that they still don't accomplish anything more than C's errors.
Since C, we've learned that you can use exceptions to force errors to be handled, or Options + matching to ensure each case is handled or extremely explicitly ignored. We've learned that errors can have contexts like call stacks attached to them.
Go ignores all of that and goes back to the C way. It doesn't provide an easy way to chain errors or force them to be handled. It doesn't provide a good idiomatic way to differentiate between the majority of errors from the stdlib because it's discouraged to have multiple error struct types; rather you're encouraged to use errors.New and make an un-differentiatable error type with no good context. It's encouraged to return an err from deep in the stack without including any additional information.
In fact, Go's even inconsistent in how it uses errors in the stdlib. For example, if you look at io, you can see the following: http://golang.org/pkg/io/#pkg-variables http://golang.org/pkg/io/#pkg-variables
They define their variables as error types which are simply strings. That means you can compare with the constants (e.g. err == io.EOF), but if you add any extra info to that err, such as callstack, you can no longer compare with it. If you look at os, you see "os.IsNotExist(err)" which tells you if an err is of a given type. If you look at net ( http://golang.org/pkg/net/#AddrError http://golang.org/pkg/net/#AddrError ) you can see they implemented their own Error interface implementations which you check by doing `if addrErr, ok := err.(AddrError); ok { // handle error }`.. the fact that the Go authors included three different error patterns in the stdlib already shows that the entire error process in go is poorly thought out. In addition, none of the methods allow you significant flexibility in adding your own info to the error as you pass it up without losing information.
If you don't like try! in rust, you're free to write your errors out explicitly, but if try! fits then it's good to use it.
The majority of bugs in code come from people being unable to keep a sufficient amount of the program state in their head to track program flow accurately. If half of your program flow is errors, then no wonder. There's an old principal that each function body should fit, in full, on one screen because that ensures it can be read without scrolling and reasoned about fairly easily. Error handling wasting space also wastes thought and makes your code provably harder to reason about (if you don't think that's true, look at the incidence of 'mistake checking error return values in c' vs 'mistake checking error return in haskell' vs 'forgot to either catch or annotate throwable for exception in java'. Yeah).
- tobz 12y agoSo what's your suggestion here? It sounds like this person feels more proficient, more on-the-ball, writing Go. So, you call them ignorant (incredibly ignorant, at that) because they're not using a language with exceptions or pattern matching, and they're wasting they're time on "C-style" error handling and... what? They're ignorant until they use something else? You're also drawing a weak conclusion here: if you use Go idomatically, which requires more lines on your screen for error handling, and a majority of programming errors are a result of the programmer not being able to keep a sufficient amount of program state in their head because of code not fitting neatly on the screen, then using Go leads to more bugs. Do you have anything that substantiates that?
- lmm 12y ago> So, you call them ignorant (incredibly ignorant, at that) because they're not using a language with exceptions or pattern matching, and they're wasting they're time on "C-style" error handling and... what? They're ignorant until they use something else? Honestly, yes, though I would try to phrase it more constructively. If you've only seen C-style languages, it's easy to be ignorant of the world out there; it's easy to try two or three languages and think you know what's going on, when in fact the languages you know all come from a very similar lineage. Like learning English, German and Dutch, and then assuming you know the general principles of human grammar. If you've tried a language pattern matching and higher kinded types, and found them to be not useful, then fair enough. But you owe it to yourself to try, and even if you end up not using the feature, understanding it will make you a better programmer. > Do you have anything that substantiates that? Over many years of research into what causes bugs, there's only one thing we've ever been able to correlate reliably with number of bugs: number of lines of code. Even across different languages, the correlation holds: http://programmers.stackexchange.com/questions/185660/is-the-average-number-of-bugs-per-loc-the-same-for-different-programming-languag http://programmers.stackexchange.com/questions/185660/is-the... . So the only evidence-based way to reduce software errors is to reduce lines of code - something you can do by switching to a more expressive language.
- artursapek 12y agoYou're right that I've never written C. I know enough bash to hate using it. I'm familiar with Maybe/pattern matching in Haskell, and I've used OCaml too. I've seen more than one approach. I also think you're correct about everything you said, especially about the inconsistent treatment of errors in Golang's stdlib, and the difficulty of differentiating between them. I've noticed the same and it has annoyed me. When writing my own application code I do maintain a consistent pattern for returning my own errors, but I have been frustrated when consuming the stdlib for this very reason. Maybe as my code base grows I'll come to agree with you, but for now at least it seems to be at a nice middle ground where the error handling isn't overwhelming and it isn't swept under the rug. And to my knowledge, none of the bugs I've created when writing Go code have come from my understanding of the program flow being interrupted by error handling code. And I've probably avoided many bugs because of this pessimistic approach I take when coding, as jalfresi put it in his comment[1]. [1] https://news.ycombinator.com/item?id=8878852 https://news.ycombinator.com/item?id=8878852