Date: Tue, 15 Sep 2020 23:26:12 +0200
Dmitry Dmitry via Std-Proposals <std-proposals_at_[hidden]> schrieb am
Di., 15. Sept. 2020, 23:03:
> As I said in https://lists.isocpp.org/std-proposals/2020/09/1811.php,
>> this already exists in C++20 in the form of coroutines... you just need to
>> opt in support for optional<T> in the only sensible way and then you can
>> write:
>>
>> std::optional<std::string> FindUsersCity(bool non_default) {
>> ConstactsSeriver cs = co_await GetOrOpenContatsServerConnection();
>> UserId uid = co_await cs.GetUserId();
>> GeoServer gs = co_await GetOrOpenGeoServerConnection();
>> Location uloc = co_await gw.GetLocationId(uid);
>> return uloc.GetCityName();
>> }
>>
>> co_await here is effectively syntax sugar for and_then() (in the same way
>> in Haskell do-notation is syntax sugar for bind). It's just that the
>> continuation gets written as the next statement in the function rather than
>> the body of a lambda that gets passed as an argument.
>>
>
> That is really nice, but can you elaborate more?
> Am I right that the trick is that expression of co_await can return
> an awaitable, await_ready() of which can return:
>
Just like that. But there is a catch to that, you need to wrap that
coroutine in order to provide a synchronous interface again. By abusing
`co_await` as an exit point for the entire coroutine, you loose the ability
to compose it with other coroutines.
So it it's actually a nasty hack, which both looks like it was using
coroutines, and simultaneously prevents you from actually using them as
intended moving forward.
> either false (in which case we effectively return from FindUsersCity and
it corresponds to some error),
And that's where you already fell for that misconception. It does not
return from FindUsersCity, but it aborts execution of the whole coroutine
context. Like an uncaught exception, unrolling the whole stack with it.
>
Di., 15. Sept. 2020, 23:03:
> As I said in https://lists.isocpp.org/std-proposals/2020/09/1811.php,
>> this already exists in C++20 in the form of coroutines... you just need to
>> opt in support for optional<T> in the only sensible way and then you can
>> write:
>>
>> std::optional<std::string> FindUsersCity(bool non_default) {
>> ConstactsSeriver cs = co_await GetOrOpenContatsServerConnection();
>> UserId uid = co_await cs.GetUserId();
>> GeoServer gs = co_await GetOrOpenGeoServerConnection();
>> Location uloc = co_await gw.GetLocationId(uid);
>> return uloc.GetCityName();
>> }
>>
>> co_await here is effectively syntax sugar for and_then() (in the same way
>> in Haskell do-notation is syntax sugar for bind). It's just that the
>> continuation gets written as the next statement in the function rather than
>> the body of a lambda that gets passed as an argument.
>>
>
> That is really nice, but can you elaborate more?
> Am I right that the trick is that expression of co_await can return
> an awaitable, await_ready() of which can return:
>
Just like that. But there is a catch to that, you need to wrap that
coroutine in order to provide a synchronous interface again. By abusing
`co_await` as an exit point for the entire coroutine, you loose the ability
to compose it with other coroutines.
So it it's actually a nasty hack, which both looks like it was using
coroutines, and simultaneously prevents you from actually using them as
intended moving forward.
> either false (in which case we effectively return from FindUsersCity and
it corresponds to some error),
And that's where you already fell for that misconception. It does not
return from FindUsersCity, but it aborts execution of the whole coroutine
context. Like an uncaught exception, unrolling the whole stack with it.
>
Received on 2020-09-15 16:26:27