Live data from Hacker News

Isaacs: try/catch is an anti-pattern

groups.google.com

131–140 of 140 posts

Re: Isaacs: try/catch is an anti-pattern

#131
How on earth can types catches be worse than untyped catches? As a Pythonista, this whole argument makes my head hurt. He's railing against everything considered beautiful about exception handling in the Python community.

Re: Isaacs: try/catch is an anti-pattern

#132
post #130

Earlier quoted context omitted.

When does this actually happen? Oh, for Pete's sake. I'm not learning what I hoped to here, and you've made up your mind.

What were you hoping to learn? Can you give me a practical situation where an exception is thrown despite there not being an error, aside from the canonical Integer.Parse() example? In my experience, that's not the bulk of any practical program, and it's still exceptional from the point of view of the Parse function. I'd be interested in discussing this, but I'm not really sure what you think would be an improvement.…

An example comes to mind, from the very issue I'm working on at the moment:

System.ComponentModel.Win32Exception: The operation completed successfully at System.Drawing.BufferedGraphicsContext.CreateCompatibleDIB(IntPtr hdc, IntPtr hpal, Int32 ulWidth, Int32 ulHeight, IntPtr& ppvBits)

Re: Isaacs: try/catch is an anti-pattern

#133
post #9

This seems to be exactly the attitude of Go: "We believe that coupling exceptions to a control structure, as in the try-catch-finally idiom, results in convoluted code. It also tends to encourage programmers to label too many ordinary errors, such as failing to open a file, as exceptional. Go takes a different approach. For plain error handling, Go's multi-value returns make it easy to report an error without overloa…

For some context here's another error handler in Google Go: defer func() { if r := recover(); r != nil { if err, ok := r.(runtime.Error); ok { if err.String() == "runtime error: index out of range" { // handle bad index return } } panic(r) } }() vs try { } catch (IndexOutOfBoundsException ex) { // handle bad index } A language where you have to resort to string compare to handle invalid array accesses can't be use as…

Whose crazy code is that? NOT idiomatic. If you need to recover from bad slice indexes then your code is broken and you have way more to worry about than a messy recover closure.

Re: Isaacs: try/catch is an anti-pattern

#134
post #130

Earlier quoted context omitted.

What were you hoping to learn? Can you give me a practical situation where an exception is thrown despite there not being an error, aside from the canonical Integer.Parse() example? In my experience, that's not the bulk of any practical program, and it's still exceptional from the point of view of the Parse function. I'd be interested in discussing this, but I'm not really sure what you think would be an improvement.…

An example comes to mind, from the very issue I'm working on at the moment: System.ComponentModel.Win32Exception: The operation completed successfully at System.Drawing.BufferedGraphicsContext.CreateCompatibleDIB(IntPtr hdc, IntPtr hpal, Int32 ulWidth, Int32 ulHeight, IntPtr& ppvBits)

That's really terrible, and I can't defend that.

However, in the interest of trying to be helpful, my guess is that you have a bug in your app that plays poorly with a bug in Win32. A quick search for BufferedGraphicsContext.CreateCompatibleDIB yielded this question on SO (link to top answer) which indicates a resource leak may be at fault:

http://stackoverflow.com/questions/1209769/system-componentm...

Re: Isaacs: try/catch is an anti-pattern

#135
post #9

This seems to be exactly the attitude of Go: "We believe that coupling exceptions to a control structure, as in the try-catch-finally idiom, results in convoluted code. It also tends to encourage programmers to label too many ordinary errors, such as failing to open a file, as exceptional. Go takes a different approach. For plain error handling, Go's multi-value returns make it easy to report an error without overloa…

I don't think this style is much better than exceptions. I think Go could have done itself a favor if it has variants + pattern matching. I find those to be, in many cases, superior to exceptions as the compiler checks you are handling everything and you can easily encode success and failure in the variant type.

This is exactly what I observed when using OCaml: Although it provides exceptions, I almost never used them. Most things were a lot simpler to implement via pattern matching (http://caml.inria.fr/pub/docs/oreilly-book/html/book-ora016....).

Re: Isaacs: try/catch is an anti-pattern

#136
post #133

Earlier quoted context omitted.

For some context here's another error handler in Google Go: defer func() { if r := recover(); r != nil { if err, ok := r.(runtime.Error); ok { if err.String() == "runtime error: index out of range" { // handle bad index return } } panic(r) } }() vs try { } catch (IndexOutOfBoundsException ex) { // handle bad index } A language where you have to resort to string compare to handle invalid array accesses can't be use as…

Whose crazy code is that? NOT idiomatic. If you need to recover from bad slice indexes then your code is broken and you have way more to worry about than a messy recover closure.

> If you need to recover from bad slice indexes then your [error handler] code is broken

You bring up a good point that when resorting to value comparisons for error handling instead of type comparisons it's easy to make mistakes. The code is as far as I can tell a simplest way to handle an index out of bounds, but to also handle a 'slice out of bounds' it would need to also compare to the string value "runtime error: slice bounds out of range" -- not helping the case for error handling in Google Go.

This code strikingly shows deficiencies in Google Go non-local error handling:

- Tons of boilerplate (defer, recover, re-panic, type check, value check)

- Not scoped so can only handle an error once per function

- Have to do value tests in addition since types are very generic due to implicit interfaces

- Error values are poorly defined

- Result for higher-level caller is buried deep in the function and non-obvious

These problems extend to all non-local error handling in Google Go, not just for this specific case of array and string indexes. That the idiomatic way to 'handle' an error is to abort the program is another separate problem.

Re: Isaacs: try/catch is an anti-pattern

#138

Earlier quoted context omitted.

It was pointed out later in the thread that it should have been 'undefined' rather than 'null'.

I'm genuinely curious: how is returning undefined any different from returning null, in this case?

> ... how is returning undefined any different from returning null ...

Because this valid JavaScript might have been silently slipped to the interpreter:

    undefined = true;

Re: Isaacs: try/catch is an anti-pattern

#139
post #96

Earlier quoted context omitted.

What are your motivations for using Mercury? Are you using it for hobby projects, research/academic purposes or actual production code?

Hobby projects and hobby research. It has some pretty intense features if you're into type theory. IMO the library support isn't yet there for production code (e.g. no or only rudimental GUI/networking code). But if you're just using it for computation (e.g. AI or compiling or some such) it's pretty solid, and its FFI is the most straightforward I've ever seen. FWIW I hear that these people: http://www.missioncritica…

I'm definitely interested. Thanks. I've now bookmarked your blog.

Re: Isaacs: try/catch is an anti-pattern

#140
post #8

Anybody who wants to judge try/catch should first go and read about Common Lisp's condition system. See for example the chapter about conditions and restarts from the excellent book "Practical Common Lisp" by Peter Seibel: http://www.gigamonkeys.com/book/beyond-exception-handling-co... Notice I'm not saying you should go and program in Common Lisp, just that you should understand those ideas before you engage in any…

Spot on, but CL's error generation/capture/recovery mechanism only helps in single-threaded code composition. Erlang's model of linking up processes so that a "supervisor" process get notified if a servant dies is the counterpart in a concurrent scenario. Together, they seem to me to cover most of the ground. Furthermore, in Haskell you can throw an exception to another thread, though I'm not sure whether that's any…

Good point! I never actually considered this, because almost all Common Lisp code I wrote was single-threaded (CL and threads aren't friends), and nowadays I write in Clojure, where I just stick to fairly plain catch/throw.

This is a great example of why it is always worth it to learn various languages, not just stick to what you know. You regularly get eye-opening revelation moments.

Post reply on HN