Boost logo

Boost :

Subject: Re: [boost] [review] Review of Outcome v2 (Fri-19-Jan to Sun-28-Jan, 2018)
From: Emil Dotchevski (emildotchevski_at_[hidden])
Date: 2018-01-29 03:55:04


On Sun, Jan 28, 2018 at 12:10 PM, Vinícius dos Santos Oliveira via Boost <
boost_at_[hidden]> wrote:

> 2018-01-28 12:12 GMT-03:00 degski via Boost <boost_at_[hidden]>:
>
> > 1. Use of outcome is more manual and cumbersome, i.e. more error-prone.
> >
>
> What is complex about the following?
>
>
> outcome::result<int> convert(const std::string& str) noexcept
> {
> if (str.empty())
> return ConversionErrc::EmptyString;
>
> if (!std::all_of(str.begin(), str.end(), ::isdigit))
> return ConversionErrc::IllegalChar;
>
> if (str.length() > 9)
> return ConversionErrc::TooLong;
>
> return atoi(str.c_str());
> }
>
>
> Or maybe about the following?
>
>
> outcome::result<void> print_half(const std::string& text)
> {
> if (outcome::result<int> r = convert(text)) // #1
> {
> std::cout << (r.value() / 2) << std::endl; // #2
> }
> else
> {
> if (r.error() == ConversionErrc::TooLong) // #3
> {
> OUTCOME_TRY (i, BigInt::fromString(text)); // #4
> std::cout << i.half() << std::endl;
> }
> else
> {
> return r.as_failure(); // #5
> }
> }
> return outcome::success(); // #6
> }
>
>
> Let's convert the first example to exceptions and see how much more
> readable your exceptions are:
>
>
> int convert(const std::string& str)
> {
> if (str.empty())
> throw ConversionErrc::EmptyString;
>
> if (!std::all_of(str.begin(), str.end(), ::isdigit))
> throw ConversionErrc::IllegalChar;
>
> if (str.length() > 9)
> throw ConversionErrc::TooLong;
>
> return atoi(str.c_str());
> }
>
>
> It looks the same to me. Let's try to convert the second example:
>
>
> void print_half(const std::string& text)
> {
> try
> {
> int r = convert(text);
> std::cout << (r / 2) << std::endl;
> }
> catch (const ConversionErrc &e)
> {
> if (e == ConversionErrc::TooLong)
> {
> BigInt i = BigInt::fromString(text);
> std::cout << i.half() << std::endl;
> }
> else
> {
> throw;
> }
> }
> }
>
>
> Also looks the same. So... you give us an example where exceptions are
> specially less verbose

Exception-neutral contexts, that is, when you can't handle the error.
Instead of:

f1();
if( error ) return error;
f2();
if( error ) return error;
f3();
if( error ) return error;

You can just say:

f1();
f2();
f3();

With exceptions, the compiler writes the ifs for you.

(and I'm not challenging that your case is uncommon
> because it looks very common to me), but then you generalize stating that
> it'll be like this everywhere.

Yes, there are very few try...catch contexts in most programs.

Note that this is not the case in garbage-collected languages. For example,
in Java you have to use try...finally to close files, handles, free
mutexes, etc but in C++ this stuff happens automatically.

Emil


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk