logoalt Hacker News

_kidlikelast Wednesday at 5:01 AM2 repliesview on HN

the obvious solution is try-catch, Java style. Which I'm surprised it's not even mentioned in the article. Not even when listing cons that wouldn't have been there with try-catch.

But of course that would hurt them and the community in so many levels that they don't want to admit...


Replies

jchwlast Wednesday at 5:59 AM

I strongly do not like try/catch. Just to list the limitations of exceptions that come to mind,

- try/catch exceptions obscure what things can throw errors. Just looking at a function body, you can't see what parts of the functions could throw errors.

- Relatedly, try/catch exceptions can unwind multiple stack frames at once, sometimes creating tricky, obscure control flow. Stack unwinding can be useful, especially if you really do want to traverse an arbitrary number of stack frames (e.g. to pass an error up in a parser or interpreter, or for error cases you really don't want to think about handling as part of the normal code flow) but it's tricky enough that it's undesirable for ordinary error handling.

- I think most errors, like I/O errors, are fairly normal occurrences, i.e. all code should be written with handling I/O errors in mind; this is not a good use case for this type of error handling mechanism—you might want to pass the error up the stack, but it's useful to be confronted with that decision each time! With exceptions, it might be hard to even know whether a given function call might throw an I/O error. Function calls that are fallible are not distinguishable from function calls that are infallible.

- This is also a downside of Go's current error handling; with try/catch exceptions you can't usually tell what exceptions a function could throw. (Java has checked exceptions, but everyone hates them. The same problem doesn't happen for enum error types in Rust Result, people generally like this.)

(...But that's certainly not all.)

Speaking just in terms of language design, I feel that Rust Result, C++ std::expected, etc. are all going in the right direction. Even Go just having errors be regular values is still better in my opinion.

(Still, traditional exceptions have been proposed too, of course, but it wasn't a mistake to not have exceptions in Go, it was intentional.)

show 2 replies
9rxlast Wednesday at 3:56 PM

> the obvious solution is try-catch, Java style.

Go already has that, of course: https://go.dev/play/p/RrO1OrzIPNe

> Not even when listing cons that wouldn't have been there with try-catch.

What would you hope to learn from it? The cons are why you're already not making use of the feature that has existed since the very first release (in most cases that is; there is certainly a time and place for everything — even the standard library uses it sometimes!). Is it that you find it necessary for a third-party to remind you of why you have made your choices? I posit that most developers have a functioning memory that sees that unnecessary.

> But of course that would hurt them and the community in so many levels that they don't want to admit...

You may not have thought this through...