220 31306 <a3cae110-2522-4364-9354-d9d87037b012@isocpp.org> article
Path: news.gmane.org!.POSTED!not-for-mail
From: Giovanni Piero Deretta <gpderetta@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: P0534: call/cc, type safety and exceptions
Date: Thu, 2 Mar 2017 02:11:07 -0800 (PST)
Lines: 275
Approved: news@gmane.org
Message-ID: <a3cae110-2522-4364-9354-d9d87037b012@isocpp.org>
References: <fc546ea4-a355-4a60-a7e7-97927993471d@isocpp.org>
 <3a57e294-7254-4358-828d-c9f7757f5295@isocpp.org>
 <4e6c13b2-4286-4df8-989b-97cbf3bf1cc7@isocpp.org>
 <312d04a6-8b20-4bf5-8357-507ba9938e84@isocpp.org>
 <a3c76a9f-ef02-4ea7-a754-66ee5a95b38f@isocpp.org>
 <762243ed-0c31-461d-b6fd-fdb8759857b2@isocpp.org>
 <f8a573b1-c4ff-48a2-8a6f-51433732ab26@isocpp.org>
 <aecc5a06-78cc-4071-8cce-b2e731439463@isocpp.org>
 <bc17b8b0-6e62-4e75-b271-7a744c57ea04@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_153_1034785371.1488449467845"
X-Trace: blaine.gmane.org 1488449472 21628 195.159.176.226 (2 Mar 2017 10:11:12 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Thu, 2 Mar 2017 10:11:12 +0000 (UTC)
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBDEP3I7TGEILZX67YUCRUBBRTWAS4@isocpp.org Thu Mar 02 11:11:06 2017
Return-path: <std-proposals+bncBDEP3I7TGEILZX67YUCRUBBRTWAS4@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-pg0-f70.google.com ([74.125.83.70])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBDEP3I7TGEILZX67YUCRUBBRTWAS4@isocpp.org>)
	id 1cjNhP-0004uo-G8
	for gclcip-std-proposals@m.gmane.org; Thu, 02 Mar 2017 11:11:03 +0100
Original-Received: by mail-pg0-f70.google.com with SMTP id d18sf86749274pgh.2
        for <gclcip-std-proposals@m.gmane.org>; Thu, 02 Mar 2017 02:11:10 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to:message-id:in-reply-to:references:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=z7p5Fbdv/2NUxhb7wbn2CY7foZNs8jNHkd65RLMShJU=;
        b=1NKqTN167KIBkiEId0MDjdvT61rS/qyVI0ICuN1VNjSQlYvQRlEUJ8rCjLntGaJaeg
         ip796gebt5esZOcKqS3dXTOqOmgkiGlmknb9+abIzg8TOIBCsVctKGFe/ACojo+aX9PN
         aeqNSZcvAaiN1Oo3dqFXMBsoOoaxWshsoexQ2Fc0n7PNV+YSjwGexhvjDscTcfxcnVWe
         JuLsFUmW9l16ObZP+rJ+FPBJ231qTbCVbqpTtZOvvpxrmcvepnSVqAZtTlO3/WH/kYbX
         AJjAOzwyPQrzRL/XYmyVI/GOeQPVA29/+tJM2tsy9l2cTOLn0U/1AM1I6LDtWAxA2f9r
         0Czw==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20161025;
        h=date:from:to:message-id:in-reply-to:references:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=z7p5Fbdv/2NUxhb7wbn2CY7foZNs8jNHkd65RLMShJU=;
        b=mISERnaKWAMAb5OfLFggUHrxn8fwEK+XJfUPdKHiqGIfmu7A3Do8STbFFDAZ4XVGDV
         HS+3kwJpPCU5+O3xnDOrxJsNlB52WQh6y5s3nnC+525fKzDKZTfv/8VdjslNRd/rnGq/
         khOvuOur3OjdryCKIazOy468DWgvGueIs+ib5TprVV1GVzuQdNgPfuwQl9VBIo8P8QgP
         dAfDnpbWUmZ53yEXfOmYn7gONLnPj9eawy7vUoOo5aySQAno3mh6SjIWvTbjKgd83ibR
         QqjjxOAyrH5HjnzwL2Ow5Rzfis1c3bMmJ+97SH7vLcGu30h2rG/nuLdbmWHAHRr4MiBO
         08pg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        h=x-gm-message-state:date:from:to:message-id:in-reply-to:references
         :subject:mime-version:x-original-sender:reply-to:precedence
         :mailing-list:list-id:x-spam-checked-in-group:list-post:list-help
         :list-archive:list-subscribe:list-unsubscribe;
        bh=z7p5Fbdv/2NUxhb7wbn2CY7foZNs8jNHkd65RLMShJU=;
        b=E51Hv3Ug2aipXTeSFpm4IaWGm2vq5rainAx2VVXY4l1DmorMaIIuglOae6j191lhLy
         3/WzXQBHvJdF+0bfbWRyU0T6HtKphJ0n8JMEUKfgOEEhB79aulWJPdXNSWYhoeCijlzV
         FF2HNyHoNu7wdzQcwRYA7b3zWW94ToLZY0L5Iimw+6ZKgZv8gnA2dzekc5N8f0kRQVFN
         rhP/y1MCHzIIAxJ6qBWJLtF9NhgvfH9q68kEdcSTYcdT1tx1lcMdN+UcQTM4pcDov7yZ
         MFECMnYoL3cTLgkTrcCfvoG2sxpMbOYA0dYT07DN3Me4wTqUzbyn5/atEbNd9lLmkDSW
         qNnw==
X-Gm-Message-State: AMke39luCbPKsBzwrmhQK3EiNd4tNNfJYnk+68jsmT+AH4EKbbjht+dnqXC7Ypzi3CM6wQ==
X-Received: by 10.98.76.199 with SMTP id e68mr2753934pfj.19.1488449469346;
        Thu, 02 Mar 2017 02:11:09 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.157.88.40 with SMTP id r40ls4428096oth.13.gmail; Thu, 02 Mar
 2017 02:11:08 -0800 (PST)
X-Received: by 10.157.56.117 with SMTP id r50mr1501984otd.12.1488449468538;
        Thu, 02 Mar 2017 02:11:08 -0800 (PST)
In-Reply-To: <bc17b8b0-6e62-4e75-b271-7a744c57ea04@isocpp.org>
X-Original-Sender: gpderetta@gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <https://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <https://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <https://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:31306
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/31306>

------=_Part_153_1034785371.1488449467845
Content-Type: multipart/alternative; 
	boundary="----=_Part_154_2084467805.1488449467845"

------=_Part_154_2084467805.1488449467845
Content-Type: text/plain; charset=UTF-8

On Thursday, March 2, 2017 at 9:43:30 AM UTC, Bengt Gustafsson wrote:
>
> Hi.
>
> I do really like the general idea of callcc and continuation class. But I 
> don't understand the need of data transfer at this low abstraction level.
>

You can of course arrange to have both sides of the continuation share a 
memory location, but it is cumbersome (especially when the two sides can 
switch freely like with symmetric coroutines) and potentially inefficient 
(The parameter passing can be made literally free in the low level 
assembler switching function by simply not saving and restoring a specific 
register). The implementation will need to pass parameters through anyway 
(to implement execute_on_top or exception transport, so it makes sense to 
expose the functionality to the user. Although I would prefer the 
functionality to be properly typed, I would settle for a single void* 
parameter as typing can be implemented on top of it with no cost.

 

> After all, these are not threads, so there is no asynchronism to think 
> about. To prove this point I implemented the classical generator pattern 
> without using continuation's data transfer possibilities (see attached 
> file). Sure enough, when the generator lambda calls yield(value) it stops 
> processing until the main program calls operator++ again. So all this time 
> the parameter to yield is valid on the generator's stack and available by 
> reference to the main program. So while there are obviously needs to send 
> data both ways for different patterns I fail to see why it must be a 
> feature of the lowest level abstraction.
>

well, yes the functionality is normally implemented by simply passing to 
the next continuation a pointer to the parameter on the stack.
 

>
> When I wrote the code for generator.h I also saw that the pattern 
> `mContinuation = mContinuation()` seems to be mandatory. If you forget the 
> assignment you loose the ability to continue the next time. While there may 
> be cases where you want to assign the continuation returned from operator() 
> to some other std::continuation object, wouldn't it be more appropriate to 
> make simple things simple by letting operator() return void and 
> automatically update its `this` to the new state before returning and then 
> applications which really do need to move the continuation object elsewhere 
> can do so afterwards. Again there are no threading issues so it should be 
> safe. In the back of my head I think there is some exception safety issue 
> at play here, but if so it needs to be explained more clearly.
>

My own implementation updates this, but I don't have a strong opinion, and 
the explicit assignment makes it more obvious that the new continuation has 
potentially no relation to the one just consumed.
 

>
> A comment on the invoke_on_top_t functionality. Why add a special tag type 
> just to be able to overload operator() to do another task when there is the 
> possibility to add a regular method: 
> std::continuation::invoke_on_top(args...). 
>

A possibility is dropping operator() and using callcc for everything. The 
full callcc signature woud be like this:

   callcc(cont, fn, arg)

Which is the same as cont(invoke_on_top, fn, args) 

A new continuation can be created with:

  callcc(make_empty_continuation(), fn, arg)

(where make_empty_continuation just creates a continuation that will exit 
immediately upon invocation)
Switching is just:

  callcc(cont, identity, arg);

This closely mimics callcc behaviour in other languages. In fact 
make_empty_continuation() and callcc are really the only two primitives you 
need.

Of course overloads and default parameters would make use of the library 
more straightforward (and, in the case of context switching, more 
efficient).

Also it would be interesting to know when this rather strange functionality 
> is useful.
>

The functionality is actually not strange at all if you think of the 
underlying CPS transformation, and it simplifies the implementation of 
continuation itself, as it can be directly used to implement continuation 
creation (just invoke on top of an empty continuation), exit (invoke on top 
of next and cleanup source), exception throwing (invoke on top then throw). 
It also greatly simplifies more complex uses of continuation (handy to 
implement scheduling, waiting, etc).
 

> An issue I stumbled upon during implementation was not being able to do 
> callcc() on a method. I think an overload of callcc specifically for method 
> pointers (in parallel with the std::function constructor set) will be 
> needed. This is as the std::continuation&& parameter gets prepended to the 
> args of callcc when calling the provided function. If the provided function 
> is a std::function wrapping a method pointer its operator() will expect to 
> get the 'this' of the object to call and instead it will get the 
> std::continuation prepended by callcc!
>
> // Example:
>
> class MyClass {
>     void fun(std::continuation&& cont);
> };
>
> MyClass myObj;
>
> callcc(&MyClass::fun, myObj);    // This is what you want to write, but 
> callcc does not take method pointers.
>
> // So you may try this:
>
> callcc(std::function<void(MyClass&, std::continuation&&)>(&MyClass::fun), 
> myObj);   // Mismatched types as callcc gets the order wrong.
>
> // Instead you have to conjure up a lambda:
>
> callcc([&](std::continuation&& cont) { myObj.fun(std::move(cont); });
>
>
>
> While the lambda solution works I think it is quite weak not to allow the 
> first version.
>
> I think a fully fledged implementation would have full INVOKE like 
semantics, but as it is very straightforward, probably implementing the 
feature is not very high in Oliver's priorities.
 

-- 
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/a3cae110-2522-4364-9354-d9d87037b012%40isocpp.org.

------=_Part_154_2084467805.1488449467845
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Thursday, March 2, 2017 at 9:43:30 AM UTC, Bengt Gustaf=
sson wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">Hi=
..<div><br></div><div>I do really like the general idea of callcc and contin=
uation class. But I don&#39;t understand the need of data transfer at this =
low abstraction level.</div></div></blockquote><div><br>You can of course a=
rrange to have both sides of the continuation share a memory location, but =
it is cumbersome (especially when the two sides can switch freely like with=
 symmetric coroutines) and potentially inefficient (The parameter passing c=
an be made literally free in the low level assembler switching function by =
simply not saving and restoring a specific register). The implementation wi=
ll need to pass parameters through anyway (to implement execute_on_top or e=
xception transport, so it makes sense to expose the functionality to the us=
er. Although I would prefer the functionality to be properly typed, I would=
 settle for a single void* parameter as typing can be implemented on top of=
 it with no cost.<br><br>=C2=A0</div><blockquote class=3D"gmail_quote" styl=
e=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left:=
 1ex;"><div dir=3D"ltr"><div> After all, these are not threads, so there is=
 no asynchronism to think about. To prove this point I implemented the clas=
sical generator pattern without using continuation&#39;s data transfer poss=
ibilities (see attached file). Sure enough, when the generator lambda calls=
 yield(value) it stops processing until the main program calls operator++ a=
gain. So all this time the parameter to yield is valid on the generator&#39=
;s stack and available by reference to the main program. So while there are=
 obviously needs to send data both ways for different patterns I fail to se=
e why it must be a feature of the lowest level abstraction.</div></div></bl=
ockquote><div><br>well, yes the functionality is normally implemented by si=
mply passing to the next continuation a pointer to the parameter on the sta=
ck.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr"><div><br></div><div>When I wrote the code for generator.h I also saw =
that the pattern `mContinuation =3D mContinuation()` seems to be mandatory.=
 If you forget the assignment you loose the ability to continue the next ti=
me. While there may be cases where you want to assign the continuation retu=
rned from operator() to some other std::continuation object, wouldn&#39;t i=
t be more appropriate to make simple things simple by letting operator() re=
turn void and automatically update its `this` to the new state before retur=
ning and then applications which really do need to move the continuation ob=
ject elsewhere can do so afterwards. Again there are no threading issues so=
 it should be safe. In the back of my head I think there is some exception =
safety issue at play here, but if so it needs to be explained more clearly.=
</div></div></blockquote><div><br>My own implementation updates this, but I=
 don&#39;t have a strong opinion, and the explicit assignment makes it more=
 obvious that the new continuation has potentially no relation to the one j=
ust consumed.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"mar=
gin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><=
div dir=3D"ltr"><div><br></div><div>A comment on the invoke_on_top_t functi=
onality. Why add a special tag type just to be able to overload operator() =
to do another task when there is the possibility to add a regular method: s=
td::continuation::invoke_on_<wbr>top(args...). </div></div></blockquote><di=
v><br>A possibility is dropping operator() and using callcc for everything.=
 The full callcc signature woud be like this:<br><br>=C2=A0=C2=A0 callcc(co=
nt, fn, arg)<br><br>Which is the same as cont(invoke_on_top, fn, args) <br>=
<br>A new continuation can be created with:<br><br>=C2=A0 callcc(make_empty=
_continuation(), fn, arg)<br><br>(where make_empty_continuation just create=
s a continuation that will exit immediately upon invocation)<br>Switching i=
s just:<br><br>=C2=A0 callcc(cont, identity, arg);<br><br>This closely mimi=
cs callcc behaviour in other languages. In fact make_empty_continuation() a=
nd callcc are really the only two primitives you need.<br><br>Of course ove=
rloads and default parameters would make use of the library more straightfo=
rward (and, in the case of context switching, more efficient).<br><br></div=
><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bo=
rder-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>Also it=
 would be interesting to know when this rather strange functionality is use=
ful.</div></div></blockquote><div><br>The functionality is actually not str=
ange at all if you think of the underlying CPS transformation, and it simpl=
ifies the implementation of continuation itself, as it can be directly used=
 to implement continuation creation (just invoke on top of an empty continu=
ation), exit (invoke on top of next and cleanup source), exception throwing=
 (invoke on top then throw). It also greatly simplifies more complex uses o=
f continuation (handy to implement scheduling, waiting, etc).<br>=C2=A0</di=
v><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;b=
order-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div>=
<div>An issue I stumbled upon during implementation was not being able to d=
o callcc() on a method. I think an overload of callcc specifically for meth=
od pointers (in parallel with the std::function constructor set) will be ne=
eded. This is as the std::continuation&amp;&amp; parameter gets prepended t=
o the args of callcc when calling the provided function. If the provided fu=
nction is a std::function wrapping a method pointer its operator() will exp=
ect to get the &#39;this&#39; of the object to call and instead it will get=
 the std::continuation prepended by callcc!</div><div><br></div><blockquote=
 style=3D"margin:0 0 0 40px;border:none;padding:0px"><div>// Example:</div>=
<div><br></div><div>class MyClass {</div><div>=C2=A0 =C2=A0 void fun(std::c=
ontinuation&amp;&amp; cont);</div><div>};</div><div><br></div><div>MyClass =
myObj;</div><div><br></div><div>callcc(&amp;MyClass::fun, myObj); =C2=A0 =
=C2=A0// This is what you want to write, but callcc does not take method po=
inters.</div><div><br></div><div>// So you may try this:</div><div><br></di=
v><div>callcc(std::function&lt;void(<wbr>MyClass&amp;, std::continuation&am=
p;&amp;)&gt;(&amp;<wbr>MyClass::fun), myObj); =C2=A0 // Mismatched types as=
 callcc gets the order wrong.</div><div><br></div><div>// Instead you have =
to conjure up a lambda:</div><div><br></div><div>callcc([&amp;](std::contin=
uation&amp;&amp; cont) { myObj.fun(std::move(cont); });</div></blockquote><=
div><br></div><div><br></div><div>While the lambda solution works I think i=
t is quite weak not to allow the first version.</div><div><br></div></div><=
/blockquote><div>I think a fully fledged implementation would have full INV=
OKE like semantics, but as it is very straightforward, probably implementin=
g the feature is not very high in Oliver&#39;s priorities.<br>=C2=A0</div><=
/div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/a3cae110-2522-4364-9354-d9d87037b012%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/a3cae110-2522-4364-9354-d9d87037b012=
%40isocpp.org</a>.<br />

------=_Part_154_2084467805.1488449467845--

------=_Part_153_1034785371.1488449467845--

.
