4 ms·
> Programming with exceptions is difficult and inelegant. Learn how to handle errors better by representing them as values. Funny how exception were invented b
by yodsanklai 5y ago
> Programming with exceptions is difficult and inelegant. Learn how to handle errors better by representing them as values.
Funny how exception were invented because handling errors as values was considered to be tedious. And now, more and more languages are going backward.
- tester34 5y agoWell, on the other hand there's difference between handling errors with values like: -1, 0, 1 and other obscure things and using proper types like Result<T>
- deleted 5y ago[deleted]
- jerf 5y agoI think it's less strange than you think. In most languages that use errors as values, the tediousness is being directly attacked instead of trying to dodge around it. Haskell, in many of its uses, cleans up the tediousness so thoroughly that the code written using errors as values can be almost indistinguishable from code written using exceptions, and yet, nevertheless, the errors are values and no exception machinery is being deployed. It has been a general trend in pragmatic programming languages in the past couple of decades. Another huge example, in my opinion, is in typing. Static typing in the 20th century was terrible. Tedious, broken, and missing a lot of its value. So a lot of languages were written that basically amount to a "screw that, we're not using types", and they became very successful. But in the 21st century, a lot of work has been done directly attacking the tediousness and problematic aspects of using static types, while also getting more value out of them with safer languages that more pervasively enforce them and make them more reliable, thus more useful, etc. So we're seeing a resurgance of the popularity of very statically-typed languages... but it's not "moving backwards" because it's not the same thing as it used to be. Much like I don't expect dynamic languages to entirely go away, I wouldn't expect exceptions as we know them to go away either. But I expect "errors as values" to continue attracting more interest over time. In fact, as test34's sibling post sort of observes, there's some synergy between these two trends here. Making strong typing easier has made it easier to have strongly-typed, rich values that can be used as error values and used in various powerful ways. Now that there are languages where it's much easier to declare and fully exploit new types than it used to be, it's much easier to just go ahead and create a new error type as needed for some bit of code without it having to be a big production.
- dkarl 5y ago> Haskell, in many of its uses, cleans up the tediousness so thoroughly that the code written using errors as values can be almost indistinguishable from code written using exceptions, and yet, nevertheless, the errors are values and no exception machinery is being deployed. I don't have experience with Haskell, but I have mixed feelings about monadic error handling in Scala for precisely this reason. It goes to great lengths to recreate the programming ergonomics of exceptions, with exactly the same drawbacks. Monadic error handling, aka "railway-oriented programming,"[0] splits your logic into two tracks: a "good" track, where all your happy path logic lives, and a "bad" track, which is automatically propagated alongside your happy path logic. In my experience, it induces the same programmer mistakes as exceptions do: errors get accidentally swallowed (especially where effects are constructed and transformed,) different errors that require different handling are accidentally treated the same, and programmers fall into the habit of seeing the error track as an inferior, second-class branch compared to the happy path. It confuses me when programmers (not talking about you, because I don't know how you write code, but people I've worked with personally) bash exceptions and then use monadic error handling to achieve exactly the same trade-offs. This hasn't turned me off of monadic error handling, but it has made me think of it as FP's version of exceptions, rather than an upgrade. Personally, I think exceptions are a good enough trade-off in most cases, but when you need to be more careful, it is better practice to give all paths the same prominence in code. FP provides a better way to do this: pattern matching. More verbose, yes; harder to spot the happy path when reading code, yes; encourages more careful and thorough thinking about errors, for me absolutely yes. YMMV. [0] https://fsharpforfunandprofit.com/rop/ https://fsharpforfunandprofit.com/rop/
- munchbunny 5y ago> This hasn't turned me off of monadic error handling, but it has made me think of it as FP's version of exceptions, rather than an upgrade. This reminds me a lot of Java's checked exceptions just with different window dressing. You move the failure mode type information from the exceptions list ("throws" clause) into the return type. Typed error return values is definitely an improvement in ergonomics over C-style error code returns, and pattern matching is definitely a big improvement on ergonomics too, but I think error handling has a problem of fundamentally irreducible complexity. For example, if you make network calls, you have to be prepared for network calls to fail, and you have to design your system to recover from it somehow, whether that happens in a try/catch or a match on Either[Throwable, Result].
- yccs27 5y agoYes, errors-as-values only works well with a type system which supports discriminated unions. And programming languages with such support have only recently become popular.
- yodsanklai 5y agoOCaml is a somewhat old language with algebraic types (so including discriminated unions) yet exceptions were introduced precisely to avoid dealing with propagating errors as a values. I agree with your point, but would argue that even with sum types, propagating errors is tedious and there's a case for using exception. I wonder if another reason why errors as value are making a come back is because of the asynchronous programming style which is becoming quite pervasive, and doesn't play well with exceptions.
- WhyNotHugo 5y agoMore idiomatic error handling has appeared too. It's become a lot easier to bubble up errors with messages (e.g.: golang) without handling every single case.