
On Wed, Jan 31, 2018 at 2:26 PM, VinÃcius dos Santos Oliveira < vini.ipsmaker@gmail.com> wrote:
2018-01-31 18:21 GMT-03:00 Emil Dotchevski via Boost < boost@lists.boost.org>:
- Making some or all control paths explicitly detailed to aid code correctness auditing, as opposed to having hidden control paths caused by exceptions potentially thrown from any place.
This is one of these axiomatic beliefs that need to be substantiated instead. It is simply not true that code that uses exception handling ("hidden control paths") is more difficult to audit or more prone to errors. In my experience it's the other way around: people who don't use exceptions are not serious about error handling; they're the ones who also need advanced logging libraries to help them figure out what went wrong _this_ time around.
It's like arguing that RAII doesn't help with resource freeing and this is just axiomatic belief.
How pushing a "I forgot to do proper error handling" to compile time errors becomes "this is just axiomatic belief and helps no-one"?
Where is the compile time error? Example?
During this same review, Andrzej Krzemienski noted an improper exceptions handling of exceptions in the swap function:
Also, it is possible that while reswapping, another exception will be
thrown. In general, you cannot guarantee the roll-back, so maybe it would be cleaner for everyone if you just declared that upon throw from swap, one cannot rely on the state of `result`: it should be reset or destroyed.
Should we remember the variant saga maybe[1][2]? These are not isolated cases. They keep happening.
How do you see that? The people who made these mistakes or took years to solve some of them are too dumb and can't use exceptions? What about every beginner C++ programmer? You'll push all these cases to compile-time errors. Even expert C++ programmers will make mistakes one time or another. Meanwhile, I haven't seen any error remotely similar to these ones in Rust.
Well, go ahead and code in Rust then. :) You can't draw conclusions only by looking at anectodal evidence like this. If you want to demonstrate that Rust-style error handling is more robust, you have to have a control, the same real-world large scale project written/designed for using C++ exception handling. Neither of us has a control. So you have to be able to make your point in the abstract, which is very difficult. It is especially difficult because using either approach, a high quality development team can produce a robust program. But just because Google managed to build a phone using Java, it doesn't mean it was a good choice. Yes, using exception handling you can make mistakes that would be less likely to make otherwise. Also, using C++ you can make a whole lot of mistakes you can't make in Java, that's one reason why some people use Java and not C++, but this doesn't make them good C++ programmers -- nor it means that there is something wrong with C++.
But then it is you who is arguing:
It is simply not true that code that uses exception handling ("hidden
control paths") is more difficult to audit
Can you show me _any_ code using Result-like error handling that had problems that made people as smart as the C++ committee take so much time just to design a variant? Because any Rust programmer will design a variant like this:
enum Either { Left(A), Right(B) }
What happened here? I designed a variant in less than 10 seconds as robust as the C++ variant which required effort by many people and wasn't designed nearly as fast as this one. Could you go into these concrete cases and tell me what I'm not seeing?
There are very many examples of things being very difficult to express in C++ while being trivial in another language. There are usually good reasons for this, and there are many examples to the contrary. The ability to use RAII and exceptions to enforce postconditions is one such advantage.
The only mistake you can do is forget to check if a value is contained before accessing such value. I'll find this easier to audit anytime. And the operator TRY will make it even easier. In Rust, it is not even possible to make this mistake.
Most of the possibly dangerous behaviour became compile time errors. The rest may be subjective, but we have plenty of clues that exception handling is not that great to say the least.
This attitude is why I think Outcome does not belong to Boost or to C++. Its focus is not to help deal with exceptions in the few cases where they're annoying or inappropriate, or to help the poor souls who have to maintain large legacy code bases; it's part of an effort to change (in my opinion break) C++, by people who really don't seem to like C++ anyway. I'll point out again that in C++ it is impossible to report an error from a constructor except by throwing, and this is a good thing. I assume you disagree -- so what do you propose instead? It can't be OUTCOME_TRY, can it? Emil