Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I think part of the insidiousness of exceptions is that we're tempted to think there's a way to use them that's not as a flow control mechanism. And there isn't. That's what they do: _alter flow_.

A sibling comment hints at the way out:

> For exceptions to work predictably, all mutation within a try-catch block should be captured in a transaction that can be rolled back.

The instant an exception can be raised from an area in code is the instant you need to make that entire area into functionally-pure side-effect-free logic, so that you can reason about it even when the exception is raised.

And then you've got a function that could just as well return an Either<Result, Error> -- what a strange "coincidence"!



> The instant an exception can be raised from an area in code is the instant you need to make that entire area into functionally-pure side-effect-free logic

I mean, that would be lovely, but is really only feasible for exceptions raised from code that is operating exclusively on values in memory (NPEs, for example). Rather a lot of exceptions are raised from necessarily side-effectful operations, especially those dealing with I/O.

Since you can't predict the future, you can't guarantee purity/transactionality of code that raises that kind, so saying "code should be pure when it can throw" is a true-but-impossible statement. That's why most languages with an emphasis on purity tend to eschew exceptions and/or invert control flow such that effectful stuff happens externally to the functions handling its output (e.g. the Maybe or IO monads).


This is correct, of course, but partial progress here is massive progress indeed.

The further you push the potentially complicated code towards functional purity, the more the I/O and other side-effecting/hard-to-roll-back things float to the top... and it becomes almost natural to group all of them together...

... into what you might almost be tempted to call a "transaction".

(Indeed, like the IO monad leads one to do. I've explicitly been trying to avoid saying the "m" word, though, because it seems to be a cognitive stop-sign for a lot of folks, for whatever reason.)


>>The instant an exception can be raised from an area in code is the instant you need to make that entire area into functionally-pure side-effect-free logic, so that you can reason about it even when the exception is raised.

Great insight. But i would say that explicit error handling doesn't help you much there. Side effects are hard and side effects can by nature normally not be reverted anyway. Deleted a file? Tough luck getting it back. IO and external interfaces could also be an issue, wrote 50% of a file to USB-stick when the user yanked it from the port? No amount of explicit error handling will help you remove it there.


Exceptions are effectively INTERCAL's "COME FROM".

If(error detected) { COME FROM (Error location); Handle Error }

It trades ease of writing error handling code for ease of debugging.


They aren't, though. COME FROM can come from anywhere; catch can only come from somewhere an exception actually got thrown. That is a night and day difference.


That is a difference without a practical consequence. The reality that unless you have only checked exceptions then effectively any line of code could throw an exception. And if that is so then you have to assume that the next line of code may not run. Just as Come From would cause the flow of control to mysteriously jump on you exception could as well. You are right that at least the stacks properly unwind with exceptions which disallow a certain class of bugs but the there is still a large body of bugs around the codes semantics itself that could occur.

Your best bet to maintain a clean state with exceptions is to never catch them and just let the whole process die. Otherwise there will be a never ending stream of bugs that your maintenance programmers will be dealing with. They'll be cursing exceptions the whole time.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: