5 ms·
F# has exceptions. It's a tool that has it use at times, but they are in essence a goto
by hvidgaard 10y ago
F# has exceptions. It's a tool that has it use at times, but they are in essence a goto
- brian_cloutier 10y agoEvery single control flow tool you've ever used is in essence a goto. Every conditional, every loop, every function call. Many modern function calls are in some respects _worse_ than gotos ever were, you don't even know which code you're going to jump to. It's not goto's that were so painful, it was unstructured gotos. Calling exceptions gotos is not a reasonable criticism. They have some very well-defined structure, and additional benefits like separating your happy-path code from your error-handling code, making both simpler.
- mafribe 10y agoIt's important that there are two very different approaches to control flow manipulation. They differ in when the target of a jump is bound. - Static binding of location to jump to. This is what goto, callcc, while, for etc. do. - Dynamic binding of location to jump to. This is what exceptions do. You can show that they are really different, in the sense that (in the absence of powerful language features), they cannot simulate each other, see [1]. Once you realise that exceptions and gotos are quite different thinking about error handling becomes more clearer. [1] J. G. Riecke, H. Thielecke, Typed Exceptions and Continuations Cannot Macro-Express Each Other.
- deleted 10y ago[deleted]
- hvidgaard 10y agoI accidently hit downvote on your post, and I cannot undo it. I hope some kind soul will upvote you to counter. Your post has solid information for the topic at hand.
- brian_cloutier 10y agoThat's a really cool result, thanks for pointing it out!
- hvidgaard 10y agoThe comparison to goto was not meant as criticism, but because both disrupt the control flow in a way that has no structure. Conditionals, loops, and calls do have structure, they are the flow. When a language support contructions such that normal control flow event are either "success + result", or "failure + error", it's much easier to follow, for me, and experience has taught me that it is far less error prone. Exceptions have a use for things that are unexpected, but happened anyway, such as OutOfMemoryException.
- codingmyway 10y agoIn essence exceptions are an implicit variant (discriminated union) extension of the return type of a function. So a function returning T can actually return T or one of the set of Exception types.
- piaste 10y agoNo, I think there's an essential difference here. The return type of a function is always handled by its direct caller and only by its direct caller. Exceptions are fundamentally different because they aren't necessarily handled by the caller, but by the nearest appropriate exception handler, wherever it is, regardless of scope. That is both their strength when they are used appropriately, and their weakness when they are not.
- codingmyway 10y agoYou're right in that the implicit bit extends all the way up the call stack. They aren't the same in practice, just in theory. That implicit parallel 'track' is useful in doing the Foo => Result<Foo, Error> for you in the form of Result<Foo, Exception> but bad in not warning of unmatched values and hiding the fact. Like many a tool it can be abused by those who know just enough to use it but not enough to know why. This is why Java originally forced you to make thrown exceptions explicit. This railway approach is one good way of dealing with error conditions explicitly.
- codingmyway 10y agoExceptions as discriminated unions in C# http://tomasp.net/blog/2015/csharp-pattern-matching/ http://tomasp.net/blog/2015/csharp-pattern-matching/