Date: Sun, 11 Oct 2020 18:56:47 +0300
On 10/11/20 6:22 PM, Jason McKesson via Std-Proposals wrote:
> It seems to me that what you want is the equivalent of a proper tail
> call for coroutines. That's a valid thing to want.
>
> But you shouldn't co-opt a mechanism like `return_value` to gain this
> functionality just because it's convenient. C++ doesn't let you use
> `return <expr>` unless your function actually returns that value. The
> same ought to be true of `co_return <expr>`. If your coroutine is not
> actually returning the result of `<expr>`, then you shouldn't express
> it as `co_return`. And if your promise has a `return_value` function,
> then that function ought to do what it says: return a value of that
> type through its future.
>
> Let's not take mechanisms and make them do weird things just because
> it's convenient. You can build what you want without a new keyword
> just by employing a bit of indirection:
>
> ```
> co_await tail_continue(yet_another());
> co_return;
> ```
>
> Where `tail_continue` is a type that stores the future returned by
> `yet_another`. `co_await`ing on it will not suspend execution.
> Instead, it does what your hypothetical call to `return_value` would
> do: change the promise to use the given future.
Interesting idea. I agree with the general sense of requiring regularity
in co_return return types.
Your alternative implementation is nice (and easy to implement in my
use-case), but gives up something: the uniqueness of the return
statement. I can write
co_await tail_continue(yet_another());
co_await tail_continue(yet_another());
co_return;
And it can only be detected at run-time that I violated a constraint
that there can be only one tail-call leading to a co_return (and
another, not shown here, that it's illegal to co_await anything once
you've co_awaited a tail_continue).
But, I think that those problems are smaller than the one in my proposed
fix.
> It seems to me that what you want is the equivalent of a proper tail
> call for coroutines. That's a valid thing to want.
>
> But you shouldn't co-opt a mechanism like `return_value` to gain this
> functionality just because it's convenient. C++ doesn't let you use
> `return <expr>` unless your function actually returns that value. The
> same ought to be true of `co_return <expr>`. If your coroutine is not
> actually returning the result of `<expr>`, then you shouldn't express
> it as `co_return`. And if your promise has a `return_value` function,
> then that function ought to do what it says: return a value of that
> type through its future.
>
> Let's not take mechanisms and make them do weird things just because
> it's convenient. You can build what you want without a new keyword
> just by employing a bit of indirection:
>
> ```
> co_await tail_continue(yet_another());
> co_return;
> ```
>
> Where `tail_continue` is a type that stores the future returned by
> `yet_another`. `co_await`ing on it will not suspend execution.
> Instead, it does what your hypothetical call to `return_value` would
> do: change the promise to use the given future.
Interesting idea. I agree with the general sense of requiring regularity
in co_return return types.
Your alternative implementation is nice (and easy to implement in my
use-case), but gives up something: the uniqueness of the return
statement. I can write
co_await tail_continue(yet_another());
co_await tail_continue(yet_another());
co_return;
And it can only be detected at run-time that I violated a constraint
that there can be only one tail-call leading to a co_return (and
another, not shown here, that it's illegal to co_await anything once
you've co_awaited a tail_continue).
But, I think that those problems are smaller than the one in my proposed
fix.
Received on 2020-10-11 10:56:51