C++ Logo

std-proposals

Advanced search

Re: [std-proposals] caller_return - a step in the direction of nicer error-by-value

From: Iúri Chaer <iuri.chaer_at_[hidden]>
Date: Sat, 2 Aug 2025 10:41:21 +0100
> returns a std::expected, and the user wants for the
control flow to continue in the calling function if it does get the
expected type, but return immediately if it gets the unexpected type.

That's essentially what the sample `returns_from_caller` code does, but I
think it's more interesting than what I understood of P2561 because it's
not necessarily aimed at errors, it would work with any monadic function.
Maybe I have multiple alternative functions returning `std::optional` and I
want to do some postprocessing and return as soon as one of them succeeds
(think multiplatform code).

The advantage of it being a property of the callable is that you can
compose with it. P2561's `try?` would boil down to something like:

auto propagate_unexpected(auto err) returns_from_caller {
    return std::unexpected(err);
}

foo.or_else(&propagate_unexpected);

But you could do many other interesting things as well. I use `return` a
lot in my code, it's a great way to avoid nested if/else blocks. I do it
both in case of error and of success, and it's not exclusive to a single
type. Like:

expected<symbols, std::string> symbolicate(const std::string&
maybe_crashlog) {
    auto addresses = stack_addresses::parse(maybe_crashlog).or_else(
        []() returns_from_caller {
            return std::unexpected<std::string>("no addresses found");
        });
    std::string errors;
    errors += addr2line::symbolicate(addresses).and_then(
        [](symbols s) returns_from_caller {
            return s;
        }) + ", ";
    errors += darwin_atos::symbolicate(addresses).and_then(
        [](symbols s) returns_from_caller {
            return s;
        }) + ", ";
    errors += win_cdb::symbolicate(addresses).and_then(
        [](symbols s) returns_from_caller {
            return s;
        });
    return std::unexpected(errors);
}

On Fri, 1 Aug 2025, 15:38 Andre Kostur, <andre_at_[hidden]> wrote:

> The first example that Ayrton started with. There exists a called
> function that returns a std::expected, and the user wants for the
> control flow to continue in the calling function if it does get the
> expected type, but return immediately if it gets the unexpected type.
> This description even encapsulates my thoughts on this feature in
> that note that I didn't have to say anything else about the called
> function, only that it returned a std::expected. I think P2561
> addresses the use-case better.
>
> This proposal feels like exceptions, just using a different mechanism
> (and is more syntactically invasive).
>
> On Fri, Aug 1, 2025 at 6:52 AM Iúri Chaer via Std-Proposals
> <std-proposals_at_[hidden]> wrote:
> >
> > > Not all return paths in the callable should cause the caller to
> immediately return.
> >
> > What's the usage scenario you have in mind? The initial example from the
> thread looks like it suffers from the same type of ergonomic constraint
> that keeps me from using monadic functions more frequently, which doesn't
> require that sort of complexity... I have to agree with the others who
> compared that form of the proposal with exceptions, it's hard to reason
> about control flow in the presence of something like that.
> >
> > On Fri, 1 Aug 2025 at 14:07, Sebastian Wittmeier via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
> >>
> >> -----Ursprüngliche Nachricht-----
> >> Von: Andre Kostur via Std-Proposals <std-proposals_at_[hidden]>
> >>
> >>
> >>
> >> >Not all return paths in the callable should cause the caller to
> immediately return.
> >>
> >>
> >> >I’m still thinking that the callable shouldn’t have to know about
> this, and it should be entirely within the caller’s domain as to whether to
> >return immediately or not.
> >>
> >>
> >>
> >>
> >>
> >> Then why not create a special command to invoke the callable.
> >>
> >> The caller can decide, whether to use this command or not..
> >>
> >>
> >>
> >>
> >>
> >> OTOH should this work the same as exceptions?
> >>
> >> Why not use the same or similar language constructs?
> >>
> >> Probably the in-between functions need to know more about, which
> exceptions can be thrown.
> >>
> >>
> >>
> >> --
> >> 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 2025-08-02 09:41:37