8 ms·
Go is definitely a step up from C (and from C++ in many important ways), but maybe they could have spent a tiny bit more of that deep thinking about the problem
by pas 2y ago
Go is definitely a step up from C (and from C++ in many important ways), but maybe they could have spent a tiny bit more of that deep thinking about the problem of error handling, so they would have come up with something better than `if err != nil {}` ... no? Just me? Hm, okay.
- bee_rider 2y agoTo be fair, though, error handling is terrible in every language, independent of how much the designers think about it.
- deleted 2y ago[deleted]
- XorNot 2y agoSeriously. For the amount people glaze Rust on HN, error handling when you actually try to use Rust is overtly discussed as "oh yeah it's completely broken, most people try to replace the whole thing..."
- vlovich123 2y agoHuh? I find error handling in Rust to be quite nice to use. You do probably want to use thiserror to make it easier to define the Error type for your crate, but other than that it's super smooth IMO.
- kibwen 2y agoLet's not flirt with false equivalences. I've seen languages that do error handling worse than Go. I've also seen languages that do better.
- MisterTea 2y ago> `if err != nil {}` What would you like instead?
- Dylan16807 2y agoThe most basic thing would be a compact way to say "do this call, if there is an error return it, otherwise give me the value"
- 9rx 2y agoThat would be the most basic thing, but you'd never be able to use it (toy code written for an internet comment aside). 1. Errors quickly lose their usefulness if you simply pass them up the stack. Even just on the surface, if you don't even know where the error came from, good luck making sense of it. Other languages have tried to avoid that problem by having things like "sidecar" handlers that can handle the error elsewhere, but in the end that's just moving code around. You haven't actually solved the overhead of needing to do something with the error. 2. Errors simply passed up the stack are, more often than not, going to leak implementation details. Consider a function that fetches data from a SQL database, where the underlying operations produce a "SQLNoResults" error. If you let that flow through, callers are going to start to rely on it. Now, imagine new requirements dictate that you need to fetch the data from an HTTP service instead. If you continue to simply pass the error along, now callers are going to get a "HTTPNotFound" error instead, breaking their usage. Not a good situation.
- Dylan16807 2y ago1. It's not just moving things around. Often you want a segment of code to all do the same thing on error. 2. There are places where you want to abstract your errors, but those places are not every function call or even most function calls.
- 9rx 2y ago> Often you want a segment of code to all do the same thing on error. Do you mean often you want multiple segments of code to all do the same thing on error? If there is only one segment then you well and truly have just moved things around. Multiple segments all doing the same thing on error would give more justification to centralizing functionality, but at the same time if you have multiple segments of code all doing the same thing you've probably not thought your design through. Papering over design mistakes with language features is commonly done, but I'm not sure it is something to strive for. > but those places are not every function call or even most function calls. If the original error is your own you don't need to abstract it, but if you are passing your own errors through multiple levels of indirection you've, again, probably not thought your design through very well. Papering over design mistakes with language features is commonly done, but I'm not sure it is something to strive for.
- burnished 2y agoYour IDE may/could collapse those blocks and also allow you to write them from templates. That resolves most peoples problems with error handling since it elides the ergonomics
- 9rx 2y ago> but maybe they could have spent a tiny bit more of that deep thinking about the problem of error handling First, to understand how to handle errors differently, you have to understand how errors are different. Like, is a person's age an error? Your gut reaction is almost certainly "What? No. A person's age isn't an error." Yet soon enough you're writing age verification checks like: if age < 18 { /* not an adult */ }. if age < 21 { /* not old enough to drink in the USA */ } – with all the exact same problems if err != nil {} has. Clearly it is an error in certain contexts. Keep going and you start to wonder what branching situation isn't error handling. So, really, it seems to me what we really want is a better way to express branching operations. "if" is one of the earliest additions to programming languages, so it stands to reason that it is getting a little long in the tooth. The effort to improve error handling is clearly there. Core team member Ian Lance Taylor submitted a new proposal and built a reference implementation just within the last few months. There have been ~200 error handling proposals! It is a super hard problem, though. A "tiny bit more" thinking is not sufficient.
- maleldil 2y ago> A "tiny bit more" thinking is not sufficient. They could've at least looked at what other languages were doing at the time, and that would have been much better than what they ended up with. However, as with many other aspects of Go, the creators ignored existing work and went with what seemed like improvements to problems from decades ago.
- 9rx 2y ago> They could've at least looked at what other languages were doing at the time Other languages at the time were doing the exact same thing, except, maybe, wrapping the error in a monad such that you have to check the error before doing anything with value, but still with "if" or an if-like construct. But that is unnecessary in Go as it believes that values should always be useful – which means you don't need to even consider the error to use the value.
- int_19h 2y ago