"If Structured Programming advocates saw Exceptions being used for regular logical flow, they would be horrified".
Agreed. Unfortunately Java and in some cases C# tend to encourage this because of the behaviour of library functions, e.g. those that parse numbers and/or dates (a string not being in a parseable format rarely justifies being considered an exception, at least at a library level).
On the other hand as an advocate of structured programming I find code that's full of ifs and multiple return statements and global error state variables to handle truly exceptional conditions where code is unable to carry out its primary function to be horrifying.
There is no distinction between "regular" and "error" control flow when it comes to reasoning and understanding, they are both control flow, they both need to be planned and synchronized in the programmer's head.
The arguments I give is for why Throw/Catch is a terrible control flow construct, a throw is an extremely dynamic goto that searches the call stack for its label, not guaranteed to be there by the way, and a catch is an extremely dynamic call that can resume control from any point underneath in the call stack. I don't know about you, but sounds to me like a disaster waiting to happen. Java tried to tame it by trying to incorporate exceptions into the type system, but it's half-baked and also comes with a big glaring hole called Unchecked Exceptions.
Errors or no errors, a bad control flow construct is a bad control flow construct. Error control flow deserve the same treatment as regular one.
>I find code that's full of ifs and multiple return statements and global error state variables to handle truly exceptional conditions
Two wrongs don't make a right. Ad-hoc error handling is awful, but so is Ad-hoc exception handling as well. There is plenty of error handling mechanism (either built-in to languages or as an architecture over boring code) that is not both.
Code that I've worked with over the last 25 years not using exceptions almost invariably has worse error handling than that without. YMMV.
(As far as regular vs exceptional flow goes, think about what sort of acceptance criteria are written into story requirements. I've never seen the expected behaviour for out of memory or even critical network failures written up as part of a user story. In many cases it's decided for you by the libraries used anyway)
Agreed. Unfortunately Java and in some cases C# tend to encourage this because of the behaviour of library functions, e.g. those that parse numbers and/or dates (a string not being in a parseable format rarely justifies being considered an exception, at least at a library level).
On the other hand as an advocate of structured programming I find code that's full of ifs and multiple return statements and global error state variables to handle truly exceptional conditions where code is unable to carry out its primary function to be horrifying.