3 ms·
My take away: Idiomatic Clojure error handling can be idiomatic Java error handling, idiomatic Erlang/Elixir error handling, or idiomatic Haskell error handlin
by jimbokun 2y ago
My take away:
Idiomatic Clojure error handling can be idiomatic Java error handling, idiomatic Erlang/Elixir error handling, or idiomatic Haskell error handling.
If everything is idiomatic, is anything idiomatic?
(This article also makes me strangely appreciative of Go's idiomatic error handling. Use multiple return values, so the error value is clearly visible in function signature and must at least be explicitly ignored by the caller. Avoids the action at a distance of exceptions, and the invisibility of errors in the dynamic approaches recommended in the article.)
- Capricorn2481 2y ago> so the error value is clearly visible in function signature and must at least be explicitly ignored by the caller Not exactly. There's nothing requiring you to handle errors. But Go doesn't let you have unused values in general. So in a transaction commit function, if you forget that it returns an error, Go will just let you ignore it. This is a big issue with treating errors as values. https://github.com/golang/go/issues/20803 https://github.com/golang/go/issues/20803
- daveliepmann 2y agoThrowing ex-info is conspicuously missing from your list of examples. >If everything is idiomatic, is anything idiomatic? Welcome to lisp! We like it here.
- ncruces 2y agoJava's exceptions are also visible in the signature, and harder to ignore. I actually like Go's solution better, because it's verbose, because the fact that I pay the cost of "if err != nil" every effin time, I'm more likely to consider what happens. Because if the flow is not linear with those, I'm more likely to break out a function and give it a name.
- daveliepmann 2y agoThe "error maps" approach from the article doesn't have Go's compiler enforcement, but shares many attributes including the "being explicit about how to handle an error" aspect you mention.
- jiehong 2y agoGo error handling is nice, but not super mandatory. I’ve seen functions only returning an error being called without the error being assigned to anything and never checked. The compiler does not care, only go ci lint would block that. I’ve also seen a function returning a value and and error, and the error being mapped to _ on the caller side. Compiler and linter are fine with that (and sometimes it’s mandatory with some weird libraries). Lastly, a nitpick: should functions return (value, error, or (error, value)? The former is a convention, but the latter happens sometimes in some libraries.
- daveliepmann 2y ago>should functions return (value, error), or (error, value)? a benefit of using maps with error keys :D semantic rather than positional destructuring. also avoids that needlessly obfuscatory Left and Right terminology for Either monads
- ncruces 2y ago> I’ve also seen a function returning a value and and error, and the error being mapped to _ on the caller side. Compiler and linter are fine with that (and sometimes it’s mandatory with some weird libraries). Yes, that's the way to explicitly ignore the error. Ignoring the result, instead of attributing to the blank identifier _ , is bad form (unless you're doing something like defer a Close).