Re:Go proposal: Leave “if err != nil” alone?
by tptacek on Saturday June 29, 2019 @02:20PM
(#20313970)
That wasn't the argument Dave made. He said that handled error returns became invisible, because the repetition lulled programmers. That's the argument I felt was untenable.
Obviously, Go does some things to mitigate the risk of ignored error returns; the damnable use requirement means that multi-valued functions returning errors either have to explicitly ignore the error by assigning it to "_", which feels as squicky as it should, or be assigned to a variable with which (usually) something must later be done.
It's not perfect, I'll freely concede.
By default, an ignored return code does nothing. The situation is shuffled under the rug.
By default, an ignored exception is loud.
Error codes have to be handled to become louder.
Exceptions have to be handled to become quieter.
The control flows underlying exceptions are syntactically invisible except at the source and destination sites. However, they reliably occur. They reliably occur because they are invisible. If exceptions had to be propagated by some visible assistance through all the layers they cross, they would become unreliable.
The problem/trade-off with exceptions (the bad aspect of how they are invisible in their own way) is that if we have statements like S1; S2; S3, we can never be sure that S2 is reached, or if S2 is reached then S3. S1 can call some function that throws, and so can S2 or S3.
Exceptions can cause partially executed statement flows to be unexpectedly abandoned. And that means that whatever those statements were doing remains half done because the programmer assumed that if S1 is reached, then S2 and S3 are an iron-clad given.
Programmers using exception-based languages have to train themselves to use unwind protection mechanisms in all situations fitting the pattern that "if we have executed S1, then S2 must execute to complete/undo/clean-up whatever S1 started". They must never rely on ordinary sequencing, except when it is obvious that the code doesn't throw (for whatever reason: triviality, or all being in the same module put together by that programmer or whatever). If any external code is involved (statements inserted by a macro, foreign callbacks, calls into third party stuff), all bets are off.