C++ Logo

std-discussion

Advanced search

With `co_return` and `return` diff symbols harms template generic programming

From: Sopl'Wang <sopl.wang_at_[hidden]>
Date: Thu, 19 Dec 2019 01:29:59 +0800
*"Subroutines (functions) are special cases of coroutines". -- from
Wikipedia*

When coding function template and fighting with distinct '*return*' and '
*co_return*' keywords, I'm certain that function and coroutine are same in
general more. But with diff wording I find it inconvenient and broken
modern C++ template and generic programming idiom.

Say if I have a `*max(a, b)*` generic function, I need write two version
with current coroutine design:


template <class T>

const T max (const T a, const T b) {

  return (a < b) ? b : a;

}


template <class T, class R>

const R max (const T a, const T b) {

  co_return (a < b) ? b : a;

}


auto x = max<int>(1, 2);

auto y = co_await max<int, std::lazy<double>>(3, 4);


But with P1485: *"Better keywords for the Coroutines"* and tweak a bit (use
`*async(bool)*`, like `*noexcept(bool)*` does), I find just need write one:


template <class T, class R = T>

const R max (const T a, const T b) async(std::is_awaitable_v<R>) {

  return (a < b) ? b : a;

}


auto x = max<int>(1, 2);

auto y = await max<int, std::lazy<double>>(3, 4);


Modern C++ is centrally on template / generic programming and still making
it more widely. But current coroutine design strangely broken it (and be
accepted in c++20).

Looks like P1485 is not just perfection keywords but also defends on
template / generic programming the modern C++ core value.

Maybe the `*max(a, b)*` example too simple. But if `*async(false)*` can
ignore `*await*`'s async behaviour it can support more useful generic
functions like this one (from P1485):


template <class Stream>

auto f(Stream str) -> std::future_if_awaitable_t<Stream, int>
async(std::is_awaitable_v<Stream>)
{

  vector<Stream::value_type> buf = ...;

  int count = await str.read(512, buf);

  return count + 11;

}


With this `*f(Stream str)*` generic function, it can support in-memory `
*std::stringstream*` without async await well.

If we want protect C++ core value on template and generic programming, I
suggest committee reconsider P1485R1 in c++20 or 23.

Thanks!

--
soplwang

Received on 2019-12-18 11:32:37