220 23904 <CADvuK0+ecVzhSbXo-1Yr-Awp2OGgR53vqe+6oCigA1wS+nVk1w@mail.gmail.com> article
Path: news.gmane.org!not-for-mail
From: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Re: RFC: Unpacking tuples to value sequences
Date: Wed, 20 Jan 2016 15:13:23 -0800
Lines: 395
Approved: news@gmane.org
Message-ID: <CADvuK0+ecVzhSbXo-1Yr-Awp2OGgR53vqe+6oCigA1wS+nVk1w@mail.gmail.com>
References: <n7jlvp$c44$1@ger.gmane.org>
	<f758483a-568d-4444-957f-41535c39be4e@isocpp.org>
	<c91a2d40-17da-4edc-b14b-4e166e9ecaeb@isocpp.org>
	<6f3ece34-e302-4d95-afd0-4c1924e8a780@isocpp.org>
	<n7locq$q98$1@ger.gmane.org>
	<e4a9f750-0608-47ac-9d91-f1201b016b99@isocpp.org>
	<n7lqmm$2d3$1@ger.gmane.org>
	<6ad65a24-8a2e-4053-b9c9-80d296d98e7d@isocpp.org>
	<n7m5v9$346$1@ger.gmane.org>
	<72de7daf-93af-4e55-95ea-67898bd2a5f6@isocpp.org>
	<n7o939$vj0$1@ger.gmane.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary=001a11420926f2207b0529cc21d5
X-Trace: ger.gmane.org 1453331613 23479 80.91.229.3 (20 Jan 2016 23:13:33 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Wed, 20 Jan 2016 23:13:33 +0000 (UTC)
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBDLZJYWNDQIJHKMAWUCRUBB3KVM76@isocpp.org Thu Jan 21 00:13:26 2016
Return-path: <std-proposals+bncBDLZJYWNDQIJHKMAWUCRUBB3KVM76@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-lf0-f71.google.com ([209.85.215.71])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBDLZJYWNDQIJHKMAWUCRUBB3KVM76@isocpp.org>)
	id 1aM1wL-0000rO-7Q
	for gclcip-std-proposals@m.gmane.org; Thu, 21 Jan 2016 00:13:25 +0100
Original-Received: by mail-lf0-f71.google.com with SMTP id k69sf8819860lfg.3
        for <gclcip-std-proposals@m.gmane.org>; Wed, 20 Jan 2016 15:13:24 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=mime-version:in-reply-to:references:date:message-id:subject:from:to
         :content-type:x-original-sender:x-original-authentication-results
         :reply-to:precedence:mailing-list:list-id:x-spam-checked-in-group
         :list-post:list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=FSgGDEfzqB+7WcJrYyUikCLtGZmnn7kTp7w9wwHH3NU=;
        b=xhqcDCYYpHgDq+6IyIh+zNB449SO16mRy0AOKB2aqWPitHAmK98k1YehHVIBjxRxvX
         Vzf1smx8Pxi2VhbHRne00BhUnKIGKrIAj2WcfW8O20u6CpfMKDdP6jhUDJ31gnJvjPNA
         Yq56bE4y2OUmsnfU0k6iWyJJK7CE/3qe6Sf9sDCqBk3+tFazupdFIOAgpVWmxYuZyiMM
         yB6zAnA8bVQTILVxg+dCm5Fi8g0L/UIsxq3lPW2nAOoPOPFXpXTrN8+/5pLPpFg7t8JZ
         CiIOkA+CgFbQ8lEA3Wh35pD0kcuo3rFRl1ikpH3DcctvLZPxFvu9lZqIaQ+yGNcVA7Ml
         VpUg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:mime-version:in-reply-to:references:date
         :message-id:subject:from:to:content-type:x-original-sender
         :x-original-authentication-results:reply-to:precedence:mailing-list
         :list-id:x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=FSgGDEfzqB+7WcJrYyUikCLtGZmnn7kTp7w9wwHH3NU=;
        b=fmVg4Hq1QK9MDAVph8hrHlFwfpgTnezMX+LByEfInPNL3iGqVSJD8+FoRRAB3woQfL
         6OG1Nm9+0m8RyixhIYiZ2/PAHMh0+46sbFx4wtQLl7q7KqQ3C4D+MW2254b8V/Eo7g+8
         pvw34bsca4SuVvjtXzYbutYCKQpkklcaKRBXFU3w7sCXVNzDtEzZSaINXkNrR+c4KtqU
         G+pqsuMHAiS1o3NMzY/gsn5gjDFUq7vPDng2PYI+I7ZKQFu+YQ4hpOWrID4lblBJ/o48
         C1MDQyVkbLp23LX0FVWQzOxh+hbjHdVF9C8/dtnp77bwcydiHbjVcXAfotHJgyZwtt5+
         EW6Q==
X-Gm-Message-State: AG10YOQGgp8cn8cG0Sursc/4Wmw8a7cnP1mBTMIkVRGpBJa3eA7ryTmNz1845UUHICLivg==
X-Received: by 10.28.148.196 with SMTP id w187mr822355wmd.6.1453331604617;
        Wed, 20 Jan 2016 15:13:24 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.28.30.76 with SMTP id e73ls225000wme.37.gmail; Wed, 20 Jan
 2016 15:13:23 -0800 (PST)
X-Received: by 10.28.126.77 with SMTP id z74mr7031636wmc.3.1453331603503;
        Wed, 20 Jan 2016 15:13:23 -0800 (PST)
Original-Received: from mail-wm0-x22b.google.com (mail-wm0-x22b.google.com. [2a00:1450:400c:c09::22b])
        by mx.google.com with ESMTPS id b9si14252088wjf.184.2016.01.20.15.13.23
        for <std-proposals@isocpp.org>
        (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
        Wed, 20 Jan 2016 15:13:23 -0800 (PST)
Received-SPF: pass (google.com: domain of arthur.j.odwyer@gmail.com designates 2a00:1450:400c:c09::22b as permitted sender) client-ip=2a00:1450:400c:c09::22b;
Original-Received: by mail-wm0-x22b.google.com with SMTP id r129so150772143wmr.0
        for <std-proposals@isocpp.org>; Wed, 20 Jan 2016 15:13:23 -0800 (PST)
X-Received: by 10.28.129.139 with SMTP id c133mr6805940wmd.30.1453331603133;
 Wed, 20 Jan 2016 15:13:23 -0800 (PST)
Original-Received: by 10.27.19.201 with HTTP; Wed, 20 Jan 2016 15:13:23 -0800 (PST)
In-Reply-To: <n7o939$vj0$1@ger.gmane.org>
X-Original-Sender: arthur.j.odwyer@gmail.com
X-Original-Authentication-Results: mx.google.com;       spf=pass (google.com:
 domain of arthur.j.odwyer@gmail.com designates 2a00:1450:400c:c09::22b as
 permitted sender) smtp.mailfrom=arthur.j.odwyer@gmail.com;       dkim=pass
 header.i=@gmail.com;       dmarc=pass (p=NONE dis=NONE) header.from=gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Spam-Checked-In-Group: 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:23904
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/23904>

--001a11420926f2207b0529cc21d5
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Wed, Jan 20, 2016 at 7:28 AM, Matthew Woehlke <mwoehlke.floss@gmail.com>
wrote:

> On 2016-01-20 01:50, Arthur O'Dwyer wrote:
> > (Matthew doesn't really mean that literally anyway, unless he's proposi=
ng
> > to allow
> >
> >     [*]x;
>
> The non-complicated version of the proposal would indeed allow this; it
> would expand to `get<0>(x), get<1>x, ..., get<N>(x);`, which is valid
> code. Silly, but valid.
>

Parameter-pack expansion doesn't allow expansion-into-the-comma-operator
here. You're proposing to add a new "tuple-like-expansion" that *does*
allow expansion-into-the-comma-operator. That's weirder than just reusing
the existing language feature (parameter-pack expansion). Having two things
that do *almost* the same thing but behave subtly differently is bad UI
design *and* bad for the people who have to come up with the normative
wording.

> Notice that in the previous parenthetical I had to write
> std::tuple_size_v<decltype(std::tie([*]x))>
> > - 1 to express the size of the "comma-separated sequence" [*]x under
> > Matthew's proposal. I think that's really the simplest thing that would
> > compile!
>
> Uh... why? What's wrong with std::tuple_size_v(x)? Recall that in the
> discussions of expanding the notion of "tuple-like", it's generally been
> implied that tuple_size would be defined, in addition to get<N>.
>

Okay, std::tie([*]x) should just be x; that was my fault. But you still
have to write std::tuple_size_v<decltype(x)>. The entity std::tuple_size_v
is a variable template, not a constexpr function.

Off-topic but FYI, I'm still a little generally uncomfortable with the idea
of "tuple-like type". For example, in C++14 std::array<T,N> has become
"tuple-like", even though it has only one template type parameter. If we
were to standardize a "typelist" template (e.g. mpl::vector<T...>), would
it *not* be "tuple-like" because you couldn't use std::get<I> on it at
runtime? And if I-the-user want to define my own "tuple-like type", how
many customization points do I have to specialize, overload, or whatever,
before I can be sure that the STL will treat my type as "tuple-like"?
Admittedly we have had the same problems since 2011 with "container-like"
types and range-based for loops, and they don't really seem to be tripping
anybody up.


> On Tuesday, January 19, 2016 at 12:23:25 PM UTC-8, Matthew Woehlke wrote:
> >> p.s. If we have genuine promotion of value sequences to parameter pack=
s,
> >> why can't we do this?
> >>
> >>   auto&&... g_unpacked =3D g;
> >>   auto result =3D make_tuple(func([*]f, g_unpacked)...);
> >
> > Because you can't have variables of parameter-pack type. Parameter pack=
s
> > aren't first-class citizens in C++.
>
> I think you missed the point; that is exactly what I meant by "If we
> have genuine promotion of value sequences to parameter packs". Note the
> "auto..." syntax.
>

I probably misunderstood the combination of the "If" (namely: *what* are we
assuming we have?) and the "why can't we" (namely: is that a real question
or did you mean it rhetorically as "we definitely can"?).
Nicol's proposal involves a new way to get a parameter-pack into the middle
of an expression, but it doesn't change anything about the
first-class-citizen-ness of parameter-packs. You still can't have "values"
of "type" *parameter-pack*. Nor can you have named variables of "type"
*parameter-pack*, except for the (previously existing) very special case of
function parameters.

That is, I understood your question to mean "Does Nicol's proposal imply
that the following should compile?" and/or "Does Matthew's proposal imply
that the following should compile?". Both answers were "no".
You may have meant, "If (under some hypothetical(?) future(?) proposal) the
following code did compile, then it would definitely compile." If so, then
yes, I agree with that statement. ;)


> The questions of "why can't I declare a pack on the stack", or "why can't
> I
> > init-capture a pack", or "why can't I declare a class A<T...> that has
> > members of types T..." are all good questions, but are completely
> > orthogonal to the two questions above. And they'll still be there for t=
he
> > solving later.
>
> But that's somewhat the point... the question is, if we want the ability
> as in the above example *anyway*, then what value is left in Nicol's
> proposal over mine (besides that it saves a little typing)? This would
> make the common case (just want to unpack in place) easy and the
> uncommon case possible, vs. making both possible, but also both ugly.
>

Using "..." to unpack things isn't the ugly part of the proposal IMHO,
though!
The ugly part, and the part that's going to get bikeshedded to death, is
the choice of [*] as a prefix operator.
Especially since there's another proposal
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0018r0.html>
before the Committee (or was, at Kona) suggesting that [*](){ ... } should
be the syntax for "capture *this by copy".

Under Nicol's proposal, I now see a further difficulty with mixing [*] and
..... Nicol, Matthew, and I have all been writing sample code under Nicol's
proposal as if

    f([*]x...)

would naturally Do The Right Thing. But in fact, the operator precedence
there is wrong: the postfix ... binds more tightly than the prefix [*].
Under Nicol's proposal, the code would have to be

    f(([*]x)...)

which I now agree is horribly ugly. :)  However, the fix is simple: you
just need to change the "unpacking" operator from prefix to postfix. For
discussion purposes, I'll nominate postfix ~.

    f(x~...)

That's only one character longer than f([*]x), and arguably more readable.

    template<class Vec>
    auto dotproduct(const Vec& a, const Vec& b)
    {
        return (... + (a~ * b~));  // this is a C++17 fold-expression
    }

Not that I'm claiming above-average readability for that snippet, mind you!
:)  But IMHO it's better than

    template<class Vec>
    auto dotproduct(const Vec& a, const Vec& b)
    {
        auto f =3D [](auto&&... aibi){
            return (... + (aibi.first * aibi.second));
        };
        return f([*]my::tuple_zip(a, b));
    }

Keep in mind that I failed the simplicity test last time I tried to write
sample code according to Matthew's proposal, so my apologies if I've missed
something simpler again.  (Something simpler that still involves unpacking,
I mean!  My code above also relies on a made-up my::tuple_zip. If we
postulate a made-up my::tuple_foldl, though, the whole problem collapses
away and we don't need any language features at all:

    template<class Vec>
    auto dotproduct(const Vec& a, const Vec& b)
    {
        auto f =3D [](auto&& accumulator, auto&& ab) {
            return accumulator + (ab.first * ab.second);
        };
        return my::tuple_foldl(f, 0, my::tuple_zip(a, b)));
    }

=E2=80=93Arthur

--=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 https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

--001a11420926f2207b0529cc21d5
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wed, Jan 20, 2016 at 7:28 AM, Matthew Woehlke <span dir=
=3D"ltr">&lt;<a href=3D"mailto:mwoehlke.floss@gmail.com" target=3D"_blank">=
mwoehlke.floss@gmail.com</a>&gt;</span> wrote:<br><div class=3D"gmail_extra=
"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,2=
04);border-left-style:solid;padding-left:1ex"><span class=3D"">On 2016-01-2=
0 01:50, Arthur O&#39;Dwyer wrote:<br></span><span class=3D"">&gt; (Matthew=
 doesn&#39;t really mean that literally anyway, unless he&#39;s proposing<b=
r>
&gt; to allow<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0[*]x;<br>
<br>
</span>The non-complicated version of the proposal would indeed allow this;=
 it<br>
would expand to `get&lt;0&gt;(x), get&lt;1&gt;x, ..., get&lt;N&gt;(x);`, wh=
ich is valid<br>
code. Silly, but valid.<br></blockquote><div><br></div><div>Parameter-pack =
expansion doesn&#39;t allow expansion-into-the-comma-operator here. You&#39=
;re proposing to add a new &quot;tuple-like-expansion&quot; that <i>does</i=
> allow expansion-into-the-comma-operator. That&#39;s weirder than just reu=
sing the existing language feature (parameter-pack expansion). Having two t=
hings that do <i>almost</i> the same thing but behave subtly differently is=
 bad UI design <i>and</i> bad for the people who have to come up with the n=
ormative wording.</div><div><br></div><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(=
204,204,204);border-left-style:solid;padding-left:1ex"><span class=3D"">&gt=
; Notice that in the previous parenthetical I had to write std::tuple_size_=
v&lt;decltype(std::tie([*]x))&gt;<br>
&gt; - 1 to express the size of the &quot;comma-separated sequence&quot; [*=
]x under<br>
&gt; Matthew&#39;s proposal. I think that&#39;s really the simplest thing t=
hat would<br>
&gt; compile!<br>
<br>
</span>Uh... why? What&#39;s wrong with std::tuple_size_v(x)? Recall that i=
n the<br>
discussions of expanding the notion of &quot;tuple-like&quot;, it&#39;s gen=
erally been<br>
implied that tuple_size would be defined, in addition to get&lt;N&gt;.<br><=
/blockquote><div><br></div><div>Okay, <font face=3D"monospace, monospace">s=
td::tie([*]x)</font> should just be <font face=3D"monospace, monospace">x</=
font>; that was my fault. But you still have to write <font face=3D"monospa=
ce, monospace">std::tuple_size_v&lt;decltype(x)&gt;</font>. The entity <fon=
t face=3D"monospace, monospace">std::tuple_size_v</font> is a variable temp=
late, not a constexpr function.</div><div><br></div><div>Off-topic but FYI,=
 I&#39;m still a little generally uncomfortable with the idea of &quot;tupl=
e-like type&quot;. For example, in C++14 <font face=3D"monospace, monospace=
">std::array&lt;T,N&gt;</font>=C2=A0has become &quot;tuple-like&quot;, even=
 though it has only one template type parameter. If we were to standardize =
a &quot;typelist&quot; template (e.g. <font face=3D"monospace, monospace">m=
pl::vector&lt;T...&gt;</font>), would it <i>not</i> be &quot;tuple-like&quo=
t; because you couldn&#39;t use <font face=3D"monospace, monospace">std::ge=
t&lt;I&gt;</font> on it at runtime? And if I-the-user want to define my own=
 &quot;tuple-like type&quot;, how many customization points do I have to sp=
ecialize, overload, or whatever, before I can be sure that the STL will tre=
at my type as &quot;tuple-like&quot;?</div><div>Admittedly we have had the =
same problems since 2011 with &quot;container-like&quot; types and range-ba=
sed for loops, and they don&#39;t really seem to be tripping anybody up.</d=
iv><div>=C2=A0</div><div><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(20=
4,204,204);border-left-style:solid;padding-left:1ex"><span class=3D"">&gt; =
On Tuesday, January 19, 2016 at 12:23:25 PM UTC-8, Matthew Woehlke wrote:<b=
r>
</span><span class=3D"">&gt;&gt; p.s. If we have genuine promotion of value=
 sequences to parameter packs,<br>
&gt;&gt; why can&#39;t we do this?<br>
&gt;&gt;<br>
&gt;&gt;=C2=A0 =C2=A0auto&amp;&amp;... g_unpacked =3D g;<br>
&gt;&gt;=C2=A0 =C2=A0auto result =3D make_tuple(func([*]f, g_unpacked)...);=
<br>
&gt;<br>
&gt; Because you can&#39;t have variables of parameter-pack type. Parameter=
 packs<br>
&gt; aren&#39;t first-class citizens in C++.<br>
<br>
</span>I think you missed the point; that is exactly what I meant by &quot;=
If we<br>
have genuine promotion of value sequences to parameter packs&quot;. Note th=
e<br>
&quot;auto...&quot; syntax.<br></blockquote><div><br></div><div>I probably =
misunderstood the combination of the &quot;If&quot; (namely: <i>what</i> ar=
e we assuming we have?) and the &quot;why can&#39;t we&quot; (namely: is th=
at a real question or did you mean it rhetorically as &quot;we definitely c=
an&quot;?).</div><div>Nicol&#39;s proposal involves a new way to get a para=
meter-pack into the middle of an expression, but it doesn&#39;t change anyt=
hing about the first-class-citizen-ness of parameter-packs. You still can&#=
39;t have &quot;values&quot; of &quot;type&quot; <i>parameter-pack</i>. Nor=
 can you have named variables of &quot;type&quot; <i>parameter-pack</i>, ex=
cept for the (previously existing) very special case of function parameters=
..</div><div><br></div><div>That is, I understood your question to mean &quo=
t;Does Nicol&#39;s proposal imply that the following should compile?&quot; =
and/or &quot;Does Matthew&#39;s proposal imply that the following should co=
mpile?&quot;. Both answers were &quot;no&quot;.</div><div>You may have mean=
t, &quot;If (under some hypothetical(?) future(?) proposal) the following c=
ode did compile, then it would definitely compile.&quot; If so, then yes, I=
 agree with that statement. ;)</div><div><br></div><div><br></div><blockquo=
te class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-widt=
h:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-le=
ft:1ex"><span class=3D"">&gt; The questions of &quot;why can&#39;t I declar=
e a pack on the stack&quot;, or &quot;why can&#39;t I<br>
&gt; init-capture a pack&quot;, or &quot;why can&#39;t I declare a class A&=
lt;T...&gt; that has<br>
&gt; members of types T...&quot; are all good questions, but are completely=
<br>
&gt; orthogonal to the two questions above. And they&#39;ll still be there =
for the<br>
&gt; solving later.<br>
<br>
</span>But that&#39;s somewhat the point... the question is, if we want the=
 ability<br>
as in the above example *anyway*, then what value is left in Nicol&#39;s<br=
>
proposal over mine (besides that it saves a little typing)? This would<br>
make the common case (just want to unpack in place) easy and the<br>
uncommon case possible, vs. making both possible, but also both ugly.<br></=
blockquote><div><br></div><div>Using &quot;...&quot; to unpack things isn&#=
39;t the ugly part of the proposal IMHO, though!</div><div>The ugly part, a=
nd the part that&#39;s going to get bikeshedded to death, is the choice of =
<font face=3D"monospace, monospace">[*]</font> as a prefix operator.</div><=
div>Especially since there&#39;s <a href=3D"http://www.open-std.org/jtc1/sc=
22/wg21/docs/papers/2015/p0018r0.html">another proposal</a> before the Comm=
ittee (or was, at Kona) suggesting that <font face=3D"monospace, monospace"=
>[*](){ </font><font face=3D"arial, helvetica, sans-serif">...</font><font =
face=3D"monospace, monospace"> }</font> should be the syntax for &quot;capt=
ure <font face=3D"monospace, monospace">*this</font> by copy&quot;.</div><d=
iv><br></div><div>Under Nicol&#39;s proposal, I now see a further difficult=
y with mixing <font face=3D"monospace, monospace">[*]</font> and <font face=
=3D"monospace, monospace">...</font>. Nicol, Matthew, and I have all been w=
riting sample code under Nicol&#39;s proposal as if</div><div><br></div><di=
v><font face=3D"monospace, monospace">=C2=A0 =C2=A0 f([*]x...)</font></div>=
<div><br></div><div>would naturally Do The Right Thing. But in fact, the op=
erator precedence there is wrong: the postfix <font face=3D"monospace, mono=
space">...</font> binds more tightly than the prefix <font face=3D"monospac=
e, monospace">[*]</font>. Under Nicol&#39;s proposal, the code would have t=
o be</div><div><br></div><div><font face=3D"monospace, monospace">=C2=A0 =
=C2=A0 f(([*]x)...)</font></div><div><br></div><div>which I now agree is ho=
rribly ugly. :) =C2=A0However, the fix is simple: you just need to change t=
he &quot;unpacking&quot; operator from prefix to postfix. For discussion pu=
rposes, I&#39;ll nominate postfix <font face=3D"monospace, monospace">~</fo=
nt>.</div><div><br></div><div><font face=3D"monospace, monospace">=C2=A0 =
=C2=A0 f(x~...)</font></div><div><br></div><div>That&#39;s only one charact=
er longer than f([*]x), and arguably more readable.</div><div><br></div><di=
v><span style=3D"font-family:monospace,monospace">=C2=A0 =C2=A0 template&lt=
;class Vec&gt;</span><br></div><div><font face=3D"monospace, monospace">=C2=
=A0 =C2=A0 auto dotproduct(const Vec&amp; a, const Vec&amp; b)</font></div>=
<div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 {</font></div><div><=
font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 return (... =
+ (a~ * b~)); =C2=A0// this is a C++17 fold-expression</font></div><div><fo=
nt face=3D"monospace, monospace">=C2=A0 =C2=A0 }</font></div><div><br></div=
><div>Not that I&#39;m claiming above-average readability for that snippet,=
 mind you! :) =C2=A0But IMHO it&#39;s better than</div><div><br></div><div>=
<div><span style=3D"font-family:monospace,monospace">=C2=A0 =C2=A0 template=
&lt;class Vec&gt;</span></div><div><span style=3D"font-family:monospace,mon=
ospace">=C2=A0 =C2=A0 auto dotproduct(const Vec&amp; a, const Vec&amp; b)</=
span><br></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 {</fo=
nt></div><div><span style=3D"font-family:monospace,monospace">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 auto f =3D [](auto&amp;&amp;... aibi){</span><br></div><div>=
<font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 return (... + (aibi.first * aibi.second));</font></div><div><font face=
=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 };</font></div><div><=
font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 return f([*]=
my</font><span style=3D"font-family:monospace,monospace">::tuple_zip(a, b)<=
/span><span style=3D"font-family:monospace,monospace">);</span></div><div><=
span style=3D"font-family:monospace,monospace">=C2=A0 =C2=A0 }</span><br></=
div></div><div><font face=3D"monospace, monospace"><br></font></div><div>Ke=
ep in mind that I failed the simplicity test last time I tried to write sam=
ple code according to Matthew&#39;s proposal, so my apologies if I&#39;ve m=
issed something simpler again. =C2=A0(Something simpler that still involves=
 unpacking, I mean!=C2=A0 My code above also relies on a made-up <font face=
=3D"monospace, monospace">my::tuple_zip</font>. If we postulate a made-up=
=C2=A0<font face=3D"monospace, monospace">my::tuple_foldl</font>, though, t=
he whole problem collapses away and we don&#39;t need any language features=
 at all:</div><div><br></div><div><div><span style=3D"font-family:monospace=
,monospace">=C2=A0 =C2=A0 template&lt;class Vec&gt;</span></div><div><span =
style=3D"font-family:monospace,monospace">=C2=A0 =C2=A0 auto dotproduct(con=
st Vec&amp; a, const Vec&amp; b)</span><br></div><div><font face=3D"monospa=
ce, monospace">=C2=A0 =C2=A0 {</font></div><div><font face=3D"monospace, mo=
nospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 auto f =3D=C2=A0</font><span style=3D"=
font-family:monospace,monospace">[](auto&amp;&amp; accumulator, auto&amp;&a=
mp; ab) {</span></div><div><span style=3D"font-family:monospace,monospace">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return accumulator + (ab.first * =
ab.second);</span></div><div><span style=3D"font-family:monospace,monospace=
">=C2=A0 =C2=A0 =C2=A0 =C2=A0 };</span></div><div><span style=3D"font-famil=
y:monospace,monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 return my::tuple_foldl(f=
</span><span style=3D"font-family:monospace,monospace">, 0, my::</span><spa=
n style=3D"font-family:monospace,monospace">tuple_zip(a, b)</span><span sty=
le=3D"font-family:monospace,monospace">));</span></div><div><span style=3D"=
font-family:monospace,monospace">=C2=A0 =C2=A0 }</span><br></div></div><div=
><span style=3D"font-family:monospace,monospace"><br></span></div><div>=E2=
=80=93Arthur</div></div></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&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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

--001a11420926f2207b0529cc21d5--

.
