4 ms·
Yes exactly, exceptions are much much nastier returns. Returns only go up exactly 1 frame, and the call/return pairs are balanced no matter what. Exceptions can
by Banana699 4y ago
Yes exactly, exceptions are much much nastier returns. Returns only go up exactly 1 frame, and the call/return pairs are balanced no matter what. Exceptions can unwind the entire stack, and the throw/catch pairs aren't balanced automatically. Returns of a single function own their call sites, nobody jumps to their call site except them, but a single catch accept every single throw from arbitrarily deep into the stack.
Exceptions are an entire call/return system hidden beneath the vanilla call/return system, with less thought in the design and more foot guns.
>I don't follow your reasoning here
Okay forget it, it was a somewhat subjective point, my main point is as above, exceptions are extremely spicy returns, they interact dangerously with the regular call/return system and scoping. That's essentially all of what objections to exceptions boil down to, and it's a legitimate reason to hate and avoid them.
- wizofaus 4y ago"it's a legitimate reason to understand them properly and use them appropriately" FIFY.
- ncmncm 4y agoExceptions interact exactly deterministically with the call/return system. There is no scope for surprises. In particular, destructors run, absolutely reliably. Rely on them. Using modern C++, you rarely need to code your own destructor; usually the language provides one that is guaranteed to be correct.
- goto11 4y ago> the call/return pairs are balanced no matter what. I don't get that. A function can have multiple returns and a return can return to multiple different places depending on where the function was called from. I don't see how they are "paired" or why that would even be a desirable property?
- ncmncm 4y agoUltimately all arguments against exceptions, as against any modern feature, come down to "don't make me think about how I code". The actual objections expressed are not meant to be examined closely. It is funny that people using Rust would code almost identically if the language had exceptions. Its lack might end up what keeps Rust performance from catching up to and passing C++. The compiler might come to quietly use exception machinery for most call chains, as an optimization. That seems hard, but a 15% performance boost is worth a lot of work.
- Banana699 4y agoThat's a very cliche and unnaunced point of view. If you like thinking about your code, you have assembly, I think x86 is a very nice flavor for you, will all its 40+ years galore of special cases. There are Turing Machines, for really testosterone-heavy programmers, there you don't even have registers, registers are for weaklings, am I right ? I think you will like them very much, just an FSM and an infinite tape, the sky is your limit, so much thinking. If you want even more kickass bragging rights, you can program in a Lambda Calculus, where every single thing you try to do with the language will force you to think about it, more thinking ! yaaay ?. Generally speaking, yes, the entirety of good design (in general, in all walks of life) and modern PL research comes down to "don't make me think about how I code", because good programmers don't think about the code, they think about the problem the code is trying to solve. As per Alfred Whitehead (a mathematician, so very much a fan of thinking) : "Civilization advances by extending the number of important operations which we can perform without thinking about them.", so is programming language research. It advances by allowing you to forget as much as possible that you're even programming a computer, a good language fades into the background, ideally you're not even programming a good language, you're simply stating the problem to be solved. This is hampered by leaky and unreliable abstractions like Exceptions. They are a step backward in Error Handling, no static gaurantees, no static type checking, aweful synchronization between use sites.
- ncmncm 4y agoI.e., "Don't make me learn anything new." You demonstrate only that you have no understanding of exceptions and their use. It is allowed not to understand things. All of us don't understand most things. Your mistake is in pontificating about what you wholly fail to grasp.
- Banana699 4y agoI understand how exceptions work, apparently much better than you, if your other comment is anything to judge by. If you're insecure enough that my different opinions about what good code is and how it should be written leads you to claim that I don't understand things without evidence, remove yourself from the conversation right now. It's much better for you.
- Banana699 4y ago>I don't get that. Call/Return Pairs are balanced at runtime, not lexically. From all possible returns in a function, only a single one runs, and terminates the whole function. Every call site is paired, at runtime, with a single return that will return control to it, and the entire set of candidate returns are known at compile time, and the compiler checks all of this to report dumb mistakes. This is not how Exceptions work, you can throw more than you can catch, and you can catch more than what can ever be thrown (this is generally harmless, just garbage code that never runs). Neither the number nor the types of throw/catch sites are kept in sync statically. >a return can return to multiple different places depending on where the function was called from Every single call site of a function is paired with all the returns of this function. The returns of a different function are paired with the call sites of that function, not the first. Unlike Exceptions, where every catch is a jump destination for every single throw of the same (dynamic) type across every single function beneath the catch on the call stack. That's literally an exponentially larger set than set of all the returns of a single function. >why that would even be a desirable property It's desirable because it gives static gaurantees. Given a throw, you can't even know how much of the stack it would unwind, it can potentially unwind the entire stack if no compatible catch is above it on the call stack*. Exceptions can break through their abstraction boundaries and unwind the stack of a calling component that doesn't know about them. Exceptions are fundamentally dynamically typed Returns that you can forget about. That's as big a footgun as you can get without being deliberately a troll. Given a catch, you can't even know where is all the places that can go to that catch (unlike a call site). Oh, there is the trivial answer of course : Every single function called in the try{...}, and every single function that those functions call, etc etc etc. Again, an intractable thing to reason about. So people don't, but they have to, the throw/catch pair is a single logical feature, their uses must be reasoned about and kept in sync in assumptions and consequences. None of this is how a return works. If Structured Programming advocates saw Exceptions, they would be horrified. Even C's gotos don't allow you to jump out of a function. * : (which, of course, is a dynamic property: in "if(...) then {Do_Something() catch(){...}} else{...}", only one branch will actually catch, one branch can crash the program, and none of this is visible to the compiler at write time)
- wizofaus 4y ago"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.