220 24447 <6e35ce65-fcb7-48bb-a1ec-ab1bace0a657@isocpp.org> article
Path: news.gmane.org!not-for-mail
From: Louis Dionne <ldionne.2@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: [tuple] extracting tuples out of a tuple
Date: Wed, 17 Feb 2016 08:16:15 -0800 (PST)
Lines: 620
Approved: news@gmane.org
Message-ID: <6e35ce65-fcb7-48bb-a1ec-ab1bace0a657@isocpp.org>
References: <CA+wfc1-FFqOJ9OSme_SpJAmGz+cshbMDVi_dLrF1ztbzkTN-WQ@mail.gmail.com>	<n9ksdc$4so$1@ger.gmane.org>	<CA+wfc18LVMDXhRYhkw0PxeOmPiOoqVteF7V+40EdOOYb2K1snA@mail.gmail.com>	<n9l3ns$33l$1@ger.gmane.org>	<7e08b6c5-853c-471e-b248-a9df7e8e27be@isocpp.org>	<n9sscb$n29$1@ger.gmane.org> <CADvuK0La9zc5NKhuzbO0awHWGyonM-P8mT26Jn8v94==P4A=KA@mail.gmail.com> <n9tgki$v5n$1@ger.gmane.org> <67c3c86d-3089-4f07-878a-3f3e706744df@isocpp.org> <42a29c5b-07e4-4e36-bab4-03a7e86ff905@isocpp.org>
 <n9vhfe$jb0$1@ger.gmane.org>
 <6e02dbfe-01f3-4840-92ab-bcc8f7824348@isocpp.org>
 <e8e9e9bc-e810-4300-ad88-d3696a1496b8@isocpp.org>
 <d5279da3-6b47-4cc3-bc13-5c668a8c9e78@isocpp.org>
 <586249ad-b4ae-4e40-bdf7-344a641ad4c9@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_274_527237065.1455725775759"
X-Trace: ger.gmane.org 1455725783 26577 80.91.229.3 (17 Feb 2016 16:16:23 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Wed, 17 Feb 2016 16:16:23 +0000 (UTC)
Cc: mwoehlke.floss@gmail.com
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBCV3HSWWRMMRBUNZSK3AKGQEGEZ7TKY@isocpp.org Wed Feb 17 17:16:22 2016
Return-path: <std-proposals+bncBCV3HSWWRMMRBUNZSK3AKGQEGEZ7TKY@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-qk0-f200.google.com ([209.85.220.200])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBCV3HSWWRMMRBUNZSK3AKGQEGEZ7TKY@isocpp.org>)
	id 1aW4m3-0004lv-Cv
	for gclcip-std-proposals@m.gmane.org; Wed, 17 Feb 2016 17:16:19 +0100
Original-Received: by mail-qk0-f200.google.com with SMTP id i123sf28082656qkd.2
        for <gclcip-std-proposals@m.gmane.org>; Wed, 17 Feb 2016 08:16:19 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to:cc:message-id:in-reply-to:references:subject
         :mime-version:content-type: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=8VwzAdvXpvmE06UOZKu9pp5jqxKt1aPgocdD3sIbIPE=;
        b=VH4pD9yGHV9S9a1Ud7NpSIEEOVQIm4B+h/PwnlY8v/YXFHMKM7rcCXVaTP4Qjpk9A+
         ESTjfru4Q4C7JNmE4vK4t8Cuf05A2o0snHPCYoYM474lE3ZqWjzAMDLAI0k70cbOdRrG
         Z2DJmpolXdqpcfYrt+ttgUHsQB1iWJoY8LN1GOtkFOd/78zJ4LhT/FlDwihUC/RWwuee
         z29Y1srHzQwbZdeUJWlSIHsKA/fLbgtpmQ2dLnU36z9hWEEBZK8pXEqSGcEHG+kpHHMv
         Bs0V5+4odEylSZP+CKE/sz9zC4HbXMDvHvpdgaQifURTzNfdGlOJqajVlhF8cXJxeJd5
         68wA==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20120113;
        h=date:from:to:cc:message-id:in-reply-to:references:subject
         :mime-version:content-type: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=8VwzAdvXpvmE06UOZKu9pp5jqxKt1aPgocdD3sIbIPE=;
        b=ttUHjnvORX3mHf0IgMPiY2HI7ZGQcMeJvvYMND7ChO9TAPabbELwh6xcfLen7bU3Xc
         +zZrnIDV+pd/26NejiGF37yXVGtSLLAmsuQkuW1saDJl7xlXabzn+zyk7HuDjqROdOPC
         5L5UojHeFYIog3mOYqYowgTZKn+60xkT7KUsolCHeJY1wF6w7i+AKcuQanf2nAkYNj8B
         /WjbD4YzOUuVapFlhFaTCmNXmFPZgwkq6GqSQvhi8fbZeeNDgZ7O3ZC/50iJVUwutN8/
         kB+0ixanmafs3FaXj9T7Hd50TolxM91DYrewtK5sNDIX62YFsxrL96apJTSWXbGFdvqZ
         kaZQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:date:from:to:cc:message-id:in-reply-to
         :references:subject:mime-version:content-type: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=8VwzAdvXpvmE06UOZKu9pp5jqxKt1aPgocdD3sIbIPE=;
        b=S0x1+2qbXJn2uumfcq7gGI9/3K9RZwgAT5HrdZbigzTSuWU1CHV5EaduYtH4ayBDsR
         ZasjukDqZ41t3WQkZnnu2VmNZEeET1NRjaPWQzEaYhLp0TvXOFqwjwQzCFg3YQ0SFyBV
         BuhwSHmOPpoEPqCDCjoQITzTswIBNqpslRNb6ac/amTg4OzZkW+tVuzP1iij1eNda5aA
         IjRn+8W2Bb3wSZuq3fCIR9KQBxxU6dM+PYL1ueUcUNbYPIgws3CgMnIXlB3o3UjguYqg
         xtEnJnixm7lPEDdWvXFGQzdZZxjRK0+Td3s3vL//Lt/RE/Quvbb/MW/z/ZfuZtmVH7b+
         n2cQ==
X-Gm-Message-State: AG10YOTS67ZhYIPJbrMfvSRU6w0v+hU6JMiyIe3Pdgzp4teMpwLfHq9/u5PNFf1EKQLFtg==
X-Received: by 10.182.243.135 with SMTP id wy7mr2124275obc.8.1455725778455;
        Wed, 17 Feb 2016 08:16:18 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.107.165.19 with SMTP id o19ls2327917ioe.53.gmail; Wed, 17 Feb
 2016 08:16:17 -0800 (PST)
X-Received: by 10.50.176.195 with SMTP id ck3mr431691igc.5.1455725777005;
        Wed, 17 Feb 2016 08:16:17 -0800 (PST)
In-Reply-To: <586249ad-b4ae-4e40-bdf7-344a641ad4c9@isocpp.org>
X-Original-Sender: ldionne.2@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:24447
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/24447>

------=_Part_274_527237065.1455725775759
Content-Type: multipart/alternative; 
	boundary="----=_Part_275_487542790.1455725775761"

------=_Part_275_487542790.1455725775761
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



On Tuesday, 16 February 2016 22:28:33 UTC-5, Nicol Bolas wrote:
>
> On Tuesday, February 16, 2016 at 6:57:59 PM UTC-5, Louis Dionne wrote:
>>
>> On Tuesday, 16 February 2016 18:19:00 UTC-5, Nicol Bolas wrote:
>>>
>>> On Tuesday, February 16, 2016 at 3:21:29 PM UTC-5, Louis Dionne wrote:
>>>>
>>>> or you could also write
>>>>
>>>>     hana::unpack(tpl, [](auto ...x) { return outer(inner(x)...); });
>>>>
>>>
>>> Whenever your library equivalent to a 1-liner language feature includes=
=20
>>> "introduce a Lambda", you have *lost* in terms of code=20
>>> comprehensibility. On the other hand, it does fix (most) of the=20
>>> functionality problems outlined above.
>>>
>>
>> You're drawing an arbitrary line without any argument for this.
>>
>
> ... yes. Code quality is always arbitrary. Some people claim that this is=
=20
> a good, easy-to-understand piece of code:
>
> char * strcpy(char *strDest, const char *strSrc)
> {
>     assert(strDest!=3DNULL && strSrc!=3DNULL);
>     char *temp =3D strDest;
>     while(*strDest++ =3D *strSrc++);
>     return temp;
> }
>
> Everyone has their own tastes. But... Concepts TS has 3 different and=20
> increasingly brief syntaxes for declaring a constrained template for a=20
> reason. In N3701, Stroustrup et. al. defended this by saying:
>
> > Do not confuse the familiar with the simple. The proposed syntax is=20
> readable and parsable. We considered =E2=80=9Clouder=E2=80=9D, more verbo=
se notations, but=20
> did not find them consistently better than what is described here.
>
> Brevity has value.
>
> Actually,
>> I tend to prefer writing things more explicitly like above than using
>> nested ... expansions when things get complex, for I think the different
>> rules for ... expansion can be confusing.
>>
>
> Welcome to the point of the whole idea.
>
> In this example, what we're trying to do is to call `inner` for each=20
> element of the tuple, then pass the results as parameters to `outer`. To=
=20
> you, this is something that "gets complex".
>
> The purpose of the language feature is so that it *isn't complex*=20
> anymore. By making it a language feature, we take something that was=20
> "complex" and make it simple. That's the point.
>
> Your library solution is much like `std::enable_if`. Yes, it gives you a=
=20
> consistent tool for invoking SFINAE. But I *bet* you'd rather be using=20
> Concepts.
>
> `enable_if` makes SFINAE doable, but it requires that you express your=20
> condition in an unnatural way. Concepts makes SFINAE *trivial*. Same=20
> here: Hana makes tuple manipulation doable, but requires that you write=
=20
> your code in unnatural ways.
>
> The principle difference is that there's nothing `enable_if` can do that=
=20
> concepts can't. Whereas there's a lot that Hana can do which tuple=20
> expansion can't. But that alone doesn't mean that it isn't worth being a=
=20
> language feature.
>
> Lambdas were supposed to obsolete std::bind too. Yet there are still some=
=20
> valid uses for it.
>
> But here's the #1 reason why the library solution is the wrong solution:=
=20
>>> you *wrote it wrong*. You forgot to `std::forward` your arguments. And=
=20
>>> you forgot to use `decltype(auto)` for the return value. Both of which =
are=20
>>> needed to be exactly equivalent to the above code. Without the=20
>>> `decltype(auto)`, if `outer` returned a reference of some kind, it coul=
d=20
>>> provoke an unwanted copy.
>>>
>>> So it really needed to be:
>>>
>>> hana::unpack(tpl, [](auto ...x) -> decltype(auto) { return outer(inner(
>>> std::forward<decltype(auto)>(x)...)); });
>>>
>>> I fail to see how this could be considered anywhere nearly as easy to=
=20
>>> understand.
>>>
>>
>> Fair enough. But if we're going to be pedantic, let's be pedantic for=20
>> real. What you wanted
>> to write is
>> hana::unpack(tpl, [](auto&& ...x) -> decltype(auto) { return outer(inner=
(
>> std::forward<decltype(x)>(x))...); });
>>
>> With this out of the way, I will argue that you actually don't need to=
=20
>> write the above, except
>> in rare cases where the tuple is potentially a rvalue. Instead, in most=
=20
>> cases, you'd just
>> have to write
>>
>> hana::unpack(tpl, [](auto& ...x) -> decltype(auto) { return outer(inner(=
x
>> )...); });
>>
>> which is slightly less verbose.
>>
>
> My point was not just that it was verbose. My point is that it is both=20
> verbose *and* easy to get wrong, which we both demonstrated (though at=20
> least my error would have shown up in the compiler ;) ).
>
> Basically, `unpack` is just `std::apply` but with the arguments reversed.
>>>>
>>>>
>>>> > Show me the Hana code for this:
>>>> >
>>>> > auto x =3D inner([:]tpl) + ...;
>>>> >
>>>> > This simply calls a function on each element of the tuple and takes=
=20
>>>> the sum
>>>> > of the results. Again, it works like parameter packs, so it reuses=
=20
>>>> existing
>>>> > knowledge.
>>>>
>>>> You could write
>>>>
>>>>     auto x =3D hana::fold_left(hana::transform(tpl, inner),=20
>>>> std::plus<>{});
>>>>
>>>
>>> And for people who natively read right to left, this would probably be=
=20
>>> decent. But that's not how the rest of C++ works.
>>>
>>
>> Wtf? How is this different from writing=20
>>
>> auto x =3D ranges::accumulate(ranges::transformed(...), std::plus<>{});
>>
>>
> You will never catch me writing *that* either.
>
> or equivalently
>>>>
>>>>     auto x =3D hana::fold_left(tpl, [](auto a, auto b) {
>>>>         return a + inner(b);
>>>>     });
>>>>
>>>
>>> Again you forgot to forward the arguments and return values properly.=
=20
>>> Not to mention, you turn a simple one-liner into a multi-line statement=
..
>>>
>>
>> Same argument as above. And the fact that I broke the statements into=20
>> multiple
>> lines to make it more readable is a feature. Honestly, I think this (and=
=20
>> especially
>> the transform/fold_left variant) is more readable than the variant with=
=20
>> ... expansions.
>> Of course, your version is more terse, but too terse is not good either.
>>
>
> It's not really that it's terse; that's not what attracts me to tuple=20
> expansion. What matters most to me is that the code looks as much like=20
> normal code ought to look.
>
> This is also what repels me from your ranges example.
>
> Most programmers know what `outer(inner(value))` does. They can understan=
d=20
> that by inspection, and its meaning is clear. Most programmers understand=
=20
> what `inner(value) + inner(value2)` means.
>
> Hana code is not obvious, not to someone who isn't familiar with template=
=20
> metaprogramming and such techniques.
>
> While an unsuspecting programmer may not understand exactly what the `...=
`=20
> and `[:]` parts mean, they can still look at `outer(inner([:]value)...)`=
=20
> and see that `inner` will be called, followed by `outer`. It carries the=
=20
> same physical structure and code layout of the simple and obvious case. I=
t=20
> may be more complex under the hood, but the user is not exposed to it.
>
> When looking at `hana::on(inner, outer)`, they have absolutely no idea=20
> what that means. Not without looking up the docs. There is no intuitive=
=20
> grasp of what's going on.
>
> So the value is more than "just" terseness. The value is that the code's=
=20
> structure remains intact. You're not exchanging a call to `+` with=20
> `std::plus<>`. You're not altering the overall order and nature of the=20
> code.=20
>

> Let's stop arguing over petty details. You want to hear it? Of course you=
r=20
>> solution
>> is better for those use cases, because it was designed with those in min=
d!
>> But it is also much more limited, and the point I'm trying to make is=20
>> that from
>> the point of view of a metaprogramming library writer, this proposal, in=
=20
>> its
>> current form, misses the goal just like fold expressions did.
>>
>
> And my overall point is that what you want was *never* the goal to begin=
=20
> with. You are denigrating a proposal for not solving a problem that it wa=
s=20
> never intended to solve.=20
>

I'm sorry if you perceived my comments as denigration, for that was never=
=20
my goal. I know the power
of getting a different perspective, especially one that has been thought=20
out, and that is what I wanted
to share with you. We're all trying to achieve the same thing here; a=20
language that allows us to express
ourselves more easily. We're disagreeing on the way to get there, and you=
=20
seem to be impermeable to
my ideas. It's fine, but my work here is done for I don't feel like=20
something good can come out of more
discussion like what we've been having.


The problem it is solving is making tuples work like parameter pack=20
> expansion, so as to be able to more effectively access data out of tuples=
=20
> in useful ways.
>

When you say "useful ways", I gather that you're saying "ways that are=20
useful for myself". Indeed, I'm
precisely saying that accessing tuples in the way you propose isn't useful=
=20
to me, but you say that this
isn't the goal. I hope you hit the needs of the standard committee members=
=20
right on the spot, otherwise
they might find it difficult to modify _the freaking language_ for your use=
=20
case.

Regards,
Louis Dionne


Arbitrary tuple transformations was never the goal. That's a legitimate and=
=20
> useful problem domain. But that's not what this is intended to handle. Th=
e=20
> fact that this syntax can indeed handle some of that via clever usage of=
=20
> the syntax is merely a fortunate coincidence.
>
> C++11 already has a construct that is tuple-like in its nature: parameter=
=20
> packs. We're just expanding it to work with actual tuples.
>

--=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/.

------=_Part_275_487542790.1455725775761
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Tuesday, 16 February 2016 22:28:33 UTC-5, Nicol=
 Bolas  wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"=
>On Tuesday, February 16, 2016 at 6:57:59 PM UTC-5, Louis Dionne wrote:<blo=
ckquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Tuesday, 16 Februar=
y 2016 18:19:00 UTC-5, Nicol Bolas  wrote:<blockquote class=3D"gmail_quote"=
 style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-lef=
t:1ex"><div dir=3D"ltr">On Tuesday, February 16, 2016 at 3:21:29 PM UTC-5, =
Louis Dionne wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;marg=
in-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div></div></blo=
ckquote></div></blockquote></div></blockquote><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding=
-left:1ex"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0;ma=
rgin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"lt=
r"><div>or you could also write</div><div><br></div><div>=C2=A0 =C2=A0 hana=
::unpack(tpl, [](auto ...x) { return outer(inner(x)...); });</div></div></b=
lockquote><div><br>Whenever your library equivalent to a 1-liner language f=
eature includes &quot;introduce a Lambda&quot;, you have <i>lost</i> in ter=
ms of code comprehensibility. On the other hand, it does fix (most) of the =
functionality problems outlined above.<br></div></div></blockquote><div><br=
></div><div>You&#39;re drawing an arbitrary line without any argument for t=
his.</div></div></blockquote><div><br>... yes. Code quality is always arbit=
rary. Some people claim that this is a good, easy-to-understand piece of co=
de:<br><br><div style=3D"background-color:rgb(250,250,250);border-color:rgb=
(187,187,187);border-style:solid;border-width:1px;word-wrap:break-word"><co=
de><div><span style=3D"color:#008">char</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#660">*</span><span style=3D"color:#000"> strcpy=
</span><span style=3D"color:#660">(</span><span style=3D"color:#008">char</=
span><span style=3D"color:#000"> </span><span style=3D"color:#660">*</span>=
<span style=3D"color:#000">strDest</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:#008">char</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#660">*</span><span s=
tyle=3D"color:#000">strSrc</span><span style=3D"color:#660">)</span><span s=
tyle=3D"color:#000"><br></span><span style=3D"color:#660">{</span><span sty=
le=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">asser=
t</span><span style=3D"color:#660">(</span><span style=3D"color:#000">strDe=
st</span><span style=3D"color:#660">!=3D</span><span style=3D"color:#000">N=
ULL </span><span style=3D"color:#660">&amp;&amp;</span><span style=3D"color=
:#000"> strSrc</span><span style=3D"color:#660">!=3D</span><span style=3D"c=
olor:#000">NULL</span><span style=3D"color:#660">);</span><span style=3D"co=
lor:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">char</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#660">*</span><span s=
tyle=3D"color:#000">temp </span><span style=3D"color:#660">=3D</span><span =
style=3D"color:#000"> strDest</span><span style=3D"color:#660">;</span><spa=
n style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">=
while</span><span style=3D"color:#660">(*</span><span style=3D"color:#000">=
strDest</span><span style=3D"color:#660">++</span><span style=3D"color:#000=
"> </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> =
</span><span style=3D"color:#660">*</span><span style=3D"color:#000">strSrc=
</span><span style=3D"color:#660">++);</span><span style=3D"color:#000"><br=
>=C2=A0 =C2=A0 </span><span style=3D"color:#008">return</span><span style=
=3D"color:#000"> temp</span><span style=3D"color:#660">;</span><span style=
=3D"color:#000"><br></span><span style=3D"color:#660">}</span><span style=
=3D"color:#000"><br></span></div></code></div><br>Everyone has their own ta=
stes. But... Concepts TS has 3 different and increasingly brief syntaxes fo=
r declaring a constrained template for a reason. In N3701, Stroustrup et. a=
l. defended this by saying:<br><br>&gt; Do not confuse the familiar with th=
e simple. The proposed syntax is readable and parsable. We considered =E2=
=80=9Clouder=E2=80=9D, more verbose notations, but did not find them consis=
tently better than what is described here.<br><br>Brevity has value.<br><br=
></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Actual=
ly,</div><div>I tend to prefer writing things more explicitly like above th=
an using</div><div>nested ... expansions when things get complex, for I thi=
nk the different</div><div>rules for ... expansion can be confusing.</div><=
/div></blockquote><div><br>Welcome to the point of the whole idea.<br><br>I=
n this example, what we&#39;re trying to do is to call `inner` for each ele=
ment of the tuple, then pass the results as parameters to `outer`. To you, =
this is something that &quot;gets complex&quot;.<br><br>The purpose of the =
language feature is so that it <i>isn&#39;t complex</i> anymore. By making =
it a language feature, we take something that was &quot;complex&quot; and m=
ake it simple. That&#39;s the point.<br><br>Your library solution is much l=
ike `std::enable_if`. Yes, it gives you a consistent tool for invoking SFIN=
AE. But I <i>bet</i> you&#39;d rather be using Concepts.<br><br>`enable_if`=
 makes SFINAE doable, but it requires that you express your condition in an=
 unnatural way. Concepts makes SFINAE <i>trivial</i>. Same here: Hana makes=
 tuple manipulation doable, but requires that you write your code in unnatu=
ral ways.<br><br>The principle difference is that there&#39;s nothing `enab=
le_if` can do that concepts can&#39;t. Whereas there&#39;s a lot that Hana =
can do which tuple expansion can&#39;t. But that alone doesn&#39;t mean tha=
t it isn&#39;t worth being a language feature.<br><br>Lambdas were supposed=
 to obsolete std::bind too. Yet there are still some valid uses for it.<br>=
<br></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"><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1=
px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>But here&#39;s the #1=
 reason why the library solution is the wrong solution: you <i>wrote it wro=
ng</i>. You forgot to `std::forward` your arguments. And you forgot to use =
`decltype(auto)` for the return value. Both of which are needed to be exact=
ly equivalent to the above code. Without the `decltype(auto)`, if `outer` r=
eturned a reference of some kind, it could provoke an unwanted copy.<br><br=
>So it really needed to be:<br><br><div style=3D"background-color:rgb(250,2=
50,250);border-color:rgb(187,187,187);border-style:solid;border-width:1px;w=
ord-wrap:break-word"><code><div><span style=3D"color:#000">hana</span><span=
 style=3D"color:#660">::</span><span style=3D"color:#000">unpack</span><spa=
n style=3D"color:#660">(</span><span style=3D"color:#000">tpl</span><span s=
tyle=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">[](</span><span style=3D"color:#008">auto</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">...</span><span style=3D=
"color:#000">x</span><span style=3D"color:#660">)</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#660">-&gt;</span><span style=3D"color=
:#000"> </span><span style=3D"color:#008">decltype</span><span style=3D"col=
or:#660">(</span><span style=3D"color:#008">auto</span><span style=3D"color=
:#660">)</span><span style=3D"color:#000"> </span><span style=3D"color:#660=
">{</span><span style=3D"color:#000"> </span><span style=3D"color:#008">ret=
urn</span><span style=3D"color:#000"> outer</span><span style=3D"color:#660=
">(</span><span style=3D"color:#000">inner</span><span style=3D"color:#660"=
>(</span><span style=3D"color:#000">std</span><span style=3D"color:#660">::=
</span><span style=3D"color:#000">forward</span><span style=3D"color:#660">=
&lt;</span><span style=3D"color:#008">declt<wbr>ype</span><span style=3D"co=
lor:#660">(</span><span style=3D"color:#008">auto</span><span style=3D"colo=
r:#660">)&gt;(</span><span style=3D"color:#000">x</span><span style=3D"colo=
r:#660">)...));</span><span style=3D"color:#000"> </span><span style=3D"col=
or:#660">});</span></div></code></div><br>I fail to see how this could be c=
onsidered anywhere nearly as easy to understand.<br></div></div></blockquot=
e><div><br></div><div>Fair enough. But if we&#39;re going to be pedantic, l=
et&#39;s be pedantic for real. What you wanted</div><div>to write is</div><=
div><div style=3D"background-color:rgb(250,250,250);border:1px solid rgb(18=
7,187,187);word-wrap:break-word"><code><div><span style=3D"color:#000">hana=
</span><span style=3D"color:#660">::</span><span style=3D"color:#000">unpac=
k</span><span style=3D"color:#660">(</span><span style=3D"color:#000">tpl</=
span><span style=3D"color:#660">,</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#660">[](</span><span style=3D"color:#008">auto</span>=
<span style=3D"color:#660">&amp;&amp;</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#660">...</span><span style=3D"color:#000">x</span=
><span style=3D"color:#660">)</span><span style=3D"color:#000"> </span><fon=
t color=3D"#666600"><span style=3D"color:#660">-&gt;</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#008">decltype</span><span style=3D=
"color:#660">(</span><span style=3D"color:#008">auto</span><span style=3D"c=
olor:#660">)</span><span style=3D"color:#000"> </span><span style=3D"color:=
#660">{</span><span style=3D"color:#000"> </span><span style=3D"color:#008"=
>return</span><span style=3D"color:#000"> outer</span><span style=3D"color:=
#660">(</span><span style=3D"color:#000">inner</span><span style=3D"color:#=
660">(</span><span style=3D"color:#000">std</span><span style=3D"color:#660=
">::</span><span style=3D"color:#000">forward</span><span style=3D"color:#6=
60">&lt;</span><span style=3D"color:#008">declt<wbr>ype</span><span style=
=3D"color:#660">(</span><span style=3D"color:#000">x</span><span style=3D"c=
olor:#660">)&gt;(</span><span style=3D"color:#000">x</span><span style=3D"c=
olor:#660">))...);</span><span style=3D"color:#000"> </span><span style=3D"=
color:#660">});</span></font></div></code></div><div><br></div><div>With th=
is out of the way, I will argue that you actually don&#39;t need to write t=
he above, except</div><div>in rare cases where the tuple is potentially a r=
value. Instead, in most cases, you&#39;d just</div><div>have to write</div>=
<div><br></div><div><div style=3D"background-color:rgb(250,250,250);border:=
1px solid rgb(187,187,187);word-wrap:break-word"><code><div><font color=3D"=
#660066"><span style=3D"color:#000">hana</span><span style=3D"color:#660">:=
:</span><span style=3D"color:#000">unpack</span><span style=3D"color:#660">=
(</span><span style=3D"color:#000">tpl</span><span style=3D"color:#660">,</=
span><span style=3D"color:#000"> </span><span style=3D"color:#660">[](</spa=
n><span style=3D"color:#008">auto</span><span style=3D"color:#660">&amp;</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#660">...</span=
><span style=3D"color:#000">x</span><span style=3D"color:#660">)</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#660">-&gt;</span><span=
 style=3D"color:#000"> </span><span style=3D"color:#008">decltype</span><sp=
an style=3D"color:#660">(</span><span style=3D"color:#008">auto</span><span=
 style=3D"color:#660">)</span><span style=3D"color:#000"> </span><span styl=
e=3D"color:#660">{</span><span style=3D"color:#000"> </span><span style=3D"=
color:#008">return</span><span style=3D"color:#000"> outer</span><span styl=
e=3D"color:#660">(</span><span style=3D"color:#000">inner</span><span style=
=3D"color:#660">(</span><span style=3D"color:#000">x</span><span style=3D"c=
olor:#660">)...);</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#660">});</span></font></div></code></div><div><br></div>which is slig=
htly less verbose.</div></div></div></blockquote><div><br>My point was not =
just that it was verbose. My point is that it is both verbose <i>and</i> ea=
sy to get wrong, which we both demonstrated (though at least my error would=
 have shown up in the compiler ;) ).<br><br></div><blockquote class=3D"gmai=
l_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr"><div><div></div></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"><div></div><blockquote class=3D"gmail_q=
uote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddin=
g-left:1ex"><div dir=3D"ltr"><div></div><div>Basically, `unpack` is just `s=
td::apply` but with the arguments reversed.</div><div><br></div><div><br></=
div><div>&gt; Show me the Hana code for this:</div><div>&gt;</div><div>&gt;=
 auto x =3D inner([:]tpl) + ...;</div><div>&gt;</div><div>&gt; This simply =
calls a function on each element of the tuple and takes the sum</div><div>&=
gt; of the results. Again, it works like parameter packs, so it reuses exis=
ting</div><div>&gt; knowledge.</div><div><br></div><div>You could write</di=
v><div><br></div><div>=C2=A0 =C2=A0 auto x =3D hana::fold_left(hana::<wbr>t=
ransform(tpl, inner), std::plus&lt;&gt;{});</div></div></blockquote><div><b=
r>And for people who natively read right to left, this would probably be de=
cent. But that&#39;s not how the rest of C++ works.<br></div></div></blockq=
uote><div><br></div><div>Wtf? How is this different from writing=C2=A0</div=
><div><br></div><div><div style=3D"background-color:rgb(250,250,250);border=
:1px solid rgb(187,187,187);word-wrap:break-word"><code><div><font color=3D=
"#000000"><span style=3D"color:#008">auto</span><span style=3D"color:#000">=
 x </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> =
ranges</span><span style=3D"color:#660">::</span><span style=3D"color:#000"=
>accumulate</span><span style=3D"color:#660">(</span></font><span style=3D"=
color:#000">ranges</span><span style=3D"color:#660">::</span><font color=3D=
"#000000"><span style=3D"color:#000">tra<wbr>nsformed</span><span style=3D"=
color:#660">(...)</span></font><font color=3D"#000000"><span style=3D"color=
:#660">,</span><span style=3D"color:#000"> std</span><span style=3D"color:#=
660">::</span><span style=3D"color:#000">plus</span><span style=3D"color:#6=
60">&lt;&gt;{});</span></font></div></code></div><div><br></div></div></div=
></blockquote><div><br>You will never catch me writing <i>that</i> either.<=
br><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-lef=
t:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>=
<div></div><div></div></div><blockquote class=3D"gmail_quote" style=3D"marg=
in:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div di=
r=3D"ltr"><div></div><blockquote class=3D"gmail_quote" style=3D"margin:0;ma=
rgin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"lt=
r"><div></div><div>or equivalently</div><div><br></div><div>=C2=A0 =C2=A0 a=
uto x =3D hana::fold_left(tpl, [](auto a, auto b) {</div><div>=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 return a + inner(b);</div><div>=C2=A0 =C2=A0 });</div></div>=
</blockquote><div><br>Again you forgot to forward the arguments and return =
values properly. Not to mention, you turn a simple one-liner into a multi-l=
ine statement.<br></div></div></blockquote><div><br></div><div>Same argumen=
t as above. And the fact that I broke the statements into multiple</div><di=
v>lines to make it more readable is a feature. Honestly, I think this (and =
especially</div><div>the transform/fold_left variant) is more readable than=
 the variant with ... expansions.</div><div>Of course, your version is more=
 terse, but too terse is not good either.</div></div></blockquote><div><br>=
It&#39;s not really that it&#39;s terse; that&#39;s not what attracts me to=
 tuple expansion. What matters most to me is that the code looks as much li=
ke normal code ought to look.<br><br>This is also what repels me from your =
ranges example.<br><br>Most programmers know what `outer(inner(value))` doe=
s. They can understand that by inspection, and its meaning is clear. Most p=
rogrammers understand what `inner(value) + inner(value2)` means.<br><br>Han=
a code is not obvious, not to someone who isn&#39;t familiar with template =
metaprogramming and such techniques.<br><br>While an unsuspecting programme=
r may not understand exactly what the `...` and `[:]` parts mean, they can =
still look at `outer(inner([:]value)...)` and see that `inner` will be call=
ed, followed by `outer`. It carries the same physical structure and code la=
yout of the simple and obvious case. It may be more complex under the hood,=
 but the user is not exposed to it.<br><br>When looking at `hana::on(inner,=
 outer)`, they have absolutely no idea what that means. Not without looking=
 up the docs. There is no intuitive grasp of what&#39;s going on.<br><br>So=
 the value is more than &quot;just&quot; terseness. The value is that the c=
ode&#39;s structure remains intact. You&#39;re not exchanging a call to `+`=
 with `std::plus&lt;&gt;`. You&#39;re not altering the overall order and na=
ture of the code.=C2=A0</div></div></blockquote><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"><div><br></div><blockquote class=3D"gmai=
l_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr"><div></div><div>Let&#39;s stop arguing over=
 petty details. You want to hear it? Of course your solution</div><div>is b=
etter for those use cases, because it was designed with those in mind!</div=
><div>But it is also much more limited, and the point I&#39;m trying to mak=
e is that from</div><div>the point of view of a metaprogramming library wri=
ter, this proposal, in its</div><div>current form, misses the goal just lik=
e fold expressions did.</div></div></blockquote><div><br>And my overall poi=
nt is that what you want was <i>never</i> the goal to begin with. You are d=
enigrating a proposal for not solving a problem that it was never intended =
to solve. </div></div></blockquote><div><br></div><div><div>I&#39;m sorry i=
f you perceived my comments as denigration, for that was never my goal. I k=
now the power</div><div>of getting a different perspective, especially one =
that has been thought out, and that is what I wanted</div><div>to share wit=
h you. We&#39;re all trying to achieve the same thing here; a language that=
 allows us to express</div><div>ourselves more easily. We&#39;re disagreein=
g on the way to get there, and you seem to be impermeable to</div><div>my i=
deas. It&#39;s fine, but my work here is done for I don&#39;t feel like som=
ething good can come out of more</div></div><div>discussion like what we&#3=
9;ve been having.</div><div><br></div><div><br></div><blockquote class=3D"g=
mail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc sol=
id;padding-left: 1ex;"><div dir=3D"ltr"><div>The problem it is solving is m=
aking tuples work like parameter pack expansion, so as to be able to more e=
ffectively access data out of tuples in useful ways.<br></div></div></block=
quote><div><br></div><div>When you say &quot;useful ways&quot;, I gather th=
at you&#39;re saying &quot;ways that are useful for myself&quot;. Indeed, I=
&#39;m</div><div>precisely saying that accessing tuples in the way you prop=
ose isn&#39;t useful to me, but you say that this</div><div>isn&#39;t the g=
oal. I hope you hit the needs of the standard committee members right on th=
e spot, otherwise</div><div>they might find it difficult to modify _the fre=
aking language_ for your use case.</div><div><br></div><div>Regards,</div><=
div>Louis Dionne</div><div><br></div><div><br></div><blockquote class=3D"gm=
ail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc soli=
d;padding-left: 1ex;"><div dir=3D"ltr"><div>Arbitrary tuple transformations=
 was never the goal. That&#39;s a legitimate and useful problem domain. But=
 that&#39;s not what this is intended to handle. The fact that this syntax =
can indeed handle some of that via clever usage of the syntax is merely a f=
ortunate coincidence.<br><br>C++11 already has a construct that is tuple-li=
ke in its nature: parameter packs. We&#39;re just expanding it to work with=
 actual tuples.<br></div></div></blockquote></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 />

------=_Part_275_487542790.1455725775761--
------=_Part_274_527237065.1455725775759--

.
