220 34161 <7b9bf263-d3ca-42bf-aed6-4c7606782a28@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: Idea: Extension of structured bindings to
 definition of structs
Date: Sat, 26 Aug 2017 18:08:11 -0700 (PDT)
Lines: 299
Approved: news@gmane.org
Message-ID: <7b9bf263-d3ca-42bf-aed6-4c7606782a28@isocpp.org>
References: <59dcbbbc-c536-4b7b-9c88-0638fb0cd58a@technion.ac.il>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_4801_1976556011.1503796091458"
X-Trace: blaine.gmane.org 1503796098 27958 195.159.176.226 (27 Aug 2017 01:08:18 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Sun, 27 Aug 2017 01:08:18 +0000 (UTC)
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBCEKFTV6ZUMBB7FWRDGQKGQEVHJ3S5A@isocpp.org Sun Aug 27 03:08:13 2017
Return-path: <std-proposals+bncBCEKFTV6ZUMBB7FWRDGQKGQEVHJ3S5A@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-io0-f197.google.com ([209.85.223.197])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBCEKFTV6ZUMBB7FWRDGQKGQEVHJ3S5A@isocpp.org>)
	id 1dlm3a-0006hl-JA
	for gclcip-std-proposals@m.gmane.org; Sun, 27 Aug 2017 03:08:06 +0200
Original-Received: by mail-io0-f197.google.com with SMTP id m40sf29470255ioi.4
        for <gclcip-std-proposals@m.gmane.org>; Sat, 26 Aug 2017 18:08:13 -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
         :list-post:list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=zPv5/c/7AIOVLC5kCGXpc5RNVOKt1oYOQZFoO+ntKD0=;
        b=t+qqAczCgET/CUwFVoxOnKDiHt/b2sIW9irHI4kipD9WqI3cFpncq87rA99PJ/hemq
         SOQ/Bq7vDpuLvwElNk1IGprHaU20nNE7KM9DtIpF/mixdvDthO7A/h0OTdaSw2zZIc2G
         c4FLNjPoTY4isq4L8ofaeSwkcpvEcozURPUdVjqLX7wDpufL/Cw0ftOIlv1Z5HRSUDhm
         8QoksaivLPTHG3V9YlaUtb/vP9LkuVUJomVdj+RiIdJ0Ptj+2X4zX/kFefmjZ5Doq8Mu
         d7tg9IGF6g0IV95IMQokHirt8JW1qTQC65UNb1jc3324RmautSwJEpBMT+pTwJC87fsf
         hZNg==
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
         :list-post:list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=zPv5/c/7AIOVLC5kCGXpc5RNVOKt1oYOQZFoO+ntKD0=;
        b=tbKc+bGRa1zuiOoEreF7fM/Oz7mF8cqRx9/xw4ALQleEy1Q+kJsEl9H2UyVAFrwHL1
         PC03LBcAEwpLcekJTBglvsOLlOsx2s5wry9XAFvXMfp3b354aMnmi4+gIECT3IyLVshU
         VRmD9GCDI1tClf7O/js08cfn2//XS9l+0CBdpRmWWIPYWU14rwTFn4ONuRFw0Vg+Ne24
         YHrEca3Cc7s9Gae9gTE5lIRJOuJblIa2ocimSiVwxnQmvK7tgQbVyWzV024sg3+Hgn4/
         NEEUiuO8y8rOgqjSor00RSWA/+x5YRExpFQEZdsgV+bgEqQ6gwMsF7buxyrqYfqKsmEl
         GHpQ==
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=zPv5/c/7AIOVLC5kCGXpc5RNVOKt1oYOQZFoO+ntKD0=;
        b=cjSJJIHF13Gzwd3YGzjxatr2oVZm0RraNPEFctfj9ONFhtGYsmV4cbJ4Tiw5g+mmDA
         uXyv5Mo0Ct6q57zqb+g4lHAqyhbUnpN6dXGARBx0s/Z8yjACb6sRTsMC4jVYXKlwyyss
         BVYyYyIe9/hPcRHMq5nFcIFt21NDXgEFJjD8OpY41qlomOqPeD6quh6IbFIxcV28Uz6L
         1aKxD4XrYW5J9X0Q5sUMZf0h28wAXf+5SCpi6hC7LRL6/aS3dAjXjc+ehXIC7pzdc4Jf
         aaHLepAo3NZMPzuXnDvtR5msRN/e2IZbnBxR1KUmTdQmfJIjYyk+B/FL6acOmOkIEUEK
         bhsg==
X-Gm-Message-State: AHYfb5hJ+ChNknn/5BU55ns535AP5NBZY9I2ijPWMNG64VpGMhQqE3Q3
	E+Ver292BrGDExgW
X-Received: by 10.36.57.199 with SMTP id l190mr66306ita.45.1503796093177;
        Sat, 26 Aug 2017 18:08:13 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.107.200.209 with SMTP id y200ls205240iof.31.gmail; Sat, 26 Aug
 2017 18:08:11 -0700 (PDT)
X-Received: by 10.31.164.205 with SMTP id n196mr32493vke.22.1503796091901;
        Sat, 26 Aug 2017 18:08:11 -0700 (PDT)
In-Reply-To: <59dcbbbc-c536-4b7b-9c88-0638fb0cd58a@technion.ac.il>
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:34161
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/34161>

------=_Part_4801_1976556011.1503796091458
Content-Type: multipart/alternative; 
	boundary="----=_Part_4802_2079588239.1503796091458"

------=_Part_4802_2079588239.1503796091458
Content-Type: text/plain; charset="UTF-8"

On Saturday, August 26, 2017 at 4:17:14 PM UTC-4, Eyal Rozenberg wrote:
>
> (This was mis-posted earlier to std-discussion, sorry.) 
>
> ---- 
>
> Today ( = C++17 standard draft, with section [dcl.struct.bind] in 
> particular), we can define multiple variables using, say: 
>
>    auto [ x, y ] = f(); 
>
> where f() returns an array, or a tuple, or a struct with two members. 
> That's very nice and good. 
>
> Now, what if I wanted my new variables x and y to be members of a 
> struct?


Stop.

They *already are* "members of a struct". Whatever `f()` returned is either 
a class type with all of its members being publicly accessible or it's a 
class type that has tuple-access machinery (or it's an array). So for all 
useful purposes, it's already a member of a struct.

So why do you want to decompose an object, just to recompose it as a 
*different* object? And why do you want to do this to an unnamed struct? 
What practical purpose are you trying to achieve here?

At the moment, I can only define a struct using types I can 
> specify in advance, e.g. 
>
>    struct { int x; double y; } s; 
>
> and together with initialization, this becomes: 
>
>    struct { int x; double y; } s = std::make_tuple(1, 2.3); 
>
> what I am imagining, or suggesting, is being able to write: 
>
>    struct { auto x; auto y; } s = std::make_tuple(1, 2.3);
>

I have a tuple. Why would I not just *use the tuple*?

which is interpreted as though we've written 
>
>    struct { 
>      decltype(1)   x; 
>      decltype(2.3) y; 
>    } s = std::make_tuple(1, 2.3); 
>
> with the possible initializers being anything that can be used as the 
> initializer for structured binding of x and y together as stand-alone 
> variables. 
>
> Motivation 
> ----------- 
>
> Well, first there's the obvious Don't Repeat Yourself even in my simple 
> example.
>
Additional motivation is to be found if we consider why we have auto 
> variables in the first place, since C++11.


Avoiding repetition of `decltype` expressions is *not* why we have `auto`.

It's good to be able to say 
>
>    auto x { long_expression_with_difficult_type_to_figure_out }; 
>
> rather than having to determine the type, or repeating yourself twice with 
>
>    decltype(expression_with_difficult_type_to_figure_out) x { 
>      expression_with_difficult_type_to_figure_out 
>    };
>
Unfortunately, at the moment we lose this feature if x needs to be a 
> member of a struct - even if we know the type of the other members. I 
> can't say 
>
>    struct { 
>      decltype(a_2_tuple_with_difficult_first_type_and_double) x; 
>      double y; 
>    } s { a_2_tuple_with_difficult_first_type_and_double }; 
>

Well, yes. Because a type has to make sense outside of the initialization 
of some object of that type. Variables don't.

What you want requires that the compiler delay figuring out what is going 
on within the struct definition until after some variable of that type is 
initialized.

and my idea, or proposition, would make this possible. 
>
> This is also "better" than structured bindings in the sense that it lets 
> you convert a product type with unidentified components to one whose 
> components are identified, e.g.: 
>
>    template<size_t N> std::array<widget_t, N> generate_widgets(); 
>    // ... 
>    struct special_widgets { 
>       auto foo; auto bar; auto baz; 
>    } s = generate_widgets<3>(); 
>
>
>
> Estimated Impact 
> ---------------- 
>
> I'm not a C++ language lawyer, but I think that this kind of syntax 
> should not clash with anything already existing in the language. 
>
> This is syntactic sugar, it seems, so it should not affect the 
> expressibility of C++. 
>
> This feature is close enough to what structured binding does already, so 
> that the burden on compiler authors to implement this would be very 
> limited (in my uninformed opinion).
>

But it is in no way like what structured binding does. What you want 
declares a new type; structured binding doesn't declare types. Structured 
binding declares a hidden variable and a number of names. But it doesn't 
declare a type.

-- 
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/7b9bf263-d3ca-42bf-aed6-4c7606782a28%40isocpp.org.

------=_Part_4802_2079588239.1503796091458
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Saturday, August 26, 2017 at 4:17:14 PM UTC-4, Eyal Roz=
enberg wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">(This was mis-pos=
ted earlier to std-discussion, sorry.)
<br>
<br>----
<br>
<br>Today ( =3D C++17 standard draft, with section [dcl.struct.bind] in=20
<br>particular), we can define multiple variables using, say:
<br>
<br>=C2=A0 =C2=A0auto [ x, y ] =3D f();
<br>
<br>where f() returns an array, or a tuple, or a struct with two members.=
=20
<br>That&#39;s very nice and good.
<br>
<br>Now, what if I wanted my new variables x and y to be members of a=20
<br>struct?</blockquote><div><br>Stop.<br><br>They <i>already are</i> &quot=
;members of a struct&quot;. Whatever `f()` returned is either a class type =
with all of its members being publicly accessible or it&#39;s a class type =
that has tuple-access machinery (or it&#39;s an array). So for all useful p=
urposes, it&#39;s already a member of a struct.<br><br>So why do you want t=
o decompose an object, just to recompose it as a <i>different</i> object? A=
nd why do you want to do this to an unnamed struct? What practical purpose =
are you trying to achieve here?<br><br></div><blockquote class=3D"gmail_quo=
te" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddi=
ng-left: 1ex;">At the moment, I can only define a struct using types I can=
=20
<br>specify in advance, e.g.
<br>
<br>=C2=A0 =C2=A0struct { int x; double y; } s;
<br>
<br>and together with initialization, this becomes:
<br>
<br>=C2=A0 =C2=A0struct { int x; double y; } s =3D std::make_tuple(1, 2.3);
<br>
<br>what I am imagining, or suggesting, is being able to write:
<br>
<br>=C2=A0 =C2=A0struct { auto x; auto y; } s =3D std::make_tuple(1, 2.3);<=
br></blockquote><div><br>I have a tuple. Why would I not just <i>use the tu=
ple</i>?<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;=
margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
which is interpreted as though we&#39;ve written
<br>
<br>=C2=A0 =C2=A0struct {
<br>=C2=A0 =C2=A0 =C2=A0decltype(1) =C2=A0 x;
<br>=C2=A0 =C2=A0 =C2=A0decltype(2.3) y;
<br>=C2=A0 =C2=A0} s =3D std::make_tuple(1, 2.3);
<br>
<br>with the possible initializers being anything that can be used as the=
=20
<br>initializer for structured binding of x and y together as stand-alone=
=20
<br>variables.
<br>
<br>Motivation
<br>-----------
<br>
<br>Well, first there&#39;s the obvious Don&#39;t Repeat Yourself even in m=
y simple=20
<br>example.<br></blockquote><blockquote class=3D"gmail_quote" style=3D"mar=
gin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
Additional motivation is to be found if we consider why we have auto=20
<br>variables in the first place, since C++11.</blockquote><div><br>Avoidin=
g repetition of `decltype` expressions is <i>not</i> why we have `auto`.<br=
><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">It&#39;s good to be=
 able to say
<br>
<br>=C2=A0 =C2=A0auto x { long_expression_with_<wbr>difficult_type_to_figur=
e_out };
<br>
<br>rather than having to determine the type, or repeating yourself twice w=
ith
<br>
<br>=C2=A0 =C2=A0decltype(expression_with_<wbr>difficult_type_to_figure_out=
) x {
<br>=C2=A0 =C2=A0 =C2=A0expression_with_difficult_<wbr>type_to_figure_out
<br>=C2=A0 =C2=A0};<br></blockquote><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;">
Unfortunately, at the moment we lose this feature if x needs to be a=20
<br>member of a struct - even if we know the type of the other members. I=
=20
<br>can&#39;t say
<br>
<br>=C2=A0 =C2=A0struct {
<br>=C2=A0 =C2=A0 =C2=A0decltype(a_2_tuple_with_<wbr>difficult_first_type_a=
nd_<wbr>double) x;
<br>=C2=A0 =C2=A0 =C2=A0double y;
<br>=C2=A0 =C2=A0} s { a_2_tuple_with_difficult_<wbr>first_type_and_double =
};
<br></blockquote><div><br>Well, yes. Because a type has to make sense outsi=
de of the initialization of some object of that type. Variables don&#39;t.<=
br><br>What you want requires that the compiler delay figuring out what is =
going on within the struct definition until after some variable of that typ=
e is initialized.<br><br></div><blockquote class=3D"gmail_quote" style=3D"m=
argin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"=
>
and my idea, or proposition, would make this possible.
<br>
<br>This is also &quot;better&quot; than structured bindings in the sense t=
hat it lets=20
<br>you convert a product type with unidentified components to one whose=20
<br>components are identified, e.g.:
<br>
<br>=C2=A0 =C2=A0template&lt;size_t N&gt; std::array&lt;widget_t, N&gt; gen=
erate_widgets();
<br>=C2=A0 =C2=A0// ...
<br>=C2=A0 =C2=A0struct special_widgets {
<br>=C2=A0 =C2=A0 =C2=A0 auto foo; auto bar; auto baz;
<br>=C2=A0 =C2=A0} s =3D generate_widgets&lt;3&gt;();
<br>
<br>
<br>
<br>Estimated Impact
<br>----------------
<br>
<br>I&#39;m not a C++ language lawyer, but I think that this kind of syntax=
=20
<br>should not clash with anything already existing in the language.
<br>
<br>This is syntactic sugar, it seems, so it should not affect the=20
<br>expressibility of C++.
<br>
<br>This feature is close enough to what structured binding does already, s=
o=20
<br>that the burden on compiler authors to implement this would be very=20
<br>limited (in my uninformed opinion).<br></blockquote><div><br>But it is =
in no way like what structured binding does. What you want declares a new t=
ype; structured binding doesn&#39;t declare types. Structured binding decla=
res a hidden variable and a number of names. But it doesn&#39;t declare a t=
ype.</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/7b9bf263-d3ca-42bf-aed6-4c7606782a28%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/7b9bf263-d3ca-42bf-aed6-4c7606782a28=
%40isocpp.org</a>.<br />

------=_Part_4802_2079588239.1503796091458--

------=_Part_4801_1976556011.1503796091458--

.
