220 32057 <3bf83fd7-8b87-45ca-ac8b-3b856776acac@isocpp.org> article
Path: news.gmane.org!.POSTED!not-for-mail
From: =?UTF-8?Q?Aar=C3=B3n_Bueno_Villares?= <abv150ci@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Proxy objects and casting to rvalues
Date: Sun, 9 Apr 2017 08:51:46 -0700 (PDT)
Lines: 245
Approved: news@gmane.org
Message-ID: <3bf83fd7-8b87-45ca-ac8b-3b856776acac@isocpp.org>
References: <9da2eb61-ab97-4b03-933e-da18139d77c0@isocpp.org>
 <CAMbYJhYK55BWCgLxcYHRzwo4MOgyFe68mnVcPvaTrAXyWUnwOA@mail.gmail.com>
 <a4e15473-7370-4a69-b126-58c48a64c401@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_1024_2110165171.1491753106814"
X-Trace: blaine.gmane.org 1491753113 22443 195.159.176.226 (9 Apr 2017 15:51:53 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Sun, 9 Apr 2017 15:51:53 +0000 (UTC)
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBCP4374NRYKBBE5RVHDQKGQEEJ6R5JY@isocpp.org Sun Apr 09 17:51:47 2017
Return-path: <std-proposals+bncBCP4374NRYKBBE5RVHDQKGQEEJ6R5JY@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-pg0-f71.google.com ([74.125.83.71])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBCP4374NRYKBBE5RVHDQKGQEEJ6R5JY@isocpp.org>)
	id 1cxF7v-0004ay-J3
	for gclcip-std-proposals@m.gmane.org; Sun, 09 Apr 2017 17:51:43 +0200
Original-Received: by mail-pg0-f71.google.com with SMTP id 68sf110791286pgj.23
        for <gclcip-std-proposals@m.gmane.org>; Sun, 09 Apr 2017 08:51:49 -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=8qQjppwor4aleWrb0QVq7lODtU9Tb0GHrWo8iANWtRs=;
        b=YN2P1Othrt5y4HFRgK+uWJ1Vxp4Y2Z8R2hVg4P7/ML7YgTA1+QCrux9kCP7Ge2fW/j
         3e8qtAHFQfz6D6DSryY2YuIk5lp7HMq5tk9ZoF0lhSD3763go2K+F9Zcne9DxyUuy3t5
         WpPc+W8ZmeVuQvaRSBB+blyQs/LvxKwrAl2LpvFc/7BYg+/+pOup9LV+BJMpXcURmqKp
         yKqxLVBYZ0WJ/Z8ITN7+wPyAHEJQ3HA2yCaIi2pvNESKndDzvW2eDWIehaxapFHasUNz
         YNxyV21RnrDo5CihLkTNy/PXPF3CWr4Fpo5jmZ+SHsLLVkkIJWO0NGltPXHd7jn/oYn2
         la7w==
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=8qQjppwor4aleWrb0QVq7lODtU9Tb0GHrWo8iANWtRs=;
        b=dQ1dH0JI/9PaNYoRHd9kEGKK0L5KovoJzC0AMBcS2x5Uv4kUKAtAeopwsLC3lipRjZ
         2MfnM4GrbrwkoDFMgPalSA1Iwa8p6wVMFq+nFGOEG2O3+vJ72DkuDq6MNL69B90qjEcY
         JCJE5BHrUN8A2MK0c9HXxYUVUVnjlypiFL6jUo0o2jpsWDA2NyIwZl0ONkEpC2usbLIU
         qE0G4CpZDNWrjMsDL8K+g9xTAUnRvHxkaRw5FwQoK9Mz9z7zA4xl4QfjoQ6I5SIKWzJ1
         XXbN8WE/Kk90EBnyZKhhXtWmClB7TOijtxAKzn3f4rvcPK+g6k5NChuv64B8agQbcZ8+
         xM8w==
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=8qQjppwor4aleWrb0QVq7lODtU9Tb0GHrWo8iANWtRs=;
        b=mlNq14XKXms+YTUaSV6+2eo84ntA2h5U/uwBmxR3ZmdaYKxd5sYZP9C5zUDZs5CMqv
         MKarooEzEfy/qCZQyh7801g2sMAtP6c7HfKtOuL+HLU77r9k8Y3GX5US2MOR1aB4UrsA
         e1ie9kfxhPOWjk+Gg8M08CjKZOaHL6Pk71XzL6tlwaoZbtP9lgGkXi7BamcDbWwshGYY
         enZv+qTZFvREox81VlhrbBGOLspLidMIMvDjGVrTioCelHMEU6f6F4C9GTEX+3CcI3rL
         xr/FqjVYXxMYuUE5gscvaC1mTQU1hPmx5fMQCrPrngVCP9701F2Aa811v/I6E3PFyGiu
         fUMw==
X-Gm-Message-State: AFeK/H1pX1Z39JFWwRET3kmwZx5K4HC02Xw3U71yW8jhgyx/leLKidhPJfIBAIZKHx6PHQ==
X-Received: by 10.99.114.92 with SMTP id c28mr19329529pgn.17.1491753108076;
        Sun, 09 Apr 2017 08:51:48 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.157.63.119 with SMTP id m110ls2992351otc.26.gmail; Sun, 09 Apr
 2017 08:51:47 -0700 (PDT)
X-Received: by 10.157.43.178 with SMTP id u47mr127040ota.3.1491753107248;
        Sun, 09 Apr 2017 08:51:47 -0700 (PDT)
In-Reply-To: <a4e15473-7370-4a69-b126-58c48a64c401@isocpp.org>
X-Original-Sender: abv150ci@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:32057
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/32057>

------=_Part_1024_2110165171.1491753106814
Content-Type: multipart/alternative; 
	boundary="----=_Part_1025_1524697587.1491753106814"

------=_Part_1025_1524697587.1491753106814
Content-Type: text/plain; charset=UTF-8


On Sunday, 9 April 2017 16:30:28 UTC+2, Nicol Bolas wrote:
>
> What you're essentially asking is a modified form of something that has 
> been discussed since `auto` came into existence: the ability to specify the 
> type that will be deduced by `auto`. And proxy objects are the primary 
> justification for it, whether it is proxy iterators or lazy evaluation of 
> expressions (you want `auto` to evaluate the lazy expression, not store the 
> lazy intermediate).
>
> The best syntactic form I've seen this in is via a member function of the 
> form:
>
> class bit_wrapper
> {
> public:
>     Typename operator auto() const { <conversion expression> }
> };
>
> Note that this allows you to do arbitrary work in the conversion section. 
> Though we might add an `= default` version which is equivalent to implicit 
> conversion via `return *this;`.
>
>
But I think it makes impossible to use `auto` to copy instances of that 
type. For instance:

```C++
struct wrapper { value_type operator auto() const { /**/ } };
auto wrapper_obj = wrapper_factory::give_me_a_new_wrapper(); 
```

or any copy I have to do with the wrapper (or any intermediary function 
returning it), will be deduced as `value_type`. However, I'm still working 
with a `wrapper`!! The "reference nature" has not been start yet. That 
conversion operator forces me to think a bit more anytime I want to use 
`auto`. 

What if I want to bind the object to a reference, to modify the real object 
that is behind?

```C++
auto const& w = *it;
w = something; // The wrapped object must be modified, as a real reference.
```

Since the proxy represents a reference, must be trated as such when taking 
it by reference or by value when it is still a "object proxy". But when 
passing it as "pure proxy" or "pure reference proxy" or the way you want to 
call it, then it must be cast to the secondary type when copying. The `! 
value_type` is not a new type, but some kind of conversion qualifier.
 

> This function is put in the actual type that would otherwise be deduced. I 
> think this works much better than your notion of adding it to the 
> `operator*` of the iterator (I assume; you put it in `vector<bool>` 
> instead, which has no `operator*`). Your way requires the compiler to 
> change what it is doing based on the return of a specific function call, so 
> it requires more work to do lazy expression evaluation, since you have to 
> apply it to every single function that returns a lazy result.
>
>
Yes, the whole thing it's crazy complex semantically. Too much context.

The big, unanswered question with such a feature is mainly about what 
> exactly it affects. Does it only affect uses of the `auto` keyword for 
> variables? If it only affects `auto` variables, would that not be strange 
> with regard to generic lambda/Concepts TS `auto` parameters, which use 
> template argument deduction? Does it affect `decltype(auto)`, and if so, 
> how exactly? If it affects every form of deduction (template argument, 
> `decltype(auto)` and `auto`), then exactly how does it work?
>

My approach has the same problems. The thing is that, when you are 
constructing a new object from a combined type, you have too much 
situations (whe asume that `value_type` cannot be a reference, but 
`wrapper` does):

```C++
/* When expr is T ! V (T is not referfence) */
// (1)
T a = expr; // Error or do we want to copy the proxy object losing the 
convert-when-copying nature?
T& ra = expr; // Same situation.
T const& ra = expr; // Same situation.

// (2)
T!V a = expr; // Ok, we copy `T`.
T!V& a = expr; // Ok, if expr returns an `lvalue`.
T!V const& a = expr; // Ok.

// (3)
auto a = expr; // Ok, we cast to V and then copy. auto decuded as V
auto& a2 = expr; // auto deduced as T!V& (a.k.a T&)
auto const& a3 = expr; // auto decuded as T!V const& (a.k.a T const&).
auto a4 = a2; // Ok, auto deduced as V since a2 is T!V&
```

The think is that, when dealing with iterators, you don't have two types, 
but have three:

* value_type represents the storage. What `sort` needs when doing copies.
* sequence_type represents the view that the iterator gives to you.
* reference is something in the middle, with allows to comunicate between 
both worlds. What `operator*` returns.

`sequence_type` doesn't need to be explicitely defined, not added to the 
Iterator concept or something. It is what users expect when reading the 
iterator (for example, the parameters of the functors passed to 
`for_each`). With `reference` being convertible to user parameters is 
enough. `value_type` is what algorithms and user expects for local storage, 
to transform and save back the value to the iterator. The `reference` type 
is then tricked to allow one of another usage depending on the context, in 
a way more or less, transparent to current implementations. 

-- 
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/3bf83fd7-8b87-45ca-ac8b-3b856776acac%40isocpp.org.

------=_Part_1025_1524697587.1491753106814
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div><br></div>On Sunday, 9 April 2017 16:30:28 UTC+2, Nic=
ol Bolas  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"lt=
r">What you&#39;re essentially asking is a modified form of something that =
has been discussed since `auto` came into existence: the ability to specify=
 the type that will be deduced by `auto`. And proxy objects are the primary=
 justification for it, whether it is proxy iterators or lazy evaluation of =
expressions (you want `auto` to evaluate the lazy expression, not store the=
 lazy intermediate).<br><br>The best syntactic form I&#39;ve seen this in i=
s via a member function of the form:<br><br><div style=3D"background-color:=
rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-wi=
dth:1px"><code><div><span style=3D"color:#008">class</span><span style=3D"c=
olor:#000"> bit_wrapper<br></span><span style=3D"color:#660">{</span><span =
style=3D"color:#000"><br></span><span style=3D"color:#008">public</span><sp=
an style=3D"color:#660">:</span><span style=3D"color:#000"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color:#606">Typename</span><span style=3D"color:#=
000"> </span><span style=3D"color:#008">operator</span><span style=3D"color=
:#000"> </span><span style=3D"color:#008">auto</span><span style=3D"color:#=
660">()</span><span style=3D"color:#000"> </span><span style=3D"color:#008"=
>const</span><span style=3D"color:#000"> </span><span style=3D"color:#660">=
{</span><span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;<=
/span><span style=3D"color:#000">conversion expression</span><span style=3D=
"color:#660">&gt;</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#660">}</span><span style=3D"color:#000"><br></span><span style=3D"col=
or:#660">};</span></div></code></div><br>Note that this allows you to do ar=
bitrary work in the conversion section. Though we might add an `=3D default=
` version which is equivalent to implicit conversion via `return *this;`.<b=
r><br></div></blockquote><div><br></div><div>But I think it makes impossibl=
e to use `auto` to copy instances of that type. For instance:<br><br>```C++=
<br>struct wrapper { value_type operator auto() const { /**/ } };<div>auto =
wrapper_obj =3D wrapper_factory::give_me_a_new_wrapper();=C2=A0<br>```</div=
><div><br>or any copy I have to do with the wrapper (or any intermediary fu=
nction returning it), will be deduced as `value_type`. However, I&#39;m sti=
ll working with a `wrapper`!! The &quot;reference nature&quot; has not been=
 start yet. That conversion operator forces me to think a bit more anytime =
I want to use `auto`.=C2=A0<br><br>What if I want to bind the object to a r=
eference, to modify the real object that is behind?<br><br>```C++<br>auto c=
onst&amp; w =3D *it;<br>w =3D something; // The wrapped object must be modi=
fied, as a real reference.<br>```</div><div><br>Since the proxy represents =
a reference, must be trated as such when taking it by reference or by value=
 when it is still a &quot;object proxy&quot;. But when passing it as &quot;=
pure proxy&quot; or &quot;pure reference proxy&quot; or the way you want to=
 call it, then it must be cast to the secondary type when copying. The `! v=
alue_type` is not a new type, but some kind of conversion qualifier.</div><=
/div><div>=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 dir=
=3D"ltr">This function is put in the actual type that would otherwise be de=
duced. I think this works much better than your notion of adding it to the =
`operator*` of the iterator (I assume; you put it in `vector&lt;bool&gt;` i=
nstead, which has no `operator*`). Your way requires the compiler to change=
 what it is doing based on the return of a specific function call, so it re=
quires more work to do lazy expression evaluation, since you have to apply =
it to every single function that returns a lazy result.<br><br></div></bloc=
kquote><div><br></div><div>Yes, the whole thing it&#39;s crazy complex sema=
ntically. Too much context.</div><div><br></div><blockquote class=3D"gmail_=
quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pa=
dding-left: 1ex;"><div dir=3D"ltr">The big, unanswered question with such a=
 feature is mainly about what exactly it affects. Does it only affect uses =
of the `auto` keyword for variables? If it only affects `auto` variables, w=
ould that not be strange with regard to generic lambda/Concepts TS `auto` p=
arameters, which use template argument deduction? Does it affect `decltype(=
auto)`, and if so, how exactly? If it affects every form of deduction (temp=
late argument, `decltype(auto)` and `auto`), then exactly how does it work?=
<br></div></blockquote><div><br></div><div>My approach has the same problem=
s. The thing is that, when you are constructing a new object from a combine=
d type, you have too much situations (whe asume that `value_type` cannot be=
 a reference, but `wrapper` does):<br></div><div><br>```C++<br>/* When expr=
 is T ! V (T is not referfence) */</div><div>// (1)<br>T a =3D expr; // Err=
or or do we want to copy the proxy object losing the convert-when-copying n=
ature?</div><div>T&amp; ra =3D expr; // Same situation.</div><div>T const&a=
mp; ra =3D expr; // Same situation.</div><div><br></div><div>// (2)</div><d=
iv>T!V a =3D expr; // Ok, we copy `T`.</div><div>T!V&amp; a =3D expr; // Ok=
, if expr returns an `lvalue`.</div><div>T!V const&amp; a =3D expr; // Ok.<=
/div><div><br></div><div>// (3)</div><div>auto a =3D expr; // Ok, we cast t=
o V and then copy. auto decuded as V</div><div>auto&amp; a2 =3D expr; // au=
to deduced as T!V&amp; (a.k.a T&amp;)</div><div>auto const&amp; a3 =3D expr=
; // auto decuded as T!V const&amp; (a.k.a T const&amp;).</div><div>auto a4=
 =3D a2; // Ok, auto deduced as V since a2 is T!V&amp;</div><div>```</div><=
div><br></div><div>The think is that, when dealing with iterators, you don&=
#39;t have two types, but have three:</div><div><br></div><div>* value_type=
 represents the storage. What `sort` needs when doing copies.</div><div>* s=
equence_type represents the view that the iterator gives to you.</div><div>=
* reference is something in the middle, with allows to comunicate between b=
oth worlds. What `operator*` returns.</div><div><br></div><div>`sequence_ty=
pe` doesn&#39;t need to be explicitely defined, not added to the Iterator c=
oncept or something. It is what users expect when reading the iterator (for=
 example, the parameters of the functors passed to `for_each`). With `refer=
ence` being convertible to user parameters is enough. `value_type` is what =
algorithms and user expects for local storage, to transform and save back t=
he value to the iterator. The `reference` type is then tricked to allow one=
 of another usage depending on the context, in a way more or less, transpar=
ent to current implementations.=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/3bf83fd7-8b87-45ca-ac8b-3b856776acac%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/3bf83fd7-8b87-45ca-ac8b-3b856776acac=
%40isocpp.org</a>.<br />

------=_Part_1025_1524697587.1491753106814--

------=_Part_1024_2110165171.1491753106814--

.
