Topic: A plea to reconsider adding Structured
Author: Marc Mutz <marc.mutz@kdab.com>
Date: Wed, 5 Oct 2016 19:08:38 +0200
Raw View
On Wednesday 05 October 2016 16:13:32 'Herb Sutter' via ISO C++ Standard -
Future Proposals wrote:
> > I heard about Structured Bindings for the first time at CppCon this year,
> > and I'd like to raise my concerns, esp. since half of the panel was
> > crazy about them.
>
> Thanks for your interest! Did you read the design paper? It answers many of
> these questions.
If with "design paper" you mean P0144R2, then, yes, I read it and, no, I'm
afraid it doesn't answer what SB is supposed to be good at except make
functions returning pairs and tuples bearable, syntax-wise, at the call site.
My main concern is that you shouldn't use these types in APIs in the first
place, and they are the current work around for the clumsiness of defining
structs to hold multiple return values.
> > The reaons it's horrible,
>
> Note that you're making a strong value judgment about something you heard
> about two weeks ago.
You misunderstand. The horrible thing is pair and tuple in APIs:
if(map.insert(...).second)
second? Second what? This is horrible, and I guess Alex Stepanov would not
disagree.
I agree SB solves this, in a way. My premise, though, is that if we stop using
pair and tuple in apis, the original problem goes away, and the solution for
the problem becomes obsolete.
> You're coming into a design discussion that has been
> discussed in depth at multiple meetings for nearly a year, and while new
> information is welcome it's always good to enter a discussion-in-progress
> by treading lightly (e.g., start by asking whether something has been
> considered). Especially when "half a panel" of people who have been in the
> deep design discussions and understand the feature like it a lot. :)
You're right, of course. My apologies.
> > is because it reverses the C++ principle that the
> > implementor of a library should have to do the work, not the user.
> >
> > It reverses the principle by requiring the *caller* to choose the names
> > of the values returned,
>
> The caller always chooses the name of a returned value in their scope:
>
> auto my_name = f();
>
> SB is just giving them a way to gives names to the individual components if
> they want to work with them directly, instead of a name to the whole
> composite entity:
>
> auto [my_name_1, my_name_2] = f();
This works fine with a very few (2) items returned. Just as function arguments
work best if there are just a few.
In both cases, if there are more than just a few, the code becomes brittle. It
doesn't matter whether you pass five values into a function or use SB to get
them out: postitional arguments are bad for that. For years, a recurring theme
is named function arguments. *I* never missed them. If a function takes too
many arguments to a function, you refactor it to make it take a struct/class.
If you don't, the code becomes unreadable.
Take this example of Qt3's QSlider constructor:
m_slider = new QSlider(0, 100, 10, 0, Qt::Horizontal, this, "m_slider");
In Qt4, this ctor was deprecated. You now have to say:
m_slider = new QSlider(this);
m_slider->setObjectName("m_slider");
m_slider->setRange(0, 100);
m_slider->setPageStep(10);
m_slider->setValue(0);
m_slider->setOrientation(Qt::Horizontal);
This was also possible in Qt3, of course. Except we're programmers, and we're
lazy, so everyone (me included) tended to use the terse constructor call.
SB is a bit like that ctor. Returning a struct is a bit like that Qt4 code:
The library authors choose the function names, same as they choose the member
names of the return struct. By forcing the use of the same name for the same
functionality in user code, familiarity with the API is built. Code using the
library becomes easier to read. Someone familiar with the API will be able to
understand the code better, even if someone else wrote it.
By allowing every user to choose the names of return values, code becomes
harder to understand, because there's no single correct name for each field.
> > when it should be the implementor of the function who
> > chooses the names.
>
> You can have your cake and eat it too, because SB works with structs:
> > IMHO, the correct solution to the multiple return value problem is to
> > return a struct with properly named fields, not a pair and not a tuple.
>
> (Actually IMO the correct solution is multiple return values. Returning a
> struct is our current workaround, the closest approximation in today's
> language.)
See above for why I think this is not a good idea. Positional arguments are
generally inferior to named ones. Positional arguments are easy to write, but
hard to read. It's the library-enforced required names of functions (and
fields) that anchor and guide the reader through unfamiliar code:
"setObjectName? Ok, not interesting, skip that.". You might make a case for
multiple return values as complementing function arguments, but they will not
help write better APIs, I think.
> That's fine, you can do that, and it works fine with SB. . Here's an
> example from my own recent gcpp library, https://github.com/hsutter/gcpp:
>
> struct contains_info_ret {
> gpage_find_result found;
> std::size_t location;
> std::size_t start_location;
> };
> contains_info_ret
> contains_info(gsl::not_null<const byte*> p) const noexcept;
Even with so much effort going into making the Qt 4 API more readable, at
roughly the same time, this slipped in:
typedef QPair<double, QColor> QGradientStop;
typedef QVector<QGradientStop> QGradientStops;
Which just goes to prove that pairs (and, by extension, tuples) are addictive.
> The only thing that C++ doesn't currently let you do is to omit the ";
> contains_info_ret" in the middle, to declare a struct in the position of a
> return value. From time to time people suggest allowing that; I wouldn't
> be surprised to see it proposed in the future. (I would like to see that
> proposal. I would even more like to see a multiple return values
> proposal.)
>
> But SB works fine with this, because it allows the caller to write both
> this:
>
> auto info = page.contains_info(ptr);
> if (info.found == /*...*/) {
> use(info.location, info.start_location);
> }
>
> and this:
>
> auto [found, offset, start] info = page.contains_info(ptr);
> if (found == /*...*/) {
> use(offset, start);
> }
>
> Returning a struct should be thought of as the callee returning "default"
> names for the caller to use. With SB, the caller has a choice and can
> either use the default names or else provide more meaningful names if they
> want to; it doesn't hurt your preference for returning a struct at all, in
> fact it cooperates very well with that -- and that's not an accident, it's
> by design since the very first design paper.
I get that it works with structs, too. And I appreciate it. My problem is that
it works with, and in a way legitimises, returning pairs and tuples instead,
too. Yes, if SB works with structs, it's more than natural to have it work
with tuples and pairs, too, but P0144R2 makes it very clear that the rationale
goes the other way around. Quoting the abstract:
> Abstract
> This paper proposes the ability to
> store a value and bind names to its components, along the lines of:
> tuple<T1,T2,T3> f(/*...*/) { /*...*/ return {a,b,c}; }
> auto [x,y,z] = f(); // x has type T1, y has type T2, z has type T3
> This addresses the requests for support of returning multiple values, which
> has become a popular request lately.
> Proposed wording appears in a separate paper, P0217.
This example would look ridiculous if you had used a struct as the return
value of f():
struct { T1 a; T2 b; T3 c; } f(/*...*/) { /*...*/ return {a,b,c}; }
auto [x,y,z] = f(); // x has type T1, y has type T2, z has type T3
"Huh? Why would I ever want to name 'a' 'x', 'b' 'y' etc? I can't change the
name of 'f', either."
The paper goes on to say:
> Today, we allow multiple return values via tuple
> pretty nicely in function declarations and definitions
No. Tuples as a vehicle to return multiple values from a funciton are *not*
nice. They are convenient, yes. For the function author. But no-one else.
Maybe with variadic content, but that's just another way to say that we need a
way to expand packs into data members. No, the basic premise is wrong, IMHO,
so SB becomes a solution for a problem that I believe is not worth solving,
and offers little-to-no benefit (granted, that I can see, and my view might be
limited) for libraries that return structs.
If there's a grander plan than that to transition smoothly from STL's
std::pair API to something hopefully better, I'd like to hear it. But there
must be better ways to achieve this. structs that implicitly convert to pairs
are one way, but break code that accesses the members directly:
if (map.insert(...).second)
For that, maybe 'using' could be (ab)used:
template <typename Iterator>
struct map_insert_result {
Iterator iterator;
bool inserted;
[[deprecated]] using first = iterator;
[[deprecated]] using second = inserted;
[[deprecated]] operator std::pair<Iterator, bool>() const
{ return {iterator, inserted}; }
};
That would help with migrating users to a better QGradientStop, too.
Thanks,
Marc
> Herb
>
> > -----Original Message-----
> > From: marc@kdab.com [mailto:marc@kdab.com] On Behalf Of Marc Mutz
> > Sent: Wednesday, October 5, 2016 3:38 AM
> > To: Herb Sutter <hsutter@microsoft.com>; bjarne@stroustrup.com; Gabriel
> > Dos Reis <gdr@microsoft.com>
> > Cc: std-proposals@isocpp.org
> > Subject: A plea to reconsider adding Structured Bindings to language
> >
> > Hi Herb, Bjarne, Gabriel,
> >
> > I heard about Structured Bindings for the first time at CppCon this year,
> > and I'd like to raise my concerns, esp. since half of the panel was
> > crazy about them.
> >
> > I strongly believe that the premise that returning std::tuple from
> > functions to solve the multiple-return-types problem is good practice,
> > is fundamentally wrong.
> >
> > It is not good in any sense of the word. It is horrible. Indeed, it is so
> > horrible that you felt inclined to add a new language feature just to
> > make it bearable.
> >
> > The reaons it's horrible, is because it reverses the C++ principle that
> > the implementor of a library should have to do the work, not the user.
> >
> > It reverses the principle by requiring the *caller* to choose the names
> > of the values returned, when it should be the implementor of the
> > function who chooses the names.
> >
> > In conjunction with auto deduction, the caller choosing the names means
> > that the code becomes brittle in the face of changes to the return type,
> > e.g. when reordering fields to fill padding holes.
> >
> > Structured Bindings would be acceptable if, like scripting languages, we
> > didn't have anything else to work with.
> >
> > But we do: We can return a struct.
> >
> > IMHO, the correct solution to the multiple return value problem is to
> > return a struct with properly named fields, not a pair and not a tuple.
> >
> > I fear Structured Bindings will lead to an explosion of *really* bad API
> > that returns std::pair or std::tuple when it should return a small
> > struct with well- named data members instead, because a) the implementor
> > couldn't be bothered to pick good names for a return struct, and b)
> > tuples can be defined on the fly, in the function declaration, whereas
> > structs can not.
> >
> > I believe there's a proposal for allowing to define structs in function
> > declarations already, but I failed to find it.
> >
> > Consider:
> > std::map::insert(...) -> std::pair<iterator, bool>
> >
> > or the other way around, I can never remember, which is a problem that
> > structured bindings don't solve for me. Yes, in this case using the
> > iterator as a boolean will fail, but what about algorithms that return
> > multiple iterators? If you get the order wrong, then you have a bug.
> >
> > No, map::insert() should have returned a
> >
> > struct { iterator iterator; bool inserted; };
> >
> > so one could say:
> > if (map.insert(...).inserted)
> >
> > or
> >
> > auto result = map.insert(...)
> > if (result.inserted)
> >
> > To summarise: I feel that Structured Bindings are too easy to use
> > incorrectly, because they put the burden of choosing a name for the
> > fields of a return value on the caller, instead of the implementor, of
> > the function. I'd like to see the pattern to return structs from
> > functions strengthened, not the anti- pattern of returning pairs and
> > tuples.
> >
> > I therefore hope that I can persuade you to reconsider adding Structured
> > Bindings to C++17.
> >
> > Thanks,
> > Marc
> >
> > --
> > Marc Mutz <marc.mutz@kdab.com> | Senior Software Engineer KDAB
> > (Deutschland) GmbH & Co.KG, a KDAB Group Company
> > Tel: +49-30-521325470
> > KDAB - Qt, C++ and OpenGL Experts
--
Marc Mutz <marc.mutz@kdab.com> | Senior Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
Tel: +49-30-521325470
KDAB - Qt, C++ and OpenGL Experts
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 5 Oct 2016 15:07:03 -0700 (PDT)
Raw View
------=_Part_92_1172176589.1475705224104
Content-Type: multipart/alternative;
boundary="----=_Part_93_1394412450.1475705224104"
------=_Part_93_1394412450.1475705224104
Content-Type: text/plain; charset=UTF-8
On Wednesday, October 5, 2016 at 1:06:51 PM UTC-4, Marc Mutz wrote:
>
> On Wednesday 05 October 2016 16:13:32 'Herb Sutter' via ISO C++ Standard -
> Future Proposals wrote:
> > > I heard about Structured Bindings for the first time at CppCon this
> year,
> > > and I'd like to raise my concerns, esp. since half of the panel was
> > > crazy about them.
> >
> > Thanks for your interest! Did you read the design paper? It answers many
> of
> > these questions.
>
> If with "design paper" you mean P0144R2, then, yes, I read it and, no, I'm
> afraid it doesn't answer what SB is supposed to be good at except make
> functions returning pairs and tuples bearable, syntax-wise, at the call
> site.
>
> My main concern is that you shouldn't use these types in APIs in the first
> place, and they are the current work around for the clumsiness of defining
> structs to hold multiple return values.
>
> > > The reaons it's horrible,
> >
> > Note that you're making a strong value judgment about something you
> heard
> > about two weeks ago.
>
> You misunderstand. The horrible thing is pair and tuple in APIs
The problem I find with your argument is this: even if we assume you're
right, that tuples should not be used as a way to return multiple values
ever, structured binding is *still a useful tool*. And we will still want
structured binding to be extensible to user-defined types with private
members. And that will include `pair` and `tuple`.
The tool may encourage certain misuse; that much is true. But it is far too
useful of a tool to disregard it just because of potential misuse.
You essentially are making a blanket statement that pairs and tuples are
inherently confusing. I contest this, and you've given a perfect example of
when their meaning is well understood:
typedef QPair<double, QColor> QGradientStop;
Just from the name of the type and the types of the arguments (and of
course the associated domain knowledge), I know exactly what these values
mean. So when I see this:
QGradientStop s = ...
if(get<double>(s) < dist)
{
...
}
We know what it is doing. Could this code be more clear if it were a struct
with named members? Probably. But it isn't *un*-clear as it currently
stands; it simply could be *more* clear. That is, the code isn't *bad* as
written; it simply may be open to improvement.
There's a lot of space between "not good" and "bad." And in many cases,
pair/tuple use, while "not good", doesn't descend to the level of "bad".
And that's good enough.
--
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/4d4b17a4-270b-4833-b8b8-d0f942e2198b%40isocpp.org.
------=_Part_93_1394412450.1475705224104
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Wednesday, October 5, 2016 at 1:06:51 PM UTC-4, Marc Mu=
tz wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Wednesday 05 Octob=
er 2016 16:13:32 'Herb Sutter' via ISO C++ Standard -=20
<br>Future Proposals wrote:
<br>> > I heard about Structured Bindings for the first time at CppCo=
n this year,
<br>> > and I'd like to raise my concerns, esp. since half of the=
panel was
<br>> > crazy about them.
<br>>=20
<br>> Thanks for your interest! Did you read the design paper? It answer=
s many of
<br>> these questions.
<br>
<br>If with "design paper" you mean P0144R2, then, yes, I read it=
and, no, I'm=20
<br>afraid it doesn't answer what SB is supposed to be good at except m=
ake=20
<br>functions returning pairs and tuples bearable, syntax-wise, at the call=
site.
<br>
<br>My main concern is that you shouldn't use these types in APIs in th=
e first=20
<br>place, and they are the current work around for the clumsiness of defin=
ing=20
<br>structs to hold multiple return values.<br>
<br>> > The reaons it's horrible,
<br>>=20
<br>> Note that you're making a strong value judgment about somethin=
g you heard
<br>> about two weeks ago.
<br>
<br>You misunderstand. The horrible thing is pair and tuple in APIs</blockq=
uote><div><br>The problem I find with your argument is this: even if we ass=
ume you're right, that tuples should not be used as a way to return mul=
tiple values ever, structured binding is <i>still a useful tool</i>. And we=
will still want structured binding to be extensible to user-defined types =
with private members. And that will include `pair` and `tuple`.<br><br>The =
tool may encourage certain misuse; that much is true. But it is far too use=
ful of a tool to disregard it just because of potential misuse.<br><br>You =
essentially are making a blanket statement that pairs and tuples are inhere=
ntly confusing. I contest this, and you've given a perfect example of w=
hen their meaning is well understood:<br><br><div style=3D"background-color=
: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid=
; border-width: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><cod=
e class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color:=
#008;" class=3D"styled-by-prettify">typedef</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" clas=
s=3D"styled-by-prettify">QPair</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify"><</span><span style=3D"color: #008;" class=3D"styled=
-by-prettify">double</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">QColor</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">></span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #606;" class=3D"styled-by-prettify">QGradientStop</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">;</span></div></code></d=
iv><br>Just from the name of the type and the types of the arguments (and o=
f course the associated domain knowledge), I know exactly what these values=
mean. So when I see this:<br><br><div style=3D"background-color: rgb(250, =
250, 250); border-color: rgb(187, 187, 187); border-style: solid; border-wi=
dth: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"=
prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #606;" cla=
ss=3D"styled-by-prettify">QGradientStop</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> s </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">...</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">if</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span=
style=3D"color: #008;" class=3D"styled-by-prettify">get</span><span style=
=3D"color: #080;" class=3D"styled-by-prettify"><double></span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">s</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify"><</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> dist</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">...</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br></span></div></code></div><br>We know=
what it is doing. Could this code be more clear if it were a struct with n=
amed members? Probably. But it isn't <b>un</b>-clear as it currently st=
ands; it simply could be <i>more</i> clear. That is, the code isn't <i>=
bad</i> as written; it simply may be open to improvement.<br><br>There'=
s a lot of space between "not good" and "bad." And in m=
any cases, pair/tuple use, while "not good", doesn't descend =
to the level of "bad".<br><br>And that's good enough.<br></di=
v></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/4d4b17a4-270b-4833-b8b8-d0f942e2198b%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/4d4b17a4-270b-4833-b8b8-d0f942e2198b=
%40isocpp.org</a>.<br />
------=_Part_93_1394412450.1475705224104--
------=_Part_92_1172176589.1475705224104--
.
Author: Marc Mutz <marc.mutz@kdab.com>
Date: Thu, 6 Oct 2016 11:42:06 +0200
Raw View
On Thursday 06 October 2016 00:07:03 Nicol Bolas wrote:
> On Wednesday, October 5, 2016 at 1:06:51 PM UTC-4, Marc Mutz wrote:
> > On Wednesday 05 October 2016 16:13:32 'Herb Sutter' via ISO C++ Standard
> > -
> >
> > Future Proposals wrote:
> > > > I heard about Structured Bindings for the first time at CppCon this
> >
> > year,
> >
> > > > and I'd like to raise my concerns, esp. since half of the panel was
> > > > crazy about them.
> > >
> > > Thanks for your interest! Did you read the design paper? It answers
> > > many
> >
> > of
> >
> > > these questions.
> >
> > If with "design paper" you mean P0144R2, then, yes, I read it and, no,
> > I'm afraid it doesn't answer what SB is supposed to be good at except
> > make functions returning pairs and tuples bearable, syntax-wise, at the
> > call site.
> >
> > My main concern is that you shouldn't use these types in APIs in the
> > first place, and they are the current work around for the clumsiness of
> > defining structs to hold multiple return values.
> >
> > > > The reaons it's horrible,
> > >
> > > Note that you're making a strong value judgment about something you
> >
> > heard
> >
> > > about two weeks ago.
> >
> > You misunderstand. The horrible thing is pair and tuple in APIs
>
> The problem I find with your argument is this: even if we assume you're
> right, that tuples should not be used as a way to return multiple values
> ever, structured binding is *still a useful tool*. And we will still want
> structured binding to be extensible to user-defined types with private
> members. And that will include `pair` and `tuple`.
>
> The tool may encourage certain misuse; that much is true. But it is far too
> useful of a tool to disregard it just because of potential misuse.
Ok, so I guess I still have to learn what this tool is useful for, except
returning pairs and tuples. Other than that, and a certain language-
theoretical symmetry with function arguments, what's so crazy cool about
aliasing existing names into something else? Because P0144R2 for sure doesn't
say. It focuses exclusively on the use-case of returning tuples.
> You essentially are making a blanket statement that pairs and tuples are
> inherently confusing. I contest this, and you've given a perfect example of
> when their meaning is well understood:
>
> typedef QPair<double, QColor> QGradientStop;
>
> Just from the name of the type and the types of the arguments (and of
> course the associated domain knowledge), I know exactly what these values
> mean. So when I see this:
>
> QGradientStop s = ...
> if(get<double>(s) < dist)
> {
> ...
> }
>
> We know what it is doing.
Do we? What's that double? You need to know QGradientStop's definition to know
what that double is. If QGradientStop would be
struct QGradientStop {
double location;
QColor color;
};
then
if (stop.location < dist)
would be self-explanatory. This doesn't matter much if you're confronted with
a small library such as the STL(!), but when you get to large-scale libraries
such as Qt (or Boost), this stuff is at the center of readability.
And what do you do in this case:
struct GammaCorrectionStop {
uchar from;
uchar to;
};
?
> Could this code be more clear if it were a struct
> with named members? Probably.
Definitely.
> But it isn't *un*-clear as it currently
> stands; it simply could be *more* clear. That is, the code isn't *bad* as
> written; it simply may be open to improvement.
I disagree. The fact that I need to call get<double>, a) that I need to call a
get function, b) that I need to specify the _type_, in the era of auto
variables, already disqualifies this for many users. Putting the user hat on,
I would loudly protest if I had to write convoluted code like that only to
access a member that the library author was too lazy to name. It could be
improved somewhat (independent of naming) by defining a special type for a
position on the gradient ray:
struct QGradientRayPosition { double percent; };
and then further, by making 'percent' a quantity.
But each such small struct, while I'm all for them, also carries a cost:
documentation needs to be written, type-traits need to be specialised
(is_trivially_relocatable, e.g.), tests need to be written.
It's so much easier to say "I return a tuple, then I document the fields in
the docs of the function returning the tuple". If you find that derogative,
look at libkdepim/libkleo: I did that, too, so I don't exclude myself here.
> There's a lot of space between "not good" and "bad." And in many cases,
> pair/tuple use, while "not good", doesn't descend to the level of "bad".
>
> And that's good enough.
But is "good enough" good enough a reason to add it to the standard? We have
bind, then came lambdas. Some bind expressions still look better than their
corresponding lambda equivalents, as do some Boost.Lambda expressions, btw,
but by and large, bind() and Boost.Lambda are dead with C++14 polymorphic
lambdas.
It seems to me that the same will be true of tuples and structured bindings
once C++ gets the missing pieces: data member generation from template packs
(as part of reflection?), structs declared within the function declaration,
maybe Herb's multiple return values,...
I have greeted every new C++ feature since its inception with "cool stuff", I
even liked auto_ptr for all its shortcomings, but SB is the first one that
gives me pause. P0144R2 didn't change my mind. What's the fuss about? What's
the bigger picture I'm not seeing here?
Thanks,
Marc
--
Marc Mutz <marc.mutz@kdab.com> | Senior Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
Tel: +49-30-521325470
KDAB - Qt, C++ and OpenGL Experts
.
Author: TONGARI J <tongari95@gmail.com>
Date: Thu, 6 Oct 2016 05:42:41 -0700 (PDT)
Raw View
------=_Part_883_1696500967.1475757761809
Content-Type: multipart/alternative;
boundary="----=_Part_884_1933724006.1475757761810"
------=_Part_884_1933724006.1475757761810
Content-Type: text/plain; charset=UTF-8
On Thursday, October 6, 2016 at 5:40:20 PM UTC+8, Marc Mutz wrote:
[...]
It seems to me that the same will be true of tuples and structured bindings
> once C++ gets the missing pieces: data member generation from template
> packs
> (as part of reflection?), structs declared within the function
> declaration,
> maybe Herb's multiple return values,...
>
I have no idea how the multiple return values that Herb mentioned will
differ from SB. A language that has built-in support for multiple return
values, e.g. Go, looks exactly like SB in C++:
https://gobyexample.com/multiple-return-values
BTW, a language feature I'm currently developing will allow you to do
something like:
std::tuple<int.a, int.b> f()
{
return {0, 1};
}
auto t = f();
assert(t.a == 0);
assert(t.b == 0);
Is this what you want?
--
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/628a808f-d40c-4912-8e55-0058aeb26e06%40isocpp.org.
------=_Part_884_1933724006.1475757761810
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Thursday, October 6, 2016 at 5:40:20 PM UTC+8, Marc Mut=
z wrote:<div><br></div><div>[...]=C2=A0</div><div><br></div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #=
ccc solid;padding-left: 1ex;">It seems to me that the same will be true of =
tuples and structured bindings=20
<br>once C++ gets the missing pieces: data member generation from template =
packs=20
<br>(as part of reflection?), structs declared within the function declarat=
ion,=20
<br>maybe Herb's multiple return values,...
<br></blockquote><div><br></div><div style=3D"font-family: arial, sans-seri=
f; font-size: small;">I have no idea how the multiple return values that He=
rb mentioned will differ from SB. A language that has built-in support for =
multiple return values, e.g. Go, looks exactly like SB in C++: https://goby=
example.com/multiple-return-values</div><div style=3D"font-family: arial, s=
ans-serif; font-size: small;"><br></div><div><span style=3D"font-family: ar=
ial, sans-serif; font-size: small;">BTW, a language feature I'm current=
ly developing will allow you to do something like:</span>=C2=A0</div><div><=
br></div><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250=
, 250); border-color: rgb(187, 187, 187); border-style: solid; border-width=
: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"su=
bprettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettify">std=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify">tuple</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">.</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">a</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">int</span><span style=3D"color: #660;" class=3D"styled-by-prettify">.=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">b</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">></span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> f</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">()</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">return</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">{</span><span style=3D"color: #066;" class=3D"styled-by-pret=
tify">0</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #066;" class=3D"styled-by-prettify">1</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br><br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> t </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> f</span><span style=3D"color: #660;" class=3D"styled-by-prettify">();<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">assert</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">t</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">.</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">a </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">=3D=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-pr=
ettify">0</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">assert</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">t</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">.</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">b </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">=3D=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-pr=
ettify">0</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)=
;</span></div></code></div><div><div><br></div></div><div>Is this what you =
want?</div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/628a808f-d40c-4912-8e55-0058aeb26e06%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/628a808f-d40c-4912-8e55-0058aeb26e06=
%40isocpp.org</a>.<br />
------=_Part_884_1933724006.1475757761810--
------=_Part_883_1696500967.1475757761809--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 6 Oct 2016 06:36:47 -0700 (PDT)
Raw View
------=_Part_764_373870578.1475761007500
Content-Type: multipart/alternative;
boundary="----=_Part_765_275008093.1475761007501"
------=_Part_765_275008093.1475761007501
Content-Type: text/plain; charset=UTF-8
On Thursday, October 6, 2016 at 5:40:20 AM UTC-4, Marc Mutz wrote:
>
> On Thursday 06 October 2016 00:07:03 Nicol Bolas wrote:
> > On Wednesday, October 5, 2016 at 1:06:51 PM UTC-4, Marc Mutz wrote:
> > > On Wednesday 05 October 2016 16:13:32 'Herb Sutter' via ISO C++
> Standard
> > >
> > > You misunderstand. The horrible thing is pair and tuple in APIs
> >
> > The problem I find with your argument is this: even if we assume you're
> > right, that tuples should not be used as a way to return multiple values
> > ever, structured binding is *still a useful tool*. And we will still
> want
> > structured binding to be extensible to user-defined types with private
> > members. And that will include `pair` and `tuple`.
> >
> > The tool may encourage certain misuse; that much is true. But it is far
> too
> > useful of a tool to disregard it just because of potential misuse.
>
> Ok, so I guess I still have to learn what this tool is useful for, except
> returning pairs and tuples. Other than that, and a certain language-
> theoretical symmetry with function arguments, what's so crazy cool about
> aliasing existing names into something else? Because P0144R2 for sure
> doesn't
> say. It focuses exclusively on the use-case of returning tuples.
>
> > You essentially are making a blanket statement that pairs and tuples are
> > inherently confusing. I contest this, and you've given a perfect example
> of
> > when their meaning is well understood:
> >
> > typedef QPair<double, QColor> QGradientStop;
> >
> > Just from the name of the type and the types of the arguments (and of
> > course the associated domain knowledge), I know exactly what these
> values
> > mean. So when I see this:
> >
> > QGradientStop s = ...
> > if(get<double>(s) < dist)
> > {
> > ...
> > }
> >
> > We know what it is doing.
>
> Do we? What's that double? You need to know QGradientStop's definition to
> know
> what that double is.
No, you don't. You just have to think about it and know what a gradient
stop is conceptually.
A "gradient" represents a gradual change between two or more locations,
commonly called "stops". Therefore, each such "stop" must have two values:
a position and the color at that position. The type `double` is certainly
not a color, so by process of elimination, it must be the position.
And what do you do in this case:
>
> struct GammaCorrectionStop {
> uchar from;
> uchar to;
> };
>
> ?
>
.... I'm not sure I understand what that case is supposed to represent.
Nobody is suggesting the wholesale replacement of all structs with tuples.
Nobody is suggesting that every two-member struct should be replaced with a
pair of two types. Indeed, I thought I made it quite clear that not all
tuple usage is reasonably clear.
I'm simply arguing against your idea that all `tuple` use is a priori bad.
> There's a lot of space between "not good" and "bad." And in many cases,
> > pair/tuple use, while "not good", doesn't descend to the level of "bad".
> >
> > And that's good enough.
>
> But is "good enough" good enough a reason to add it to the standard?
for(auto[x, y] : zip(vector1, vector2))
{
...
}
The ability to do that *alone* justifies the feature. `zip` here combines
the given ranges into a single range over a tuple of values. Which of
course goes back to Matt's point about the utility of tuples in generic
contexts.
Is this code hard to understand? Is it difficult to know what the return of
that `zip` range will be? Or what the return of a zip iterator will be? No;
so long as you know what `zip` does, this code is quite readable.
> We have
> bind, then came lambdas. Some bind expressions still look better than
> their
> corresponding lambda equivalents, as do some Boost.Lambda expressions,
> btw,
> but by and large, bind() and Boost.Lambda are dead with C++14 polymorphic
> lambdas.
>
> It seems to me that the same will be true of tuples and structured
> bindings
> once C++ gets the missing pieces: data member generation from template
> packs
> (as part of reflection?), structs declared within the function
> declaration,
> maybe Herb's multiple return values,...
>
If C++20 gets designated initializers, then it becomes possible to have
named parameters for functions by using a struct:
struct params
{
int x; int y; int z = 2;
};
void func(params p);
func({.x = ..., .y = ...});
Does that mean that *every function* will start taking a single struct and
force you to write that? Of course not. It will only be done for functions
where the number of parameters is large, functions which have a lot of
defaults, or functions which it would otherwise be more confusing to take
parameters directly than to use named parameters of a struct.
The same goes for returning a tuple vs. a struct. There are cases where
returning a `tuple` is sufficiently self-documenting as to its meaning. And
there are cases where it is not. So even if we have the ability to put a
struct in a function's return type, people will still return `tuple`s.
Let's say we added the ability to make this code work:
template<typename ...Ts>
struct {zip_range<Ts> &ranges...;} zip(Ts&& ...ts) {...}
And on the receiving end:
auto z_ranges = zip(vector1, vector2);
z_ranges.ranges[0]; //represents vector1
How is that any more clear to the reader than:
auto z_ranges = zip(vector1, vector2);
get<0>(z_ranges); //Represents vector1
There's no magical reflection that can give the struct version knowledge
that the first index corresponds to a parameter who's argument comes from a
variable named `vector1`. There is no way that `zip` can *possibly* give
the members of its return value a semantic name. These values *only exist*
as positions relative to the positions of the inputs. Only the caller knows
what the meaning of the inputs is, so only the caller can know what the
meaning of the outputs will be. So there's no advantage to using a struct
instead of a tuple.
Returning `tuple`s is not going away. As metaprogramming techniques become
easier to use, so too will `tuple`s become more commonly used. Best to get
used to it.
--
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/2f3d3d52-9b04-41c1-876b-3135722e0a14%40isocpp.org.
------=_Part_765_275008093.1475761007501
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Thursday, October 6, 2016 at 5:40:20 AM UTC-4, Marc Mut=
z wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0=
..8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Thursday 06 October=
2016 00:07:03 Nicol Bolas wrote:
<br>> On Wednesday, October 5, 2016 at 1:06:51 PM UTC-4, Marc Mutz wrote=
:
<br>> > On Wednesday 05 October 2016 16:13:32 'Herb Sutter' v=
ia ISO C++ Standard
<br>> >=20
<br>> > You misunderstand. The horrible thing is pair and tuple in AP=
Is
<br>>=20
<br>> The problem I find with your argument is this: even if we assume y=
ou're
<br>> right, that tuples should not be used as a way to return multiple =
values
<br>> ever, structured binding is *still a useful tool*. And we will sti=
ll want
<br>> structured binding to be extensible to user-defined types with pri=
vate
<br>> members. And that will include `pair` and `tuple`.
<br>>
<br>> The tool may encourage certain misuse; that much is true. But it i=
s far too
<br>> useful of a tool to disregard it just because of potential misuse.
<br>
<br>Ok, so I guess I still have to learn what this tool is useful for, exce=
pt=20
<br>returning pairs and tuples. Other than that, and a certain language-
<br>theoretical symmetry with function arguments, what's so crazy cool =
about=20
<br>aliasing existing names into something else? Because P0144R2 for sure d=
oesn't=20
<br>say. It focuses exclusively on the use-case of returning tuples.
<br>=C2=A0
<br>> You essentially are making a blanket statement that pairs and tupl=
es are
<br>> inherently confusing. I contest this, and you've given a perfe=
ct example of
<br>> when their meaning is well understood:
<br>>=20
<br>> typedef QPair<double, QColor> QGradientStop;
<br>>=20
<br>> Just from the name of the type and the types of the arguments (and=
of
<br>> course the associated domain knowledge), I know exactly what these=
values
<br>> mean. So when I see this:
<br>>=20
<br>> QGradientStop s =3D ...
<br>> if(get<double>(s) < dist)
<br>> {
<br>> =C2=A0 ...
<br>> }
<br>>=20
<br>> We know what it is doing.
<br>
<br>Do we? What's that double? You need to know QGradientStop's def=
inition to know=20
<br>what that double is.</blockquote><div><br>No, you don't. You just h=
ave to think about it and know what a gradient stop is conceptually.<br><br=
>A "gradient" represents a gradual change between two or more loc=
ations, commonly called "stops". Therefore, each such "stop&=
quot; must have two values: a position and the color at that position. The =
type `double` is certainly not a color, so by process of elimination, it mu=
st be the position.<br><br></div><blockquote class=3D"gmail_quote" style=3D=
"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex=
;">And what do you do in this case:
<br>
<br>=C2=A0 =C2=A0struct GammaCorrectionStop {
<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0uchar from;
<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0uchar to;
<br>=C2=A0 =C2=A0};
<br>
<br>?<br></blockquote><div><br>... I'm not sure I understand what that =
case is supposed to represent. Nobody is suggesting the wholesale replaceme=
nt of all structs with tuples. Nobody is suggesting that every two-member s=
truct should be replaced with a pair of two types. Indeed, I thought I made=
it quite clear that not all tuple usage is reasonably clear.<br><br>I'=
m simply arguing against your idea that all `tuple` use is a priori bad.<br=
><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
> There's a lot of space between "not good" and "bad.=
" And in many cases,
<br>> pair/tuple use, while "not good", doesn't descend to=
the level of "bad".
<br>>=20
<br>> And that's good enough.
<br>
<br>But is "good enough" good enough a reason to add it to the st=
andard?</blockquote><div><br><div style=3D"background-color: rgb(250, 250, =
250); border-color: rgb(187, 187, 187); border-style: solid; border-width: =
1px; overflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"prett=
yprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D=
"styled-by-prettify">for</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">auto</span><span style=3D"color: #660;" class=3D"styled-by-prettify">[=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">x</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> y</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">]</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">:</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> zip</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">vec=
tor1</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> vector2</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">))</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">...</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br></span></div></code></div><br>The ability to do that <i>=
alone</i> justifies the feature. `zip` here combines the given ranges into =
a single range over a tuple of values. Which of course goes back to Matt=
9;s point about the utility of tuples in generic contexts.<br><br>Is this c=
ode hard to understand? Is it difficult to know what the return of that `zi=
p` range will be? Or what the return of a zip iterator will be? No; so long=
as you know what `zip` does, this code is quite readable.<br>=C2=A0</div><=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;">We have=20
<br>bind, then came lambdas. Some bind expressions still look better than t=
heir=20
<br>corresponding lambda equivalents, as do some Boost.Lambda expressions, =
btw,=20
<br>but by and large, bind() and Boost.Lambda are dead with C++14 polymorph=
ic=20
<br>lambdas.
<br>
<br>It seems to me that the same will be true of tuples and structured bind=
ings=20
<br>once C++ gets the missing pieces: data member generation from template =
packs=20
<br>(as part of reflection?), structs declared within the function declarat=
ion,=20
<br>maybe Herb's multiple return values,...<br></blockquote><div><br>If=
C++20 gets designated initializers, then it becomes possible to have named=
parameters for functions by using a struct:<br><br><div style=3D"backgroun=
d-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style=
: solid; border-width: 1px; overflow-wrap: break-word;" class=3D"prettyprin=
t"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D=
"color: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">params</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br>=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">int</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> x</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">int</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> y</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> z </span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify">2</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color:=
#008;" class=3D"styled-by-prettify">void</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> func</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">params</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> p</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
><br>func</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(=
{.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">x </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">...,</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">.</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">y </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">...})=
;</span></div></code></div><br>Does that mean that <i>every function</i> wi=
ll start taking a single struct and force you to write that? Of course not.=
It will only be done for functions where the number of parameters is large=
, functions which have a lot of defaults, or functions which it would other=
wise be more confusing to take parameters directly than to use named parame=
ters of a struct.<br><br>The same goes for returning a tuple vs. a struct. =
There are cases where returning a `tuple` is sufficiently self-documenting =
as to its meaning. And there are cases where it is not. So even if we have =
the ability to put a struct in a function's return type, people will st=
ill return `tuple`s.<br><br>Let's say we added the ability to make this=
code work:<br><br><div style=3D"background-color: rgb(250, 250, 250); bord=
er-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; overf=
low-wrap: break-word;" class=3D"prettyprint"><code class=3D"prettyprint"><d=
iv class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by=
-prettify">template</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify"><</span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">typename</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">...</spa=
n><span style=3D"color: #606;" class=3D"styled-by-prettify">Ts</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">></span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">zip_range</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify"><</span><span style=3D"color: #606;" class=3D"styled-b=
y-prettify">Ts</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">></span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">&</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">ranges</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">...;}</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> zip</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #=
606;" class=3D"styled-by-prettify">Ts</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">&&</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">...</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">ts</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">{...}</span></d=
iv></code></div><br>And on the receiving end:<br><br><div style=3D"backgrou=
nd-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-styl=
e: solid; border-width: 1px; overflow-wrap: break-word;" class=3D"prettypri=
nt"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=
=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> z_ranges </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> zip</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">vector1</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> vector2</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>z_ranges</span><span style=3D"color: #660;" class=3D"styled-by-prettify">.=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">ranges</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">[</span><span =
style=3D"color: #066;" class=3D"styled-by-prettify">0</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">];</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #800;" cla=
ss=3D"styled-by-prettify">//represents vector1</span></div></code></div><br=
>How is that any more clear to the reader than:<br><br><div style=3D"backgr=
ound-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-st=
yle: solid; border-width: 1px; overflow-wrap: break-word;" class=3D"prettyp=
rint"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=
=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> z_ranges </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> zip</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">vector1</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> vector2</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
></span><span style=3D"color: #008;" class=3D"styled-by-prettify">get</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify"><</span><span=
style=3D"color: #066;" class=3D"styled-by-prettify">0</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">>(</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">z_ranges</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #800;" class=3D"=
styled-by-prettify">//Represents vector1</span></div></code></div><br>There=
's no magical reflection that can give the struct version knowledge tha=
t the first index corresponds to a parameter who's argument comes from =
a variable named `vector1`. There is no way that `zip` can <i>possibly</i> =
give the members of its return value a semantic name. These values <i>only =
exist</i> as positions relative to the positions of the inputs. Only the ca=
ller knows what the meaning of the inputs is, so only the caller can know w=
hat the meaning of the outputs will be. So there's no advantage to usin=
g a struct instead of a tuple.<br><br>Returning `tuple`s is not going away.=
As metaprogramming techniques become easier to use, so too will `tuple`s b=
ecome more commonly used. Best to get used to it.</div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/2f3d3d52-9b04-41c1-876b-3135722e0a14%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/2f3d3d52-9b04-41c1-876b-3135722e0a14=
%40isocpp.org</a>.<br />
------=_Part_765_275008093.1475761007501--
------=_Part_764_373870578.1475761007500--
.
Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Thu, 6 Oct 2016 08:51:01 -0700
Raw View
--001a113f5c18bd6ffe053e34428b
Content-Type: text/plain; charset=UTF-8
On Thu, Oct 6, 2016 at 5:42 AM, TONGARI J <tongari95@gmail.com> wrote:
> On Thursday, October 6, 2016 at 5:40:20 PM UTC+8, Marc Mutz wrote:
>
> [...]
>
> It seems to me that the same will be true of tuples and structured
>> bindings
>> once C++ gets the missing pieces: data member generation from template
>> packs
>> (as part of reflection?), structs declared within the function
>> declaration,
>> maybe Herb's multiple return values,...
>>
>
> I have no idea how the multiple return values that Herb mentioned will
> differ from SB. A language that has built-in support for multiple return
> values
>
I agree. I thought about this a lot when I first started working on Regular
void (for in-depth discussion as to why this came up, you'd have to look at
the Regular void paper or the initial std-future-proposals discussion).
Basically, any worthwhile multiple-return-value facility in C++ would be
equivalent in functionality to tuples. The reason for this is that for such
return values to be useful in generic code (or even non-generic code),
you'd want that *pack* of results to itself be a first-class object that
can be held or forwarded along as a single object. A quick example of why
"multiple return values" should be able to be used as a single object,
consider something like
std::future<decltype(some_function_returning_multiple_values())>. Should
this work? I'd certainly hope so. This very entity comes up frequently if
you wish to execute a function asynchronously and refer to the result via a
future. There are various answers to what the decltype there should yield:
a library-level tuple, one of Mike Spertus's parameter pack objects, an
actual parameter-pack of multiple types (in other words, a comma separated
list of types passed as separate parameters), an error, etc.. Of those
options, the ones that end up being most-useful are a tuple-like type or a
single parameter pack object. Put another way, either a library-level tuple
or a language-level tuple. Other solutions only end up making the facility
not very practical. In either case (or the struct case), I'd expect
structured bindings to work at the call-site.
And again, the language will always have a need for library-level or
language-level tuple types with unnamed elements, and similarly for
library-level or language-level variants with unnamed alternatives. These
are necessary any time the number of elements/alternatives are known at
compile-time, but are, for instance, dependent on a template parameter. If
used correctly, the fact that the elements/alternatives do not have
individual names is as much of a "problem" as the elements of any
std::vector or of any std::array not having individual names. That isn't to
say that sometimes tuples are misused in places where a struct would be
better -- that's certainly true, and even so in the standard library. The
necessity for such algebraic types is still there, though, and with respect
to structured bindings, the facility is useful whether that is acknowledged
or not.
--
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/CANh8DEnqePPzAUgBGnST3aDEEyb05fwTvLtThU7z6AUuqbBKwQ%40mail.gmail.com.
--001a113f5c18bd6ffe053e34428b
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
hu, Oct 6, 2016 at 5:42 AM, TONGARI J <span dir=3D"ltr"><<a href=3D"mail=
to:tongari95@gmail.com" target=3D"_blank">tongari95@gmail.com</a>></span=
> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bo=
rder-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Thursday, Oc=
tober 6, 2016 at 5:40:20 PM UTC+8, Marc Mutz wrote:<div><br></div><div>[...=
]=C2=A0</div><span class=3D""><div><br></div><blockquote class=3D"gmail_quo=
te" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-=
left:1ex">It seems to me that the same will be true of tuples and structure=
d bindings=20
<br>once C++ gets the missing pieces: data member generation from template =
packs=20
<br>(as part of reflection?), structs declared within the function declarat=
ion,=20
<br>maybe Herb's multiple return values,...
<br></blockquote><div><br></div></span><div style=3D"font-family:arial,sans=
-serif;font-size:small">I have no idea how the multiple return values that =
Herb mentioned will differ from SB. A language that has built-in support fo=
r multiple return values</div></div></blockquote><div><br></div><div>I agre=
e. I thought about this a lot when I first started working on Regular void =
(for in-depth discussion as to why this came up, you'd have to look at =
the Regular void paper or the initial std-future-proposals discussion). Bas=
ically, any worthwhile multiple-return-value facility in C++ would be equiv=
alent in functionality to tuples. The reason for this is that for such retu=
rn values to be useful in generic code (or even non-generic code), you'=
d want that *pack* of results to itself be a first-class object that can be=
held or forwarded along as a single object. A quick example of why "m=
ultiple return values" should be able to be used as a single object, c=
onsider something like std::future<decltype(some_function_returning_mult=
iple_values())>. Should this work? I'd certainly hope so. This very =
entity comes up frequently if you wish to execute a function asynchronously=
and refer to the result via a future. There are various answers to what th=
e decltype there should yield: a library-level tuple, one of Mike Spertus&#=
39;s parameter pack objects, an actual parameter-pack of multiple types (in=
other words, a comma separated list of types passed as separate parameters=
), an error, etc.. Of those options, the ones that end up being most-useful=
are a tuple-like type or a single parameter pack object. Put another way, =
either a library-level tuple or a language-level tuple. Other solutions onl=
y end up making the facility not very practical. In either case (or the str=
uct case), I'd expect structured bindings to work at the call-site.</di=
v><div><br></div><div>And again, the language will always have a need for l=
ibrary-level or language-level tuple types with unnamed elements, and simil=
arly for library-level or language-level variants with unnamed alternatives=
.. These are necessary any time the number of elements/alternatives are know=
n at compile-time, but are, for instance, dependent on a template parameter=
.. If used correctly, the fact that the elements/alternatives do not have in=
dividual names is as much of a "problem" as the elements of any s=
td::vector or of any std::array not having individual names. That isn't=
to say that sometimes tuples are misused in places where a struct would be=
better -- that's certainly true, and even so in the standard library. =
The necessity for such algebraic types is still there, though, and with res=
pect to structured bindings, the facility is useful whether that is acknowl=
edged or not.</div></div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CANh8DEnqePPzAUgBGnST3aDEEyb05fwTvLtT=
hU7z6AUuqbBKwQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANh8DEnqePPzAUgB=
GnST3aDEEyb05fwTvLtThU7z6AUuqbBKwQ%40mail.gmail.com</a>.<br />
--001a113f5c18bd6ffe053e34428b--
.
Author: Farid Mehrabi <farid.mehrabi@gmail.com>
Date: Thu, 6 Oct 2016 19:52:00 +0330
Raw View
--001a113ef85cea9d51053e34b3b8
Content-Type: text/plain; charset=UTF-8
My understanding is that from the OP's perspective, built-in tuple or some
similar feature would address broader range of solutions than SB and
involves less burden on the syntax. But at the same time, lack of multiple
return is an obstacle against proper use of ranges in 'for' loops. Am I
correct?
regards,
FM.
2016-10-06 19:21 GMT+03:30 'Matt Calabrese' via ISO C++ Standard - Future
Proposals <std-proposals@isocpp.org>:
> On Thu, Oct 6, 2016 at 5:42 AM, TONGARI J <tongari95@gmail.com> wrote:
>
>> On Thursday, October 6, 2016 at 5:40:20 PM UTC+8, Marc Mutz wrote:
>>
>> [...]
>>
>> It seems to me that the same will be true of tuples and structured
>>> bindings
>>> once C++ gets the missing pieces: data member generation from template
>>> packs
>>> (as part of reflection?), structs declared within the function
>>> declaration,
>>> maybe Herb's multiple return values,...
>>>
>>
>> I have no idea how the multiple return values that Herb mentioned will
>> differ from SB. A language that has built-in support for multiple return
>> values
>>
>
> I agree. I thought about this a lot when I first started working on
> Regular void (for in-depth discussion as to why this came up, you'd have to
> look at the Regular void paper or the initial std-future-proposals
> discussion). Basically, any worthwhile multiple-return-value facility in
> C++ would be equivalent in functionality to tuples. The reason for this is
> that for such return values to be useful in generic code (or even
> non-generic code), you'd want that *pack* of results to itself be a
> first-class object that can be held or forwarded along as a single object.
> A quick example of why "multiple return values" should be able to be used
> as a single object, consider something like std::future<decltype(some_
> function_returning_multiple_values())>. Should this work? I'd certainly
> hope so. This very entity comes up frequently if you wish to execute a
> function asynchronously and refer to the result via a future. There are
> various answers to what the decltype there should yield: a library-level
> tuple, one of Mike Spertus's parameter pack objects, an actual
> parameter-pack of multiple types (in other words, a comma separated list of
> types passed as separate parameters), an error, etc.. Of those options, the
> ones that end up being most-useful are a tuple-like type or a single
> parameter pack object. Put another way, either a library-level tuple or a
> language-level tuple. Other solutions only end up making the facility not
> very practical. In either case (or the struct case), I'd expect structured
> bindings to work at the call-site.
>
> And again, the language will always have a need for library-level or
> language-level tuple types with unnamed elements, and similarly for
> library-level or language-level variants with unnamed alternatives. These
> are necessary any time the number of elements/alternatives are known at
> compile-time, but are, for instance, dependent on a template parameter. If
> used correctly, the fact that the elements/alternatives do not have
> individual names is as much of a "problem" as the elements of any
> std::vector or of any std::array not having individual names. That isn't to
> say that sometimes tuples are misused in places where a struct would be
> better -- that's certainly true, and even so in the standard library. The
> necessity for such algebraic types is still there, though, and with respect
> to structured bindings, the facility is useful whether that is acknowledged
> or not.
>
> --
> 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/CANh8DEnqePPzAUgBGnST3aDEEyb05
> fwTvLtThU7z6AUuqbBKwQ%40mail.gmail.com
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANh8DEnqePPzAUgBGnST3aDEEyb05fwTvLtThU7z6AUuqbBKwQ%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>
--
how am I supposed to end the twisted road of your hair in such a dark
night??
unless the candle of your face does shed some light upon my way!!!
--
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/CALDL7dFpG2zkX%2BpcyeaoZvL_45CqNRt%2B-s%2Bxm0zLUoGB5Po%3D-Q%40mail.gmail.com.
--001a113ef85cea9d51053e34b3b8
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"rtl"><div class=3D"gmail_default" style=3D"font-family:arial na=
rrow,sans-serif;font-size:large" dir=3D"ltr">My understanding is that from =
the OP's perspective, built-in tuple or some similar feature would addr=
ess broader range of solutions than SB and involves less burden on the synt=
ax. But at the same time, lack of multiple return is an obstacle against pr=
oper use of ranges in 'for' loops. Am I correct?</div><div class=3D=
"gmail_default" style=3D"text-align:right;font-family:"arial narrow&qu=
ot;,sans-serif;font-size:large" dir=3D"ltr">regards,</div><div class=3D"gma=
il_default" style=3D"text-align:right;font-family:"arial narrow",=
sans-serif;font-size:large" dir=3D"ltr">FM.</div></div><div class=3D"gmail_=
extra"><br><div class=3D"gmail_quote"><div dir=3D"ltr">2016-10-06 19:21 GMT=
+03:30 'Matt Calabrese' via ISO C++ Standard - Future Proposals <sp=
an dir=3D"ltr"><<a href=3D"mailto:std-proposals@isocpp.org" target=3D"_b=
lank">std-proposals@isocpp.org</a>></span>:</div><blockquote class=3D"gm=
ail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quo=
te"><span class=3D"">On Thu, Oct 6, 2016 at 5:42 AM, TONGARI J <span dir=3D=
"ltr"><<a href=3D"mailto:tongari95@gmail.com" target=3D"_blank">tongari9=
5@gmail.com</a>></span> wrote:<br><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div di=
r=3D"ltr">On Thursday, October 6, 2016 at 5:40:20 PM UTC+8, Marc Mutz wrote=
:<div><br></div><div>[...]=C2=A0</div><span><div><br></div><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc =
solid;padding-left:1ex">It seems to me that the same will be true of tuples=
and structured bindings=20
<br>once C++ gets the missing pieces: data member generation from template =
packs=20
<br>(as part of reflection?), structs declared within the function declarat=
ion,=20
<br>maybe Herb's multiple return values,...
<br></blockquote><div><br></div></span><div style=3D"font-family:arial,sans=
-serif;font-size:small">I have no idea how the multiple return values that =
Herb mentioned will differ from SB. A language that has built-in support fo=
r multiple return values</div></div></blockquote><div><br></div></span><div=
>I agree. I thought about this a lot when I first started working on Regula=
r void (for in-depth discussion as to why this came up, you'd have to l=
ook at the Regular void paper or the initial std-future-proposals discussio=
n). Basically, any worthwhile multiple-return-value facility in C++ would b=
e equivalent in functionality to tuples. The reason for this is that for su=
ch return values to be useful in generic code (or even non-generic code), y=
ou'd want that *pack* of results to itself be a first-class object that=
can be held or forwarded along as a single object. A quick example of why =
"multiple return values" should be able to be used as a single ob=
ject, consider something like std::future<decltype(some_<wbr>function_re=
turning_multiple_<wbr>values())>. Should this work? I'd certainly ho=
pe so. This very entity comes up frequently if you wish to execute a functi=
on asynchronously and refer to the result via a future. There are various a=
nswers to what the decltype there should yield: a library-level tuple, one =
of Mike Spertus's parameter pack objects, an actual parameter-pack of m=
ultiple types (in other words, a comma separated list of types passed as se=
parate parameters), an error, etc.. Of those options, the ones that end up =
being most-useful are a tuple-like type or a single parameter pack object. =
Put another way, either a library-level tuple or a language-level tuple. Ot=
her solutions only end up making the facility not very practical. In either=
case (or the struct case), I'd expect structured bindings to work at t=
he call-site.</div><div><br></div><div>And again, the language will always =
have a need for library-level or language-level tuple types with unnamed el=
ements, and similarly for library-level or language-level variants with unn=
amed alternatives. These are necessary any time the number of elements/alte=
rnatives are known at compile-time, but are, for instance, dependent on a t=
emplate parameter. If used correctly, the fact that the elements/alternativ=
es do not have individual names is as much of a "problem" as the =
elements of any std::vector or of any std::array not having individual name=
s. That isn't to say that sometimes tuples are misused in places where =
a struct would be better -- that's certainly true, and even so in the s=
tandard library. The necessity for such algebraic types is still there, tho=
ugh, and with respect to structured bindings, the facility is useful whethe=
r that is acknowledged or not.</div></div></div></div><span class=3D"">
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></span>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CANh8DEnqePPzAUgBGnST3aDEEyb05fwTvLtT=
hU7z6AUuqbBKwQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
target=3D"_blank">https://groups.google.com/a/<wbr>isocpp.org/d/msgid/std-=
<wbr>proposals/<wbr>CANh8DEnqePPzAUgBGnST3aDEEyb05<wbr>fwTvLtThU7z6AUuqbBKw=
Q%40mail.<wbr>gmail.com</a>.<br>
</blockquote></div><br><br clear=3D"all"><div><br></div>-- <br><div class=
=3D"gmail_signature" data-smartmail=3D"gmail_signature"><div dir=3D"rtl"><d=
iv><div dir=3D"ltr">how am I supposed to end the twisted road of=C2=A0 your=
hair in such a dark night??<br>unless the candle of your face does shed so=
me light upon my way!!!<br></div></div></div></div>
</div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CALDL7dFpG2zkX%2BpcyeaoZvL_45CqNRt%2B=
-s%2Bxm0zLUoGB5Po%3D-Q%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALDL7dFp=
G2zkX%2BpcyeaoZvL_45CqNRt%2B-s%2Bxm0zLUoGB5Po%3D-Q%40mail.gmail.com</a>.<br=
/>
--001a113ef85cea9d51053e34b3b8--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 6 Oct 2016 10:57:26 -0700 (PDT)
Raw View
------=_Part_760_1246758082.1475776646348
Content-Type: multipart/alternative;
boundary="----=_Part_761_934834994.1475776646348"
------=_Part_761_934834994.1475776646348
Content-Type: text/plain; charset=UTF-8
On Thursday, October 6, 2016 at 12:22:48 PM UTC-4, Farid Mehrabi wrote:
>
> My understanding is that from the OP's perspective, built-in tuple or some
> similar feature would address broader range of solutions than SB and
> involves less burden on the syntax.
>
The fundamental difference between a "tuple" and a "struct" is that
elements of the former don't have names; they only have positions and
types. If tuples were built-in, it would simply be a language feature
rather than a library feature. So you might be able to access the elements
with more natural syntax than `get<0>`, but you'd still be using `0` rather
than `name`. The OP isn't talking about built-in tuples; he's talking about
making it easier to define one-off structs for MRV returning.
What the OP is essentially arguing is that returning objects with named
members is always the correct solution to the MRV problem. And given that
assumption, there's no point in using structured binding.
I find neither of these positions to be particularly compelling. I agree
that tuples and pairs can be (have been, and currently are) misused. But
there are places where tuples are very appropriate and cannot reasonably be
replaced by `structs` (at least, not in any way that is an improvement).
Structured binding is extremely useful when used in tandem with tuples of
that sort. And the fact that a tool can be misused cannot by itself
override the good that this tool can do.
Will structured binding make people use tuple types in places where a
genuine struct would be more appropriate? Yes. But it encourages plenty of
appropriate tuple use as well. And even if we do get unnamed struct
returning, we *will still use* structured binding to catch those multiple
return values.
But at the same time, lack of multiple return is an obstacle against proper
> use of ranges in 'for' loops. Am I correct?
>
--
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/19e2e672-80cf-4f89-8c0c-1515dac7a217%40isocpp.org.
------=_Part_761_934834994.1475776646348
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Thursday, October 6, 2016 at 12:22:48 PM UTC-4, Farid M=
ehrabi wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"rtl">=
<div style=3D"font-family:arial narrow,sans-serif;font-size:large" dir=3D"l=
tr">My understanding is that from the OP's perspective, built-in tuple =
or some similar feature would address broader range of solutions than SB an=
d involves less burden on the syntax.</div></div></blockquote><div><br>The =
fundamental difference between a "tuple" and a "struct"=
is that elements of the former don't have names; they only have positi=
ons and types. If tuples were built-in, it would simply be a language featu=
re rather than a library feature. So you might be able to access the elemen=
ts with more natural syntax than `get<0>`, but you'd still be usi=
ng `0` rather than `name`. The OP isn't talking about built-in tuples; =
he's talking about making it easier to define one-off structs for MRV r=
eturning.<br><br>What the OP is essentially arguing is that returning objec=
ts with named members is always the correct solution to the MRV problem. An=
d given that assumption, there's no point in using structured binding.<=
br><br>I find neither of these positions to be particularly compelling. I a=
gree that tuples and pairs can be (have been, and currently are) misused. B=
ut there are places where tuples are very appropriate and cannot reasonably=
be replaced by `structs` (at least, not in any way that is an improvement)=
.. Structured binding is extremely useful when used in tandem with tuples of=
that sort. And the fact that a tool can be misused cannot by itself overri=
de the good that this tool can do.<br><br>Will structured binding make peop=
le use tuple types in places where a genuine struct would be more appropria=
te? Yes. But it encourages plenty of appropriate tuple use as well. And eve=
n if we do get unnamed struct returning, we <i>will still use</i> structure=
d binding to catch those multiple return values.<br><br></div><blockquote c=
lass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px=
#ccc solid;padding-left: 1ex;"><div dir=3D"rtl"><div style=3D"font-family:=
arial narrow,sans-serif;font-size:large" dir=3D"ltr"> But at the same time,=
lack of multiple return is an obstacle against proper use of ranges in =
9;for' loops. Am I correct?<br></div></div></blockquote></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/19e2e672-80cf-4f89-8c0c-1515dac7a217%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/19e2e672-80cf-4f89-8c0c-1515dac7a217=
%40isocpp.org</a>.<br />
------=_Part_761_934834994.1475776646348--
------=_Part_760_1246758082.1475776646348--
.
Author: FrankHB1989 <frankhb1989@gmail.com>
Date: Sun, 9 Oct 2016 21:03:07 -0700 (PDT)
Raw View
------=_Part_999_295966724.1476072188052
Content-Type: multipart/alternative;
boundary="----=_Part_1000_1839779545.1476072188052"
------=_Part_1000_1839779545.1476072188052
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
=E5=9C=A8 2016=E5=B9=B410=E6=9C=886=E6=97=A5=E6=98=9F=E6=9C=9F=E5=9B=9B UTC=
+8=E4=B8=8B=E5=8D=885:40:20=EF=BC=8CMarc Mutz=E5=86=99=E9=81=93=EF=BC=9A
>
> On Thursday 06 October 2016 00:07:03 Nicol Bolas wrote:=20
>
> But is "good enough" good enough a reason to add it to the standard? We=
=20
> have=20
> bind, then came lambdas. Some bind expressions still look better than=20
> their=20
> corresponding lambda equivalents, as do some Boost.Lambda expressions,=20
> btw,=20
> but by and large, bind() and Boost.Lambda are dead with C++14 polymorphic=
=20
> lambdas.=20
>
> No, even polymorphic lambda expressions can't replace `bind` totally, for=
:
1. Duplicated placeholders.
2. Nested bind expressions (subtle different in boost and std, not=20
considered good practice).
3. More importantly, proper abstraction. There are cases where bind=20
expressions are more preferred than lambda expressions. Bind expression=20
without differences above are essentially forms of partial function=20
application. They can be *implemented *with or without lambda expressions,=
=20
but the latter is in the implementation detail. For cases where bind=20
expressions are enough, instead using lambda expressions directly is=20
unnecessarily relying on the leaky abstraction. (Ideally, for typical=20
environments, bind expressions should also be optimized builtins like=20
std::index_sequence.)
=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/742d0246-36fe-4a20-853f-9cf7cf3035b8%40isocpp.or=
g.
------=_Part_1000_1839779545.1476072188052
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>=E5=9C=A8 2016=E5=B9=B410=E6=9C=886=E6=97=A5=E6=98=
=9F=E6=9C=9F=E5=9B=9B UTC+8=E4=B8=8B=E5=8D=885:40:20=EF=BC=8CMarc Mutz=E5=
=86=99=E9=81=93=EF=BC=9A<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Thu=
rsday 06 October 2016 00:07:03 Nicol Bolas wrote:
<br>
<br>But is "good enough" good enough a reason to add it to the st=
andard? We have=20
<br>bind, then came lambdas. Some bind expressions still look better than t=
heir=20
<br>corresponding lambda equivalents, as do some Boost.Lambda expressions, =
btw,=20
<br>but by and large, bind() and Boost.Lambda are dead with C++14 polymorph=
ic=20
<br>lambdas.
<br>
<br></blockquote><div>No, even polymorphic lambda expressions can't rep=
lace `bind` totally, for:<br>1. Duplicated placeholders.<br>2. Nested bind =
expressions (subtle different in boost and std, not considered good practic=
e).<br>3. More importantly, proper abstraction. There are cases where bind =
expressions are more preferred than lambda expressions. Bind expression wit=
hout differences above are essentially forms of partial function applicatio=
n. They can be <i>implemented </i>with or without lambda expressions, but t=
he latter is in the implementation detail. For cases where bind expressions=
are enough, instead using lambda expressions directly is unnecessarily rel=
ying on the leaky abstraction. (Ideally, for typical environments, bind exp=
ressions should also be optimized builtins like std::index_sequence.)<br><b=
r><br><br>=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" 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/742d0246-36fe-4a20-853f-9cf7cf3035b8%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/742d0246-36fe-4a20-853f-9cf7cf3035b8=
%40isocpp.org</a>.<br />
------=_Part_1000_1839779545.1476072188052--
------=_Part_999_295966724.1476072188052--
.