Topic: About possible generalization of N3722 -
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sun, 5 Jan 2014 23:59:08 +0200
Raw View
On 5 January 2014 23:55, Vicente J. Botet Escriba
<vicente.botet@wanadoo.fr> wrote:
> I was wondering if it would be acceptable to use the await operator for
> expected types, which makes the code much clean and easy to read.
Well, the discussions I've had with Niklas sort-of-indicate that it's
theoretically
possible to generalize resumption to any type that has shared semantics.
future works, shared_ptr should be possible to make work, but value-semantics
types like vectors don't fit in (if you 'yield' from an async
processing function
and do that by moving, what will your processing function do if it wants to
push_back more data? And the same question applies even if it yields by
copying).
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Mon, 06 Jan 2014 00:14:45 +0100
Raw View
Le 05/01/14 22:59, Ville Voutilainen a =E9crit :
> On 5 January 2014 23:55, Vicente J. Botet Escriba
> <vicente.botet@wanadoo.fr> wrote:
>> I was wondering if it would be acceptable to use the await operator for
>> expected types, which makes the code much clean and easy to read.
>
> Well, the discussions I've had with Niklas sort-of-indicate that it's
> theoretically
> possible to generalize resumption to any type that has shared semantics.
I don't understand what you mean.
> future works, shared_ptr should be possible to make work, but value-seman=
tics
> types like vectors don't fit in (if you 'yield' from an async
> processing function
> and do that by moving, what will your processing function do if it wants =
to
> push_back more data? And the same question applies even if it yields by
> copying).
>
I'm completely lost. I'm not talking about yield neither asynchronous=20
processing.
Vicente
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Mon, 6 Jan 2014 13:20:04 +0200
Raw View
On 6 January 2014 01:14, Vicente J. Botet Escriba
<vicente.botet@wanadoo.fr> wrote:
> Le 05/01/14 22:59, Ville Voutilainen a =E9crit :
>
>> On 5 January 2014 23:55, Vicente J. Botet Escriba
>> <vicente.botet@wanadoo.fr> wrote:
>>>
>>> I was wondering if it would be acceptable to use the await operator for
>>> expected types, which makes the code much clean and easy to read.
>>
>>
>> Well, the discussions I've had with Niklas sort-of-indicate that it's
>> theoretically
>> possible to generalize resumption to any type that has shared semantics.
>
> I don't understand what you mean.
I mean that the mechanism of transforming a resumable function into a,
well, stateful
function can likely be generalized further than the current proposal
that requires
futures.
>
>> future works, shared_ptr should be possible to make work, but
>> value-semantics
>> types like vectors don't fit in (if you 'yield' from an async
>> processing function
>> and do that by moving, what will your processing function do if it wants
>> to
>> push_back more data? And the same question applies even if it yields by
>> copying).
>>
> I'm completely lost. I'm not talking about yield neither asynchronous
> processing.
Why do you want to use await if your resumable functions aren't stateful?
That's what I meant by 'yield'. And as mentioned above, having a stateful
resumable function doesn't indeed necessarily mean that the function
is asynchronous, just that it's well, stateful.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Mon, 06 Jan 2014 19:34:19 +0100
Raw View
This is a multi-part message in MIME format.
--------------040800030306080106020002
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 06/01/14 12:20, Ville Voutilainen a =E9crit :
> On 6 January 2014 01:14, Vicente J. Botet Escriba
> <vicente.botet@wanadoo.fr> wrote:
>> Le 05/01/14 22:59, Ville Voutilainen a =E9crit :
>>
>>> On 5 January 2014 23:55, Vicente J. Botet Escriba
>>> <vicente.botet@wanadoo.fr> wrote:
>>>> I was wondering if it would be acceptable to use the await operator fo=
r
>>>> expected types, which makes the code much clean and easy to read.
>>>
>>> Well, the discussions I've had with Niklas sort-of-indicate that it's
>>> theoretically
>>> possible to generalize resumption to any type that has shared semantics=
..
>> I don't understand what you mean.
> I mean that the mechanism of transforming a resumable function into a,
> well, stateful
> function can likely be generalized further than the current proposal
> that requires
> futures.
>
>>> future works, shared_ptr should be possible to make work, but
>>> value-semantics
>>> types like vectors don't fit in (if you 'yield' from an async
>>> processing function
>>> and do that by moving, what will your processing function do if it want=
s
>>> to
>>> push_back more data? And the same question applies even if it yields by
>>> copying).
>>>
>> I'm completely lost. I'm not talking about yield neither asynchronous
>> processing.
>
> Why do you want to use await if your resumable functions aren't stateful?
The functions that I want to define are neither resumable nor stateful.=20
I want to use some syntactic sugar (as the do-notation of Haskell)
expected<int> madd(expected<int> a, expected<int> b) {
x <- a;
y <- b;
return x +*y*;
}
> That's what I meant by 'yield'. And as mentioned above, having a stateful
> resumable function doesn't indeed necessarily mean that the function
> is asynchronous, just that it's well, stateful.
>
Right. But I don't want to define resumable functions. My main concerns=20
is: is there a sens to use the proposed await operator for functions=20
that are not resumable. If not, I would need to look for an additional,=20
let me say, 'expect' operator.
expected<int> madd(expected<int> a, expected<int> b) {
auto x =3D expect a;
auto y =3D expect b;
return x +*y*;
}
Or said in other words. Could the new operator be used for both expected=20
and future?
template <class T>
// requires Monad<T>();
T madd(T a, T b) resumable(is_blocking<T>::value) {
return*$* a +*$* b;
}
Vicente
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--------------040800030306080106020002
Content-Type: text/html; charset=ISO-8859-1
<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<div class="moz-cite-prefix">Le 06/01/14 12:20, Ville Voutilainen a
écrit :<br>
</div>
<blockquote
cite="mid:CAFk2RUaebV5ijNhTo=E_48sisR0TvykJqNgmvcQPVCx6hS5ONw@mail.gmail.com"
type="cite">
<pre wrap="">On 6 January 2014 01:14, Vicente J. Botet Escriba
<a class="moz-txt-link-rfc2396E" href="mailto:vicente.botet@wanadoo.fr"><vicente.botet@wanadoo.fr></a> wrote:
</pre>
<blockquote type="cite">
<pre wrap="">Le 05/01/14 22:59, Ville Voutilainen a écrit :
</pre>
<blockquote type="cite">
<pre wrap="">On 5 January 2014 23:55, Vicente J. Botet Escriba
<a class="moz-txt-link-rfc2396E" href="mailto:vicente.botet@wanadoo.fr"><vicente.botet@wanadoo.fr></a> wrote:
</pre>
<blockquote type="cite">
<pre wrap="">
I was wondering if it would be acceptable to use the await operator for
expected types, which makes the code much clean and easy to read.
</pre>
</blockquote>
<pre wrap="">
Well, the discussions I've had with Niklas sort-of-indicate that it's
theoretically
possible to generalize resumption to any type that has shared semantics.
</pre>
</blockquote>
<pre wrap="">
I don't understand what you mean.
</pre>
</blockquote>
<pre wrap="">
I mean that the mechanism of transforming a resumable function into a,
well, stateful
function can likely be generalized further than the current proposal
that requires
futures.
</pre>
<blockquote type="cite">
<pre wrap="">
</pre>
<blockquote type="cite">
<pre wrap="">future works, shared_ptr should be possible to make work, but
value-semantics
types like vectors don't fit in (if you 'yield' from an async
processing function
and do that by moving, what will your processing function do if it wants
to
push_back more data? And the same question applies even if it yields by
copying).
</pre>
</blockquote>
<pre wrap="">I'm completely lost. I'm not talking about yield neither asynchronous
processing.
</pre>
</blockquote>
<pre wrap="">
Why do you want to use await if your resumable functions aren't stateful?</pre>
</blockquote>
The functions that I want to define are neither resumable nor
stateful. I want to use some syntactic sugar (as the do-notation of
Haskell)<br>
<br>
<pre>expected<int> madd(expected<int> a, expected<int> b) {
x <- a;
y <- b;
return x + <b>y</b>;
}
</pre>
<br>
<blockquote
cite="mid:CAFk2RUaebV5ijNhTo=E_48sisR0TvykJqNgmvcQPVCx6hS5ONw@mail.gmail.com"
type="cite">
<pre wrap="">
That's what I meant by 'yield'. And as mentioned above, having a stateful
resumable function doesn't indeed necessarily mean that the function
is asynchronous, just that it's well, stateful.
</pre>
</blockquote>
Right. But I don't want to define resumable functions. My main
concerns is: is there a sens to use the proposed await operator for
functions that are not resumable. If not, I would need to look for
an additional, let me say, 'expect' operator.<br>
<br>
<pre>expected<int> madd(expected<int> a, expected<int> b) {
auto x = expect a;
auto y = expect b;
return x + <b>y</b>;
}
</pre>
Or said in other words. Could the new operator be used for both
expected and future?<br>
<br>
<pre>template <class T>
// requires Monad<T>();
T madd(T a, T b) resumable(is_blocking<T>::value) {
return <b>$</b> a + <b>$</b> b;
}
</pre>
<br>
Vicente<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href="http://groups.google.com/a/isocpp.org/group/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br />
--------------040800030306080106020002--
.
Author: Oliver Kowalke <oliver.kowalke@gmail.com>
Date: Mon, 6 Jan 2014 19:42:52 +0100
Raw View
--001a11c1fd6293b82e04ef51a0cf
Content-Type: text/plain; charset=ISO-8859-1
2014/1/6 Vicente J. Botet Escriba <vicente.botet@wanadoo.fr>
> expected<int> madd(expected<int> a, expected<int> b) {
> auto x = expect a;
> auto y = expect b;
> return x + *y*;
> }
>
> do this mean that operator 'expect' suspends madd() until 'a' becomes
ready (and the same for 'b')?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a11c1fd6293b82e04ef51a0cf
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">2014=
/1/6 Vicente J. Botet Escriba <span dir=3D"ltr"><<a href=3D"mailto:vicen=
te.botet@wanadoo.fr" target=3D"_blank">vicente.botet@wanadoo.fr</a>></sp=
an><br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-lef=
t:1px #ccc solid;padding-left:1ex"><div bgcolor=3D"#FFFFFF" text=3D"#000000=
"><pre>expected<int> madd(expected<int> a, expected<int> =
b) {
auto x =3D expect a;
auto y =3D expect b;
=A0return x + <b>y</b>;
}<br></pre></div></blockquote></div>=A0do this mean that operator 'expe=
ct' suspends madd() until 'a' becomes ready (and the same for &=
#39;b')?<br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a11c1fd6293b82e04ef51a0cf--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Mon, 6 Jan 2014 20:46:14 +0200
Raw View
On 6 January 2014 20:34, Vicente J. Botet Escriba
<vicente.botet@wanadoo.fr> wrote:
>> Why do you want to use await if your resumable functions aren't stateful?
>
> The functions that I want to define are neither resumable nor stateful. I
> want to use some syntactic sugar (as the do-notation of Haskell)
>
> expected<int> madd(expected<int> a, expected<int> b) {
> x <- a;
> y <- b;
> return x + y;
> }
I don't speak Haskell, so I have no idea what this syntactic sugar is
supposed to do.
> Right. But I don't want to define resumable functions. My main concerns is:
> is there a sens to use the proposed await operator for functions that are
> not resumable. If not, I would need to look for an additional, let me say,
I don't think so. await is for suspending a resumable function if its
shared-semantics
result is not ready yet.
> 'expect' operator.
>
> expected<int> madd(expected<int> a, expected<int> b) {
> auto x = expect a;
> auto y = expect b;
> return x + y;
> }
>
> Or said in other words. Could the new operator be used for both expected and
> future?
>
> template <class T>
> // requires Monad<T>();
> T madd(T a, T b) resumable(is_blocking<T>::
> value) {
> return $ a + $ b;
> }
That would likely depend on what this operator is supposed to do. :)
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Jeffrey Yasskin <jyasskin@google.com>
Date: Mon, 6 Jan 2014 11:13:31 -0800
Raw View
I believe it would be possible to define the "Awaitable" concept so
that it would work for arbitrary monads, but I haven't found time to
write up the definition that would be required, so I can't be sure. If
you're motivated about this feature, I think it would be valuable for
you to try to define the needed concept. Usage examples in an email
aren't going to be enough to demonstrate what's actually needed,
although they will be useful in the eventual paper.
On Mon, Jan 6, 2014 at 10:34 AM, Vicente J. Botet Escriba
<vicente.botet@wanadoo.fr> wrote:
> Le 06/01/14 12:20, Ville Voutilainen a =E9crit :
>
> On 6 January 2014 01:14, Vicente J. Botet Escriba
> <vicente.botet@wanadoo.fr> wrote:
>
> Le 05/01/14 22:59, Ville Voutilainen a =E9crit :
>
> On 5 January 2014 23:55, Vicente J. Botet Escriba
> <vicente.botet@wanadoo.fr> wrote:
>
> I was wondering if it would be acceptable to use the await operator for
> expected types, which makes the code much clean and easy to read.
>
> Well, the discussions I've had with Niklas sort-of-indicate that it's
> theoretically
> possible to generalize resumption to any type that has shared semantics.
>
> I don't understand what you mean.
>
> I mean that the mechanism of transforming a resumable function into a,
> well, stateful
> function can likely be generalized further than the current proposal
> that requires
> futures.
>
> future works, shared_ptr should be possible to make work, but
> value-semantics
> types like vectors don't fit in (if you 'yield' from an async
> processing function
> and do that by moving, what will your processing function do if it wants
> to
> push_back more data? And the same question applies even if it yields by
> copying).
>
> I'm completely lost. I'm not talking about yield neither asynchronous
> processing.
>
> Why do you want to use await if your resumable functions aren't stateful?
>
> The functions that I want to define are neither resumable nor stateful. I
> want to use some syntactic sugar (as the do-notation of Haskell)
>
> expected<int> madd(expected<int> a, expected<int> b) {
> x <- a;
> y <- b;
> return x + y;
> }
>
>
> That's what I meant by 'yield'. And as mentioned above, having a stateful
> resumable function doesn't indeed necessarily mean that the function
> is asynchronous, just that it's well, stateful.
>
> Right. But I don't want to define resumable functions. My main concerns i=
s:
> is there a sens to use the proposed await operator for functions that are
> not resumable. If not, I would need to look for an additional, let me say=
,
> 'expect' operator.
>
> expected<int> madd(expected<int> a, expected<int> b) {
> auto x =3D expect a;
> auto y =3D expect b;
> return x + y;
> }
>
> Or said in other words. Could the new operator be used for both expected =
and
> future?
>
> template <class T>
> // requires Monad<T>();
> T madd(T a, T b) resumable(is_blocking<T>::
> value) {
> return $ a + $ b;
> }
>
>
> Vicente
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Mon, 06 Jan 2014 22:02:31 +0100
Raw View
This is a multi-part message in MIME format.
--------------030602090002020308040305
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 06/01/14 19:42, Oliver Kowalke a =E9crit :
> 2014/1/6 Vicente J. Botet Escriba <vicente.botet@wanadoo.fr=20
> <mailto:vicente.botet@wanadoo.fr>>
>
> expected<int> madd(expected<int> a, expected<int> b) {
> auto x =3D expect a;
> auto y =3D expect b;
> return x +*y*;
> }
>
> do this mean that operator 'expect' suspends madd() until 'a' becomes=20
> ready (and the same for 'b')?
>
No. a and b (as any expected<T>) are always ready by construction. The=20
meaning of madd depends on the validity of a and b as defined by
expected<int> madd(expected<int> a, expected<int> b) {
if (!a.valid()) return exceptional(a);
auto x =3D a.value();
if (!b.valid()) return exceptional(a);
auto y =3D b.value();
return x +*y*;
}
The syntactic sugar the expect operator would provide is to just replace
expected<int> madd(expected<int> a, expected<int> b) {
return expect a + expect b;
}
by the preceding definition.
But if we define a generic function
template <class T>
// requires Monad<T>();
T madd(T a, T b)*resumable**(is_blocking<T>::value)* {
return $ a + $ b;
}
where $ is the new operator, the meaning of
future<int> f1();
future<int> f2();
auto f =3D madd(f1(), f2());
would be the one given by the Resumable function
future<int> madd(future<int> a, future<int> b)*resumable* {
return*await* a +*await* b;
}
while
std::expected<int> f1();
std::expected<int> f2();
auto f =3D madd(f1(), f2());
would be one I give before with
expected<int> madd(expected<int> a, expected<int> b) {
return*expect* a +*expect* b;
}
Resuming the question is: is it good to be able to define such generic=20
functions that can work with=20
future/shared_future/expected/optional/unique_ptr/shared_ptr ...
Vicente
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--------------030602090002020308040305
Content-Type: text/html; charset=ISO-8859-1
<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<div class="moz-cite-prefix">Le 06/01/14 19:42, Oliver Kowalke a
écrit :<br>
</div>
<blockquote
cite="mid:CA+wfc18i=UCSai4+yb8uR-Ththy2Srkd8EmNaWtXeGOS9LtpJQ@mail.gmail.com"
type="cite">
<div dir="ltr">
<div class="gmail_extra">
<div class="gmail_quote">2014/1/6 Vicente J. Botet Escriba <span
dir="ltr"><<a moz-do-not-send="true"
href="mailto:vicente.botet@wanadoo.fr" target="_blank">vicente.botet@wanadoo.fr</a>></span><br>
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">
<div bgcolor="#FFFFFF" text="#000000">
<pre>expected<int> madd(expected<int> a, expected<int> b) {
auto x = expect a;
auto y = expect b;
return x + <b>y</b>;
}
</pre>
</div>
</blockquote>
</div>
do this mean that operator 'expect' suspends madd() until 'a'
becomes ready (and the same for 'b')?<br>
</div>
</div>
<br>
</blockquote>
No. a and b (as any expected<T>) are always ready by
construction. The meaning of madd depends on the validity of a and b
as defined by<br>
<pre>expected<int> madd(expected<int> a, expected<int> b) {
if (!a.valid()) return exceptional(a);
auto x = a.value();
if (!b.valid()) return exceptional(a);
auto y = b.value();
return x + <b>y</b>;
}
The syntactic sugar the expect operator would provide is to just replace
expected<int> madd(expected<int> a, expected<int> b) {
return expect a + expect b;
}
by the preceding definition.
But if we define a generic function
template <class T>
// requires Monad<T>();
T madd(T a, T b) <b>resumable</b><b>(is_blocking<T>::value)</b> {
return $ a + $ b;
}
where $ is the new operator, the meaning of
future<int> f1();
future<int> f2();
auto f = madd(f1(), f2());
would be the one given by the Resumable function
future<int> madd(future<int> a, future<int> b) <b>resumable</b> {
return <b>await</b> a + <b>await</b> b;
}
while
std::expected<int> f1();
std::expected<int> f2();
auto f = madd(f1(), f2());
would be one I give before with
expected<int> madd(expected<int> a, expected<int> b) {
return <b>expect</b> a + <b>expect</b> b;
}
</pre>
Resuming the question is: is it good to be able to define such
generic functions that can work with
future/shared_future/expected/optional/unique_ptr/shared_ptr ...<br>
<br>
Vicente<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href="http://groups.google.com/a/isocpp.org/group/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br />
--------------030602090002020308040305--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Mon, 06 Jan 2014 23:14:29 +0100
Raw View
This is a multi-part message in MIME format.
--------------070603070500000200030508
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 06/01/14 20:13, Jeffrey Yasskin a =E9crit :
> I believe it would be possible to define the "Awaitable" concept so
> that it would work for arbitrary monads, but I haven't found time to
> write up the definition that would be required, so I can't be sure. If
> you're motivated about this feature, I think it would be valuable for
> you to try to define the needed concept. Usage examples in an email
> aren't going to be enough to demonstrate what's actually needed,
> although they will be useful in the eventual paper.
>
>
Agreed. My intention is to get feedback and see if there is enough=20
interest in order to write such a paper.
future<T> and expected<T> can be seen as monads and the .then() function=20
as the monad bind function.
I see two alternatives. Either both conforms to a common syntax and=20
semantics or we define a concept map that allows to see=20
unique_ptr/optional/expected as models of the monad concept even if the=20
class doesn't defines a .then() function.
A good and elegant example of this mapping is given in [1] Monads in=20
C++. Please read it before continuing.
The library allows to define functions as
template< class M , class Mo=3DMonad<Cat<M>>
M addM( const M& a, const M& b )
{
return mbind (
[&]( int x ) {
return mbind (
[=3D]( int y ) { return mreturn<M>(x+y); },
b
);
}, a
);
}
where Cat<M> is used as tag dispatcher and
template< class ... > struct Monad;
template< class F, class M, class Mo=3DMonad<Cat<M>> >
auto mbind( F&& f, M&& m )
-> decltype( Mo::mbind(std::declval<F>(),std::declval<M>()) )
{
return Mo::mbind( std::forward<F>(f), std::forward<M>(m) );
}
// The first template argument must be explicit!
template< class M, class X, class Mo =3D Monad<Cat<M>> >
M mreturn( X&& x ) {
// We have to forward the monad type, too.
return Mo::template mreturn<M>( std::forward<X>(x) );
}
This function addM can be used with unique_ptr/vector/... provided the=20
convenient specialization of the Monad class. E.g. for monads having=20
pointer like semantics the specialization is
template< > struct Monad< pointer_tag > {
template< class F, template<class...>class Ptr, class X,
class R =3D typename std::result_of<F(X)>::type >
static R mbind( F&& f, const Ptr<X>& p ) {
// Just like fmap, but without needing to explicitly return the co=
rrect type.
return p ? std::forward<F>(f)( *p ) : nullptr;
}
template< class M, class X >
static M mreturn( X&& x ) {
// All smart pointers define element_type.
using Y =3D typename M::element_type;
return M( new Y(std::forward<X>(x)) );
}
};
Once you have the good Monad concept, the syntactic sugar would be=20
applicable to any model of this concept.
The generic semantics of the operator$ (await/expect or whatever is a=20
good name) could be given by program transformation.
After a 1st step flattening the operator$ calls
template <class T>
// requires Monad<T>();
T madd(T a, T b) resumable(is_blocking<T>::value) {
return $ a + $ b;
}
the function becomes
template <class T>
// requires Monad<T>();
T madd(T a, T b) resumable(is_blocking<T>::value) {
auto x =3D $ a;
auto y =3D $ b;
return x + y;
}
Next auto x =3D $ a; .... is transformed as follows
template <class T>
// requires Monad<T>();
T madd(T a, T b) resumable(is_blocking<T>::value) {
return a.then([](auto x) { // Or mbind
auto y =3D $ b;
return x + y;
});
}
and then auto y =3D $ b; .... is transformed as follows
template <class T>
// requires Monad<T>();
T madd(T a, T b) resumable(is_blocking<T>::value) {
return a.then([=3D](auto x) {
return b.then([=3D](auto y) {
return x + y;
});
});
}
This transformation gives the generic meaning, but this could be not=20
efficient enough and the compiler could be able to generate=20
implementations that are more efficient for a specific kind of monad.=20
E.g. N3722 suggest two possible implementations of resumable functions=20
and resumable points on future/shared_future. The implementation I gave=20
for expected when the function is not resumable is the most efficient=20
implementation I know. If tags were use, the compiler could generate=20
different code depending on the tag.
Vicente
[1] http://yapb-soc.blogspot.fr/2012/10/monads-in-c.html
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--------------070603070500000200030508
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta content=3D"text/html; charset=3DISO-8859-1"
http-equiv=3D"Content-Type">
</head>
<body bgcolor=3D"#FFFFFF" text=3D"#000000">
<div class=3D"moz-cite-prefix">Le 06/01/14 20:13, Jeffrey Yasskin a
écrit :<br>
</div>
<blockquote
cite=3D"mid:CANh-dXnyR_-OS6u+nj1W6e5uumL2RM1mw20gzPzm67kch1zKsw@mail.gmail.=
com"
type=3D"cite">
<pre wrap=3D"">I believe it would be possible to define the "Awaitabl=
e" concept so
that it would work for arbitrary monads, but I haven't found time to
write up the definition that would be required, so I can't be sure. If
you're motivated about this feature, I think it would be valuable for
you to try to define the needed concept. Usage examples in an email
aren't going to be enough to demonstrate what's actually needed,
although they will be useful in the eventual paper.
</pre>
</blockquote>
Agreed. My intention is to get feedback and see if there is enough
interest in order to write such a paper.<br>
<br>
future<T> and expected<T> can be seen as monads and the
.then() function as the monad bind function.<br>
<br>
I see two alternatives. Either both conforms to a common syntax and
semantics or we define a concept map that allows to see
unique_ptr/optional/expected as models of the monad concept even if
the class doesn't defines a .then() function. <br>
<br>
A good and elegant example of this mapping is given in [1] Monads in
C++. Please read it before continuing.<br>
<br>
The library allows to define functions as<br>
<br>
<meta charset=3D"utf-8">
<pre style=3D"color: rgb(0, 0, 0); font-style: normal; font-variant: no=
rmal; font-weight: normal; letter-spacing: normal; line-height: normal; orp=
hans: auto; text-align: start; text-indent: 0px; text-transform: none; wido=
ws: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">template< =
class M , class Mo=3DMonad<Cat<M>>
M addM( const M& a, const M& b )=20
{
return mbind (
[&]( int x ) {
return mbind (=20
[=3D]( int y ) { return mreturn<M>(x+y); },
b
);
}, a
);
}
where Cat<M> is used as tag dispatcher and
<meta charset=3D"utf-8">template< class ... > struct Monad;
template< class F, class M, class Mo=3DMonad<Cat<M>> >
auto mbind( F&& f, M&& m )
-> decltype( Mo::mbind(std::declval<F>(),std::declva=
l<M>()) )
{
return Mo::mbind( std::forward<F>(f), std::forward<M=
>(m) );
}
// The first template argument must be explicit!
template< class M, class X, class Mo =3D Monad<Cat<M>> >
M mreturn( X&& x ) {
// We have to forward the monad type, too.
return Mo::template mreturn<M>( std::forward<X>(x=
) );
}
<pre style=3D"color: rgb(0, 0, 0); font-style: normal; font-variant: normal=
; font-weight: normal; letter-spacing: normal; line-height: normal; orphans=
: auto; text-align: start; text-indent: 0px; text-transform: none; widows: =
auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"></pre></pre>
This function addM can be used with unique_ptr/vector/... provide=
d
the convenient specialization of the Monad class. E.g. for monads
having pointer like semantics the specialization is<br>
<br>
<meta charset=3D"utf-8">
<pre style=3D"color: rgb(0, 0, 0); font-style: normal; font-variant: no=
rmal; font-weight: normal; letter-spacing: normal; line-height: normal; orp=
hans: auto; text-align: start; text-indent: 0px; text-transform: none; wido=
ws: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">template< =
> struct Monad< pointer_tag > {
template< class F, template<class...>class Ptr, clas=
s X,
class R =3D typename std::=
result_of<F(X)>::type >
static R mbind( F&& f, const Ptr<X>& p ) {
// Just like fmap, but without needing to expli=
citly return the correct type.
return p ? std::forward<F>(f)( *p ) : nul=
lptr;
}
template< class M, class X >
static M mreturn( X&& x ) {
// All smart pointers define element_type.
using Y =3D typename M::element_type;=20
return M( new Y(std::forward<X>(x)) );
}
};</pre>
<br>
Once you have the good Monad concept, the syntactic sugar would be
applicable to any model of this concept. <br>
The generic semantics of the operator$ (await/expect or whatever is
a good name) could be given by program transformation.<br>
<br>
After a 1st step flattening the operator$ calls<br>
<pre>template <class T>
// requires Monad<T>();
T madd(T a, T b) resumable(is_blocking<T>::value) {
return $ a + $ b;
}
the function becomes
template <class T>
// requires Monad<T>();
T madd(T a, T b) resumable(is_blocking<T>::value) {
auto x =3D $ a;
auto y =3D $ b;
return x + y;
}
</pre>
Next auto x =3D $ a; .... is transformed as follows<br>
<br>
<pre>template <class T>
// requires Monad<T>();
T madd(T a, T b) resumable(is_blocking<T>::value) {
return a.then([](auto x) { // Or mbind
auto y =3D $ b;
return x + y;
});=20
}
and then auto y =3D $ b; .... is transformed as follows
template <class T>
// requires Monad<T>();
T madd(T a, T b) resumable(is_blocking<T>::value) {
return a.then([=3D](auto x) {
return b.then([=3D](auto y) {
return x + y;
});=20
});=20
}
</pre>
This transformation gives the generic meaning, but this could be not
efficient enough and the compiler could be able to generate
implementations that are more efficient for a specific kind of
monad. E.g. N3722 suggest two possible implementations of resumable
functions and resumable points on future/shared_future. The
implementation I gave for expected when the function is not
resumable is the most efficient implementation I know. If tags were
use, the compiler could generate different code depending on the
tag.<br>
<br>
Vicente<br>
<br>
[1] <a class=3D"moz-txt-link-freetext" href=3D"http://yapb-soc.blogspot=
..fr/2012/10/monads-in-c.html">http://yapb-soc.blogspot.fr/2012/10/monads-in=
-c.html</a><br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--------------070603070500000200030508--
.
Author: hun.nemethpeter@gmail.com
Date: Mon, 6 Jan 2014 15:06:57 -0800 (PST)
Raw View
------=_Part_839_17099960.1389049617574
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
We can use compile time reflection here. So you can write a pattern
(definition of pattern comes from here:=20
https://github.com/hun-nemethpeter/cpp-reflector-mini/blob/master/Proposal.=
md
)
that takes the original madd function definition and transform it to an=20
other definition.
$buildResumableFunction(madd, "madd_r");
Peter
On Monday, January 6, 2014 10:02:31 PM UTC+1, Vicente J. Botet Escriba=20
wrote:
>
> Le 06/01/14 19:42, Oliver Kowalke a =E9crit :
> No. a and b (as any expected<T>) are always ready by construction. The=
=20
> meaning of madd depends on the validity of a and b as defined by
>
> expected<int> madd(expected<int> a, expected<int> b) {
> if (!a.valid()) return exceptional(a);
> auto x =3D a.value();
> if (!b.valid()) return exceptional(a);
> auto y =3D b.value();
> return x + *y*;
> }
>
> The syntactic sugar the expect operator would provide is to just replace
>
> expected<int> madd(expected<int> a, expected<int> b) {
> return expect a + expect b;
> }
>
> by the preceding definition.
>
>
> =20
>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_839_17099960.1389049617574
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">We can use compile time reflection here. So you can write =
a pattern<br>(definition of pattern comes from here: <a href=3D"https://git=
hub.com/hun-nemethpeter/cpp-reflector-mini/blob/master/Proposal.md">https:/=
/github.com/hun-nemethpeter/cpp-reflector-mini/blob/master/Proposal.md</a>)=
<br> that takes the original madd function definition and transform it=
to an other definition.<br><br>$buildResumableFunction(madd, "madd_r");<br=
><br>Peter<br><br>On Monday, January 6, 2014 10:02:31 PM UTC+1, Vicente J. =
Botet Escriba wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
=20
=20
=20
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<div>Le 06/01/14 19:42, Oliver Kowalke a
=E9crit :<br>
</div>
=20
No. a and b (as any expected<T>) are always ready by
construction. The meaning of madd depends on the validity of a and b
as defined by<br>
<pre>expected<int> madd(expected<int> a, expected<int>=
; b) {
if (!a.valid()) return exceptional(a);
auto x =3D a.value();
if (!b.valid()) return exceptional(a);
auto y =3D b.value();
return x + <b>y</b>;
}
The syntactic sugar the expect operator would provide is to just replace
expected<int> madd(expected<int> a, expected<int> b) {
return expect a + expect b;
}
by the preceding definition.
<br>
</pre><br></div>
</blockquote></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_839_17099960.1389049617574--
.
Author: Geoffrey Romer <gromer@google.com>
Date: Tue, 7 Jan 2014 11:59:27 -0800
Raw View
--001a11c2b27c4fa35204ef66d08d
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Note that N3722's predecessors used to support exactly what you want:
in N3328, 'await' was defined as more or less a fully general monadic
binding operator. However, this was changed in N3564, where 'await' was
restricted to future/shared_future operands. If you can determine why that
change was made, that might give you some clues about whether and how to
reverse it.
On Mon, Jan 6, 2014 at 2:14 PM, Vicente J. Botet Escriba <
vicente.botet@wanadoo.fr> wrote:
> Le 06/01/14 20:13, Jeffrey Yasskin a =E9crit :
>
> I believe it would be possible to define the "Awaitable" concept so
> that it would work for arbitrary monads, but I haven't found time to
> write up the definition that would be required, so I can't be sure. If
> you're motivated about this feature, I think it would be valuable for
> you to try to define the needed concept. Usage examples in an email
> aren't going to be enough to demonstrate what's actually needed,
> although they will be useful in the eventual paper.
>
>
>
> Agreed. My intention is to get feedback and see if there is enough
> interest in order to write such a paper.
>
> future<T> and expected<T> can be seen as monads and the .then() function
> as the monad bind function.
>
> I see two alternatives. Either both conforms to a common syntax and
> semantics or we define a concept map that allows to see
> unique_ptr/optional/expected as models of the monad concept even if the
> class doesn't defines a .then() function.
>
> A good and elegant example of this mapping is given in [1] Monads in C++.
> Please read it before continuing.
>
> The library allows to define functions as
>
> template< class M , class Mo=3DMonad<Cat<M>>
> M addM( const M& a, const M& b )
> {
> return mbind (
> [&]( int x ) {
> return mbind (
> [=3D]( int y ) { return mreturn<M>(x+y); },
> b
> );
> }, a
>
> );
> }
>
> where Cat<M> is used as tag dispatcher and
>
> template< class ... > struct Monad;
>
> template< class F, class M, class Mo=3DMonad<Cat<M>> >
> auto mbind( F&& f, M&& m )
> -> decltype( Mo::mbind(std::declval<F>(),std::declval<M>()) )
> {
> return Mo::mbind( std::forward<F>(f), std::forward<M>(m) );
> }
>
> // The first template argument must be explicit!
> template< class M, class X, class Mo =3D Monad<Cat<M>> >
> M mreturn( X&& x ) {
> // We have to forward the monad type, too.
> return Mo::template mreturn<M>( std::forward<X>(x) );
> }
>
>
> This function addM can be used with unique_ptr/vector/... provided the
> convenient specialization of the Monad class. E.g. for monads having
> pointer like semantics the specialization is
>
> template< > struct Monad< pointer_tag > {
> template< class F, template<class...>class Ptr, class X,
> class R =3D typename std::result_of<F(X)>::type >
> static R mbind( F&& f, const Ptr<X>& p ) {
> // Just like fmap, but without needing to explicitly return the c=
orrect type.
> return p ? std::forward<F>(f)( *p ) : nullptr;
> }
>
> template< class M, class X >
> static M mreturn( X&& x ) {
> // All smart pointers define element_type.
> using Y =3D typename M::element_type;
> return M( new Y(std::forward<X>(x)) );
> }
> };
>
>
> Once you have the good Monad concept, the syntactic sugar would be
> applicable to any model of this concept.
> The generic semantics of the operator$ (await/expect or whatever is a goo=
d
> name) could be given by program transformation.
>
> After a 1st step flattening the operator$ calls
>
> template <class T>
> // requires Monad<T>();
> T madd(T a, T b) resumable(is_blocking<T>::
> value) {
> return $ a + $ b;
> }
>
> the function becomes
>
> template <class T>
> // requires Monad<T>();
> T madd(T a, T b) resumable(is_blocking<T>::value) {
> auto x =3D $ a;
> auto y =3D $ b;
> return x + y;
> }
>
> Next auto x =3D $ a; .... is transformed as follows
>
> template <class T>
> // requires Monad<T>();
> T madd(T a, T b) resumable(is_blocking<T>::
> value) {
> return a.then([](auto x) { // Or mbind
> auto y =3D $ b;
> return x + y;
> });
> }
>
> and then auto y =3D $ b; .... is transformed as follows
>
>
> template <class T>
> // requires Monad<T>();
> T madd(T a, T b) resumable(is_blocking<T>::value) {
> return a.then([=3D](auto x) {
> return b.then([=3D](auto y) {
> return x + y;
> });
> });
> }
>
>
> This transformation gives the generic meaning, but this could be not
> efficient enough and the compiler could be able to generate implementatio=
ns
> that are more efficient for a specific kind of monad. E.g. N3722 suggest
> two possible implementations of resumable functions and resumable points =
on
> future/shared_future. The implementation I gave for expected when the
> function is not resumable is the most efficient implementation I know. If
> tags were use, the compiler could generate different code depending on th=
e
> tag.
>
> Vicente
>
> [1] http://yapb-soc.blogspot.fr/2012/10/monads-in-c.html
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--001a11c2b27c4fa35204ef66d08d
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Note that N3722's predecessors used to support exactly=
what you want: in=A0N3328, 'await' was defined=A0as more or less a=
fully general monadic binding operator. However, this was changed in N3564=
, where 'await' was restricted to future/shared_future operands. If=
you can determine why that change was made, that might give you some clues=
about whether and how to reverse it.</div>
<div class=3D"gmail_extra"><br><br><div class=3D"gmail_quote">On Mon, Jan 6=
, 2014 at 2:14 PM, Vicente J. Botet Escriba <span dir=3D"ltr"><<a href=
=3D"mailto:vicente.botet@wanadoo.fr" target=3D"_blank">vicente.botet@wanado=
o.fr</a>></span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">
=20
=20
=20
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<div>Le 06/01/14 20:13, Jeffrey Yasskin a
=E9crit=A0:<br>
</div><div class=3D"im">
<blockquote type=3D"cite">
<pre>I believe it would be possible to define the "Awaitable&quo=
t; concept so
that it would work for arbitrary monads, but I haven't found time to
write up the definition that would be required, so I can't be sure. If
you're motivated about this feature, I think it would be valuable for
you to try to define the needed concept. Usage examples in an email
aren't going to be enough to demonstrate what's actually needed,
although they will be useful in the eventual paper.
</pre>
</blockquote></div>
Agreed. My intention is to get feedback and see if there is enough
interest in order to write such a paper.<br>
<br>
future<T> and expected<T> can be seen as monads and the
.then() function as the monad bind function.<br>
<br>
I see two alternatives. Either both conforms to a common syntax and
semantics or we define a concept map that allows to see
unique_ptr/optional/expected as models of the monad concept even if
the class doesn't defines a .then() function. <br>
<br>
A good and elegant example of this mapping is given in [1] Monads in
C++.=A0 Please read it before continuing.<br>
<br>
The library allows to define functions as<br>
<br>
=20
<pre style=3D"line-height:normal;text-indent:0px;letter-spacing:normal;=
text-align:start;font-variant:normal;text-transform:none;font-style:normal;=
font-weight:normal;word-spacing:0px">template< class M , class Mo=3DMona=
d<Cat<M>>
M addM( const M& a, const M& b )=20
{
=A0 =A0 return mbind (
[&]( int x ) {
return mbind (=20
[=3D]( int y ) { return mreturn<M>(x+y); },
b
);
}, a
=A0 =A0 );
}
where Cat<M> is used as tag dispatcher and
template< class ... > struct Monad;
template< class F, class M, class Mo=3DMonad<Cat<M>> >
auto mbind( F&& f, M&& m )
=A0 =A0 -> decltype( Mo::mbind(std::declval<F>(),std::declval<M=
>()) )
{
=A0 =A0 return Mo::mbind( std::forward<F>(f), std::forward<M>(m=
) );
}
// The first template argument must be explicit!
template< class M, class X, class Mo =3D Monad<Cat<M>> >
M mreturn( X&& x ) {
=A0 =A0 // We have to forward the monad type, too.
=A0 =A0 return Mo::template mreturn<M>( std::forward<X>(x) );
}
<pre style=3D"line-height:normal;text-indent:0px;letter-spacing:normal;text=
-align:start;font-variant:normal;text-transform:none;font-style:normal;font=
-weight:normal;word-spacing:0px"></pre></pre>
This function addM can be used=A0 with unique_ptr/vector/... provided
the convenient specialization of the Monad class. E.g. for monads
having pointer like semantics the specialization is<br>
<br>
=20
<pre style=3D"line-height:normal;text-indent:0px;letter-spacing:normal;=
text-align:start;font-variant:normal;text-transform:none;font-style:normal;=
font-weight:normal;word-spacing:0px">template< > struct Monad< poi=
nter_tag > {
=A0 =A0 template< class F, template<class...>class Ptr, class X,
=A0 =A0 =A0 =A0 =A0 =A0 =A0 class R =3D typename std::result_of<F(X)>=
::type >
=A0 =A0 static R mbind( F&& f, const Ptr<X>& p ) {
=A0 =A0 =A0 =A0 // Just like fmap, but without needing to explicitly return=
the correct type.
=A0 =A0 =A0 =A0 return p ? std::forward<F>(f)( *p ) : nullptr;
=A0 =A0 }
=A0 =A0 template< class M, class X >
=A0 =A0 static M mreturn( X&& x ) {
=A0 =A0 =A0 =A0 // All smart pointers define element_type.
=A0 =A0 =A0 =A0 using Y =3D typename M::element_type;=20
=A0 =A0 =A0 =A0 return M( new Y(std::forward<X>(x)) );
=A0 =A0 }
};</pre>
<br>
Once you have the good Monad concept, the syntactic sugar would be
applicable to any model of this concept. <br>
The generic semantics of the operator$ (await/expect or whatever is
a good name) could be given by program transformation.<br>
<br>
After a 1st step flattening the operator$ calls<br>
<pre><div class=3D"im">template <class T>
// requires Monad<T>();
T madd(T a, T b) resumable(is_blocking<T>::</div>value) {
return $ a + $ b;
}
the function becomes
template <class T>
// requires Monad<T>();
T madd(T a, T b) resumable(is_blocking<T>::value) {
=A0auto x =3D $ a;
auto y =3D $ b;
=A0return x + y;
}
</pre>
Next auto x =3D $ a; .... is transformed as follows<br>
<br>
<pre><div class=3D"im">template <class T>
// requires Monad<T>();
T madd(T a, T b) resumable(is_blocking<T>::</div>value) {
=A0return a.then([](auto x) { // Or mbind
auto y =3D $ b;
=A0 return x + y;
});=20
}
and then auto y =3D $ b; .... is transformed as follows
template <class T>
// requires Monad<T>();
T madd(T a, T b) resumable(is_blocking<T>::value) {
=A0return a.then([=3D](auto x) {
=A0 return b.then([=3D](auto y) {
=A0 return x + y;
});=20
});=20
}
</pre>
This transformation gives the generic meaning, but this could be not
efficient enough and the compiler could be able to generate
implementations that are more efficient for a specific kind of
monad. E.g. N3722 suggest two possible implementations of resumable
functions and resumable points on future/shared_future. The
implementation I gave for expected when the function is not
resumable is the most efficient implementation I know. If tags were
use, the compiler could generate different code depending on the
tag.<br>
<br>
Vicente<br>
<br>
[1] <a href=3D"http://yapb-soc.blogspot.fr/2012/10/monads-in-c.html" ta=
rget=3D"_blank">http://yapb-soc.blogspot.fr/2012/10/monads-in-c.html</a><br=
>
</div><div class=3D"HOEnZb"><div class=3D"h5">
<p></p>
-- <br>
=A0<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org" target=3D=
"_blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a11c2b27c4fa35204ef66d08d--
.
Author: =?UTF-8?Q?Klaim_=2D_Jo=C3=ABl_Lamotte?= <mjklaim@gmail.com>
Date: Tue, 7 Jan 2014 22:25:22 +0100
Raw View
--001a11c2903c972c8204ef680340
Content-Type: text/plain; charset=ISO-8859-1
On Tue, Jan 7, 2014 at 8:59 PM, Geoffrey Romer <gromer@google.com> wrote:
> Note that N3722's predecessors used to support exactly what you want:
> in N3328, 'await' was defined as more or less a fully general monadic
> binding operator. However, this was changed in N3564, where 'await' was
> restricted to future/shared_future operands. If you can determine why that
> change was made, that might give you some clues about whether and how to
> reverse it.
My guess would be that it would make the proposal easier to get voted
favorably when the feature is more restricted and it still allow relaxing
the requirements later.
I guess that having a separate proposal to change/make less restrictive the
first one is a modular approach to work with proposals.
But I might be wrong (I have no real experience of the process yet of
submitting proposals)
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a11c2903c972c8204ef680340
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">=
On Tue, Jan 7, 2014 at 8:59 PM, Geoffrey Romer <span dir=3D"ltr"><<a hre=
f=3D"mailto:gromer@google.com" target=3D"_blank">gromer@google.com</a>><=
/span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">Note that N3722's predecessors used to s=
upport exactly what you want: in=A0N3328, 'await' was defined=A0as =
more or less a fully general monadic binding operator. However, this was ch=
anged in N3564, where 'await' was restricted to future/shared_futur=
e operands. If you can determine why that change was made, that might give =
you some clues about whether and how to reverse it.</blockquote>
</div><br>My guess would be that it would make the proposal easier to get v=
oted favorably when the feature is more restricted and it still allow relax=
ing the requirements later.<br>I guess that having a separate proposal to c=
hange/make less restrictive the first one is a modular approach to work wit=
h proposals.</div>
<div class=3D"gmail_extra">But I might be wrong (I have no real experience =
of the process yet of submitting proposals)</div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a11c2903c972c8204ef680340--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Tue, 7 Jan 2014 13:45:39 -0800 (PST)
Raw View
------=_Part_790_11233981.1389131139491
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
6 January2014 =D0=B3., 1:55:23 UTC+4 Vicente J. Botet Escriba :
>
> I was wondering if it would be acceptable to use the *await* operator fo=
r expected types, which makes the code much clean and easy to read.
>
>
Having whole computation chain expressed as chain of nested continuations=
=20
allow us to do some special processing between steps, i.e. do "bind" of=20
given monad.
The obvious downside is that we have to cut computation code into=20
continuations and nest them.
"do" syntax sugar in Haskell basically linearizes chain of nested=20
continuations by doing automatic code transformation from linear form to=20
nested.
Coroutines (stackful or stackless, or await as higher-level abstraction on=
=20
top of them) allows to stop execution at some point and resume later.
"Resuming ticket" can be passed around, and can be used to resume function=
=20
execution at the right time.
In other words coroutines allow us to automatically turn rest of function=
=20
into continuation and pass it around.
So, I think that any monadic-style computation can be simulated by using=20
await (or coroutines in general) as you suggested.
=20
> The trait is_blocking<future<T>> would be true_type, while is_blocking<ex=
pected<T>> would be false_type.
>
> When the function is not resumable the translation of await expr is much =
simpler as there is no need to track the resume point.
>
> E.g.
>
> expected<int> madd(expected<int> a, expected<int> b) {
> return *await* a + *await* b;
> }
>
>
> could be equivalent to=20
>
> expected<int> madd(expected<int> a, expected<int> b) {
> auto x =3D await a;
> auto y =3D await b;
> return x + *y*;
> }
>
> that could be translated to
>
>
> expected<int> madd(expected<int> a, expected<int> b) {
> if (!a.valid()) return exceptional(a);
> auto x =3D a.value();
> if (!b.valid()) return exceptional(a);
> auto y =3D b.value();
> return x + *y*;
> }
>
>
As we are aimed to provide general solution, which should work for any=20
monad - what do you think, which form of definition bind or >>=3D should ha=
ve?
In Haskell it is function which takes continuation as second parameter, but=
=20
transformation from
auto x =3D await a;
to
if (!a.valid()) return exceptional(a);
auto x =3D a.value();
looks like a macro.
How to define such transformation in general way? Unless there is good=20
answer for that - we should stick to continuations (for await approach it=
=20
means to have resumable functions even for expected<T> monad).
P.S. In case if you want to play with internals of await - I made=20
proof-of-concept implementation of await based on Boost.Coroutine some time=
=20
ago - https://github.com/panaseleus/await_emu .=20
P.P.S. Today I have made simple linearizion of nested continuations based=
=20
on Boost.Preprocessor - DO macro: https://github.com/panaseleus/monad_do
P.P.P.S. I don't like N3722 - it merges cons of stackful (Boost.Coroutine)=
=20
and stackless coroutines (C# awat/yield) and loses their unique pros. I=20
should prepare new topic about this.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_790_11233981.1389131139491
Content-Type: text/html; charset=KOI8-R
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">6 January2014 =C7., 1:55:23 UTC+4 Vicente J. Botet Es=
criba :<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
=20
=20
=20
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
=20
<pre>I was wondering if it would be acceptable to use the <b>await</b> =
operator for expected types, which makes the code much clean and easy to re=
ad.
</pre></div></blockquote><div><br>Having whole computation chain expressed =
as chain of nested continuations allow us to do some special processing bet=
ween steps, i.e. do "bind" of given monad.<br>The obvious downside is=
that we have to cut computation code into continuations and nest them.<br>=
"do" syntax sugar in Haskell basically linearizes chain of nested continuat=
ions by doing automatic code transformation from linear form to nested.<br>=
<br>Coroutines (stackful or stackless, or await as higher-level abstraction=
on top of them) allows to stop execution at some point and resume later.<b=
r>"Resuming ticket" can be passed around, and can be used to resume functio=
n execution at the right time.<br>In other words coroutines allow us to aut=
omatically turn rest of function into continuation and pass it around.<br><=
br>So, I think that any monadic-style computation can be simulated by using=
await (or coroutines in general) as you suggested.<br> </div><blockqu=
ote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left=
: 1px #ccc solid;padding-left: 1ex;"><div bgcolor=3D"#FFFFFF" text=3D"#0000=
00"><pre>The trait is_blocking<future<T>> would be true_type, w=
hile is_blocking<expected<T>> would be false_type.
When the function is not resumable the translation of await expr is much si=
mpler as there is no need to track the resume point.
E.g.
expected<int> madd(expected<int> a, expected<int> b) {
return <b>await</b> a + <b>await</b> b;
}
could be equivalent to=20
expected<int> madd(expected<int> a, expected<int> b) {
auto x =3D await a;
auto y =3D await b;
return x + <b>y</b>;
}
that could be translated to
expected<int> madd(expected<int> a, expected<int> b) {
if (!a.valid()) return exceptional(a);
auto x =3D a.value();
if (!b.valid()) return exceptional(a);
auto y =3D b.value();
return x + <b>y</b>;
}
</pre></div></blockquote><br>As we are aimed to provide general solution, w=
hich should work for any monad - what do you think, which form of definitio=
n bind or >>=3D should have?<br>In Haskell it is function which takes=
continuation as second parameter, but transformation from<br><div class=3D=
"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-color: =
rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: brea=
k-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><pre><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> x </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> await a</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">;</span></pre></div></code></div>to<br><di=
v class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); bord=
er-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-=
wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint=
"><pre><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">if</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">(!</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify">a</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">.</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">valid</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">())</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">ret=
urn</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> except=
ional</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">a</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br> </span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> x </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> a</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">.</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">value</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">();</span></pre></div></code></div>looks like a macro.<br>How to define s=
uch transformation in general way? Unless there is good answer for that - w=
e should stick to continuations (for await approach it means to have resuma=
ble functions even for expected<T> monad).<br><br>P.S. In case if you=
want to play with internals of await - I made proof-of-concept implementat=
ion of await based on Boost.Coroutine some time ago - https://github.com/pa=
naseleus/await_emu . <br>P.P.S. Today I have made simple linearizion of nes=
ted continuations based on Boost.Preprocessor - DO macro: https://github.co=
m/panaseleus/monad_do<br>P.P.P.S. I don't like N3722 - it merges cons of st=
ackful (Boost.Coroutine) and stackless coroutines (C# awat/yield) and loses=
their unique pros. I should prepare new topic about this.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_790_11233981.1389131139491--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Tue, 7 Jan 2014 15:23:49 -0800 (PST)
Raw View
------=_Part_754_19483374.1389137029804
Content-Type: text/plain; charset=KOI8-R
Content-Transfer-Encoding: quoted-printable
8 January 2014 =C7., 1:45:39 UTC+4 Evgeny Panasyuk :
>
> So, I think that any monadic-style computation can be simulated by using=
=20
> await (or coroutines in general) as you suggested.
>
There are cases when bind will call same continuation several times, for=20
example in List monad.
I think for stackful coroutines it is hard to preserve immutable or=20
guarantee equal continuation for each call, constant stack, etc (just think=
=20
about destructors). So, approach based on stackful coroutines is applicable=
=20
only to subset of all monads.
But for stackless coroutines it should be easy - it is possible to have=20
const continuation or make copy per each call, because such continuation is=
=20
just C++ object which contains whole state. Boost.Asio has example of=20
stackless coroutines based on macros -=20
http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/overview/core/coro=
utine.html
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_754_19483374.1389137029804
Content-Type: text/html; charset=KOI8-R
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">8 January 2014 =C7., 1:45:39 UTC+4 Evgeny Panasyuk :<=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">So, I think th=
at any monadic-style computation can be simulated by using await (or corout=
ines in general) as you suggested.<br></div></blockquote><div><br>There are=
cases when bind will call same continuation several times, for example in =
List monad.<br>I think for stackful coroutines it is hard to preserve immut=
able or guarantee equal continuation for each call, constant stack, etc (ju=
st think about destructors). So, approach based on stackful coroutines is a=
pplicable only to subset of all monads.<br>But for stackless coroutines it =
should be easy - it is possible to have const continuation or make copy per=
each call, because such continuation is just C++ object which contains who=
le state. Boost.Asio has example of stackless coroutines based on macros - =
http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/overview/core/coro=
utine.html</div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_754_19483374.1389137029804--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Wed, 08 Jan 2014 02:01:44 +0100
Raw View
Le 07/01/14 20:59, Geoffrey Romer a =E9crit :
> Note that N3722's predecessors used to support exactly what you want:=20
> in N3328, 'await' was defined as more or less a fully general monadic=20
> binding operator. However, this was changed in N3564, where 'await'=20
> was restricted to future/shared_future operands. If you can determine=20
> why that change was made, that might give you some clues about whether=20
> and how to reverse it.
Hi,
thanks for pointing me to this first version that I didn't read enough=20
carefully before.
I like much better how this version describes the constraints and how it=20
could take care of non blocking monads.
"
In order to support higher performance when the contained value is=20
already available at the point that
the await operator is executed, S=92<T=92> may also define one or both of=
=20
the following public member
function:
bool is_done();
bool try_get(T=92 &);
The former reports whether the instance already contains a value at the=20
time it is invoked, while the
latter reports the same information and also retrieves the value if it=20
is available. If try_get() is defined, T=92
is not required to have an assignment operator.
"
With a is_blocking trait we don't need the run-time is_done() function=20
when is_blocking<M> is false. And the macro like substitution would be a=20
good implementation.
Vicente
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Wed, 08 Jan 2014 02:11:40 +0100
Raw View
This is a multi-part message in MIME format.
--------------060300070004070409000501
Content-Type: text/plain; charset=KOI8-R; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 07/01/14 22:45, Evgeny Panasyuk a e'crit :
> 6 January2014 =C7., 1:55:23 UTC+4 Vicente J. Botet Escriba :
>
> I was wondering if it would be acceptable to use the*await* operator=
for expected types, which makes the code much clean and easy to read.
>
>
> Having whole computation chain expressed as chain of nested=20
> continuations allow us to do some special processing between steps,=20
> i.e. do "bind" of given monad.
> The obvious downside is that we have to cut computation code into=20
> continuations and nest them.
> "do" syntax sugar in Haskell basically linearizes chain of nested=20
> continuations by doing automatic code transformation from linear form=20
> to nested.
>
> Coroutines (stackful or stackless, or await as higher-level=20
> abstraction on top of them) allows to stop execution at some point and=20
> resume later.
> "Resuming ticket" can be passed around, and can be used to resume=20
> function execution at the right time.
> In other words coroutines allow us to automatically turn rest of=20
> function into continuation and pass it around.
>
> So, I think that any monadic-style computation can be simulated by=20
> using await (or coroutines in general) as you suggested.
>
> The trait is_blocking<future<T>> would be true_type, while is_blockin=
g<expected<T>> would be false_type.
>
> When the function is not resumable the translation of await expr is m=
uch simpler as there is no need to track the resume point.
>
> E.g.
>
> expected<int> madd(expected<int> a, expected<int> b) {
> return*await* a +*await* b;
> }
>
>
> could be equivalent to
>
> expected<int> madd(expected<int> a, expected<int> b) {
> auto x =3D await a;
> auto y =3D await b;
> return x +*y*;
> }
>
> that could be translated to
>
>
> expected<int> madd(expected<int> a, expected<int> b) {
> if (!a.valid()) return exceptional(a);
> auto x =3D a.value();
> if (!b.valid()) return exceptional(a);
> auto y =3D b.value();
> return x +*y*;
> }
>
>
> As we are aimed to provide general solution, which should work for any=20
> monad - what do you think, which form of definition bind or >>=3D should=
=20
> have?
> In Haskell it is function which takes continuation as second=20
> parameter, but transformation from
> |
> auto x=3D await a;
> |
> to
> |
> if (!a.valid()) return exceptional(a);
> auto x=3D a.value();
> |
> looks like a macro.
Maybe you missed that this macro like substitution was an optimization=20
for the case of expected with no stackless functions.
> How to define such transformation in general way?
Why the Haskell response using bind (.then) is not a good answer?
> Unless there is good answer for that - we should stick to=20
> continuations (for await approach it means to have resumable functions=20
> even for expected<T> monad).
I think that users would not use await with expected if they know that=20
the consequence is that their functions becomes corrutines (which imo=20
will be always less efficient than using normal function and the macro=20
like replacement hack.
>
> P.S. In case if you want to play with internals of await - I made=20
> proof-of-concept implementation of await based on Boost.Coroutine some=20
> time ago - https://github.com/panaseleus/await_emu .
Very clever. I have a doubt about how it manages with exceptions.
For me await expr would not throw when the expression stores a=20
exception, but will make the function containing such expression to=20
return the associated monad with such a exception and this is the main=20
point of await. Could you confirm you implementation behaves in a such way?
> P.P.S. Today I have made simple linearizion of nested continuations=20
> based on Boost.Preprocessor - DO macro:=20
> https://github.com/panaseleus/monad_do
Very clever yet. The do notation is a good thing a first step froward,=20
but I would not like to be forced to sequence the await
auto x =3D await a;
auto y =3D await b;
return x +*y*;
and be able to do
return*await* a +*await* b;
Can the your POC take care of this situation?
> P.P.P.S. I don't like N3722 - it merges cons of stackful=20
> (Boost.Coroutine) and stackless coroutines (C# awat/yield) and loses=20
> their unique pros. I should prepare new topic about this.
Let me know if you would consider how await could be managed when the=20
expected value is already there, that it, the await couldn't not block,=20
and there is not need to resume nothing.
Vicente
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--------------060300070004070409000501
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta content=3D"text/html; charset=3DKOI8-R" http-equiv=3D"Content-Typ=
e">
</head>
<body bgcolor=3D"#FFFFFF" text=3D"#000000">
<div class=3D"moz-cite-prefix">Le 07/01/14 22:45, Evgeny Panasyuk a
écrit=C2=A0:<br>
</div>
<blockquote
cite=3D"mid:d066e1e7-ac27-4df7-94bb-fa01c1dce2c0@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">6 January2014=C2=A0=D0=B3., 1:55:23 UTC+4 Vicente J.=
Botet
Escriba :
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<pre>I was wondering if it would be acceptable to use the <b>aw=
ait</b> operator for expected types, which makes the code much clean and ea=
sy to read.
</pre>
</div>
</blockquote>
<div><br>
Having whole computation chain expressed as chain of nested
continuations allow us to do some special processing between
steps, i.e.=C2=A0 do "bind" of given monad.<br>
The obvious downside is that we have to cut computation code
into continuations and nest them.<br>
"do" syntax sugar in Haskell basically linearizes chain of
nested continuations by doing automatic code transformation
from linear form to nested.<br>
<br>
Coroutines (stackful or stackless, or await as higher-level
abstraction on top of them) allows to stop execution at some
point and resume later.<br>
"Resuming ticket" can be passed around, and can be used to
resume function execution at the right time.<br>
In other words coroutines allow us to automatically turn rest
of function into continuation and pass it around.<br>
<br>
So, I think that any monadic-style computation can be
simulated by using await (or coroutines in general) as you
suggested.<br>
=C2=A0</div>
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<pre>The trait is_blocking<future<T>> would be true=
_type, while is_blocking<expected<T>> would be false_type.
When the function is not resumable the translation of await expr is much si=
mpler as there is no need to track the resume point.
E.g.
expected<int> madd(expected<int> a, expected<int> b) {
return <b>await</b> a + <b>await</b> b;
}
could be equivalent to=20
expected<int> madd(expected<int> a, expected<int> b) {
auto x =3D await a;
auto y =3D await b;
=C2=A0return x + <b>y</b>;
}
that could be translated to
expected<int> madd(expected<int> a, expected<int> b) {
if (!a.valid()) return exceptional(a);
auto x =3D a.value();
if (!b.valid()) return exceptional(a);
auto y =3D b.value();
=C2=A0return x + <b>y</b>;
}
</pre>
</div>
</blockquote>
<br>
As we are aimed to provide general solution, which should work
for any monad - what do you think, which form of definition bind
or >>=3D should have?<br>
In Haskell it is function which takes continuation as second
parameter, but transformation from<br>
<div class=3D"prettyprint" style=3D"background-color: rgb(250, 250,
250); border-color: rgb(187, 187, 187); border-style: solid;
border-width: 1px; word-wrap: break-word;"><code
class=3D"prettyprint">
<div class=3D"subprettyprint">
<pre><span style=3D"color: #008;" class=3D"styled-by-prettify=
">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> x <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> await a</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">;</span></pre>
</div>
</code></div>
to<br>
<div class=3D"prettyprint" style=3D"background-color: rgb(250, 250,
250); border-color: rgb(187, 187, 187); border-style: solid;
border-width: 1px; word-wrap: break-word;"><code
class=3D"prettyprint">
<div class=3D"subprettyprint">
<pre><span style=3D"color: #000;" class=3D"styled-by-prettify=
">=C2=A0</span><span style=3D"color: #008;" class=3D"styled-by-prettify">if=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">(!</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">a</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">.</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify">valid</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">())</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">return</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> exceptional</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">a<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">
=C2=A0</span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> x </span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> a</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">.</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">value</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">();</span></pre>
</div>
</code></div>
looks like a macro.<br>
</div>
</blockquote>
Maybe you missed that this macro like substitution was an
optimization for the case of expected with no stackless functions.<br>
<blockquote
cite=3D"mid:d066e1e7-ac27-4df7-94bb-fa01c1dce2c0@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">How to define such transformation in general way? </=
div>
</blockquote>
Why the Haskell response using bind (.then) is not a good answer?<br>
<blockquote
cite=3D"mid:d066e1e7-ac27-4df7-94bb-fa01c1dce2c0@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">Unless there is good answer for that - we should
stick to continuations (for await approach it means to have
resumable functions even for expected<T> monad).<br>
</div>
</blockquote>
I think that users would not use await with expected if they know
that the consequence is that their functions becomes corrutines
(which imo will be always less efficient than using normal function
and the macro like replacement hack.<br>
<blockquote
cite=3D"mid:d066e1e7-ac27-4df7-94bb-fa01c1dce2c0@isocpp.org"
type=3D"cite">
<div dir=3D"ltr"><br>
P.S. In case if you want to play with internals of await - I
made proof-of-concept implementation of await based on
Boost.Coroutine some time ago -
<a class=3D"moz-txt-link-freetext" href=3D"https://github.com/panas=
eleus/await_emu">https://github.com/panaseleus/await_emu</a> . <br>
</div>
</blockquote>
Very clever. I have a doubt about how it manages with exceptions.<br>
For me await expr would not throw when the expression stores a
exception, but will make the function containing such expression to
return the associated monad with such a exception and this is the
main point of await. Could you confirm you implementation behaves in
a such way?<br>
<blockquote
cite=3D"mid:d066e1e7-ac27-4df7-94bb-fa01c1dce2c0@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">P.P.S. Today I have made simple linearizion of
nested continuations based on Boost.Preprocessor - DO macro:
<a class=3D"moz-txt-link-freetext" href=3D"https://github.com/panas=
eleus/monad_do">https://github.com/panaseleus/monad_do</a><br>
</div>
</blockquote>
Very clever yet. The do notation is a good thing a first step
froward, but I would not like to be forced to sequence the await <br>
<pre> auto x =3D await a;
auto y =3D await b;
=C2=A0return x + <b>y</b>;
</pre>
and be able to do<br>
<br>
<pre> return <b>await</b> a + <b>await</b> b;</pre>
Can the your POC take care of this situation?<br>
<blockquote
cite=3D"mid:d066e1e7-ac27-4df7-94bb-fa01c1dce2c0@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">P.P.P.S. I don't like N3722 - it merges cons of
stackful (Boost.Coroutine) and stackless coroutines (C#
awat/yield) and loses their unique pros. I should prepare new
topic about this.<br>
</div>
</blockquote>
Let me know if you would consider how await could be managed when
the expected value is already there, that it, the await couldn't not
block, and there is not need to resume nothing.<br>
<br>
Vicente <br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--------------060300070004070409000501--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Wed, 08 Jan 2014 03:10:25 +0100
Raw View
Le 07/01/14 00:06, hun.nemethpeter@gmail.com a =E9crit :
> We can use compile time reflection here. So you can write a pattern
> (definition of pattern comes from here:=20
> https://github.com/hun-nemethpeter/cpp-reflector-mini/blob/master/Proposa=
l.md)
> that takes the original madd function definition and transform it to=20
> an other definition.
>
> $buildResumableFunction(madd, "madd_r");
>
Hi,
I'm all for a compile time reflection solution if it can take in account=20
the efficiency concerns a user would expect.
Waiting for a reflection proposal that could take care of this case,
Vicente
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Wed, 8 Jan 2014 11:14:15 -0800 (PST)
Raw View
------=_Part_464_20089712.1389208456213
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
>
>
> Maybe you missed that this macro like substitution was an optimization fo=
r=20
> the case of expected with no stackless functions.
>
I understood that this is optimization (it is indeed desirable). I just=20
don't know in which form user is supposed to define "bind" with such=20
optimization.
=20
> How to define such transformation in general way?=20
>
> Why the Haskell response using bind (.then) is not a good answer?
>
It would look like:
template<typename F, typename T>
auto operator>>=3D(expected<T> m, F continuation)
{
return m.valid() ? continuation(m.value()) : exceptional(m);
}
It is clearly not the same as injecting
if (!a.valid()) return exceptional(a);
auto x =3D a.value();
to await place in user code. Such injection should be defined in other way=
=20
(some kind of macro?). Or maybe I missed something.
Also note, in general case >>=3D can call continuation several times, like =
in=20
List monad.
> Unless there is good answer for that - we should stick to continuations=
=20
> (for await approach it means to have resumable functions even for=20
> expected<T> monad).
> =20
> I think that users would not use await with expected if they know that th=
e=20
> consequence is that their functions becomes corrutines (which imo will be=
=20
> always less efficient than using normal function and the macro like=20
> replacement hack.
>
I agree - using stackful coroutines for await expected<T> is not optimal at=
=20
all. I just don't see in which form "macro like replacement hack" should be=
=20
defined by user.
Should user define overloadable macro BIND? Like pseudocode:
#define BIND(expected<T> a) \
( a.valid() ? a.value() : return exceptional(a) )
/**/=20
> =20
> P.S. In case if you want to play with internals of await - I made=20
> proof-of-concept implementation of await based on Boost.Coroutine some ti=
me=20
> ago - https://github.com/panaseleus/await_emu .=20
> =20
> Very clever. I have a doubt about how it manages with exceptions.
> For me await expr would not throw when the expression stores a exception,=
=20
> but will make the function containing such expression to return the=20
> associated monad with such a exception and this is the main point of awai=
t.=20
> Could you confirm you implementation behaves in a such way?
>
Well, current version is just quick proof of concept, and it has some=20
issues (solvable) with exception safety. It doesn't store exception in=20
promise::set_exception. But such behavior can be implemented.
> P.P.S. Today I have made simple linearizion of nested continuations=20
> based on Boost.Preprocessor - DO macro:=20
> https://github.com/panaseleus/monad_do
> =20
> Very clever yet. The do notation is a good thing a first step froward, bu=
t=20
> I would not like to be forced to sequence the await=20
>
> auto x =3D await a;
> auto y =3D await b;
> =D0=9E=C2=A9=E2=95=ABreturn x + *y*;
>
>
> and be able to do
>
> return *await* a + *await* b;
>
> Can the your POC take care of this situation?
>
No, with current implementation it will be:
return DO(Expected,
(x, a)
(y, b)
(_, unit(x + y))
);
I doubt if Haskell's do-notation supports "return await a + await b;"=20
style. For such case it has liftM2 function: liftM2 (+) a b
> P.P.P.S. I don't like N3722 - it merges cons of stackful=20
> (Boost.Coroutine) and stackless coroutines (C# awat/yield) and loses thei=
r=20
> unique pros. I should prepare new topic about this.
> =20
> Let me know if you would consider how await could be managed when the=20
> expected value is already there, that it, the await couldn't not block, a=
nd=20
> there is not need to resume nothing.
>
Ok.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_464_20089712.1389208456213
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div bgcolor=
=3D"#FFFFFF" text=3D"#000000"><br>
Maybe you missed that this macro like substitution was an
optimization for the case of expected with no stackless functions.<br><=
/div></blockquote><div><br>I understood that this is optimization (it is in=
deed desirable). I just don't know in which form user is supposed to define=
"bind" with such optimization.<br> </div><blockquote class=3D"gmail_q=
uote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pad=
ding-left: 1ex;"><div bgcolor=3D"#FFFFFF" text=3D"#000000">
<blockquote type=3D"cite">
<div dir=3D"ltr">How to define such transformation in general way? </=
div>
</blockquote>
Why the Haskell response using bind (.then) is not a good answer?<br></=
div></blockquote><div><br>It would look like:<br><div class=3D"prettyprint"=
style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187,=
187); border-style: solid; border-width: 1px; word-wrap: break-word;"><cod=
e class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color:=
#008;" class=3D"styled-by-prettify">template</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">typename</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> F</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>typename</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">></spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">operator</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">>>=3D(</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">expected</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">T</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">></span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> m</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> F continuation</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
></span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br> =
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">return</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> m</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">valid</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">()</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">?</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> continuation</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">m</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
..</span><span style=3D"color: #000;" class=3D"styled-by-prettify">value</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">())</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">:</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> exceptional</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">m</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br></span></div></code></div>It is clearly not the same as injecting<br><=
div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); bo=
rder-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; wor=
d-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettypri=
nt"><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">if</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">(!</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">a</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">.</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">valid</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">())</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">return=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> exception=
al</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">a</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br> </span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> x </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> a</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">.</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">value</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(=
);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></sp=
an></div></code></div>to await place in user code. Such injection should be=
defined in other way (some kind of macro?). Or maybe I missed something.<b=
r><br>Also note, in general case >>=3D can call continuation several =
times, like in List monad.<br></div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div bgcolor=3D"#FFFFFF" text=3D"#000000">
<blockquote type=3D"cite">
<div dir=3D"ltr">Unless there is good answer for that - we should
stick to continuations (for await approach it means to have
resumable functions even for expected<T> monad).<br>
</div>
</blockquote>
I think that users would not use await with expected if they know
that the consequence is that their functions becomes corrutines
(which imo will be always less efficient than using normal function
and the macro like replacement hack.<br></div></blockquote><div><br>I a=
gree - using stackful coroutines for await expected<T> is not optimal=
at all. I just don't see in which form "macro like replacement hack" shoul=
d be defined by user.<br>Should user define overloadable macro BIND? Like p=
seudocode:<br><div class=3D"prettyprint" style=3D"background-color: rgb(250=
, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; border-=
width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #800;" class=3D"styled-by-prettif=
y">#define</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
BIND</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">expected</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify"><</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify">T</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">></span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> a</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">\</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br> </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> a</span><span style=3D"color: #660;" class=3D"styled-by-prettify">.</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">valid</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">?</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> a</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">.</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">value</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">()</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">:</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">return</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> exceptional</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">a</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br></span><span style=3D"color: #800;" class=3D"styled-by-prettify">/**/=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <br></spa=
n></div></code></div></div><blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v bgcolor=3D"#FFFFFF" text=3D"#000000">
<blockquote type=3D"cite">
<div dir=3D"ltr"><br>
P.S. In case if you want to play with internals of await - I
made proof-of-concept implementation of await based on
Boost.Coroutine some time ago -
<a href=3D"https://github.com/panaseleus/await_emu" target=3D"_blan=
k" onmousedown=3D"this.href=3D'https://www.google.com/url?q\75https%3A%2F%2=
Fgithub.com%2Fpanaseleus%2Fawait_emu\46sa\75D\46sntz\0751\46usg\75AFQjCNEjZ=
KUW8FjVHCowRyLvkHeXj90mRg';return true;" onclick=3D"this.href=3D'https://ww=
w.google.com/url?q\75https%3A%2F%2Fgithub.com%2Fpanaseleus%2Fawait_emu\46sa=
\75D\46sntz\0751\46usg\75AFQjCNEjZKUW8FjVHCowRyLvkHeXj90mRg';return true;">=
https://github.com/panaseleus/<wbr>await_emu</a> . <br>
</div>
</blockquote>
Very clever. I have a doubt about how it manages with exceptions.<br>
For me await expr would not throw when the expression stores a
exception, but will make the function containing such expression to
return the associated monad with such a exception and this is the
main point of await. Could you confirm you implementation behaves in
a such way?<br></div></blockquote><div><br>Well, current version is jus=
t quick proof of concept, and it has some issues (solvable) with exception =
safety. It doesn't store exception in promise::set_exception. But such beha=
vior can be implemented.<br></div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div bgcolor=3D"#FFFFFF" text=3D"#000000">
<blockquote type=3D"cite">
<div dir=3D"ltr">P.P.S. Today I have made simple linearizion of
nested continuations based on Boost.Preprocessor - DO macro:
<a href=3D"https://github.com/panaseleus/monad_do" target=3D"_blank=
" onmousedown=3D"this.href=3D'https://www.google.com/url?q\75https%3A%2F%2F=
github.com%2Fpanaseleus%2Fmonad_do\46sa\75D\46sntz\0751\46usg\75AFQjCNHiESa=
HKsfhiSfXOsebrGv1UWRoyg';return true;" onclick=3D"this.href=3D'https://www.=
google.com/url?q\75https%3A%2F%2Fgithub.com%2Fpanaseleus%2Fmonad_do\46sa\75=
D\46sntz\0751\46usg\75AFQjCNHiESaHKsfhiSfXOsebrGv1UWRoyg';return true;">htt=
ps://github.com/panaseleus/<wbr>monad_do</a><br>
</div>
</blockquote>
Very clever yet. The do notation is a good thing a first step
froward, but I would not like to be forced to sequence the await <br>
<pre> auto x =3D await a;
auto y =3D await b;
=D0=9E=C2=A9=E2=95=ABreturn x + <b>y</b>;
</pre>
and be able to do<br>
<br>
<pre> return <b>await</b> a + <b>await</b> b;</pre>
Can the your POC take care of this situation?<br></div></blockquote><di=
v><br>No, with current implementation it will be:<br><div class=3D"prettypr=
int" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, =
187, 187); border-style: solid; border-width: 1px; word-wrap: break-word;">=
<code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">return</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> DO</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">(</span><span style=3D"color: #606;" class=3D=
"styled-by-prettify">Expected</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br> </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">x</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> a</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br> </span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">y</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> b</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">_</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> un=
it</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">x </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">+</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> y</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">))</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br></span></div></code></div>I doubt if Haskell's do-notation s=
upports "return await a + await b;" style. For such case it has liftM2 func=
tion: liftM2 (+) a b<br></div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">=
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<blockquote type=3D"cite">
<div dir=3D"ltr">P.P.P.S. I don't like N3722 - it merges cons of
stackful (Boost.Coroutine) and stackless coroutines (C#
awat/yield) and loses their unique pros. I should prepare new
topic about this.<br>
</div>
</blockquote>
Let me know if you would consider how await could be managed when
the expected value is already there, that it, the await couldn't not
block, and there is not need to resume nothing.<br></div></blockquote><=
div><br>Ok.<br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_464_20089712.1389208456213--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Wed, 08 Jan 2014 20:36:50 +0100
Raw View
This is a multi-part message in MIME format.
--------------070203060505000404020400
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 08/01/14 20:14, Evgeny Panasyuk a =C3=A9crit :
>
>
> Maybe you missed that this macro like substitution was an
> optimization for the case of expected with no stackless functions.
>
>
> I understood that this is optimization (it is indeed desirable). I=20
> just don't know in which form user is supposed to define "bind" with=20
> such optimization.
>
>> How to define such transformation in general way?
> Why the Haskell response using bind (.then) is not a good answer?
>
>
> It would look like:
> |
> template<typenameF,typenameT>
> autooperator>>=3D(expected<T>m,F continuation)
> {
> returnm.valid()?continuation(m.value()):exceptional(m);
> }
> |
> It is clearly not the same as injecting
> |
> if(!a.valid())returnexceptional(a);
> autox =3Da.value();
> |
> to await place in user code. Such injection should be defined in other=20
> way (some kind of macro?). Or maybe I missed something.
Humm, if you look carefully you will see that both are equivalents. The=20
continuation has as parameter the value x and starts just after the=20
initialization of x.
If a is not valid the result of the function is the same exceptional(m).
>
> Also note, in general case >>=3D can call continuation several times,=20
> like in List monad.
>
>> Unless there is good answer for that - we should stick to
>> continuations (for await approach it means to have resumable
>> functions even for expected<T> monad).
> I think that users would not use await with expected if they know
> that the consequence is that their functions becomes corrutines
> (which imo will be always less efficient than using normal
> function and the macro like replacement hack.
>
>
> I agree - using stackful coroutines for await expected<T> is not=20
> optimal at all. I just don't see in which form "macro like replacement=20
> hack" should be defined by user.
> Should user define overloadable macro BIND? Like pseudocode:
> |
> #defineBIND(expected<T>a)\
> (a.valid()?a.value():returnexceptional(a))
> /**/
> |
|No I don't think so. The general case must use >>=3D(.then) in order to=20
resume the function when the monad is ready.
But when the monad is not blocking, |we don't need to create artificial=20
continuations.
>
>>
>> P.S. In case if you want to play with internals of await - I made
>> proof-of-concept implementation of await based on Boost.Coroutine
>> some time ago - https://github.com/panaseleus/await_emu
>> <https://github.com/panaseleus/await_emu> .
> Very clever. I have a doubt about how it manages with exceptions.
> For me await expr would not throw when the expression stores a
> exception, but will make the function containing such expression
> to return the associated monad with such a exception and this is
> the main point of await. Could you confirm you implementation
> behaves in a such way?
>
>
> Well, current version is just quick proof of concept, and it has some=20
> issues (solvable) with exception safety. It doesn't store exception in=20
> promise::set_exception. But such behavior can be implemented.
>
>> P.P.S. Today I have made simple linearizion of nested
>> continuations based on Boost.Preprocessor - DO macro:
>> https://github.com/panaseleus/monad_do
>> <https://github.com/panaseleus/monad_do>
> Very clever yet. The do notation is a good thing a first step
> froward, but I would not like to be forced to sequence the await
>
> auto x =3D await a;
> auto y =3D await b;
> =D0=9E=C2=A9=E2=95=ABreturn x +*y*;
>
> and be able to do
>
> return*await* a +*await* b;
>
> Can the your POC take care of this situation?
>
>
> No, with current implementation it will be:
> |
> returnDO(Expected,
> (x,a)
> (y,b)
> (_,unit(x +y))
> );
> |
> I doubt if Haskell's do-notation supports "return await a + await b;"=20
> style.
No, it doesn't support them. I think the reason is related to the fact=20
the order of evaluation is undefined and can be evaluated concurrently.
> For such case it has liftM2 function: liftM2 (+) a b
>
>> P.P.P.S. I don't like N3722 - it merges cons of stackful
>> (Boost.Coroutine) and stackless coroutines (C# awat/yield) and
>> loses their unique pros. I should prepare new topic about this.
> Let me know if you would consider how await could be managed when
> the expected value is already there, that it, the await couldn't
> not block, and there is not need to resume nothing.
>
>
> Ok.
>
Best,
Vicente
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--------------070203060505000404020400
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta content=3D"text/html; charset=3DUTF-8" http-equiv=3D"Content-Type=
">
</head>
<body bgcolor=3D"#FFFFFF" text=3D"#000000">
<div class=3D"moz-cite-prefix">Le 08/01/14 20:14, Evgeny Panasyuk a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote
cite=3D"mid:121d3b18-19ba-42bb-ab5e-9a5896744003@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<div bgcolor=3D"#FFFFFF" text=3D"#000000"><br>
Maybe you missed that this macro like substitution was an
optimization for the case of expected with no stackless
functions.<br>
</div>
</blockquote>
<div><br>
I understood that this is optimization (it is indeed
desirable). I just don't know in which form user is supposed
to define "bind" with such optimization.<br>
=C2=A0</div>
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<blockquote type=3D"cite">
<div dir=3D"ltr">How to define such transformation in
general way? </div>
</blockquote>
Why the Haskell response using bind (.then) is not a good
answer?<br>
</div>
</blockquote>
<div><br>
It would look like:<br>
<div class=3D"prettyprint" style=3D"background-color: rgb(250,
250, 250); border-color: rgb(187, 187, 187); border-style:
solid; border-width: 1px; word-wrap: break-word;"><code
class=3D"prettyprint">
<div class=3D"subprettyprint"><span style=3D"color: #008;"
class=3D"styled-by-prettify">template</span><span
style=3D"color: #660;" class=3D"styled-by-prettify"><<=
/span><span
style=3D"color: #008;" class=3D"styled-by-prettify">typen=
ame</span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> F</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
style=3D"color: #008;" class=3D"styled-by-prettify">typen=
ame</span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> T</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">><=
/span><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
</span><span style=3D"color: #008;"
class=3D"styled-by-prettify">auto</span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
style=3D"color: #008;" class=3D"styled-by-prettify">opera=
tor</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">>&=
gt;=3D(</span><span
style=3D"color: #000;" class=3D"styled-by-prettify">expec=
ted</span><span
style=3D"color: #660;" class=3D"styled-by-prettify"><<=
/span><span
style=3D"color: #000;" class=3D"styled-by-prettify">T</sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify">><=
/span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> m</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify"> F
continuation</span><span style=3D"color: #660;"
class=3D"styled-by-prettify">)</span><span style=3D"color=
:
#000;" class=3D"styled-by-prettify"><br>
</span><span style=3D"color: #660;"
class=3D"styled-by-prettify">{</span><span style=3D"color=
:
#000;" class=3D"styled-by-prettify"><br>
=C2=A0 =C2=A0 </span><span style=3D"color: #008;"
class=3D"styled-by-prettify">return</span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> m</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">.</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify">valid=
</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">()</s=
pan><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify">?</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify">
continuation</span><span style=3D"color: #660;"
class=3D"styled-by-prettify">(</span><span style=3D"color=
:
#000;" class=3D"styled-by-prettify">m</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">.</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify">value=
</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">())</=
span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify">:</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify">
exceptional</span><span style=3D"color: #660;"
class=3D"styled-by-prettify">(</span><span style=3D"color=
:
#000;" class=3D"styled-by-prettify">m</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">);</s=
pan><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
</span><span style=3D"color: #660;"
class=3D"styled-by-prettify">}</span><span style=3D"color=
:
#000;" class=3D"styled-by-prettify"><br>
</span></div>
</code></div>
It is clearly not the same as injecting<br>
<div class=3D"prettyprint" style=3D"background-color: rgb(250,
250, 250); border-color: rgb(187, 187, 187); border-style:
solid; border-width: 1px; word-wrap: break-word;"><code
class=3D"prettyprint">
<div class=3D"subprettyprint"><span style=3D"color: #000;"
class=3D"styled-by-prettify">=C2=A0</span><span style=3D"=
color:
#008;" class=3D"styled-by-prettify">if</span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify">(!</s=
pan><span
style=3D"color: #000;" class=3D"styled-by-prettify">a</sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify">.</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify">valid=
</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">())</=
span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
style=3D"color: #008;" class=3D"styled-by-prettify">retur=
n</span><span
style=3D"color: #000;" class=3D"styled-by-prettify">
exceptional</span><span style=3D"color: #660;"
class=3D"styled-by-prettify">(</span><span style=3D"color=
:
#000;" class=3D"styled-by-prettify">a</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">);</s=
pan><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
=C2=A0</span><span style=3D"color: #008;"
class=3D"styled-by-prettify">auto</span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> x </=
span><span
style=3D"color: #660;" class=3D"styled-by-prettify">=3D</=
span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> a</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">.</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify">value=
</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">();</=
span><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
</span></div>
</code></div>
to await place in user code. Such injection should be defined
in other way (some kind of macro?). Or maybe I missed
something.<br>
</div>
</div>
</blockquote>
Humm, if you look carefully you will see that both are equivalents.
The continuation has as parameter the value x and starts just after
the initialization of x. <br>
If a is not valid the result of the function is the same
exceptional(m). <br>
<br>
<br>
<blockquote
cite=3D"mid:121d3b18-19ba-42bb-ab5e-9a5896744003@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div><br>
Also note, in general case >>=3D can call continuation
several times, like in List monad.<br>
</div>
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<blockquote type=3D"cite">
<div dir=3D"ltr">Unless there is good answer for that - we
should stick to continuations (for await approach it
means to have resumable functions even for
expected<T> monad).<br>
</div>
</blockquote>
I think that users would not use await with expected if they
know that the consequence is that their functions becomes
corrutines (which imo will be always less efficient than
using normal function and the macro like replacement hack.<br>
</div>
</blockquote>
<div><br>
I agree - using stackful coroutines for await
expected<T> is not optimal at all. I just don't see in
which form "macro like replacement hack" should be defined by
user.<br>
Should user define overloadable macro BIND? Like pseudocode:<br>
<div class=3D"prettyprint" style=3D"background-color: rgb(250,
250, 250); border-color: rgb(187, 187, 187); border-style:
solid; border-width: 1px; word-wrap: break-word;"><code
class=3D"prettyprint">
<div class=3D"subprettyprint"><span style=3D"color: #800;"
class=3D"styled-by-prettify">#define</span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> BIND=
</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify">expec=
ted</span><span
style=3D"color: #660;" class=3D"styled-by-prettify"><<=
/span><span
style=3D"color: #000;" class=3D"styled-by-prettify">T</sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify">><=
/span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> a</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">)</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify">\</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
=C2=A0 =C2=A0 </span><span style=3D"color: #660;"
class=3D"styled-by-prettify">(</span><span style=3D"color=
:
#000;" class=3D"styled-by-prettify"> a</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">.</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify">valid=
</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">()</s=
pan><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify">?</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify"> a</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">.</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify">value=
</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">()</s=
pan><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify">:</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
style=3D"color: #008;" class=3D"styled-by-prettify">retur=
n</span><span
style=3D"color: #000;" class=3D"styled-by-prettify">
exceptional</span><span style=3D"color: #660;"
class=3D"styled-by-prettify">(</span><span style=3D"color=
:
#000;" class=3D"styled-by-prettify">a</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">)</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify">)</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
</span><span style=3D"color: #800;"
class=3D"styled-by-prettify">/**/</span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> <br>
</span></div>
</code></div>
</div>
</div>
</blockquote>
<code>No I don't think so. The general case must use
>>=3D(.then) in order to resume the function when the monad is
ready. <br>
But when the monad is not blocking, </code>we don't need to
create artificial continuations.<br>
<blockquote
cite=3D"mid:121d3b18-19ba-42bb-ab5e-9a5896744003@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<blockquote type=3D"cite">
<div dir=3D"ltr"><br>
P.S. In case if you want to play with internals of await
- I made proof-of-concept implementation of await based
on Boost.Coroutine some time ago - <a
moz-do-not-send=3D"true"
href=3D"https://github.com/panaseleus/await_emu"
target=3D"_blank"
onmousedown=3D"this.href=3D'https://www.google.com/url?q\=
75https%3A%2F%2Fgithub.com%2Fpanaseleus%2Fawait_emu\46sa\75D\46sntz\0751\46=
usg\75AFQjCNEjZKUW8FjVHCowRyLvkHeXj90mRg';return
true;"
onclick=3D"this.href=3D'https://www.google.com/url?q\75ht=
tps%3A%2F%2Fgithub.com%2Fpanaseleus%2Fawait_emu\46sa\75D\46sntz\0751\46usg\=
75AFQjCNEjZKUW8FjVHCowRyLvkHeXj90mRg';return
true;">https://github.com/panaseleus/<wbr>await_emu</a>
. <br>
</div>
</blockquote>
Very clever. I have a doubt about how it manages with
exceptions.<br>
For me await expr would not throw when the expression stores
a exception, but will make the function containing such
expression to return the associated monad with such a
exception and this is the main point of await. Could you
confirm you implementation behaves in a such way?<br>
</div>
</blockquote>
<div><br>
Well, current version is just quick proof of concept, and it
has some issues (solvable) with exception safety. It doesn't
store exception in promise::set_exception. But such behavior
can be implemented.<br>
</div>
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<blockquote type=3D"cite">
<div dir=3D"ltr">P.P.S. Today I have made simple linearizion
of nested continuations based on Boost.Preprocessor - DO
macro: <a moz-do-not-send=3D"true"
href=3D"https://github.com/panaseleus/monad_do"
target=3D"_blank"
onmousedown=3D"this.href=3D'https://www.google.com/url?q\=
75https%3A%2F%2Fgithub.com%2Fpanaseleus%2Fmonad_do\46sa\75D\46sntz\0751\46u=
sg\75AFQjCNHiESaHKsfhiSfXOsebrGv1UWRoyg';return
true;"
onclick=3D"this.href=3D'https://www.google.com/url?q\75ht=
tps%3A%2F%2Fgithub.com%2Fpanaseleus%2Fmonad_do\46sa\75D\46sntz\0751\46usg\7=
5AFQjCNHiESaHKsfhiSfXOsebrGv1UWRoyg';return
true;">https://github.com/panaseleus/<wbr>monad_do</a><br=
>
</div>
</blockquote>
Very clever yet. The do notation is a good thing a first
step froward, but I would not like to be forced to sequence
the await <br>
<pre> auto x =3D await a;
auto y =3D await b;
=D0=9E=C2=A9=E2=95=ABreturn x + <b>y</b>;
</pre>
and be able to do<br>
<br>
<pre> return <b>await</b> a + <b>await</b> b;</pre>
Can the your POC take care of this situation?<br>
</div>
</blockquote>
<div><br>
No, with current implementation it will be:<br>
<div class=3D"prettyprint" style=3D"background-color: rgb(250,
250, 250); border-color: rgb(187, 187, 187); border-style:
solid; border-width: 1px; word-wrap: break-word;"><code
class=3D"prettyprint">
<div class=3D"subprettyprint"><span style=3D"color: #008;"
class=3D"styled-by-prettify">return</span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> DO</=
span><span
style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span
style=3D"color: #606;" class=3D"styled-by-prettify">Expec=
ted</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
=C2=A0 =C2=A0 </span><span style=3D"color: #660;"
class=3D"styled-by-prettify">(</span><span style=3D"color=
:
#000;" class=3D"styled-by-prettify">x</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify"> a</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">)</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
=C2=A0 =C2=A0 </span><span style=3D"color: #660;"
class=3D"styled-by-prettify">(</span><span style=3D"color=
:
#000;" class=3D"styled-by-prettify">y</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify"> b</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">)</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
=C2=A0 =C2=A0 </span><span style=3D"color: #660;"
class=3D"styled-by-prettify">(</span><span style=3D"color=
:
#000;" class=3D"styled-by-prettify">_</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify"> unit=
</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify">x </s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">+</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify"> y</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">))</s=
pan><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
</span><span style=3D"color: #660;"
class=3D"styled-by-prettify">);</span><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
</span></div>
</code></div>
I doubt if Haskell's do-notation supports "return await a +
await b;" style. </div>
</div>
</blockquote>
No, it doesn't support them. I think the reason is related to the
fact the order of evaluation is undefined and can be evaluated
concurrently.<br>
<blockquote
cite=3D"mid:121d3b18-19ba-42bb-ab5e-9a5896744003@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div>For such case it has liftM2 function: liftM2 (+) a b<br>
</div>
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<blockquote type=3D"cite">
<div dir=3D"ltr">P.P.P.S. I don't like N3722 - it merges
cons of stackful (Boost.Coroutine) and stackless
coroutines (C# awat/yield) and loses their unique pros.
I should prepare new topic about this.<br>
</div>
</blockquote>
Let me know if you would consider how await could be managed
when the expected value is already there, that it, the await
couldn't not block, and there is not need to resume nothing.<br=
>
</div>
</blockquote>
<div><br>
Ok.<br>
</div>
</div>
<br>
</blockquote>
Best,<br>
Vicente<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--------------070203060505000404020400--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Wed, 8 Jan 2014 12:07:27 -0800 (PST)
Raw View
------=_Part_6360_29392565.1389211647572
Content-Type: text/plain; charset=KOI8-R
Content-Transfer-Encoding: quoted-printable
8 January 2014 =C7., 23:36:50 UTC+4 Vicente J. Botet Escriba:
>
> How to define such transformation in general way?=20
>>
>> Why the Haskell response using bind (.then) is not a good answer?
>> =20
>
> It would look like:
> template<typename F, typename T>
> auto operator>>=3D(expected<T> m, F continuation)
> {
> return m.valid() ? continuation(m.value()) : exceptional(m);
> }
> It is clearly not the same as injecting
> if (!a.valid()) return exceptional(a);
> auto x =3D a.value();
> to await place in user code. Such injection should be defined in other=
=20
> way (some kind of macro?). Or maybe I missed something.
> =20
> Humm, if you look carefully you will see that both are equivalents. The=
=20
> continuation has as parameter the value x and starts just after the=20
> initialization of x.=20
> If a is not valid the result of the function is the same exceptional(m).=
=20
>
Both are equal, indeed. At least from the point of view of user.
But first requires continuation, and second is injected directly into place=
=20
of "await", like a macro (implicitly viewing rest of code as continuation).
I just don't see how compiler should deduce this from definition of operato=
r
>>=3D. I mean, there should be requirement in ISO that compiler is obliged =
tomake such optimization - but it is a bit fuzzy.
Best Regards,
Evgeny
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_6360_29392565.1389211647572
Content-Type: text/html; charset=KOI8-R
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">8 January 2014 =C7., 23:36:50 UTC+4 Vicente J. Botet =
Escriba:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0=
..8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
=20
=20
=20
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
=20
<blockquote type=3D"cite"><div dir=3D"ltr"><blockquote class=3D"gmail_q=
uote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddin=
g-left:1ex">
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<blockquote type=3D"cite">
<div dir=3D"ltr">How to define such transformation in
general way? </div>
</blockquote>
Why the Haskell response using bind (.then) is not a good
answer?<br>
</div>
</blockquote>
<div><br>
It would look like:<br>
<div style=3D"background-color:rgb(250,250,250);border-color:rgb(=
187,187,187);border-style:solid;border-width:1px;word-wrap:break-word"><cod=
e>
<div><span style=3D"color:#008">template</span><span style=3D=
"color:#660"><</span><span style=3D"color:#008">typename</span><span sty=
le=3D"color:#000"> F</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">typename</span><span sty=
le=3D"color:#000"> T</span><span style=3D"color:#660">></span><span styl=
e=3D"color:#000"><br>
</span><span style=3D"color:#008">auto</span><span style=3D=
"color:#000"> </span><span style=3D"color:#008">operator</span><span style=
=3D"color:#660">>>=3D(</span><span style=3D"color:#000">expected</spa=
n><span style=3D"color:#660"><</span><span style=3D"color:#000">T</span>=
<span style=3D"color:#660">></span><span style=3D"color:#000"> m</span><=
span style=3D"color:#660">,</span><span style=3D"color:#000"> F
continuation</span><span style=3D"color:#660">)</span><sp=
an style=3D"color:#000"><br>
</span><span style=3D"color:#660">{</span><span style=3D"co=
lor:#000"><br>
</span><span style=3D"color:#008">return</s=
pan><span style=3D"color:#000"> m</span><span style=3D"color:#660">.</span>=
<span style=3D"color:#000">valid</span><span style=3D"color:#660">()</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#660">?</span><span=
style=3D"color:#000">
continuation</span><span style=3D"color:#660">(</span><sp=
an style=3D"color:#000">m</span><span style=3D"color:#660">.</span><span st=
yle=3D"color:#000">value</span><span style=3D"color:#660">())</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#660">:</span><span style=
=3D"color:#000">
exceptional</span><span style=3D"color:#660">(</span><spa=
n style=3D"color:#000">m</span><span style=3D"color:#660">);</span><span st=
yle=3D"color:#000"><br>
</span><span style=3D"color:#660">}</span><span style=3D"co=
lor:#000"><br>
</span></div>
</code></div>
It is clearly not the same as injecting<br>
<div style=3D"background-color:rgb(250,250,250);border-color:rgb(=
187,187,187);border-style:solid;border-width:1px;word-wrap:break-word"><cod=
e>
<div><span style=3D"color:#000"> </span><span style=3D"c=
olor:#008">if</span><span style=3D"color:#000"> </span><span style=3D"color=
:#660">(!</span><span style=3D"color:#000">a</span><span style=3D"color:#66=
0">.</span><span style=3D"color:#000">valid</span><span style=3D"color:#660=
">())</span><span style=3D"color:#000"> </span><span style=3D"color:#008">r=
eturn</span><span style=3D"color:#000">
exceptional</span><span style=3D"color:#660">(</span><spa=
n style=3D"color:#000">a</span><span style=3D"color:#660">);</span><span st=
yle=3D"color:#000"><br>
</span><span style=3D"color:#008">auto</span><span =
style=3D"color:#000"> x </span><span style=3D"color:#660">=3D</span><span s=
tyle=3D"color:#000"> a</span><span style=3D"color:#660">.</span><span style=
=3D"color:#000">value</span><span style=3D"color:#660">();</span><span styl=
e=3D"color:#000"><br>
</span></div>
</code></div>
to await place in user code. Such injection should be defined
in other way (some kind of macro?). Or maybe I missed
something.<br>
</div>
</div>
</blockquote>
Humm, if you look carefully you will see that both are equivalents.
The continuation has as parameter the value x and starts just after
the initialization of x. <br>
If a is not valid the result of the function is the same
exceptional(m). <br></div></blockquote><div><br></div><div>Both are equ=
al, indeed. At least from the point of view of user.<br>But first requires =
continuation, and second is injected directly into place of "await", like a=
macro (implicitly viewing rest of code as continuation).<br>I just don't s=
ee how compiler should deduce this from definition of <code><span style=3D"=
color:#000"></span><span style=3D"color:#008">operator</span><span style=3D=
"color:#660">>>=3D</span></code>. I mean, there should be requirement=
in ISO that compiler is<span id=3D"result_box" class=3D"short_text" lang=
=3D"en"><span class=3D"hps alt-edited"> obliged to</span></span> make such =
optimization - but it is a bit fuzzy.<br><br>Best Regards,<br>Evgeny<br></d=
iv></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_6360_29392565.1389211647572--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Thu, 09 Jan 2014 00:01:10 +0100
Raw View
This is a multi-part message in MIME format.
--------------010501000706020509020305
Content-Type: text/plain; charset=KOI8-R; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 08/01/14 21:07, Evgeny Panasyuk a e'crit :
> 8 January 2014 =C7., 23:36:50 UTC+4 Vicente J. Botet Escriba:
>
>>> How to define such transformation in general way?
>> Why the Haskell response using bind (.then) is not a good answer=
?
>>
>>
>> It would look like:
>> |
>> template<typenameF,typenameT>
>> autooperator>>=3D(expected<T>m,F continuation)
>> {
>> returnm.valid()?continuation(m.value()):exceptional(m);
>> }
>> |
>> It is clearly not the same as injecting
>> |
>> if(!a.valid())returnexceptional(a);
>> autox =3Da.value();
>> |
>> to await place in user code. Such injection should be defined in
>> other way (some kind of macro?). Or maybe I missed something.
> Humm, if you look carefully you will see that both are
> equivalents. The continuation has as parameter the value x and
> starts just after the initialization of x.
> If a is not valid the result of the function is the same
> exceptional(m).
>
>
> Both are equal, indeed. At least from the point of view of user.
> But first requires continuation, and second is injected directly into=20
> place of "await", like a macro (implicitly viewing rest of code as=20
> continuation).
> I just don't see how compiler should deduce this from definition of=20
> |operator>>=3D|. I mean, there should be requirement in ISO that=20
> compiler isobliged to make such optimization - but it is a bit fuzzy.
>
I agree that more formalism will be needed for the standard. Maybe some=20
tags could be needed to address some optimizations.
Vicente
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--------------010501000706020509020305
Content-Type: text/html; charset=KOI8-R
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta content=3D"text/html; charset=3DKOI8-R" http-equiv=3D"Content-Typ=
e">
</head>
<body bgcolor=3D"#FFFFFF" text=3D"#000000">
<div class=3D"moz-cite-prefix">Le 08/01/14 21:07, Evgeny Panasyuk a
écrit=9A:<br>
</div>
<blockquote
cite=3D"mid:f32cdb85-b304-4949-a831-e28a637e2dbb@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">8 January 2014=9A=C7., 23:36:50 UTC+4 Vicente J. Bot=
et
Escriba:
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<blockquote type=3D"cite">
<div dir=3D"ltr">
<blockquote class=3D"gmail_quote"
style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc
solid;padding-left:1ex">
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<blockquote type=3D"cite">
<div dir=3D"ltr">How to define such transformation
in general way? </div>
</blockquote>
Why the Haskell response using bind (.then) is not a
good answer?<br>
</div>
</blockquote>
<div><br>
It would look like:<br>
<div
style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);bo=
rder-style:solid;border-width:1px;word-wrap:break-word"><code>
<div><span style=3D"color:#008">template</span><span
style=3D"color:#660"><</span><span
style=3D"color:#008">typename</span><span
style=3D"color:#000"> F</span><span
style=3D"color:#660">,</span><span
style=3D"color:#000"> </span><span
style=3D"color:#008">typename</span><span
style=3D"color:#000"> T</span><span
style=3D"color:#660">></span><span
style=3D"color:#000"><br>
</span><span style=3D"color:#008">auto</span><span
style=3D"color:#000"> </span><span
style=3D"color:#008">operator</span><span
style=3D"color:#660">>>=3D(</span><span
style=3D"color:#000">expected</span><span
style=3D"color:#660"><</span><span
style=3D"color:#000">T</span><span
style=3D"color:#660">></span><span
style=3D"color:#000"> m</span><span
style=3D"color:#660">,</span><span
style=3D"color:#000"> F continuation</span><span
style=3D"color:#660">)</span><span
style=3D"color:#000"><br>
</span><span style=3D"color:#660">{</span><span
style=3D"color:#000"><br>
=9A =9A </span><span style=3D"color:#008">return<=
/span><span
style=3D"color:#000"> m</span><span
style=3D"color:#660">.</span><span
style=3D"color:#000">valid</span><span
style=3D"color:#660">()</span><span
style=3D"color:#000"> </span><span
style=3D"color:#660">?</span><span
style=3D"color:#000"> continuation</span><span
style=3D"color:#660">(</span><span
style=3D"color:#000">m</span><span
style=3D"color:#660">.</span><span
style=3D"color:#000">value</span><span
style=3D"color:#660">())</span><span
style=3D"color:#000"> </span><span
style=3D"color:#660">:</span><span
style=3D"color:#000"> exceptional</span><span
style=3D"color:#660">(</span><span
style=3D"color:#000">m</span><span
style=3D"color:#660">);</span><span
style=3D"color:#000"><br>
</span><span style=3D"color:#660">}</span><span
style=3D"color:#000"><br>
</span></div>
</code></div>
It is clearly not the same as injecting<br>
<div
style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);bo=
rder-style:solid;border-width:1px;word-wrap:break-word"><code>
<div><span style=3D"color:#000">=9A</span><span
style=3D"color:#008">if</span><span
style=3D"color:#000"> </span><span
style=3D"color:#660">(!</span><span
style=3D"color:#000">a</span><span
style=3D"color:#660">.</span><span
style=3D"color:#000">valid</span><span
style=3D"color:#660">())</span><span
style=3D"color:#000"> </span><span
style=3D"color:#008">return</span><span
style=3D"color:#000"> exceptional</span><span
style=3D"color:#660">(</span><span
style=3D"color:#000">a</span><span
style=3D"color:#660">);</span><span
style=3D"color:#000"><br>
=9A</span><span style=3D"color:#008">auto</span><=
span
style=3D"color:#000"> x </span><span
style=3D"color:#660">=3D</span><span
style=3D"color:#000"> a</span><span
style=3D"color:#660">.</span><span
style=3D"color:#000">value</span><span
style=3D"color:#660">();</span><span
style=3D"color:#000"><br>
</span></div>
</code></div>
to await place in user code. Such injection should be
defined in other way (some kind of macro?). Or maybe I
missed something.<br>
</div>
</div>
</blockquote>
Humm, if you look carefully you will see that both are
equivalents. The continuation has as parameter the value x
and starts just after the initialization of x. <br>
If a is not valid the result of the function is the same
exceptional(m). <br>
</div>
</blockquote>
<div><br>
</div>
<div>Both are equal, indeed. At least from the point of view of
user.<br>
But first requires continuation, and second is injected
directly into place of "await", like a macro (implicitly
viewing rest of code as continuation).<br>
I just don't see how compiler should deduce this from
definition of <code><span style=3D"color:#000"></span><span
style=3D"color:#008">operator</span><span style=3D"color:#660=
">>>=3D</span></code>.
I mean, there should be requirement in ISO that compiler is<span
id=3D"result_box" class=3D"short_text" lang=3D"en"><span
class=3D"hps alt-edited"> obliged to</span></span> make such
optimization - but it is a bit fuzzy.<br>
<br>
</div>
</div>
</blockquote>
I agree that more formalism will be needed for the standard. Maybe
some tags could be needed to address some optimizations.<br>
<br>
Vicente<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--------------010501000706020509020305--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Fri, 10 Jan 2014 19:12:03 +0100
Raw View
This is a multi-part message in MIME format.
--------------020400030506020502040900
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: quoted-printable
Maybe the authors of N3722 have some comments to add on this thread.
Vicente
Le 05/01/14 22:55, Vicente J. Botet Escriba a =E9crit :
> Hi,
>
> We are working on a proposal (see [1] and [2]) for a expected<t> class (s=
omething like an immediate future<T>). This class shares a lot of interface=
s with std::future.
> An example of a function using expected could be a madd function that ret=
urn an expected with the the store values if both arguments are valid.
>
> expected<int> madd(expected<int> a, expected<int> b) {
> return a.then([=3D](int x) {
> return b.then([=3D](int y) {
> return x+y;
> });
> });
> }
>
>
> The expected<T>::then() function has a continuation function as parameter=
.. The continuation takes the underlying type as parameter.
> Note that this differs from N3721 proposal and at the end both proposals =
would need to take the same approach..
> expected<T> provides a recover function that takes a continuation with a =
exception_ptr as parameter.
> The advantage of splitting the valid and invalid behavior is that the use=
r code doesn't needs to check the validity or use try-catch blocks.
>
> I was wondering if it would be acceptable to use the*await* operator for=
expected types, which makes the code much clean and easy to read.
>
>
> expected<int> madd(expected<int> a, expected<int> b) {
> return*await* a +*await* b;
> }
>
>
> Note that I have not tagged the function as resumable, as expected are al=
ways ready, that is, expected<T>::get() never blocks.
>
> This madd function can be made more generic for any type M that is a '*Mo=
nad*'
>
> template <class M>
> // requires Monad<M>();
> M madd(M a, M b) {
> return a.then([=3D](int x) {
> return b.then([=3D](int y) {
> return x+y;
> });
> });
> }
>
>
> This generic madd function could be used with future<U> and expected<U> o=
r any other 'Monad' as e.g. optional<U>.
>
> The question is how this function must be written using resumable/await. =
I don't know if the proposal included resumable function templates, but if =
not I think it is worth considering it.
> It seems that it should be
>
>
> template <class T>
> // requires Monad<T>();
> T madd(T a, T b)*resumable* {
> return*await* a +*await* b;
> }
>
> but it is not evident that the type T is std::future<U> or shared_future<=
U> before instantiating it, so maybe the N3722 restrictions should be relax=
ed.
>
> I was wondering also if resumable functions couldn't be resumable conditi=
onally (as noexcept).
>
> template <class T>
> // requires Monad<T>();
> T madd(T a, T b)*resumable**(is_blocking<T>::value)* {
> return*await* a +*await* b;
> }
>
> The trait is_blocking<future<T>> would be true_type, while is_blocking<ex=
pected<T>> would be false_type.
>
> When the function is not resumable the translation of await expr is much =
simpler as there is no need to track the resume point.
>
> E.g.
>
> expected<int> madd(expected<int> a, expected<int> b) {
> return*await* a +*await* b;
> }
>
>
> could be equivalent to
>
> expected<int> madd(expected<int> a, expected<int> b) {
> auto x =3D await a;
> auto y =3D await b;
> return x +*y*;
> }
>
> that could be translated to
>
>
> expected<int> madd(expected<int> a, expected<int> b) {
> if (!a.valid()) return exceptional(a);
> auto x =3D a.value();
> if (!b.valid()) return exceptional(a);
> auto y =3D b.value();
> return x +*y*;
> }
>
> expected provides an explicit conversion to exceptional that requires tha=
t the expected is not valid().
> expected<T> is implicitly convertible from this exceptional class.
> value() is like get() but requires that the expected is valid().
>
> Comments?
>
> Best,
> Vicente
>
>
> [1]https://github.com/ptal/std-expected-proposal
> [2]https://github.com/ptal/Boost.Expected
>
>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--------------020400030506020502040900
Content-Type: text/html; charset=ISO-8859-1
<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<div class="moz-cite-prefix">Maybe the authors of N3722 have some
comments to add on this thread.<br>
<br>
Vicente<br>
<br>
Le 05/01/14 22:55, Vicente J. Botet Escriba a écrit :<br>
</div>
<blockquote cite="mid:52C9D4CB.6010209@wanadoo.fr" type="cite">
<meta http-equiv="content-type" content="text/html;
charset=ISO-8859-1">
<meta http-equiv="content-type" content="text/html;
charset=ISO-8859-1">
<pre>Hi,
We are working on a proposal (see [1] and [2]) for a expected<t> class (something like an immediate future<T>). This class shares a lot of interfaces with std::future.
An example of a function using expected could be a madd function that return an expected with the the store values if both arguments are valid.
expected<int> madd(expected<int> a, expected<int> b) {
return a.then([=](int x) {
return b.then([=](int y) {
return x+y;
});
});
}
The expected<T>::then() function has a continuation function as parameter. The continuation takes the underlying type as parameter.
Note that this differs from N3721 proposal and at the end both proposals would need to take the same approach..
expected<T> provides a recover function that takes a continuation with a exception_ptr as parameter.
The advantage of splitting the valid and invalid behavior is that the user code doesn't needs to check the validity or use try-catch blocks.
I was wondering if it would be acceptable to use the <b>await</b> operator for expected types, which makes the code much clean and easy to read.
expected<int> madd(expected<int> a, expected<int> b) {
return <b>await</b> a + <b>await</b> b;
}
Note that I have not tagged the function as resumable, as expected are always ready, that is, expected<T>::get() never blocks.
This madd function can be made more generic for any type M that is a '<b>Monad</b>'
template <class M>
// requires Monad<M>();
M madd(M a, M b) {
return a.then([=](int x) {
return b.then([=](int y) {
return x+y;
});
});
}
This generic madd function could be used with future<U> and expected<U> or any other 'Monad' as e.g. optional<U>.
The question is how this function must be written using resumable/await. I don't know if the proposal included resumable function templates, but if not I think it is worth considering it.
It seems that it should be
template <class T>
// requires Monad<T>();
T madd(T a, T b) <b>resumable</b> {
return <b>await</b> a + <b>await</b> b;
}
but it is not evident that the type T is std::future<U> or shared_future<U> before instantiating it, so maybe the N3722 restrictions should be relaxed.
I was wondering also if resumable functions couldn't be resumable conditionally (as noexcept).
template <class T>
// requires Monad<T>();
T madd(T a, T b) <b>resumable</b><b>(is_blocking<T>::value)</b> {
return <b>await</b> a + <b>await</b> b;
}
The trait is_blocking<future<T>> would be true_type, while is_blocking<expected<T>> would be false_type.
When the function is not resumable the translation of await expr is much simpler as there is no need to track the resume point.
E.g.
expected<int> madd(expected<int> a, expected<int> b) {
return <b>await</b> a + <b>await</b> b;
}
could be equivalent to
expected<int> madd(expected<int> a, expected<int> b) {
auto x = await a;
auto y = await b;
return x + <b>y</b>;
}
that could be translated to
expected<int> madd(expected<int> a, expected<int> b) {
if (!a.valid()) return exceptional(a);
auto x = a.value();
if (!b.valid()) return exceptional(a);
auto y = b.value();
return x + <b>y</b>;
}
expected provides an explicit conversion to exceptional that requires that the expected is not valid().
expected<T> is implicitly convertible from this exceptional class.
value() is like get() but requires that the expected is valid().
Comments?
Best,
Vicente
[1] <a moz-do-not-send="true" class="moz-txt-link-freetext" href="https://github.com/ptal/std-expected-proposal">https://github.com/ptal/std-expected-proposal</a>
[2] <a moz-do-not-send="true" class="moz-txt-link-freetext" href="https://github.com/ptal/Boost.Expected">https://github.com/ptal/Boost.Expected</a>
</pre>
</blockquote>
<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href="http://groups.google.com/a/isocpp.org/group/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br />
--------------020400030506020502040900--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Wed, 8 Jan 2014 02:25:48 -0800 (PST)
Raw View
------=_Part_9578_12715079.1389176748192
Content-Type: text/plain; charset=KOI8-R
Content-Transfer-Encoding: quoted-printable
8 January 2014 =C7., 5:11:40 UTC+4 Vicente J. Botet Escriba:
>
> Maybe you missed that this macro like substitution was an optimization fo=
r=20
> the case of expected with no stackless functions.
>
> I understood that this is optimization (it is indeed desirable). I just=
=20
don't know in which form user is supposed to define "bind" with such=20
optimization.
> How to define such transformation in general way?=20
>
> Why the Haskell response using bind (.then) is not a good answer?
>
It would look like:
template<typename F, typename T>
auto operator>>=3D(expected<T> m, F continuation)
{
return m.valid() ? continuation(m.value()) : exceptional(m);
}
It is clearly not the same as injecting
if (!a.valid()) return exceptional(a);
auto x =3D a.value();
to await place in user code. Such injection should be defined in other way=
=20
(some kind of macro?). Or maybe I missed something.
Also note, in general case >>=3D can call continuation several times, like =
in=20
List monad.
> Unless there is good answer for that - we should stick to continuations=
=20
> (for await approach it means to have resumable functions even for=20
> expected<T> monad).
> =20
> I think that users would not use await with expected if they know that th=
e=20
> consequence is that their functions becomes corrutines (which imo will be=
=20
> always less efficient than using normal function and the macro like=20
> replacement hack.
>
I agree - using stackful coroutines for await expected<T> is not optimal at=
=20
all. I just don't see in which form "macro like replacement hack" should be=
=20
defined by user.
Should user define overloadable macro BIND? Like pseudocode:
#define BIND(expected<T> a) \
( a.valid() ? a.value() : return exceptional(a) )
/**/
P.S. In case if you want to play with internals of await - I made=20
> proof-of-concept implementation of await based on Boost.Coroutine some ti=
me=20
> ago - https://github.com/panaseleus/await_emu .=20
> =20
> Very clever. I have a doubt about how it manages with exceptions.
>
For me await expr would not throw when the expression stores a exception,=
=20
> but will make the function containing such expression to return the=20
> associated monad with such a exception and this is the main point of awai=
t.=20
> Could you confirm you implementation behaves in a such way?
>
Well, current version is just quick proof of concept, and it has some=20
issues (solvable) with exception safety. It doesn't store exception in=20
promise::set_exception. But such behavior can be implemented.
> P.P.S. Today I have made simple linearizion of nested continuations=20
> based on Boost.Preprocessor - DO macro:=20
> https://github.com/panaseleus/monad_do
> =20
> Very clever yet. The do notation is a good thing a first step froward, bu=
t=20
> I would not like to be forced to sequence the await=20
>
> auto x =3D await a;
> auto y =3D await b;
> =EF=BF=BDreturn x + *y*;
>
>
> and be able to do
>
> return *await* a + *await* b;
>
> Can the your POC take care of this situation?
>
No, with current implementation it will be:
return DO(Expected,
(x, a)
(y, b)
(_, unit(x + y))
);
I doubt if Haskell's do-notation supports "return await a + await b;"=20
style. For such specific case it has liftM2 function: liftM2 (+) a b
> P.P.P.S. I don't like N3722 - it merges cons of stackful=20
> (Boost.Coroutine) and stackless coroutines (C# awat/yield) and loses thei=
r=20
> unique pros. I should prepare new topic about this.
> =20
> Let me know if you would consider how await could be managed when the=20
> expected value is already there, that it, the await couldn't not block, a=
nd=20
> there is not need to resume nothing.
>
Ok.=20
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_9578_12715079.1389176748192
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">8 January 2014 =D0=B3., 5:11:40 UTC+4 Vicente J=
.. Botet Escriba:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
=20
=20
=20
<div bgcolor=3D"#FFFFFF" text=3D"#000000">Maybe you missed that this macr=
o like substitution was an
optimization for the case of expected with no stackless functions.<br>
<blockquote type=3D"cite">
<div dir=3D"ltr"></div></blockquote></div></blockquote><div>I underst=
ood that this is optimization (it is indeed desirable). I just don't know i=
n which form user is supposed to define "bind" with such optimization.<br><=
/div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;"><div bgcolor=3D"#FFFFFF" =
text=3D"#000000"><blockquote type=3D"cite"><div dir=3D"ltr">How to define s=
uch transformation in general way? </div>
</blockquote>
Why the Haskell response using bind (.then) is not a good answer?<br></=
div></blockquote><div><br>It would look like:<br><div class=3D"prettyprint"=
style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187,=
187); border-style: solid; border-width: 1px; word-wrap: break-word;"><cod=
e class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color:=
#008;" class=3D"styled-by-prettify">template</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">typename</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> F</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>typename</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">></spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">operator</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">>>=3D(</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">expected</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">T</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">></span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> m</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> F continuation</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
></span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br> =
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">return</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> m</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">valid</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">()</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">?</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><code class=3D"prettyprint"><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">continuation</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify"></span></code><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">m</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">.</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">value</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>())</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">:</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> exceptional</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">m</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">}</span></div></code></div>It is clearly not the same =
as injecting<br><div class=3D"prettyprint" style=3D"background-color: rgb(2=
50, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; borde=
r-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div clas=
s=3D"subprettyprint"><div style=3D"background-color:rgb(250,250,250);border=
-color:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:break=
-word"><code><div><pre><span style=3D"color:#000"> </span><span style=
=3D"color:#008">if</span><span style=3D"color:#000"> </span><span style=3D"=
color:#660">(!</span><span style=3D"color:#000">a</span><span style=3D"colo=
r:#660">.</span><span style=3D"color:#000">valid</span><span style=3D"color=
:#660">())</span><span style=3D"color:#000"> </span><span style=3D"color:#0=
08">return</span><span style=3D"color:#000"> exceptional</span><span style=
=3D"color:#660">(</span><span style=3D"color:#000">a</span><span style=3D"c=
olor:#660">);</span><span style=3D"color:#000"><br> </span><span style=
=3D"color:#008">auto</span><span style=3D"color:#000"> x </span><span style=
=3D"color:#660">=3D</span><span style=3D"color:#000"> a</span><span style=
=3D"color:#660">.</span><span style=3D"color:#000">value</span><span style=
=3D"color:#660">();</span></pre></div></code></div><span style=3D"color: #6=
60;" class=3D"styled-by-prettify"></span></div></code></div>to await place =
in user code. Such injection should be defined in other way (some kind of m=
acro?). Or maybe I missed something.<br><br>Also note, in general case >=
>=3D can call continuation several times, like in List monad.<br></div><=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;"><div bgcolor=3D"#FFFFFF" text=
=3D"#000000">
<blockquote type=3D"cite">
<div dir=3D"ltr">Unless there is good answer for that - we should
stick to continuations (for await approach it means to have
resumable functions even for expected<T> monad).<br>
</div>
</blockquote>
I think that users would not use await with expected if they know
that the consequence is that their functions becomes corrutines
(which imo will be always less efficient than using normal function
and the macro like replacement hack.<br>
</div></blockquote><div><br>I agree - using stackful coroutines for awa=
it expected<T> is not optimal at all. I just don't see in which form =
"macro like replacement hack" should be defined by user.<br>Should user def=
ine overloadable macro BIND? Like pseudocode:<br><div class=3D"prettyprint"=
style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187,=
187); border-style: solid; border-width: 1px; word-wrap: break-word;"><cod=
e class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color:=
#660;" class=3D"styled-by-prettify">#define BIND(expected<T> a) \<br=
> ( a.valid() ? a.value() : return exceptional(a) )<br>/*=
*/<br></span><span style=3D"color: #660;" class=3D"styled-by-prettify"></sp=
an></div></code></div><br></div><blockquote class=3D"gmail_quote" style=3D"=
margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;=
"><div bgcolor=3D"#FFFFFF" text=3D"#000000"><blockquote type=3D"cite"><div =
dir=3D"ltr">
P.S. In case if you want to play with internals of await - I
made proof-of-concept implementation of await based on
Boost.Coroutine some time ago -
<a href=3D"https://github.com/panaseleus/await_emu" target=3D"_blan=
k" onmousedown=3D"this.href=3D'https://www.google.com/url?q\75https%3A%2F%2=
Fgithub.com%2Fpanaseleus%2Fawait_emu\46sa\75D\46sntz\0751\46usg\75AFQjCNEjZ=
KUW8FjVHCowRyLvkHeXj90mRg';return true;" onclick=3D"this.href=3D'https://ww=
w.google.com/url?q\75https%3A%2F%2Fgithub.com%2Fpanaseleus%2Fawait_emu\46sa=
\75D\46sntz\0751\46usg\75AFQjCNEjZKUW8FjVHCowRyLvkHeXj90mRg';return true;">=
https://github.com/panaseleus/<wbr>await_emu</a> . <br>
</div>
</blockquote>
Very clever. I have a doubt about how it manages with exceptions.<br></=
div></blockquote><div></div><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv bgcolor=3D"#FFFFFF" text=3D"#000000">
For me await expr would not throw when the expression stores a
exception, but will make the function containing such expression to
return the associated monad with such a exception and this is the
main point of await. Could you confirm you implementation behaves in
a such way?<br></div></blockquote><div><br>Well, current version is jus=
t quick proof of concept, and it has some issues (solvable) with exception =
safety. It doesn't store exception in promise::set_exception. But such beha=
vior can be implemented.<br></div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div bgcolor=3D"#FFFFFF" text=3D"#000000">
<blockquote type=3D"cite">
<div dir=3D"ltr">P.P.S. Today I have made simple linearizion of
nested continuations based on Boost.Preprocessor - DO macro:
<a href=3D"https://github.com/panaseleus/monad_do" target=3D"_blank=
" onmousedown=3D"this.href=3D'https://www.google.com/url?q\75https%3A%2F%2F=
github.com%2Fpanaseleus%2Fmonad_do\46sa\75D\46sntz\0751\46usg\75AFQjCNHiESa=
HKsfhiSfXOsebrGv1UWRoyg';return true;" onclick=3D"this.href=3D'https://www.=
google.com/url?q\75https%3A%2F%2Fgithub.com%2Fpanaseleus%2Fmonad_do\46sa\75=
D\46sntz\0751\46usg\75AFQjCNHiESaHKsfhiSfXOsebrGv1UWRoyg';return true;">htt=
ps://github.com/panaseleus/<wbr>monad_do</a><br>
</div>
</blockquote>
Very clever yet. The do notation is a good thing a first step
froward, but I would not like to be forced to sequence the await <br>
<pre> auto x =3D await a;
auto y =3D await b;
=D0=9E=C2=A9=E2=95=ABreturn x + <b>y</b>;
</pre>
and be able to do<br>
<br>
<pre> return <b>await</b> a + <b>await</b> b;</pre>
Can the your POC take care of this situation?<br></div></blockquote><di=
v><br> No, with current implementation it will be:<br><div class=3D"pr=
ettyprint" style=3D"background-color: rgb(250, 250, 250); border-color: rgb=
(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: break-w=
ord;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=
=3D"color: #660;" class=3D"styled-by-prettify">return DO(Expected,<br> =
; (x, a)<br> (y, b)<br> (_,=
unit(x + y))<br>);</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify"></span></div></code></div>I doubt if Haskell's do-notation support=
s "return await a + await b;" style. For such specific case it has liftM2 f=
unction: liftM2 (+) a b<br></div><blockquote class=3D"gmail_quote" style=3D=
"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex=
;"><div bgcolor=3D"#FFFFFF" text=3D"#000000">
<blockquote type=3D"cite">
<div dir=3D"ltr">P.P.P.S. I don't like N3722 - it merges cons of
stackful (Boost.Coroutine) and stackless coroutines (C#
awat/yield) and loses their unique pros. I should prepare new
topic about this.<br>
</div>
</blockquote>
Let me know if you would consider how await could be managed when
the expected value is already there, that it, the await couldn't not
block, and there is not need to resume nothing.<br></div></blockquote><=
div><br>Ok. <br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_9578_12715079.1389176748192--
.