C++ Logo

std-proposals

Advanced search

Re: Alternative return-paths

From: Jake Arkinstall <jake.arkinstall_at_[hidden]>
Date: Mon, 8 Jun 2020 14:35:29 +0100
I like this. It bears similarity to a slightly different use case that I
brought up in https://lists.isocpp.org/std-proposals/2020/02/0964.php

It can already be done with callbacks, albeit with the control flow
limitations that callbacks provide (e.g. It isn't possible to return from
the parent scope). On that basis, simplifying the approach and allowing
code blocks following a function call to act along similar lines as generic
callbacks would be great for establishing multi-type pipelines without the
overhead of std::variant and friends. Error handling is a part of that too.

On Mon, 8 Jun 2020, 12:51 Toby Brull via Std-Proposals, <
std-proposals_at_[hidden]> wrote:

> Yes, sorry, that should've had curly braces around it. Obviously, none of
> the above compiles, so I could not verify it through a compiler.
>
> On the other hand, the same way alternative return-paths map to
> std::variant, I briefly thought about a similar mechanism that would map to
> std::tuple. This would basically mean that any function (and any
> return-path) could return multiple values (akin to a return value of type std::variant<std::tuple,
> std::tuple, ...>). So, you could rewrite the above function as
>
> int, int parse_int_square(std::string_view const str)
> ->[parse_error] std::string
> {
> auto const i = parse_int(str);
> return i, i * i;
> }
>
> int main() {
> // ...
> auto i, i_sq = parse_int_squared(str) ->[parse_error] throw;
> // ...
> }
>
> But I'm not proposing this here.
>
> On Mon, 8 Jun 2020 at 12:05, Nikolay Mihaylov <nmmm_at_[hidden]> wrote:
>
>> Since when this compiles?
>>
>> Isn't it needs {} ?
>>
>> auto parse_int_square(std::string_view const str)
>> -> std::tuple<int, int>
>> {
>> auto const i = parse_int(str);
>> return i, i * i; // <-------
>> }
>>
>>
>> On Mon, Jun 8, 2020 at 1:53 PM Toby Brull via Std-Proposals <
>> std-proposals_at_[hidden]> wrote:
>>
>>> Hi,
>>>
>>> I was thinking about error-handling recently (see references [1] and [2]
>>> below). Of course, there are several proposals aimed at improving the
>>> error-handling mechanisms in C++ (p0709, p1028, p1029, p1144; p0323, p0798).
>>>
>>> I was particularly interested in p0709 (title: "Zero-overhead
>>> deterministic exceptions: Throwing values"). I would summarise this
>>> proposal here as making error-handling better by making exceptions better.
>>> My thought was that maybe one could tackle the problem of error-handling at
>>> a lower level first, and only bring exceptions into the picture later,
>>> especially given that some people don’t want to use exceptions.
>>>
>>> So, my idea was to allow functions to have multiple, alternative
>>> return-paths at the language level. Basically, a function declaration would
>>> be allowed to declare any number of alternative return-paths (each with an
>>> associated alternative return-type). The function implementation could then
>>> return along any of those return-paths at any point in its execution. The
>>> caller of such a function would always be required to handle all
>>> alternative return-paths in some way: either (a) explicitly (e.g. by
>>> throwing an exception or handling the error otherwise) or (b) by declaring
>>> the same alternative return-path (in which case the mechanism would work
>>> similar to stack unwinding). Failure to do either (a) or (b) results in a
>>> compile-time error.
>>>
>>> Here is a short snippet of what it might look like (inspired by [2]):
>>>
>>> int parse_int(std::string_view const str)
>>> ->[parse_error] std::string
>>> {
>>> std::stringstream ss; ss << str;
>>> int i; ss >> i;
>>> if (ss.fail()) {
>>> return[parse_error] "parse_positive_int: not an int";
>>> }
>>> else {
>>> return i;
>>> }
>>> }
>>>
>>> auto parse_int_square(std::string_view const str)
>>> -> std::tuple<int, int>
>>> ->[parse_error] std::string
>>> {
>>> auto const i = parse_int(str);
>>> return i, i * i;
>>> }
>>>
>>> int main() {
>>> std::string input;
>>> std::cin >> input;
>>>
>>> auto const [i, i_sq] = parse_int_square(input)
>>> ->[parse_error] auto const& msg {
>>> std::cerr << “Error: “ << msg;
>>> return 1;
>>> };
>>>
>>> assert(i * i == i_sq);
>>> std::cout << "i_sq = " << i_sq << '\n';
>>> return 0;
>>> }
>>>
>>> More extensive brain storming here:
>>> https://github.com/TobyBrull/scratchpad/blob/master/alternative_return_paths.cpp
>>>
>>> I imagine all this would still be compatible with p1028/std::error. It
>>> might also have other applications besides error-handling; essentially,
>>> every function that returns a std::variant could use this mechanism.
>>>
>>> I don't have any experience working on compilers, but I imagine this
>>> should be possible to implement efficiently, although it would require an
>>> ABI extension. I imagine the alternative returns-paths to be part of the
>>> function type and thus affect name mangling.
>>>
>>> What do you think?
>>>
>>> Cheers,
>>> Toby
>>>
>>> References:
>>> [1] http://lucteo.ro/2018/04/21/exception-exploration-2/
>>> [2] Phil Nash's CppCon 2019 talk,
>>> "The Dawn of a New Error" ( https://www.youtube.com/watch?v=ZUH8p1EQswA
>>> )
>>> --
>>> Std-Proposals mailing list
>>> Std-Proposals_at_[hidden]
>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>>
>> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2020-06-08 08:38:48