220 32755 <6416578b-a1b5-4124-8334-f735460038b5@isocpp.org> article
Path: news.gmane.org!.POSTED!not-for-mail
From: Nicol Bolas <jmckesson@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: The Proxies - A Language Feature Decoupling
 Implementations from Requirements of Polymorphism
Date: Tue, 13 Jun 2017 08:20:26 -0700 (PDT)
Lines: 254
Approved: news@gmane.org
Message-ID: <6416578b-a1b5-4124-8334-f735460038b5@isocpp.org>
References: <8d79a013-fe0e-4fb6-8278-d438ae9b4c64@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_4049_519534447.1497367226690"
X-Trace: blaine.gmane.org 1497367235 25894 195.159.176.226 (13 Jun 2017 15:20:35 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Tue, 13 Jun 2017 15:20:35 +0000 (UTC)
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBCEKFTV6ZUMBBO4FQDFAKGQEXBUBPQI@isocpp.org Tue Jun 13 17:20:27 2017
Return-path: <std-proposals+bncBCEKFTV6ZUMBBO4FQDFAKGQEXBUBPQI@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-ot0-f199.google.com ([74.125.82.199])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBCEKFTV6ZUMBBO4FQDFAKGQEXBUBPQI@isocpp.org>)
	id 1dKncH-00066d-OL
	for gclcip-std-proposals@m.gmane.org; Tue, 13 Jun 2017 17:20:26 +0200
Original-Received: by mail-ot0-f199.google.com with SMTP id r9sf28304612oth.11
        for <gclcip-std-proposals@m.gmane.org>; Tue, 13 Jun 2017 08:20:28 -0700 (PDT)
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=Bobe9US8j6OoGFQ6dVIwflaPKxytgp8PDVRGLcIAql0=;
        b=akw+ftlZ+rRJ45v5uTwf8XrU0yYaL2Jq40dfgRueG2GPOt0Hx3g0qBueTdLxMC9Uom
         jhQCJVAC/7H8PaPOm605y4QMUyW/40g5ed9rdAGCigtJZ3gurPRG8b5duUD5TcuSyDsj
         bjf6Cx/UbUGPqQPQDbtZsXNo6U96OYyxt51QnzhPkkbJcZA6P9YrwuTQ3rsp5gcslqoj
         SwHYYNNsp5UUcoizFlOneCgFTHHO9yY6+Gkkk37Gz4ecTumXKVe8xJJsaIXvwxkHRKM/
         DFiSn2XYuOoNM8aQ0CoBky5YUWYZMmTUJfiqUJoN7aBfLUklI2WIThc2QR5sPaUX6QmX
         XCqw==
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=Bobe9US8j6OoGFQ6dVIwflaPKxytgp8PDVRGLcIAql0=;
        b=Yh+lh5ZJ34e4tIoZDfdWML+wEUP7vpcpXQ0QJMrr8kyYCRlUrtq+bCPxNpf5wS2auO
         RKYlbtGBK/9AEH3eEcesDPWqNLmItcqnhBDvxgVqx1sYFexzddQuhxFlLI6qmW5Q8Zh6
         Hmc9csTa+uvFYwT4QeTVCwXEfuT1MJWnFt+G6+/ls++gqV2x99vGjs6bzaHto0JsMYoA
         xNHjwVTF88WxwzmGnRYyjwn16mszHVE/UwHeTC8dcJVEh4YYOVwjWoAsYqgyIcTLfLEn
         cjAOK+0vEyPJ1q8DtRzTSbFgSCXuQx5ck8d7SaHaFdLA0FHZHRap4/Kcn+XDUiPzHOPH
         occQ==
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=Bobe9US8j6OoGFQ6dVIwflaPKxytgp8PDVRGLcIAql0=;
        b=YOsSTLeBA29dxao6z6VtXnchqIDf2L6dOEXcNi2aS4eOqwon8+vzPvaTF0iSwk0ha5
         +5GN6daY/+S+D7PTS/xTBZik1WXFWUQJTZLjVkjPZ6fWxA7JZGPYy4pT5nXaTLj3vkF4
         iy6s0tjUoiZWvz2dqpP4PQywsxbre1tD4uYT1v6waUyJJs/Qf9AGRlSh2zPQkz7wl2+v
         TmyVbf5EDSSzGn7rkr03mgGLJrFRkC8/sMufM6F2HFMkWxxYnB/3ob71yJ4YfrLWHckR
         a5WrCJ3ZBbmtdwbpCQX9TcVkw1t4XXGKNwoVD/fTIz+ZSzOkXHxShTM1NHSTAiibLXxj
         qOpg==
X-Gm-Message-State: AKS2vOyh+g8W4d/nI8fhJsVVhjohY2aWaN7qANxbqCTN2VSWw/q7oNj4
	kyBroC6NnxYy2bLD
X-Received: by 10.157.25.143 with SMTP id k15mr3160664otk.64.1497367228215;
        Tue, 13 Jun 2017 08:20:28 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.157.13.231 with SMTP id 94ls17036819ots.32.gmail; Tue, 13 Jun
 2017 08:20:27 -0700 (PDT)
X-Received: by 10.157.51.170 with SMTP id u42mr152789otc.7.1497367227232;
        Tue, 13 Jun 2017 08:20:27 -0700 (PDT)
In-Reply-To: <8d79a013-fe0e-4fb6-8278-d438ae9b4c64@isocpp.org>
X-Original-Sender: jmckesson@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:32755
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/32755>

------=_Part_4049_519534447.1497367226690
Content-Type: multipart/alternative; 
	boundary="----=_Part_4050_251918191.1497367226690"

------=_Part_4050_251918191.1497367226690
Content-Type: text/plain; charset="UTF-8"

On Tuesday, June 13, 2017 at 9:49:43 AM UTC-4, Mingxin Wang wrote:
>
> *Technical Specifications*
>
> *Wrapper requirements*
>
> A type W meets the Wrapper requirements if the following expressions are 
> well-formed and have the specific semantics (w denotes a value of type W).
>
> w.get()
> Requires: w is initialized with an object.
> Effects: acquires the pointer of the wrapped object if there is one.
> Return type: void*.
> Returns: a pointer of the wrapped object.
>
>
This seems decidedly thin on details.

As I understand your design, the "wrapper" provides both the storage for 
the object/pointer as well as determining the semantics relative to that 
object/pointer. This is not entirely clear from your technical 
specifications, but everything else I'm going to say is based on this 
assumption.

First, "wrapper" is a *terrible* name for this concept. It isn't "wrapping" 
anything; it's providing storage and specifying the semantics of the proxy 
(which also isn't a particularly good name). That isn't "wrapping". It's 
simply providing the semantics of the type. So "Semantics" seems a much 
more descriptive name.

Second, the `get` interface is entirely insufficient to fully define this 
concept. The "wrapper" needs to be able to be initialized from any object 
that matches `I`, so that has to be part of its interface. Your example 
code shows this, but these "Wrapper requirements" don't mention it. 
Furthermore:

Third, it's not clear who is actually responsible for the *type erasure* 
part of this. The type `T` provided to a "proxy" seems to be erased by the 
code generated data. But since the "wrapper" holds the storage for said 
`T`, it must also have enough information to *destroy* that object. After 
all, the "wrapper" may copy/move from the given `T` into new storage for 
that `T`. Which means that the "wrapper" implementation has to know what 
that `T` was when it goes to destroy it.

This means that any "wrapper" that actually owns a `T` must *itself* 
perform type-erasure, for the purpose of destroying the `T`. We discussed 
this in your last thread. Double-type-erasure is less efficient than 
single-type-erasure, thus violating one of your design goals.

Now, you might be able to work around this problem. You could design it so 
that the "wrapper" explicitly advertises in its interface that it is an 
"owning" wrapper, such that it needs to be provided with the un-erased `T` 
when the "proxy" is being destroyed. But that's a much more complex 
interface than you have outlined here.

*Class template proxy*
>
> Expression "proxy<I, W>" is a well-formed type if I is a pure virtual 
> class (without a virtual destructor) and W is a type meets the Wrapper 
> requirements defined above.
>
> "proxy<I, W>" is MoveConstructible if W is MoveConstructible, while 
> "proxy<I, W>" is CopyConstructible if W is CopyConstructible.
>
> Providing p is a value of "proxy<I, W>" and i is a pointer of I, 
> "p.f(args...)" shall be a valid expression if "(*i).f(args...)" is a valid 
> expression, where f is any valid function name (including operator 
> overloads) and "args..." is any valid combination of values of any type.
>

As previously mentioned, the "proxy" ought to provide `any_cast`-like 
functionality. That is, the ability to extract an object/reference to the 
exact `T` which was provided. Since the "proxy" type's semantics are part 
of its type declaration (defined by `W`), it would be easy to specialize 
the interface for reference proxies vs. value proxies.

Alternatively, you could use the `std::function::target` interface for a 
lighter-weight version. But the overall point is the same: a type-erased 
type ought to be able to extract what it was given.

*Prototypes for Wrappers*
>
> Class "SharedWrapper" (with shared semantics), class template 
> "DeepWrapper" (with value semantics and SOO feature) and class 
> "DefferedWrapper" (with reference semantics) are designed to meet the 
> Wrapper requirements. Possible implementation is included in the 
> attachments.
>

"DeepWrapper" is the wrong name. It provides "value semantics". Calling it 
"deep" suggests "deep copying", which is *not* what this provides. It 
should simply be "ValueWrapper". And there should also be a 
"MoveValueWrapper", for use in cases where you want to allow users to 
provide move-only types.

"DefferedWrapper" is similarly misnamed (though also misspelled). It 
provides "reference semantics", so it is a "ReferenceWrapper". Admittedly, 
we already have a type with that name, but that's another reason not to 
call them "wrappers" at all.

Also, it's not clear what "SharedWrapper" means. Does it copy/move into 
memory owned by the proxy, ala `make_shared`? Can you pass it a 
`shared_ptr<T>` instead of a `T`, so that you can share ownership of the 
object with the proxy? If not, why not? If you're going to allow shared 
ownership of the value, then it is just as reasonable to allow shared 
ownership of the value with objects that *aren't* the proxy.

This is one of the problems of going to a generic mechanism for handling 
semantics: the rabbit hole of possibilities is infinite.

That being said, since the "wrapper" is part of the proxy's template 
declaration, it is possible to have the "wrapper" actually influence the 
proxy's interface. So the "wrapper" could affect the definition of the 
proxy's template constructor from `T`, as well as the template function 
which extracts a pointer/reference to the proxied type. A `SharedWrapper` 
could therefore allow you to pass a `shared_ptr<T>`, as well as allow you 
to extract a `shared_ptr<T>`.

-- 
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/6416578b-a1b5-4124-8334-f735460038b5%40isocpp.org.

------=_Part_4050_251918191.1497367226690
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Tuesday, June 13, 2017 at 9:49:43 AM UTC-4, Mingxin Wan=
g 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"><div>=
</div><div><font size=3D"6"><b>Technical Specifications</b></font></div><di=
v><br></div><div><font size=3D"4"><b>Wrapper requirements</b></font></div><=
div><br></div><div>A type W meets the Wrapper requirements if the following=
 expressions are well-formed and have the specific semantics (w denotes a v=
alue of type W).</div><div><br></div><div>w.get()</div><div><span style=3D"=
white-space:pre">	</span>Requires: w is initialized with an object.</div><d=
iv><span style=3D"white-space:pre">	</span>Effects: acquires the pointer of=
 the wrapped object if there is one.</div><div><span style=3D"white-space:p=
re">	</span>Return type: void*.</div><div><span style=3D"white-space:pre">	=
</span>Returns: a pointer of the wrapped object.</div><div><br></div></div>=
</blockquote><div><br>This seems decidedly thin on details.<br><br>As I und=
erstand your design, the &quot;wrapper&quot; provides both the storage for =
the object/pointer as well as determining the semantics relative to that ob=
ject/pointer. This is not entirely clear from your technical specifications=
, but everything else I&#39;m going to say is based on this assumption.<br>=
<br>First, &quot;wrapper&quot; is a <i>terrible</i> name for this concept. =
It isn&#39;t &quot;wrapping&quot; anything; it&#39;s providing storage and =
specifying the semantics of the proxy (which also isn&#39;t a particularly =
good name). That isn&#39;t &quot;wrapping&quot;. It&#39;s simply providing =
the semantics of the type. So &quot;Semantics&quot; seems a much more descr=
iptive name.<br><br>Second, the `get` interface is entirely insufficient to=
 fully define this concept. The &quot;wrapper&quot; needs to be able to be =
initialized from any object that matches `I`, so that has to be part of its=
 interface. Your example code shows this, but these &quot;Wrapper requireme=
nts&quot; don&#39;t mention it. Furthermore:<br><br>Third, it&#39;s not cle=
ar who is actually responsible for the <i>type erasure</i> part of this. Th=
e type `T` provided to a &quot;proxy&quot; seems to be erased by the code g=
enerated data. But since the &quot;wrapper&quot; holds the storage for said=
 `T`, it must also have enough information to <i>destroy</i> that object. A=
fter all, the &quot;wrapper&quot; may copy/move from the given `T` into new=
 storage for that `T`. Which means that the &quot;wrapper&quot; implementat=
ion has to know what that `T` was when it goes to destroy it.<br><br>This m=
eans that any &quot;wrapper&quot; that actually owns a `T` must <i>itself</=
i> perform type-erasure, for the purpose of destroying the `T`. We discusse=
d this in your last thread. Double-type-erasure is less efficient than sing=
le-type-erasure, thus violating one of your design goals.<br><br>Now, you m=
ight be able to work around this problem. You could design it so that the &=
quot;wrapper&quot; explicitly advertises in its interface that it is an &qu=
ot;owning&quot; wrapper, such that it needs to be provided with the un-eras=
ed `T` when the &quot;proxy&quot; is being destroyed. But that&#39;s a much=
 more complex interface than you have outlined here.<br><br></div><blockquo=
te class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left:=
 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><div><font =
size=3D"4"><b>Class template proxy</b></font></div><div><br></div><div>Expr=
ession &quot;proxy&lt;I, W&gt;&quot; is a well-formed type if I is a pure v=
irtual class (without a virtual destructor) and W is a type meets the Wrapp=
er requirements defined above.</div><div><br></div><div>&quot;proxy&lt;I, W=
&gt;&quot; is MoveConstructible if W is MoveConstructible, while &quot;prox=
y&lt;I, W&gt;&quot; is CopyConstructible if W is CopyConstructible.</div><d=
iv><br></div><div>Providing p is a value of &quot;proxy&lt;I, W&gt;&quot; a=
nd i is a pointer of I, &quot;p.f(args...)&quot; shall be a valid expressio=
n if &quot;(*i).f(args...)&quot; is a valid expression, where f is any vali=
d function name (including operator overloads) and &quot;args...&quot; is a=
ny valid combination of values of any type.</div></div></blockquote><div><b=
r>As previously mentioned, the &quot;proxy&quot; ought to provide `any_cast=
`-like functionality. That is, the ability to extract an object/reference t=
o the exact `T` which was provided. Since the &quot;proxy&quot; type&#39;s =
semantics are part of its type declaration (defined by `W`), it would be ea=
sy to specialize the interface for reference proxies vs. value proxies.<br>=
<br>Alternatively, you could use the `std::function::target` interface for =
a lighter-weight version. But the overall point is the same: a type-erased =
type ought to be able to extract what it was given.<br><br></div><blockquot=
e class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: =
1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><div><b><fon=
t size=3D"4">Prototypes for Wrappers</font></b></div><div><br></div><div>Cl=
ass &quot;SharedWrapper&quot; (with shared semantics), class template &quot=
;DeepWrapper&quot; (with value semantics and SOO feature) and class &quot;D=
efferedWrapper&quot; (with reference semantics) are designed to meet the Wr=
apper requirements. Possible implementation is included in the attachments.=
</div></div></blockquote><div><br>&quot;DeepWrapper&quot; is the wrong name=
.. It provides &quot;value semantics&quot;. Calling it &quot;deep&quot; sugg=
ests &quot;deep copying&quot;, which is <i>not</i> what this provides. It s=
hould simply be &quot;ValueWrapper&quot;. And there should also be a &quot;=
MoveValueWrapper&quot;, for use in cases where you want to allow users to p=
rovide move-only types.<br><br>&quot;DefferedWrapper&quot; is similarly mis=
named (though also misspelled). It provides &quot;reference semantics&quot;=
, so it is a &quot;ReferenceWrapper&quot;. Admittedly, we already have a ty=
pe with that name, but that&#39;s another reason not to call them &quot;wra=
ppers&quot; at all.<br><br>Also, it&#39;s not clear what &quot;SharedWrappe=
r&quot; means. Does it copy/move into memory owned by the proxy, ala `make_=
shared`? Can you pass it a `shared_ptr&lt;T&gt;` instead of a `T`, so that =
you can share ownership of the object with the proxy? If not, why not? If y=
ou&#39;re going to allow shared ownership of the value, then it is just as =
reasonable to allow shared ownership of the value with objects that <i>aren=
&#39;t</i> the proxy.<br><br> This is one of the problems of going to a gen=
eric mechanism for=20
handling semantics: the rabbit hole of possibilities is infinite.<br><br>Th=
at being said, since the &quot;wrapper&quot; is part of the proxy&#39;s tem=
plate declaration, it is possible to have the &quot;wrapper&quot; actually =
influence the proxy&#39;s interface. So the &quot;wrapper&quot; could affec=
t the definition of the proxy&#39;s template constructor from `T`, as well =
as the template function which extracts a pointer/reference to the proxied =
type. A `SharedWrapper` could therefore allow you to pass a `shared_ptr&lt;=
T&gt;`, as well as allow you to extract a `shared_ptr&lt;T&gt;`.<br></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/6416578b-a1b5-4124-8334-f735460038b5%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/6416578b-a1b5-4124-8334-f735460038b5=
%40isocpp.org</a>.<br />

------=_Part_4050_251918191.1497367226690--

------=_Part_4049_519534447.1497367226690--

.
