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!
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