Topic: RFC: Unpacking tuples to value sequences


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 18 Jan 2016 16:38:01 -0500
Raw View
This is a multi-part message in MIME format.
--------------040701080604080000030303
Content-Type: text/plain; charset=UTF-8

Okay, after Vicente convinced me I should write this, I present to you
the start of a paper proposing a '[*]' operator (not pushed yet, and
just .rst for now; sorry).

The general gist is:

  struct Datum { int id; double value; };

  auto d1 = Datum{42, 2.7};
  auto d2 = Datum{[*]d1};
  foo([*]d1, [*]d2);

  // equivalent to:
  auto d2 = Datum{get<0>(d1), get<1>(d2)};
  foo(get<0>(d1), get<1>(d1), get<0>(d2), get<1>(d2));

(Yes, the first case is silly; it's more interesting if instead of a
Datum in both cases, the second was a different but layout-compatible
type. The paper has a somewhat better version of the example.)

As described in the paper, there is at least one use case for this
language feature that cannot be (easily) accomplished otherwise:

  template <type T>
  foo(T const& tuple_like)
  {
    new Bar{next_id(), [*]tuple_like};
  }

If Bar cannot take a T directly (e.g. because it is an external library
type), but the 'tuple size' of T is not known, it is impossible to write
a single generic definition of foo() (and hard, or at least very
annoying, to write specializations).

I haven't written a proposed wording yet, and not sure if I will be able
to until "tuple like" is specified. (BTW, is there an official paper on
that yet?)

Comments, as always, welcome. Motivating use cases especially welcome :-).

--
Matthew

--

---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

--------------040701080604080000030303
Content-Type: text/prs.fallenstein.rst;
 name="PXXXX Value Sequence Unpacking.rst"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
 filename="PXXXX Value Sequence Unpacking.rst"

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
  Value Sequence Unpacking
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D

:Document:  PXXXX (TBD)
:Date:      2016-01-15
:Author:    Matthew Woehlke (mwoehlke.floss@gmail.com)

=2E. raw:: html

  <style>
    html { color: black; background: white; }
  </style>


Abstract
=3D=3D=3D=3D=3D=3D=3D=3D

This proposal describes a new language feature which allows tuple-like ob=
jects to be "unpacked" into a value sequence.

(Note: references made to the existing draft standard are made against N4=
567_.)

=2E. contents::


Rationale
=3D=3D=3D=3D=3D=3D=3D=3D=3D

There is an increasing push in C++ to add interoperability between values=
 and value sequences, exemplified by the recent addition of ``std::tuple`=
` and proposals such as P0144_ / P0151_, the anticipated proposal for ext=
ending the concept of "tuple-like" to arbitrary types, the existing ``std=
::experimental::apply``, and the anticipated and competing proposal to ad=
d a library based ``std::unpack`` function and corresponding ``std::unpac=
ked`` type. Similar features have long been present in other languages, w=
ith Python frequently held up as a representative example.

While we feel that P0144_ / P0151_ represent an important step in the rig=
ht direction, these proposals address only one of two facets of "unpackin=
g"; namely, unpacking as part of variable assignment. The problem of how =
to unpack a tuple-like in other contexts remains to be addressed. Possibl=
e contexts include:

=2E. code:: c++

  auto t =3D get_tuple_like();

  int a[] =3D {t...};
  auto b =3D Bar{t...};
  foo(t...);
  return {t...};

The existing ``std::experimental::apply`` is only capable of addressing t=
he third example, and only in the limited case that the tuple is exactly =
the set of arguments to be passed. The competing ``std::unpack`` proposal=
 would address the second limitation, but cannot address the first.

(The problem of what exactly constitutes a "tuple-like" also remains to b=
e addressed. However, we feel that this is out of scope for this proposal=
, and anticipate a separate proposal covering this issue.)

The ability to unpack a tuple-like into a value sequence raises many inte=
resting possibilities, but especially a degree of type amorphism. For exa=
mple, one complaint levied against PXXXX_ is that it provides no mechanis=
m for implicit conversion between different but layout-compatible aggrega=
tes. As discussed in that proposal, we believe that such an *implicit* me=
chanism would be wrong, but the lack of even an *explicit* mechanism repr=
esents an understandable reservation. Unpacking (and generalized support =
for tuple-like entities) would trivially provide such a mechanism:

=2E. code:: c++

  struct Foo { int id; double value; };
  struct Bar { int identifier; double numeric_value; };

  Foo f =3D foo();
  auto b =3D Bar{[*]f};

  // ...or even
  auto b =3D Bar{[*]foo()};

Other possibilities include trivially deserializing arguments to RPC's or=
 using ``std::any`` to type-erase a variadic argument list through part o=
f a complex call chain.

One use case that demands special attention relates to generic code. Cons=
ider a problem such as:

=2E. code:: c++

  template <typename T>
  void foo(T const& tuple_like)
  {
    bar(...); // unpack tuple_like into arguments to bar()
  }

The obvious problem here is that we do not know the "tuple size" of ``tup=
le_like``, so we cannot simply write out a list of ``get<N>(tuple_like)``=
 calls. While it may be possible here, in this simple case, to use ``std:=
:experimental::apply``, this breaks down almost immediately if the contex=
t into which we need to unpack ``tuple_like`` differs (see previous comme=
nts). While we believe it is theoretically possible to resolve this issue=
 by partially specializing on the "tuple size" of ``T``, this becomes ext=
remely awkward and verbose almost immediately, not to mention the copious=
 amounts of duplicated code.


Proposal
=3D=3D=3D=3D=3D=3D=3D=3D

We propose to add a language feature to perform unpacking in non-assignme=
nt contexts. This would conceptually be a code transformation or "syntax =
sugar", meaning that it does not allow us to do anything truly novel (alt=
hough unpacking a template-parameter type comes very close), but greatly =
simplifies the amount of code that must be written for common cases. Spec=
ifically, we propose to introduce a new prefix operator ``[*]`` which sha=
ll instruct the compiler to unpack a tuple-like "in place". For example:

=2E. code:: c++

  std::tuple<int, double> foo();
  bar(int, int, double);

  bar(42, [*]foo());

This would be equivalent to:

=2E. code:: c++

  auto&& __t =3D foo(); // compiler-internal temporary
  bar(42, get<0>(__t), get<1>(__t));

This would allow unpacking to be performed in any context where a ``,``-s=
eparated sequence of expressions is accepted:

=2E. code:: c++

  // Let t1, t2, etc. be functions returning tuples

  // Constructor arguments
  auto b =3D bar{[*]t1()};

  // Function arguments
  // Note unpacking of multiple tuples mixed with single arguments
  foo(1, 15, [*]t2(), "hello", [*]t3(), 3.14159);

  // Initializer list
  int arr[] =3D {[*]t4()};

  // Return with elided type
  return {[*]t5()};


Proposed Wording
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

=2E. TODO


Discussion
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

What syntax should be used?
---------------------------

Astute readers will notice that different syntax was used in the Rational=
e_ section than has been proposed. To some extent, we feel that the exact=
 syntax is less important than the feature as a whole. However, there are=
 a few reasons why we prefer the proposed syntax to an alternative such a=
s a trailing ``...`` operator. First, there is the potential for ambiguit=
y with "unpacking" as it relates to template argument packs, which are no=
t quite the same as tuple-like objects. Second, as noted in `Future Direc=
tions`_, we anticipate the eventual desire to be able to slice the object=
 being unpacked; addition of such syntax fits naturally with the proposed=
 syntax, but would be more difficult with ``...``. That being said, we re=
cognize that other syntaxes may be possible and equally desirable, and ar=
e open to revision in this respect.

What about a library solution?
------------------------------

As previously mentioned, we anticipate presentation of a competing propos=
al (not yet available at time of writing) providing a library-only soluti=
on to unpacking in the context of ``std::invoke``. This proposal would in=
troduce the helper ``std::unpack`` which transforms a tuple-like into a c=
orresponding type ``std::unpacked``. The problem, as we see it, with this=
 proposal is two-fold. First, the creation of an actual type raises the p=
ossibility of ambiguity; is a ``std::unpacked`` meant to be treated as a =
value sequence, or as a single container-like object? Second, and more cr=
itical, is that a library solution is vastly more limited. For instance, =
it is not possible (without resorting to some form of indirection, such a=
s ``std::invoke``) to call legacy functions with an unpacked tuple-like. =
Second, such a proposal would, at best, require complicated specification=
 of how an unpacked tuple-like is to be used in certain special contexts,=
 such as initializer lists or constructor parameters.

A language feature, implemented as a compile-time code transformation (si=
milar to range-based for), does not have these limitations. The proposed =
language feature is usable in any context where a value sequence is accep=
ted, including argument lists and initializer lists. Also, because it *is=
* a code transform, there is no "magic type" where ambiguity of intent mi=
ght be introduced.


Future Directions
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

Python supports array slicing. It seems clearly desirable that at some po=
int a tuple slicing mechanism should be added to C++ as well. While there=
 will invariably be cases where slicing must be done at run-time where a =
library solution is the best answer, creating a library solution that can=
 be evaluated at compile-time in order to use sliced tuple-likes for unpa=
cking may prove difficult. It may therefore be desirable to extend the pr=
oposed feature to include slicing support, e.g.:

=2E. code:: c++

  auto t =3D get_tuple_like();
  foo([1]t); // foo(get<1>(t));
  foo([1:3]t); // foo(get<1>(t), get<2>(t));

This could even be expanded beyond Python's modest support to allow for c=
omplex slicing and even rearranging of values:

=2E. code:: c++

  foo([1,5:7,2]t); // foo(get<1>(t), get<5>(t), get<6>(t), get<2>(t));


Acknowledgments
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

We wish to thank everyone on the ``std-proposals`` forum that has contrib=
uted (unfortunately, this idea has been marinating for a long time, and w=
e would have difficulty identifying again everyone who has contributed in=
 the past). More recently, we wish to thank Vicente J. Botet Escriba for =
submitting a competing proposal and therefore providing the motivation to=
 turn our idea into a concrete proposal.

=2E. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..=
 .. ..

=2E. _N4560: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n456=
0.pdf
=2E. _N4567: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n456=
7.pdf
=2E. _P0144: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p014=
4r0.pdf
=2E. _P0151: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p015=
1r0.pdf

=2E. TODO proper link to anonymous struct proposal (PXXXX)

=2E. |--| unicode:: U+02014 .. em dash

--------------040701080604080000030303--


.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 18 Jan 2016 15:20:18 -0800 (PST)
Raw View
------=_Part_1720_2105999007.1453159218759
Content-Type: multipart/alternative;
 boundary="----=_Part_1721_710578536.1453159218760"

------=_Part_1721_710578536.1453159218760
Content-Type: text/plain; charset=UTF-8

This is a good first try, but I think you need to go much deeper. I would
envision handling reverse-aggregate expansion *exactly* like template
parameter packs: with `...`. Which also means you get to unpack entire
expressions that use the pack.

Of course, a problem shows up. Many types are reverse-aggregate types, so
`...` could start unpacking things you don't expect. Plus, there's already
existing code that expects `...` to *not* unpack reverse aggregates. So, we
need a way to explicitly say that you want to use a specific expression as
a value sequence. That would be where a notation like `[*]` would be useful.

So, let's say you have this:


template<typename ...Args)
func(Args&& ...pack)
{
  auto rev_agg = ...; //Some reverse-aggregate.

  auto test1 = make_tuple(func(rev_agg)...); //Compile error; nothing in
the expression is a value sequence.
  auto test2 = make_tuple(func([*]rev_agg)...); //Success. Treats `rev_agg`
as though it were a parameter pack.
  auto test3 = make_tuple(func(rev_agg, pack)...); //Success. `rev_agg`
gets no special treatment. Every call to `func` gets the same `rev_agg`,
just as it would in current code.
  auto test4 = make_tuple(func([*]rev_agg, pack)...); //Success. Unpacks
both `rev_agg` and `pack`. Only works if the two are the same size, just
like for two parameter packs.
}

See what I'm getting at?

If you're going to have unpacking of tuples, it *needs* to be able to work
just like unpacking parameter packs. That makes it so much more useful.

Also, it'd be useful to build parameter packs without having to use
`make_tuple`:

auto ...stuff = {func([*]rev_agg)...};

Here, `stuff` is not a tuple. It is exactly equivalent to a template
parameter pack.

Of course, structured binding can key off of this too:

auto {x, y, z} = {func([*]rev_agg)...};

Naturally, this also means that this works too:

auto (w, u, v} = {pack...};

The goal here is to be able to control two different operations:
transforming a type into a value sequence and unpacking a value sequence.
We already have the latter, if we consider parameter packs to simply be a
special case of value sequences. We simply need syntax to turn a type into
a value sequence.

That's what `[*]` does; it turns the given expression into a value
sequence, which is a construct that works exactly like a parameter pack. So
it must be unpacked at some point, but not necessarily at the moment it is
generated.

--

---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_1721_710578536.1453159218760
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">This is a good first try, but I think you need to go much =
deeper. I would envision handling reverse-aggregate expansion <i>exactly</i=
> like template parameter packs: with `...`. Which also means you get to un=
pack entire expressions that use the pack.<br><br>Of course, a problem show=
s up. Many types are reverse-aggregate types, so `...` could start unpackin=
g things you don&#39;t expect. Plus, there&#39;s already existing code that=
 expects `...` to *not* unpack reverse aggregates. So, we need a way to exp=
licitly say that you want to use a specific expression as a value sequence.=
 That would be where a notation like `[*]` would be useful.<br><br>So, let&=
#39;s say you have this:<br><br><div class=3D"prettyprint" style=3D"backgro=
und-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-sty=
le: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"pretty=
print"><div class=3D"subprettyprint"><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled=
-by-prettify">template</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">typename</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">...</=
span><span style=3D"color: #606;" class=3D"styled-by-prettify">Args</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br>func</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #606;" class=3D"styled-by-prettify">Args</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">&amp;&amp;</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"sty=
led-by-prettify">pack</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">{</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> rev_agg </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">...;</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #800;" clas=
s=3D"styled-by-prettify">//Some reverse-aggregate.</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br><br>=C2=A0 </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> test1 </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> make_tuple</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">func</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">rev_agg</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">)...);</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">//Compi=
le error; nothing in the expression is a value sequence.</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> test2 </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> make_tuple</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">func</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">([*]</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">rev_agg</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">)...);</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">//Su=
ccess. Treats `rev_agg` as though it were a parameter pack.</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> test3 </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"> make_tuple</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">func</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">rev_agg</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
pack</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)...);=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #800;" class=3D"styled-by-prettify">//Success. `rev_agg=
` gets no special treatment. Every call to `func` gets the same `rev_agg`, =
just as it would in current code.</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> test4 </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> make_tuple</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>func</span><span style=3D"color: #660;" class=3D"styled-by-prettify">([*]<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify">rev_agg</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> pack</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: #8=
00;" class=3D"styled-by-prettify">//Success. Unpacks both `rev_agg` and `pa=
ck`. Only works if the two are the same size, just like for two parameter p=
acks.</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></span></div></c=
ode></div><br>See what I&#39;m getting at?<br><br>If you&#39;re going to ha=
ve unpacking of tuples, it <i>needs</i> to be able to work just like unpack=
ing parameter packs. That makes it so much more useful.<br><br>Also, it&#39=
;d be useful to build parameter packs without having to use `make_tuple`:<b=
r><br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 2=
50); border-color: rgb(187, 187, 187); border-style: solid; border-width: 1=
px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subpr=
ettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">...</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">stuff </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;" cl=
ass=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">func</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">([*]</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">rev_agg</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">)...};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br></span></div></code></div><br>Here, `stuff` is not a tuple. It is exactl=
y equivalent to a template parameter pack.<br><br>Of course, structured bin=
ding can key off of this too:<br><br><div class=3D"prettyprint" style=3D"ba=
ckground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); borde=
r-style: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"p=
rettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </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">,</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> y</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> z</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">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">func</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">([*]</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify">rev_agg</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">)...};</span></div></code=
></div><br>Naturally, this also means that this works too:<br><br><div clas=
s=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-col=
or: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: =
break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify">w</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> u</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> v</s=
pan><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;" class=3D"styled-by-prettify">=3D</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">pack</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">...};</span></div></code></div><br>The goal here is to be able=
 to control two different operations: transforming a type into a value sequ=
ence and unpacking a value sequence. We already have the latter, if we cons=
ider parameter packs to simply be a special case of value sequences. We sim=
ply need syntax to turn a type into a value sequence.<br><br>That&#39;s wha=
t `[*]` does; it turns the given expression into a value sequence, which is=
 a construct that works exactly like a parameter pack. So it must be unpack=
ed at some point, but not necessarily at the moment it is generated.<br></d=
iv>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

------=_Part_1721_710578536.1453159218760--
------=_Part_1720_2105999007.1453159218759--

.


Author: =?UTF-8?Q?Jens_=C3=85kerblom?= <akerblom.jens@gmail.com>
Date: Mon, 18 Jan 2016 22:41:39 -0800 (PST)
Raw View
------=_Part_3268_769495139.1453185699790
Content-Type: text/plain; charset=UTF-8

Seems similar to my idea regarding structure bindings. Look for "Structured Bindings with Variadic Templates". The base idea there is to allow you to unpack (not only tuples) like:

<code>
<auto... t> = make_tuple(foo()...);
</code>

I decided to put the proposal on ice until the structured bindings proposal has matured.

--

---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_3268_769495139.1453185699790--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Tue, 19 Jan 2016 10:21:11 -0500
Raw View
On 2016-01-19 01:41, Jens =C3=85kerblom wrote:
> Seems similar to my idea regarding structure bindings.

No, really it isn't. Structured binding and value sequence unpacking are
related, but significantly different. I tried to make that clear in the
beginning of the Rationale.

What can I say to make this clearer?

--=20
Matthew

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 19 Jan 2016 07:29:01 -0800 (PST)
Raw View
------=_Part_67_1848616644.1453217341540
Content-Type: multipart/alternative;
 boundary="----=_Part_68_1098742104.1453217341540"

------=_Part_68_1098742104.1453217341540
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Tuesday, January 19, 2016 at 10:21:25 AM UTC-5, Matthew Woehlke wrote:
>
> On 2016-01-19 01:41, Jens =C3=85kerblom wrote:=20
> > Seems similar to my idea regarding structure bindings.=20
>
> No, really it isn't. Structured binding and value sequence unpacking are=
=20
> related, but significantly different. I tried to make that clear in the=
=20
> beginning of the Rationale.=20
>
> What can I say to make this clearer?=20
>

He's talking about something he suggested earlier=20
<https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/CcOGSKE=
oQa0>,=20
which he *calls* a form of "structured binding", but it's really something=
=20
else. It's the ability to convert a tuple into a named parameter pack, via=
=20
a syntax that *looks* somewhat like structured binding.

You made some posts in that thread a month back, so you should be aware of=
=20
it.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

------=_Part_68_1098742104.1453217341540
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Tuesday, January 19, 2016 at 10:21:25 AM UTC-5, Matthew=
 Woehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2016-01-19 0=
1:41, Jens =C3=85kerblom wrote:
<br>&gt; Seems similar to my idea regarding structure bindings.
<br>
<br>No, really it isn&#39;t. Structured binding and value sequence unpackin=
g are
<br>related, but significantly different. I tried to make that clear in the
<br>beginning of the Rationale.
<br>
<br>What can I say to make this clearer?
<br></blockquote><div><br>He&#39;s talking about something <a href=3D"https=
://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/CcOGSKEoQa0">=
he suggested earlier</a>, which he <i>calls</i> a form of &quot;structured =
binding&quot;, but it&#39;s really something else. It&#39;s the ability to =
convert a tuple into a named parameter pack, via a syntax that <i>looks</i>=
 somewhat like structured binding.<br><br>You made some posts in that threa=
d a month back, so you should be aware of it.<br></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

------=_Part_68_1098742104.1453217341540--
------=_Part_67_1848616644.1453217341540--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 19 Jan 2016 07:40:26 -0800 (PST)
Raw View
------=_Part_609_521054266.1453218026371
Content-Type: multipart/alternative;
 boundary="----=_Part_610_858560864.1453218026372"

------=_Part_610_858560864.1453218026372
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Tuesday, January 19, 2016 at 1:41:40 AM UTC-5, Jens =C3=85kerblom wrote:
>
> Seems similar to my idea regarding structure bindings. Look for=20
> "Structured Bindings with Variadic Templates". The base idea there is to=
=20
> allow you to unpack (not only tuples) like:
>
> <code>
> <auto... t> =3D make_tuple(foo()...);
> </code>
>
> I decided to put the proposal on ice until the structured bindings=20
> proposal has matured.
>

 The problem with your idea is two fold:

1) It really has nothing to do with structured bindings at all. Well, it=20
may internally use the same configurable constructs to access the members=
=20
when using the value sequence. But otherwise, it doesn't really interact=20
with structured bindings. You're simply piggy-backing off the syntax with=
=20
your `<auto... t>` stuff. You could just as easily use `auto... t` instead.

2) It has the problem that I aluded to earlier in this thread: how to know=
=20
when a user meant to unpack reverse-aggregate and when the user meant to=20
pass it as a type. Your syntax cannot distinguish between what mine can.=20
Which are these cases:

tuple<int, float> f =3D ...
tuple<bool, std::string> g =3D ...

auto ...thing1 =3D func([*]f, [*]g)...;
auto ...thing2 =3D func([*]f, g)...;
auto ...thing3 =3D func(f, [*]g)...;
auto ...thing4 =3D func(f, g)...;

For `thing1`, you create a value sequence from `func(int, bool),=20
func(float, string)` calls.

For `thing2`, you create a value sequence from `func(int, tuple<bool,=20
std::string>), func(float, tuple<bool, std::string>)`calls. `thing3` is=20
quite similar, except for the values of `g`.

`thing4` is a compile error, since neither `f` nor `g`

Remember, if we allow any possible reverse-aggregate (all public members,=
=20
no virtuals) to be unpacked in expressions, then we *really* need to be=20
able to control which particular values are intended to be unpacked and=20
which are not. The `[*]` syntax is used to designate an expression to be=20
able to be unpacked as a value 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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

------=_Part_610_858560864.1453218026372
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Tuesday, January 19, 2016 at 1:41:40 AM UTC-5, Jens =C3=
=85kerblom wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Seems
 similar to my idea regarding structure bindings. Look for &quot;Structured=
=20
Bindings with Variadic Templates&quot;. The base idea there is to allow you=
=20
to unpack (not only tuples) like:<p>&lt;code&gt;<br>&lt;auto... t&gt; =3D m=
ake_tuple(foo()...);<br>&lt;/code&gt;</p><p>I decided to put the proposal o=
n ice until the structured bindings proposal has matured.<br></p></blockquo=
te><div><br>=C2=A0The problem with your idea is two fold:<br><br>1)
 It really has nothing to do with structured bindings at all. Well, it=20
may internally use the same configurable constructs to access the=20
members when using the value sequence. But otherwise, it doesn&#39;t really=
=20
interact with structured bindings. You&#39;re simply piggy-backing off the=
=20
syntax with your `&lt;auto... t&gt;` stuff. You could just as easily use
 `auto... t` instead.<br><br>2) It has the problem that I aluded to=20
earlier in this thread: how to know when a user meant to unpack=20
reverse-aggregate and when the user meant to pass it as a type. Your=20
syntax cannot distinguish between what mine can. Which are these cases:<br>=
<br><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"subpret=
typrint"><span style=3D"color: #000;" class=3D"styled-by-prettify">tuple</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">int</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">float</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> f </span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">...=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>tuple<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">bool</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">,</span><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: #008;" =
class=3D"styled-by-prettify">string</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> g </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">...<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">...</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">thing1 </span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> func</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">([*]</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">f</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;" class=3D"styled-by-prettify">[*]</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">g</span><span s=
tyle=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">auto</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">...</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">thing2 </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> func</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">([*]</span><span style=3D"color: #000;" class=3D"styled-by-prettify">f<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> g</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">)...;</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: =
#008;" class=3D"styled-by-prettify">auto</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">thing3 </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> func</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">f</span><s=
pan 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;" class=3D"styled-by-prettify">[*]</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">g</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">)...;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">..=
..</span><span style=3D"color: #000;" class=3D"styled-by-prettify">thing4 </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> func</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">f</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> g</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">)...;</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br></span></div></code></div><br>For `thing1`, you create a val=
ue sequence from `func(int, bool), func(float, string)` calls.<br><br>For
 `thing2`, you create a value sequence from `func(int, tuple&lt;bool,=20
std::string&gt;), func(float, tuple&lt;bool, std::string&gt;)`calls.=20
`thing3` is quite similar, except for the values of `g`.<br><br>`thing4` is=
 a compile error, since neither `f` nor `g`<br><br>Remember, if we allow an=
y possible reverse-aggregate (all public members, no virtuals) to be unpack=
ed in expressions, then we <i>really</i>
 need to be able to control which particular values are intended to be=20
unpacked and which are not. The `[*]` syntax is used to designate an=20
expression to be able to be unpacked as a value sequence.<br></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

------=_Part_610_858560864.1453218026372--
------=_Part_609_521054266.1453218026371--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Tue, 19 Jan 2016 11:02:05 -0500
Raw View
On 2016-01-19 10:29, Nicol Bolas wrote:
> On Tuesday, January 19, 2016 at 10:21:25 AM UTC-5, Matthew Woehlke wrote:
>> On 2016-01-19 01:41, Jens =C3=85kerblom wrote:=20
>>> Seems similar to my idea regarding structure bindings.=20
>>
>> No, really it isn't. Structured binding and value sequence unpacking are=
=20
>> related, but significantly different. I tried to make that clear in the=
=20
>> beginning of the Rationale.=20
>>
>> What can I say to make this clearer?=20
>=20
> He's talking about something he suggested earlier=20
> <https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/CcOGS=
KEoQa0>,=20
> which he *calls* a form of "structured binding", but it's really somethin=
g=20
> else. It's the ability to convert a tuple into a named parameter pack, vi=
a=20
> a syntax that *looks* somewhat like structured binding.

Yes, I found the thread again, and have some recollection of it :-).

I can understand the argument that it "isn't structured binding, per
se". Unless I am really confused, however, it's still *a* form of
binding, which is (mostly) orthogonal to my proposal, besides that they
both deal with (different aspects of) very similar concepts.

On further consideration, however, I can see where my proposal might
make the one referenced mostly irrelevant. IOW, if this:

auto {x, y, z...} =3D some_tuple;

....translated to:

  auto x =3D get<0>(some_tuple);
  auto y =3D get<1>(some_tuple);
  auto z =3D make_tuple([2:]some_tuple);

....then Jens' proposal becomes much simplified and doesn't need to
involve mucking about with parameter packs. But it would depend on mine
in order to be able to use the "trailing bits" in the same ways that
were proposed in that thread.

(Please ignore various errors and gratuitous use of novel syntax in the
above; it is just for illustrative purposes.)

> You made some posts in that thread a month back, so you should be aware o=
f=20
> it.

My comments seem to have drifted from the "variadic" part and relate to
"what is tuple-like?". (And... I mentioned this idea there, also :-).)

--=20
Matthew

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 19 Jan 2016 08:10:54 -0800 (PST)
Raw View
------=_Part_6586_1251271087.1453219855125
Content-Type: multipart/alternative;
 boundary="----=_Part_6587_1908849468.1453219855126"

------=_Part_6587_1908849468.1453219855126
Content-Type: text/plain; charset=UTF-8

I want to explain my idea a bit more rigorously, because if I do, I think
it can make it more clear what some things mean.

A *value sequence* is a sequence of expressions which can be unpacked.
Function parameter packs and non-type template parameter packs are value
sequences. Value sequences have a known length.

A *value sequence expression* is an expression involving a value sequence
and/or type/template template parameter packs. These are effectively
"patterns" in parameter pack unpacking. Any expression that acts on a value
sequence or other parameter pack becomes a value sequence expression. If
two separate value sequence expressions form a larger value sequence
expression, then both sequences must have the same length.

A value sequence expression can be stored in a name with the following
syntax:

auto... name = <value sequence expression>

`name` is itself a value sequence, which can later be used to create
further value sequence expressions.

The length of a value sequence can be determined with:

sizeof...(<value sequence>)

A value sequence expression can be unpacked into a regular expression with
the `...` syntax:

<value sequence expression>...

This creates a comma-separated expression, just as it did with pattern
unpacking in regular parameter packs. If the value sequence expression
contains type or template template parameter packs, then they too are
expanded, again as before for parameter packs.

An expression can be converted into a value sequence expression with the
value sequence conversion operator `[*]`. The type of the expression
determines the specifics of how to get the sequence of expressions when it
comes time to later unpack them. This functionality uses the same
customization point as structured binding for accessing the members of the
type, as well as getting the length of the value sequence.

Structured binding is currently defined to work on types, and that
shouldn't change. But it should also be allowed to work on value sequence
expressions:

auto {x, y, z} = args; //Function parameter pack decomposed into 3 elements.
auto {x, y, z} = unpackable; //Unpackable type stored via normal structured
binding.
auto {x, y, z} = [*]unpackable; //Value sequence stored via structured
binding. Identical to previous statement.

--

---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_6587_1908849468.1453219855126
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I want to explain my idea a bit more rigorously, because i=
f I do, I think it can make it more clear what some things mean.<br><br>A <=
u>value sequence</u> is a sequence of expressions which can be unpacked. Fu=
nction parameter packs and non-type template parameter packs are value sequ=
ences. Value sequences have a known length.<br><br>A <u>value sequence expr=
ession</u> is an expression involving a value sequence and/or type/template=
 template parameter packs. These are effectively &quot;patterns&quot; in pa=
rameter pack unpacking. Any expression that acts on a value sequence or oth=
er parameter pack becomes a value sequence expression. If two separate valu=
e sequence expressions form a larger value sequence expression, then both s=
equences must have the same length.<br><br>A value sequence expression can =
be stored in a name with the following syntax:<br><br><div class=3D"prettyp=
rint" 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"subprettyprint"><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">...</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> name </span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">value sequence expression</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">&gt;</span></div></code></div><br>`name` is itself a valu=
e sequence, which can later be used to create further value sequence expres=
sions.<br><br>The length of a value sequence can be determined with:<br><br=
><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); =
border-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; w=
ord-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyp=
rint"><span style=3D"color: #008;" class=3D"styled-by-prettify">sizeof</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">...(&lt;</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">value sequence</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;)</span><=
/div></code></div><br>A value sequence expression can be unpacked into a re=
gular expression with the `...` syntax:<br><br><div class=3D"prettyprint" s=
tyle=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 1=
87); border-style: solid; border-width: 1px; word-wrap: break-word;"><code =
class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #=
008;" class=3D"styled-by-prettify">&lt;value</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" clas=
s=3D"styled-by-prettify">sequence</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"style=
d-by-prettify">expression</span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">...</span></div></code></div><br>This creates a comma-separated ex=
pression, just as it did with pattern unpacking in regular parameter packs.=
 If the value sequence expression contains type or template template parame=
ter packs, then they too are expanded, again as before for parameter packs.=
<br><br>An expression can be converted into a value sequence expression wit=
h the value sequence conversion operator `[*]`. The type of the expression =
determines the specifics of how to get the sequence of expressions when it =
comes time to later unpack them. This functionality uses the same customiza=
tion point as structured binding for accessing the members of the type, as =
well as getting the length of the value sequence.<br><br>Structured binding=
 is currently defined to work on types, and that shouldn&#39;t change. But =
it should also be allowed to work on value sequence expressions:<br><br><di=
v class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); bord=
er-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-=
wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint=
"><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><spa=
n 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">x</span><span 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"color: #660;" class=3D"styled-b=
y-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> z</span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> args</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #800;" class=
=3D"styled-by-prettify">//Function parameter pack decomposed into 3 element=
s.</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><sp=
an 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">x</span><span 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"color: #660;" class=3D"styled-b=
y-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> z</span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> unpackable</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #800;"=
 class=3D"styled-by-prettify">//Unpackable type stored via normal structure=
d binding.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n 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">,</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> y</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> z</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">[*]</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">unpackable</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: #800;" class=
=3D"styled-by-prettify">//Value sequence stored via structured binding. Ide=
ntical to previous statement.</span></div></code></div><br></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

------=_Part_6587_1908849468.1453219855126--
------=_Part_6586_1251271087.1453219855125--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 19 Jan 2016 08:14:54 -0800 (PST)
Raw View
------=_Part_825_1916680416.1453220094576
Content-Type: multipart/alternative;
 boundary="----=_Part_826_1706372869.1453220094576"

------=_Part_826_1706372869.1453220094576
Content-Type: text/plain; charset=UTF-8

It should be noted that this changes some of my code from before:

auto {x, y, z} = {func([*]rev_agg)...};

Becomes:

auto {x, y, z} = func([*]rev_agg);

There's no need for unpacking here, since it's just a value sequence.

--

---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_826_1706372869.1453220094576
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">It should be noted that this changes some of my code from =
before:<br><br><div class=3D"prettyprint" style=3D"background-color: rgb(25=
0, 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"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">x</span><span 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"color: #660;"=
 class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> z</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">func</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">([*]</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">rev_agg</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">)...};</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br></span></div></code></div><br>Becomes:<br><=
br><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187=
,187);border-style:solid;border-width:1px;word-wrap:break-word"><code><div>=
<span style=3D"color:#008">auto</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#660">{</span><span style=3D"color:#000">x</span><span s=
tyle=3D"color:#660">,</span><span style=3D"color:#000"> y</span><span style=
=3D"color:#660">,</span><span style=3D"color:#000"> z</span><span style=3D"=
color:#660">}</span><span style=3D"color:#000"> </span><span style=3D"color=
:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#0=
00">func</span><span style=3D"color:#660">([*]</span><span style=3D"color:#=
000">rev_agg</span><span style=3D"color:#660">);</span></div></code></div><=
br>There&#39;s no need for unpacking here, since it&#39;s just a value sequ=
ence.<br></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

------=_Part_826_1706372869.1453220094576--
------=_Part_825_1916680416.1453220094576--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Tue, 19 Jan 2016 11:15:25 -0500
Raw View
On 2016-01-18 18:20, Nicol Bolas wrote:
> This is a good first try, but I think you need to go much deeper. I would
> envision handling reverse-aggregate expansion *exactly* like template
> parameter packs: with `...`. Which also means you get to unpack entire
> expressions that use the pack.
>
> Of course, a problem shows up. Many types are reverse-aggregate types, so
> `...` could start unpacking things you don't expect. Plus, there's already
> existing code that expects `...` to *not* unpack reverse aggregates. So, we
> need a way to explicitly say that you want to use a specific expression as
> a value sequence. That would be where a notation like `[*]` would be useful.

Yes, I think it needs to use some syntax other than `...` for various
reasons. Conflict with parameter packs is one. Extensibility (see Future
Directions), e.g. to slicing, is another. (Huh. And if we get that,
`[5]t` becomes syntax sugar for `get<5>(t)`, which is kinda nice...)

BTW, what is a "reverse aggregate"? I don't think I'm familiar with the
term. I am guessing you mean "tuple-like"?

> So, let's say you have this:
>
> template<typename ...Args)
> func(Args&& ...pack)
> {
>   auto rev_agg = ...; //Some reverse-aggregate.
>
>   auto test2 = make_tuple(func([*]rev_agg)...); //Success. Treats `rev_agg`
> as though it were a parameter pack.

If that works, I would expect this to work also:

  make_tuple(func(1, 2, a, b)...);

....but that seems silly, and at best should be an orthogonal proposal.
Moreover, I don't see it as worth a language change. Even though it's
considerably more verbose, this seems like a job for a transform function:

  auto temporary_tuple = std::apply_each(func, args...);
  foo([*]temporary_tuple);

....where `args...` is any expression sequence, e.g. `[*]rev_agg`.
(apply_each is a hypothetical function that takes a functor and a
parameter pack and returns a tuple where each element of the result is
the return value of the functor applied to each input value.)

IOW, if I were on the committee, I would insist on a separate rationale
why that specific example warrants a(n additional) language change
beyond my proposal as presented. Do you have such a rationale?

>   auto test4 = make_tuple(func([*]rev_agg, pack)...); //Success. Unpacks
> both `rev_agg` and `pack`. Only works if the two are the same size, just
> like for two parameter packs.

Wrong. As the proposal is currently written, the effect of the above
code is well defined to be:

  make_tuple(
    func(get<0>(rev_agg), get<1>(rev_agg), ..., pack<0>),
    func(get<0>(rev_agg), get<1>(rev_agg), ..., pack<1>),
    ...
    );

Changing the meaning in this context makes the feature much more
complicated, and precludes using it to achieve the above effect. If you
really need the effect you described, use (hypothetical) std::zip:

  auto zipped = std::zip(rev_agg, make_tuple(pack...));
  auto test4 =
    std::apply_each([](auto pair){ return func([*]pair); }, zipped);

(std::zip of course returns a tuple of pairs, where the first of each
pair is from the first tuple[-like], and the second of each pair is from
the second tuple[-like].)

> See what I'm getting at?

Yes, but I don't agree. You are suggesting to make the language feature,
which in my proposal is straight forward,

> If you're going to have unpacking of tuples, it *needs* to be able to work
> just like unpacking parameter packs. That makes it so much more useful.

I do see the utility of something like apply_each. I don't so much see
why it needs to be a language feature rather than a library feature.
Again, please provide a rationale to back up such claims.

(Note that I gave one example where achieving the same effect as with
the proposed `[*]` would be very, very hard. I don't see that for what
you are suggesting.)

> Also, it'd be useful to build parameter packs without having to use
> `make_tuple`:
>
> auto ...stuff = {func([*]rev_agg)...};
>
> Here, `stuff` is not a tuple. It is exactly equivalent to a template
> parameter pack.

See above comments. Also, this smells very much like an orthogonal
feature. Why shouldn't I be able to write:

  auto ...stuff = {12, "brown", 53.5};

....? (Actually, this feels very much like Jens' proposal...)

> Naturally, this also means that this works too:
>
> auto (w, u, v} = {pack...};

Doesn't this already work with P0144R0? Again, orthogonal!

> The goal here is to be able to control two different operations:
> transforming a type into a value sequence and unpacking a value sequence.
> We already have the latter, if we consider parameter packs to simply be a
> special case of value sequences. We simply need syntax to turn a type into
> a value sequence.
>
> That's what `[*]` does; it turns the given expression into a value
> sequence,

Right.

> which is a construct that works exactly like a parameter pack. So
> it must be unpacked at some point, but not necessarily at the moment it is
> generated.

That's not how it's proposed. I don't see the utility, and in fact, I
feel that raises the same issue as `std::unpacked`, namely, creating an
ambiguity when it *should* be unpacked, which is specifically a point I
wish to *avoid*.

I'm very tempted to take Vicente's approach here, and suggest that you
write a counter-proposal if you feel strongly about these matters.

--
Matthew

--

---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Tue, 19 Jan 2016 11:31:22 -0500
Raw View
On 2016-01-19 10:40, Nicol Bolas wrote:
> auto ...thing1 = func([*]f, [*]g)...;

I alluded to this in my other reply, but I think it bears repeating...
what does this (RHS) mean?

  - { func(f<0>, g<0>), func(f<1>, g<1>) }
  - { func(f<0>, f<1>, g<0>), func(f<0>, f<1>, g<1>) }
  - { func(f<0>, g<0>, g<1>), func(f<1>, g<0>, g<1>) }
  - func(f<0>, f<1>, g<0>, g<1>)

I could legitimately want *any* of those. Conflating concepts (template
argument packs and value sequence unpacking of tuple-likes) makes it
impossible to specify which. Not to mention that I'm not convinced the
syntax isn't overly obtuse.

If, instead, we have apply_each (and zip), I can be precise:

  - apply_each([](auto p){return func([*]p);}, [*]zip(f, g))
  - apply_each([](auto v){return func([*]f, v);}, [*]g)
  - apply_each([](auto v){return func(v, [*]g);}, [*]f)
  - func([*]f, [*]g)

Now there is no ambiguity as to my intent.

--
Matthew

--

---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 19 Jan 2016 08:44:04 -0800 (PST)
Raw View
------=_Part_6534_286162026.1453221845016
Content-Type: multipart/alternative;
 boundary="----=_Part_6535_740617807.1453221845016"

------=_Part_6535_740617807.1453221845016
Content-Type: text/plain; charset=UTF-8



On Tuesday, January 19, 2016 at 11:31:31 AM UTC-5, Matthew Woehlke wrote:
>
> On 2016-01-19 10:40, Nicol Bolas wrote:
> > auto ...thing1 = func([*]f, [*]g)...;
>
> I alluded to this in my other reply, but I think it bears repeating...
> what does this (RHS) mean?
>
>   - { func(f<0>, g<0>), func(f<1>, g<1>) }
>   - { func(f<0>, f<1>, g<0>), func(f<0>, f<1>, g<1>) }
>   - { func(f<0>, g<0>, g<1>), func(f<1>, g<0>, g<1>) }
>   - func(f<0>, f<1>, g<0>, g<1>)
>

> I could legitimately want *any* of those.


And my syntax can provide *all* of them:

func([*]f, [*]g)...;
func([*]f..., [*]g)...;
func([*]f, [*]g...)...;
func([*]f..., [*]g...);

So what's the problem?


> Conflating concepts (template
> argument packs and value sequence unpacking of tuple-likes) makes it
> impossible to specify which. Not to mention that I'm not convinced the
> syntax isn't overly obtuse.
>
> If, instead, we have apply_each (and zip), I can be precise:
>
>   - apply_each([](auto p){return func([*]p);}, [*]zip(f, g))
>   - apply_each([](auto v){return func([*]f, v);}, [*]g)
>   - apply_each([](auto v){return func(v, [*]g);}, [*]f)
>   - func([*]f, [*]g)
>
> Now there is no ambiguity as to my intent.
>

No ambiguity, perhaps. But lots and lots of heinous syntax.

--

---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_6535_740617807.1453221845016
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Tuesday, January 19, 2016 at 11:31:31 AM UTC-5,=
 Matthew Woehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2016=
-01-19 10:40, Nicol Bolas wrote:
<br>&gt; auto ...thing1 =3D func([*]f, [*]g)...;
<br>
<br>I alluded to this in my other reply, but I think it bears repeating...
<br>what does this (RHS) mean?
<br>
<br>=C2=A0 - { func(f&lt;0&gt;, g&lt;0&gt;), func(f&lt;1&gt;, g&lt;1&gt;) }
<br>=C2=A0 - { func(f&lt;0&gt;, f&lt;1&gt;, g&lt;0&gt;), func(f&lt;0&gt;, f=
&lt;1&gt;, g&lt;1&gt;) }
<br>=C2=A0 - { func(f&lt;0&gt;, g&lt;0&gt;, g&lt;1&gt;), func(f&lt;1&gt;, g=
&lt;0&gt;, g&lt;1&gt;) }
<br>=C2=A0 - func(f&lt;0&gt;, f&lt;1&gt;, g&lt;0&gt;, g&lt;1&gt;)
<br></blockquote><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>I could legitimately want *any* of those.</blockquote><div><br>And my s=
yntax can provide *all* of them:<br><br>func([*]f, [*]g)...;<br>func([*]f..=
.., [*]g)...;<br>func([*]f, [*]g...)...;<br>func([*]f..., [*]g...);<br><br>S=
o what&#39;s the problem?<br>=C2=A0</div><blockquote class=3D"gmail_quote" =
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-l=
eft: 1ex;">Conflating concepts (template
<br>argument packs and value sequence unpacking of tuple-likes) makes it
<br>impossible to specify which. Not to mention that I&#39;m not convinced =
the
<br>syntax isn&#39;t overly obtuse.
<br>
<br>If, instead, we have apply_each (and zip), I can be precise:
<br>
<br>=C2=A0 - apply_each([](auto p){return func([*]p);}, [*]zip(f, g))
<br>=C2=A0 - apply_each([](auto v){return func([*]f, v);}, [*]g)
<br>=C2=A0 - apply_each([](auto v){return func(v, [*]g);}, [*]f)
<br>=C2=A0 - func([*]f, [*]g)
<br>
<br>Now there is no ambiguity as to my intent.<br></blockquote><div><br>No =
ambiguity, perhaps. But lots and lots of heinous syntax.<br></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

------=_Part_6535_740617807.1453221845016--
------=_Part_6534_286162026.1453221845016--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Tue, 19 Jan 2016 12:10:45 -0500
Raw View
On 2016-01-19 11:44, Nicol Bolas wrote:
> On Tuesday, January 19, 2016 at 11:31:31 AM UTC-5, Matthew Woehlke wrote:
>> On 2016-01-19 10:40, Nicol Bolas wrote:
>>> auto ...thing1 = func([*]f, [*]g)...;
>>
>> I alluded to this in my other reply, but I think it bears repeating...
>> what does this (RHS) mean?
>>
>>   - { func(f<0>, g<0>), func(f<1>, g<1>) }
>>   - { func(f<0>, f<1>, g<0>), func(f<0>, f<1>, g<1>) }
>>   - { func(f<0>, g<0>, g<1>), func(f<1>, g<0>, g<1>) }
>>   - func(f<0>, f<1>, g<0>, g<1>)
>>
>> I could legitimately want *any* of those.
>
> And my syntax can provide *all* of them:
>
> func([*]f, [*]g)...;
> func([*]f..., [*]g)...;
> func([*]f, [*]g...)...;
> func([*]f..., [*]g...);

Why do I have to unpack it *twice*? Ugh...

> [...] lots and lots of heinous syntax.

I find your proposal much too complicated and severely lacking in
rationale why we need such as a *language* feature. (I have yet to see
you offer a rationale, besides "hey, wouldn't it be great if...".) As
such, I cannot support it in good conscience, and so I will reiterate my
earlier comment: If you feel strongly, I recommend that you write and
present a competing paper.

Unless you can provide a better justification, at this time I intend to
continue with my version in its current form.

--
Matthew

--

---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 19 Jan 2016 11:15:10 -0800 (PST)
Raw View
------=_Part_1014_1685240265.1453230910971
Content-Type: multipart/alternative;
 boundary="----=_Part_1015_312115754.1453230910972"

------=_Part_1015_312115754.1453230910972
Content-Type: text/plain; charset=UTF-8

On Tuesday, January 19, 2016 at 12:11:03 PM UTC-5, Matthew Woehlke wrote:
>
> On 2016-01-19 11:44, Nicol Bolas wrote:
> > On Tuesday, January 19, 2016 at 11:31:31 AM UTC-5, Matthew Woehlke
> wrote:
> >> On 2016-01-19 10:40, Nicol Bolas wrote:
> >>> auto ...thing1 = func([*]f, [*]g)...;
> >>
> >> I alluded to this in my other reply, but I think it bears repeating...
> >> what does this (RHS) mean?
> >>
> >>   - { func(f<0>, g<0>), func(f<1>, g<1>) }
> >>   - { func(f<0>, f<1>, g<0>), func(f<0>, f<1>, g<1>) }
> >>   - { func(f<0>, g<0>, g<1>), func(f<1>, g<0>, g<1>) }
> >>   - func(f<0>, f<1>, g<0>, g<1>)
> >>
> >> I could legitimately want *any* of those.
> >
> > And my syntax can provide *all* of them:
> >
> > func([*]f, [*]g)...;
> > func([*]f..., [*]g)...;
> > func([*]f, [*]g...)...;
> > func([*]f..., [*]g...);
>
> Why do I have to unpack it *twice*? Ugh...
>

Because that's *what you're doing*. Take the second case. You want to
unpack `f` within the argument list. But you want to unpack `g` *across*
`func`. That's two separate unpack steps, so it needs two separate unpack
operations.

Your mechanism is too simplified to be of *general* use. There are
legitimate reasons for people to use all of these forms, and your
particular use case(s) are not sufficiently important to force users to
resort to arbitrary other methods to get them.

We'd be better off with *no* unpacking syntax than with a half-baked one.

> [...] lots and lots of heinous syntax.
>
> I find your proposal much too complicated and severely lacking in
> rationale why we need such as a *language* feature. (I have yet to see
> you offer a rationale, besides "hey, wouldn't it be great if...".)


.... The *only part* of your proposal that absolutely needs to be a
*language* feature is the ability to unpack a tuple into a
braced-init-list. You could always create a variadic version of `apply`
that walks through the argument list and unpacks any tuples it sees. So the
only place in your proposal that absolutely needs it to be a part of the
language is braced-init-lists.

So if we're going by what absolutely cannot possibly be done without a
language feature, then your proposal is really no more motivated than mine.
Since mine also includes that, but much more.

Furthermore, if that were the standard by which features were approved, we
wouldn't have lambdas. Because there is nothing there that couldn't be done
with structs declared within the function. In-function structs couldn't
participate in template deduction in C++03, which is why they couldn't have
been used in many cases. So technically, all C++11 *had* to do was allow
them to participate like any other type. And in fact, the committee did
this. Yet they still provided lambdas anyway. Why?

Because it's a highly useful feature for a wide variety of circumstances
that makes code so much easier to write. Same goes for range-for and many
other things.

And if we continue with your logic, we should only have allowed `...` to be
applied to the pack itself, rather than to expression "patterns". After
all, we could always find ways to metaprogram around unpacking patterns. No
need to create confusion if you want to do `func(args)...` to call the
function multiple times with each argument. No, we clearly should have made
people say `broadcast(func, args...)` instead.

Yet we didn't. We allowed `...` to expand almost any expression. Why?

Because it was *exceptionally useful*.

So clearly the standard for what should be a language feature is not merely
"things that* cannot* be a library feature."

However, if you really want something that absolutely must be a language
feature, there's this: efficiency.

In a different post, I pointed out this use case:

auto test4 = make_tuple(func([*]rev_agg, pack)...);

Where `pack` is a function parameter pack. This calls `func` for each pair
of values, capturing them in a tuple.

And you said you could do it under your syntax with:

auto zipped = std::zip(rev_agg, make_tuple(pack...));
auto test4 =
  std::apply_each([](auto pair){ return func([*]pair); }, zipped);

So, step 1 is to take the elements of the function parameter pack and make
a tuple out of them. Well, that's going to copy/move some of them into a
temporary. Then, we create a tuple of pairs of those values, which
copy/moves them again. It *also* copies out of `rev_agg` for no reason. The
temporary is then destroyed.

Or you can do what I said, which will always boil down to the most
efficient code. No temporaries are created. It's just a sequence of `get<>`
calls.

Oh, and proper argument forwarding can be used:

auto test4 = make_tuple(func([*]rev_agg, forward<Args>(pack))...);

Even if you change your version to use `forward_as_tuple`, you're still
using copying out of `rev_agg`. Whereas mine just uses `get<I>` directly in
situ. No pointless lambdas, no zipping or copying. It boils down to exactly
what you want and no more.

In the best possible case, where `zip` returns a tuple of references (which
kinda breaks `forward_as_tuple`), you're still creating a needless
temporary, which takes up unnecessary room on the stack.

Your way costs both memory and runtime performance. Mine does not. Mine
doesn't make you pay for something you don't have to.

Oh, and the temporary in this case must be named. Weren't you one of those
who were saying that naming things is hard, that it's a cost we have to
pay, so we should be able to return unnamed types ;) (note: I'm not against
the temporary because it's named. I'm against it because it's taking up
space and performance. The name is irrelevant to me).

As
> such, I cannot support it in good conscience, and so I will reiterate my
> earlier comment: If you feel strongly, I recommend that you write and
> present a competing paper.
>
> Unless you can provide a better justification, at this time I intend to
> continue with my version in its current form.
>

--

---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_1015_312115754.1453230910972
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Tuesday, January 19, 2016 at 12:11:03 PM UTC-5, Matthew Woehlke wrote:<b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;">On 2016-01-19 11:44, Nicol Bolas=
 wrote:
<br>&gt; On Tuesday, January 19, 2016 at 11:31:31 AM UTC-5, Matthew Woehlke=
 wrote:
<br>&gt;&gt; On 2016-01-19 10:40, Nicol Bolas wrote:=20
<br>&gt;&gt;&gt; auto ...thing1 =3D func([*]f, [*]g)...;=20
<br>&gt;&gt;
<br>&gt;&gt; I alluded to this in my other reply, but I think it bears repe=
ating...=20
<br>&gt;&gt; what does this (RHS) mean?=20
<br>&gt;&gt;
<br>&gt;&gt; =C2=A0 - { func(f&lt;0&gt;, g&lt;0&gt;), func(f&lt;1&gt;, g&lt=
;1&gt;) }=20
<br>&gt;&gt; =C2=A0 - { func(f&lt;0&gt;, f&lt;1&gt;, g&lt;0&gt;), func(f&lt=
;0&gt;, f&lt;1&gt;, g&lt;1&gt;) }=20
<br>&gt;&gt; =C2=A0 - { func(f&lt;0&gt;, g&lt;0&gt;, g&lt;1&gt;), func(f&lt=
;1&gt;, g&lt;0&gt;, g&lt;1&gt;) }=20
<br>&gt;&gt; =C2=A0 - func(f&lt;0&gt;, f&lt;1&gt;, g&lt;0&gt;, g&lt;1&gt;)=
=20
<br>&gt;&gt;=20
<br>&gt;&gt; I could legitimately want *any* of those.
<br>&gt;=20
<br>&gt; And my syntax can provide *all* of them:
<br>&gt;=20
<br>&gt; func([*]f, [*]g)...;
<br>&gt; func([*]f..., [*]g)...;
<br>&gt; func([*]f, [*]g...)...;
<br>&gt; func([*]f..., [*]g...);
<br>
<br>Why do I have to unpack it *twice*? Ugh...
<br></blockquote><div><br>Because that&#39;s <i>what you&#39;re doing</i>. =
Take the second case. You want to unpack `f` within the argument list. But =
you want to unpack `g` <i>across</i> `func`. That&#39;s two separate unpack=
 steps, so it needs two separate unpack operations.<br><br>Your mechanism i=
s too simplified to be of <i>general</i> use. There are legitimate reasons =
for people to use all of these forms, and your particular use case(s) are n=
ot sufficiently important to force users to resort to arbitrary other metho=
ds to get them.<br><br>We&#39;d be better off with <i>no</i> unpacking synt=
ax than with a half-baked one.<br><br></div><blockquote class=3D"gmail_quot=
e" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddin=
g-left: 1ex;">
&gt; [...] lots and lots of heinous syntax.
<br>
<br>I find your proposal much too complicated and severely lacking in
<br>rationale why we need such as a *language* feature. (I have yet to see
<br>you offer a rationale, besides &quot;hey, wouldn&#39;t it be great if..=
..&quot;.)</blockquote><div><br>... The <i>only part</i> of your proposal th=
at absolutely needs to be a *language* feature is the ability to unpack a t=
uple into a braced-init-list. You could always create a variadic version of=
 `apply` that walks through the argument list and unpacks any tuples it see=
s. So the only place in your proposal that absolutely needs it to be a part=
 of the language is braced-init-lists.<br><br>So if we&#39;re going by what=
 absolutely cannot possibly be done without a language feature, then your p=
roposal is really no more motivated than mine. Since mine also includes tha=
t, but much more.<br><br>Furthermore, if that were the standard by which fe=
atures were approved, we wouldn&#39;t have lambdas. Because there is nothin=
g there that couldn&#39;t be done with structs declared within the function=
.. In-function structs couldn&#39;t participate in template deduction in C++=
03, which is why they couldn&#39;t have been used in many cases. So technic=
ally, all C++11 <i>had</i> to do was allow them to participate like any oth=
er type. And in fact, the committee did this. Yet they still provided lambd=
as anyway. Why?<br><br>Because it&#39;s a highly useful feature for a wide =
variety of circumstances that makes code so much easier to write. Same goes=
 for range-for and many other things.<br><br>And if we continue with your l=
ogic, we should only have allowed `...` to be applied to the pack itself, r=
ather than to expression &quot;patterns&quot;. After all, we could always f=
ind ways to metaprogram around unpacking patterns. No need to create confus=
ion if you want to do `func(args)...` to call the function multiple times w=
ith each argument. No, we clearly should have made people say `broadcast(fu=
nc, args...)` instead.<br><br>Yet we didn&#39;t. We allowed `...` to expand=
 almost any expression. Why?<br><br>Because it was <i>exceptionally useful<=
/i>.<br><br>So clearly the standard for what should be a language feature i=
s not merely &quot;things that<i> cannot</i> be a library feature.&quot;<br=
><br>However, if you really want something that absolutely must be a langua=
ge feature, there&#39;s this: efficiency.<br><br>In a different post, I poi=
nted out this use case:<br><br><div class=3D"prettyprint" style=3D"backgrou=
nd-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-styl=
e: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"prettyp=
rint"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> test4 </span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> make_tuple</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">func<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">([*]</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">rev_agg</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> pack</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">)...);</span></div></code></div><=
br>Where `pack` is a function parameter pack. This calls `func` for each pa=
ir of values, capturing them in a tuple.<br><br>And you said you could do i=
t under your syntax with:<br><br><div class=3D"prettyprint" style=3D"backgr=
ound-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-st=
yle: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"prett=
yprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D=
"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> zipped </span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">zip</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">rev_agg</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> make_tuple</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">pack</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">...));</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> test4 </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br>=C2=A0 std</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">apply=
_each</span><span style=3D"color: #660;" class=3D"styled-by-prettify">([](<=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> pair</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=
: #008;" class=3D"styled-by-prettify">return</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> func</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">([*]</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">pair</span><span style=3D"color: #660;" class=3D"st=
yled-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-by-prettify"> zipped=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><=
/div></code></div><br> So, step 1 is to take the elements of the function p=
arameter pack and make a tuple out of them. Well, that&#39;s going to copy/=
move some of them into a temporary. Then, we create a tuple of pairs of tho=
se values, which copy/moves them again. It <i>also</i> copies out of `rev_a=
gg` for no reason. The temporary is then destroyed.<br><br>Or you can do wh=
at I said, which will always boil down to the most efficient code. No tempo=
raries are created. It&#39;s just a sequence of `get&lt;&gt;` calls.<br><br=
>Oh, and proper argument forwarding can be used:<br><br><div class=3D"prett=
yprint" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(18=
7, 187, 187); border-style: solid; border-width: 1px; word-wrap: break-word=
;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D=
"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> test4 </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> make_tuple</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">func</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">([*]</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">rev_agg</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> for=
ward</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</=
span><span style=3D"color: #606;" class=3D"styled-by-prettify">Args</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;(</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify">pack</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">))...);</span></div></code><=
/div><br>Even if you change your version to use `forward_as_tuple`, you&#39=
;re still using copying out of `rev_agg`. Whereas mine just uses `get&lt;I&=
gt;` directly in situ. No pointless lambdas, no zipping or copying. It boil=
s down to exactly what you want and no more.<br><br>In the best possible ca=
se, where `zip` returns a tuple of references=20
(which kinda breaks `forward_as_tuple`), you&#39;re still creating a=20
needless temporary, which takes up unnecessary room on the stack.<br><br>Yo=
ur way costs both memory and runtime performance. Mine does not. Mine doesn=
&#39;t make you pay for something you don&#39;t have to.<br><br>Oh, and the=
 temporary in this case must be named. Weren&#39;t you one of those who wer=
e saying that naming things is hard, that it&#39;s a cost we have to pay, s=
o we should be able to return unnamed types ;) (note: I&#39;m not against t=
he temporary because it&#39;s named. I&#39;m against it because it&#39;s ta=
king up space and performance. The name is irrelevant to me).<br><br></div>=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;">As
<br>such, I cannot support it in good conscience, and so I will reiterate m=
y
<br>earlier comment: If you feel strongly, I recommend that you write and
<br>present a competing paper.
<br>
<br>Unless you can provide a better justification, at this time I intend to
<br>continue with my version in its current form.
<br></blockquote>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

------=_Part_1015_312115754.1453230910972--
------=_Part_1014_1685240265.1453230910971--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Tue, 19 Jan 2016 15:23:05 -0500
Raw View
On 2016-01-19 14:15, Nicol Bolas wrote:
> Your mechanism is too simplified to be of *general* use.

I disagree. I can think of immediate examples of unpacking in place (and
some have been given). I would like to see a reasonable example for:

  auto result =3D make_tuple(func([*]f..., [*]g)...);

....along with a rationale why this merits a language feature.

p.s. If we have genuine promotion of value sequences to parameter packs,
why can't we do this?

  auto&&... g_unpacked =3D g;
  auto result =3D make_tuple(func([*]f, g_unpacked)...);

This is only slightly more verbose, but doesn't make [*] unreasonably
complicated. I also can't think of why this shouldn't be equally
efficient; the compiler ought to be able to inline use of `g_unpacked`
to use `g` directly.

Or, maybe a similar syntax can be used to indicate the intent to turn a
tuple-like into a parameter pack in place. This would even be orthogonal
(or at least, in addition to) my proposal.

> There are legitimate reasons for people to use all of these forms,
> and your particular use case(s) are not sufficiently important to
> force users to resort to arbitrary other methods to get them.

I could (and will) say the same thing about your proposal.

> ... The *only part* of your proposal that absolutely needs to be a=20
> *language* feature is the ability to unpack a tuple into a=20
> braced-init-list.

I think you're severely understating the usefulness of this case. I
don't feel that being able to unpack into e.g. constructor calls is so
rare as to be so lightly glossed over.

> You could always create a variadic version of `apply`=20
> that walks through the argument list and unpacks any tuples it sees.

You can't *just* do that. You have to annotate somehow when you want
something unpacked and when you don't... which leads to Vicente's
proposal and a "magic type" that has special meaning in
std::experimental::apply / std::invoke. And also, more of that clumsy
syntax you claim to dislike so much.

> So if we're going by what absolutely cannot possibly be done without a=20
> language feature, then your proposal is really no more motivated than min=
e.=20
> Since mine also includes that, but much more.

I at least gave a motivating example (conversion between different but
layout-compatible aggregates). I'm still waiting on a realistic example
from you.

BTW, here is a random, trivially located example from real, production
code=C2=B9 where I wish I had `[*]`:

  out->SetPosition(center[0], center[1], center[2]);
  out->SetViewUp(up[0], up[1], up[2]);
  out->SetFocalPoint(focus[0], focus[1], focus[2]);

  // out->SetPosition([*]center);
  // out->SetViewUp([*]up);
  // out->SetFocalPoint([*]focus);

(=C2=B9 https://github.com/Kitware/maptk/blob/master/gui/vtkMaptkCamera.cxx=
#L70)

> [...lots more stuff...]

Fine. You Win. You have seriously trashed my motivation to work on this
proposal. Congratulations, it's now on you if we are to get this feature
at all.

I'll be waiting to see the paper you write. I'll even be happy to
critique it (I still absolutely loathe the idea of having to write both
`[*]` *and* `...` to actually use an unpacked tuple, for example; IMO
that's just absurd).

> Oh, and the temporary in this case must be named. Weren't you one of thos=
e=20
> who were saying that naming things is hard

Naming *API* is hard :-). I dub the temporary 't'. Or 't0'. Or whatever;
the names of temporar^Wlocal scratch variables don't matter the way the
names of API types do.

--=20
Matthew

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Wed, 20 Jan 2016 00:08:00 +0100
Raw View
Le 18/01/2016 22:38, Matthew Woehlke a =C3=A9crit :
> Okay, after Vicente convinced me I should write this, I present to you
> the start of a paper proposing a '[*]' operator (not pushed yet, and
> just .rst for now; sorry).
Hi, not that I'm against your proposal, but I believe you will need to=20
justify why this operator that IMHO is almost equivalent to=20
unpack()/unpacked<T> is more important than one that could replace=20
ref()/reference_wrapper<T>. The goals for both (ref and unpack) are=20
similar and the library solution limitations are the same.
Note that all the limitations of the library solution you describe are=20
already characteristics of reference-wrapper and invoke.

About the "require complicated specification" of a library solution, I=20
believe that the language solution will not be simple neither.

Would the operator be applicable to rvalue references? universal=20
references? What would be its meaning?

Could the tuple-like contains reference_wrapper<T> elements? How will=20
the operator[*] take in account this specific elements?
> The general gist is:
>
>    struct Datum { int id; double value; };
>
>    auto d1 =3D Datum{42, 2.7};
>    auto d2 =3D Datum{[*]d1};
>    foo([*]d1, [*]d2);
>
>    // equivalent to:
>    auto d2 =3D Datum{get<0>(d1), get<1>(d2)};
>    foo(get<0>(d1), get<1>(d1), get<0>(d2), get<1>(d2));
>
> (Yes, the first case is silly; it's more interesting if instead of a
> Datum in both cases, the second was a different but layout-compatible
> type. The paper has a somewhat better version of the example.)
>
> As described in the paper, there is at least one use case for this
> language feature that cannot be (easily) accomplished otherwise:
>
>    template <type T>
>    foo(T const& tuple_like)
>    {
>      new Bar{next_id(), [*]tuple_like};
>    }
>
> If Bar cannot take a T directly (e.g. because it is an external library
> type), but the 'tuple size' of T is not known, it is impossible to write
> a single generic definition of foo() (and hard, or at least very
> annoying, to write specializations).
I guest that when you say that tuple size of T is not known, you mean=20
that it is not fixed and that it depends on T (tuple_size<T>::value=20
should give the number.
I recognize that my library proposal doesn't takes in account=20
constructors, as we can not take its address. We will need a Bar factory.

An alternative to your foo is

   template <type ..Ts>
   foo(Ts const& ...vs)
   {
     new Bar{next_id(), vs...};
   }

This version could be called using apply

     apply(foo, t);

But I agree, this will not be always possible, e.g. if there are 2=20
tuples. Maybe it is worth changing the example.
> I haven't written a proposed wording yet, and not sure if I will be able
> to until "tuple like" is specified. (BTW, is there an official paper on
> that yet?)
Not, that I know.
> Comments, as always, welcome. Motivating use cases especially welcome :-)=
..
>


BTW, I've started the library proposal paper but it is not ready yet ;-)

I've not a library solution for constructors or returning an aggregate=20
with elided type.

Respect to use case,

pair<int, S> parse_int(S);
void g(int, int, S);

g(1, [*]parse_int(s));

Maybe OT. It is a pity that we don't have an associated type for an=20
aggregate initializer {1,"b",3} that could be managed as a tuple-like=20
type, let me name it initializer_aggregate. Constructing from an=20
initializer_aggregate could be equivalent to constructing from its=20
elements.

   template <type T>
   foo(T const& tuple_like)
   {
     new Bar{ make_aggreagte_initializer(next_id(), unpack(tuple_like) };
   }


Calling a function with a initializer_aggregate could be equivalent to=20
calling it with its elements.


Vicente


--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

.


Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Tue, 19 Jan 2016 22:50:34 -0800 (PST)
Raw View
------=_Part_627_2046547581.1453272634390
Content-Type: multipart/alternative;
 boundary="----=_Part_628_1113157909.1453272634391"

------=_Part_628_1113157909.1453272634391
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Tuesday, January 19, 2016 at 12:23:25 PM UTC-8, Matthew Woehlke wrote:
>
> On 2016-01-19 14:15, Nicol Bolas wrote:=20
> > Your mechanism is too simplified to be of *general* use.=20
>
> I disagree. I can think of immediate examples of unpacking in place (and=
=20
> some have been given). I would like to see a reasonable example for:=20
>
>   auto result =3D make_tuple(func([*]f..., [*]g)...);=20
>
> ...along with a rationale why this merits a language feature.=20
>

Aren't you both (Nicol and Matthew) proposing language features? Matthew is=
=20
proposing `[*]`, and Nicol is proposing `[*]...`.  I don't see how either=
=20
of those can be implemented as a library-only feature.

The only difference between Nicol's proposal and Matthew's (AFAICT) is=20
whether [*]x "expands in place" into a comma-separated sequence of gets=20
(Matthew's), or whether it evaluates to a parameter pack at the AST level=
=20
(Nicol's).

If that is in fact the only difference, then *of course* Nicol's proposal=
=20
is better. Parameter packs are well-understood, are composable in=20
interesting ways (e.g. `f(g(x)...)` versus `f(g(x...))`), and are going to=
=20
become even more composable in C++17 (e.g. fold-expressions). A=20
comma-separated sequence is *just one possible result* of expanding a=20
parameter pack.
Plus, parameter packs have Standard wording already, so you wouldn't need=
=20
to write any new wording to describe what you (Matthew) mean by *"any=20
context where a ``,``-separated sequence of expressions is accepted"*.=20
(Matthew doesn't really mean that literally anyway, unless he's proposing=
=20
to allow

    [*]x;

as an expression statement containing std::tuple_size_v<decltype(std::tie([=
*]x))>=20
- 1 instances of the comma operator.)

Notice that in the previous parenthetical I had to write std::tuple_size_v<=
decltype(std::tie([*]x))>=20
- 1 to express the size of the "comma-separated sequence" [*]x under=20
Matthew's proposal. I think that's really the simplest thing that would=20
compile! Under Nicol's proposal, the same notion would be expressed as=20
sizeof...([*]x). This illustrates what I mean by the statement "Parameter=
=20
packs are well-understood." We know how to work with them; we have language=
=20
tools that have been carefully designed to work with them. Whereas, IMO,=20
"comma-separated sequences" are weird and un-C++thonic.


p.s. If we have genuine promotion of value sequences to parameter packs,=20
> why can't we do this?=20
>
>   auto&&... g_unpacked =3D g;=20
>   auto result =3D make_tuple(func([*]f, g_unpacked)...);=20
>

Because you can't have variables of parameter-pack type. Parameter packs=20
aren't first-class citizens in C++. Maybe they should be; but that seems=20
like a distraction from the issue at hand, which is
- should tuples be convertible back into packs, or into some other kind of=
=20
entity? and
- what should the syntax for that look like?
The questions of "why can't I declare a pack on the stack", or "why can't I=
=20
init-capture a pack", or "why can't I declare a class A<T...> that has=20
members of types T..." are all good questions, but are completely=20
orthogonal to the two questions above. And they'll still be there for the=
=20
solving later.

=20

> > ... The *only part* of your proposal that absolutely needs to be a=20
> > *language* feature is the ability to unpack a tuple into a=20
> > braced-init-list.=20
>
> I think you're severely understating the usefulness of this case. I=20
> don't feel that being able to unpack into e.g. constructor calls is so=20
> rare as to be so lightly glossed over.=20
>

I suspect Nicol was implying that "unpacking into the arguments of a=20
constructor call" can be simulated by "unpacking into the arguments of a=20
function call":
    new (addr) T(pack...)
is exactly equivalent to
    std::experimental::apply(std::allocator<T>::construct,=20
std::allocator<T>{}, addr, pack...);
and creating temporary objects of type T can also be done with constructs=
=20
such as my::make<T>(pack...), as long as T is moveable.  Richard Smith's=20
P0135 "Guaranteed copy elision through simplified value categories" removes=
=20
even that "moveable" requirement.
Whereas, there is no library solution for "creating a braced-init-list".=20
Braced-init-lists are special in that they force left-to-right (LTR)=20
evaluation of their contents. You can't do that with a function call.=20
(Although, as previously noted on this list, I wish you could. ;))

> Oh, and the temporary in this case must be named. Weren't you one of=20
> those=20
> > who were saying that naming things is hard=20
>
> Naming *API* is hard :-). I dub the temporary 't'. Or 't0'. Or whatever;=
=20
> the names of temporar^Wlocal scratch variables don't matter the way the=
=20
> names of API types do.=20
>

Depends on your domain, as always. If your codebase has a lot of deeply=20
nested constructs and compiles with -Wshadow, naming local variables *can*=
=20
be challenging. If you're working on a code-generator that generates C++=20
code, the first time you run into some construct that *requires* you to=20
implement a

std::string get_temp_variable_name() {
    static int x =3D 0;
    return "t"+std::to_string(x++);
}

if you're like me you're going to spend at least half an hour tearing your=
=20
hair out to find any workaround for this *$*#$% stupid language feature*=20
that *requires* making up ad-hoc names. Naming things sucks; IMHO half the=
=20
attraction of "point-free style=20
<https://en.wikipedia.org/wiki/Tacit_programming>" is that it eliminates=20
most of the bikeshedding over naming! :)

=E2=80=93Arthur

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

------=_Part_628_1113157909.1453272634391
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Tuesday, January 19, 2016 at 12:23:25 PM UTC-8, Matthew=
 Woehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2016-01-19 1=
4:15, Nicol Bolas wrote:
<br>&gt; Your mechanism is too simplified to be of *general* use.
<br>
<br>I disagree. I can think of immediate examples of unpacking in place (an=
d
<br>some have been given). I would like to see a reasonable example for:
<br>
<br>=C2=A0 auto result =3D make_tuple(func([*]f..., [*]g)...);
<br>
<br>...along with a rationale why this merits a language feature.
<br></blockquote><div><br></div><div>Aren&#39;t you both (Nicol and Matthew=
) proposing language features? Matthew is proposing `[*]`, and Nicol is pro=
posing `[*]...`. =C2=A0I don&#39;t see how either of those can be implement=
ed as a library-only feature.</div><div><br></div><div>The only difference =
between Nicol&#39;s proposal and Matthew&#39;s (AFAICT) is whether [*]x &qu=
ot;expands in place&quot; into a comma-separated sequence of gets (Matthew&=
#39;s), or whether it evaluates to a parameter pack at the AST level (Nicol=
&#39;s).</div><div><br></div><div>If that is in fact the only difference, t=
hen <i>of course</i> Nicol&#39;s proposal is better. Parameter packs are we=
ll-understood, are composable in interesting ways (e.g. `f(g(x)...)` versus=
 `f(g(x...))`), and are going to become even more composable in C++17 (e.g.=
 fold-expressions). A comma-separated sequence is <i>just one possible resu=
lt</i> of expanding a parameter pack.</div><div>Plus, parameter packs have =
Standard wording already, so you wouldn&#39;t need to write any new wording=
 to describe what you (Matthew) mean by <u>&quot;<span style=3D"color: rgb(=
0, 0, 0); white-space: pre-wrap;">any context where a ``,``-separated seque=
nce of expressions is accepted&quot;</span></u>. (Matthew doesn&#39;t reall=
y mean that literally anyway, unless he&#39;s proposing to allow</div><div>=
<br></div><div>=C2=A0 =C2=A0 [*]x;</div><div><br></div><div>as an expressio=
n statement containing <font face=3D"courier new, monospace">std::tuple_siz=
e_v&lt;decltype(std::tie([*]x))&gt; - 1</font> instances of the comma opera=
tor.)</div><div><br></div><div>Notice that in the previous parenthetical I =
had to write <font face=3D"courier new, monospace">std::tuple_size_v&lt;dec=
ltype(std::tie([*]x))&gt; - 1</font> to express the size of the &quot;comma=
-separated sequence&quot; <font face=3D"courier new, monospace">[*]x</font>=
 under Matthew&#39;s proposal. I think that&#39;s really the simplest thing=
 that would compile! Under Nicol&#39;s proposal, the same notion would be e=
xpressed as <font face=3D"courier new, monospace">sizeof...([*]x)</font>. T=
his illustrates what I mean by the statement &quot;Parameter packs are well=
-understood.&quot; We know how to work with them; we have language tools th=
at have been carefully designed to work with them. Whereas, IMO, &quot;comm=
a-separated sequences&quot; are weird and un-C++thonic.</div><div><br></div=
><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">p.s. If we hav=
e genuine promotion of value sequences to parameter packs,
<br>why can&#39;t we do this?
<br>
<br>=C2=A0 auto&amp;&amp;... g_unpacked =3D g;
<br>=C2=A0 auto result =3D make_tuple(func([*]f, g_unpacked)...);
<br></blockquote><div><br></div><div>Because you can&#39;t have variables o=
f parameter-pack type. Parameter packs aren&#39;t first-class citizens in C=
++. Maybe they should be; but that seems like a distraction from the issue =
at hand, which is</div><div>- should tuples be convertible back into packs,=
 or into some other kind of entity? and</div><div>- what should the syntax =
for that look like?</div><div>The questions of &quot;why can&#39;t I declar=
e a pack on the stack&quot;, or &quot;why can&#39;t I init-capture a pack&q=
uot;, or &quot;why can&#39;t I declare a class A&lt;T...&gt; that has membe=
rs of types T...&quot; are all good questions, but are completely orthogona=
l to the two questions above. And they&#39;ll still be there for the solvin=
g later.</div><div><br></div><div>=C2=A0</div><blockquote class=3D"gmail_qu=
ote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padd=
ing-left: 1ex;">&gt; ... The *only part* of your proposal that absolutely n=
eeds to be a=20
<br>&gt; *language* feature is the ability to unpack a tuple into a=20
<br>&gt; braced-init-list.
<br>
<br>I think you&#39;re severely understating the usefulness of this case. I
<br>don&#39;t feel that being able to unpack into e.g. constructor calls is=
 so
<br>rare as to be so lightly glossed over.
<br></blockquote><div><br></div><div>I suspect Nicol was implying that &quo=
t;unpacking into the arguments of a constructor call&quot; can be simulated=
 by &quot;unpacking into the arguments of a function call&quot;:</div><div>=
=C2=A0 =C2=A0 new (addr) T(pack...)<br></div><div>is exactly equivalent to<=
/div><div>=C2=A0 =C2=A0 std::experimental::apply(std::allocator&lt;T&gt;::c=
onstruct, std::allocator&lt;T&gt;{}, addr, pack...);</div><div>and creating=
 temporary objects of type T can also be done with constructs such as my::m=
ake&lt;T&gt;(pack...), as long as T is moveable. =C2=A0Richard Smith&#39;s =
P0135=C2=A0&quot;Guaranteed copy elision through simplified value categorie=
s&quot; removes even that &quot;moveable&quot; requirement.</div><div>Where=
as, there is no library solution for &quot;creating a braced-init-list&quot=
;. Braced-init-lists are special in that they force left-to-right (LTR) eva=
luation of their contents. You can&#39;t do that with a function call. (Alt=
hough, as previously noted on this list, I wish you could. ;))</div><div><b=
r></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0=
..8ex;border-left: 1px #ccc solid;padding-left: 1ex;">&gt; Oh, and the tempo=
rary in this case must be named. Weren&#39;t you one of those=20
<br>&gt; who were saying that naming things is hard
<br>
<br>Naming *API* is hard :-). I dub the temporary &#39;t&#39;. Or &#39;t0&#=
39;. Or whatever;
<br>the names of temporar^Wlocal scratch variables don&#39;t matter the way=
 the
<br>names of API types do.
<br></blockquote><div><br></div><div>Depends on your domain, as always. If =
your codebase has a lot of deeply nested constructs and compiles with -Wsha=
dow, naming local variables <i>can</i> be challenging. If you&#39;re workin=
g on a code-generator that generates C++ code, the first time you run into =
some construct that <i>requires</i> you to implement a</div><div><br></div>=
<div><font face=3D"courier new, monospace">std::string get_temp_variable_na=
me() {</font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0=
 static int x =3D 0;</font></div><div><font face=3D"courier new, monospace"=
>=C2=A0 =C2=A0 return &quot;t&quot;+std::to_string(x++);</font></div><div><=
font face=3D"courier new, monospace">}</font></div><div><br></div><div>if y=
ou&#39;re like me you&#39;re going to spend at least half an hour tearing y=
our hair out to find any workaround for this <i>$*#$% stupid language featu=
re</i> that <i>requires</i> making up ad-hoc names. Naming things sucks; IM=
HO half the attraction of &quot;<a href=3D"https://en.wikipedia.org/wiki/Ta=
cit_programming">point-free style</a>&quot; is that it eliminates most of t=
he bikeshedding over naming! :)</div><div><br></div><div>=E2=80=93Arthur</d=
iv></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

------=_Part_628_1113157909.1453272634391--
------=_Part_627_2046547581.1453272634390--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Wed, 20 Jan 2016 10:28:40 -0500
Raw View
On 2016-01-20 01:50, Arthur O'Dwyer wrote:
> Aren't you both (Nicol and Matthew) proposing language features? Matthew is
> proposing `[*]`, and Nicol is proposing `[*]...`.  I don't see how either
> of those can be implemented as a library-only feature.

Yes, to all points. I feel like I've provided better examples, however,
and that the specification of my version is significantly simpler. Maybe
if Nicol will present a specification of his version, I will change my
mind, but it still seems to me that his is more complicated and harder
to use.

> Plus, parameter packs have Standard wording already, so you wouldn't need
> to write any new wording to describe what you (Matthew) mean by *"any
> context where a ``,``-separated sequence of expressions is accepted"*.

I didn't actually intend to. `[*]` is expanded early. It may result in
invalid code, which would then be an error.

> (Matthew doesn't really mean that literally anyway, unless he's proposing
> to allow
>
>     [*]x;

The non-complicated version of the proposal would indeed allow this; it
would expand to `get<0>(x), get<1>x, ..., get<N>(x);`, which is valid
code. Silly, but valid.

> Notice that in the previous parenthetical I had to write std::tuple_size_v<decltype(std::tie([*]x))>
> - 1 to express the size of the "comma-separated sequence" [*]x under
> Matthew's proposal. I think that's really the simplest thing that would
> compile!

Uh... why? What's wrong with std::tuple_size_v(x)? Recall that in the
discussions of expanding the notion of "tuple-like", it's generally been
implied that tuple_size would be defined, in addition to get<N>.

> On Tuesday, January 19, 2016 at 12:23:25 PM UTC-8, Matthew Woehlke wrote:
>> p.s. If we have genuine promotion of value sequences to parameter packs,
>> why can't we do this?
>>
>>   auto&&... g_unpacked = g;
>>   auto result = make_tuple(func([*]f, g_unpacked)...);
>
> Because you can't have variables of parameter-pack type. Parameter packs
> aren't first-class citizens in C++.

I think you missed the point; that is exactly what I meant by "If we
have genuine promotion of value sequences to parameter packs". Note the
"auto..." syntax.

> - should tuples be convertible back into packs, or into some other kind of
> entity?

I'm not proposing "some other kind of entity". I'm proposing an
immediate code (AST?) transform at point of use. Introducing some new
(or even existing) "other kind of entity" is specifically something I
want to *avoid*.

> The questions of "why can't I declare a pack on the stack", or "why can't I
> init-capture a pack", or "why can't I declare a class A<T...> that has
> members of types T..." are all good questions, but are completely
> orthogonal to the two questions above. And they'll still be there for the
> solving later.

But that's somewhat the point... the question is, if we want the ability
as in the above example *anyway*, then what value is left in Nicol's
proposal over mine (besides that it saves a little typing)? This would
make the common case (just want to unpack in place) easy and the
uncommon case possible, vs. making both possible, but also both ugly.

--
Matthew

--

---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Wed, 20 Jan 2016 10:49:03 -0500
Raw View
On 2016-01-19 18:08, Vicente J. Botet Escriba wrote:
> Le 18/01/2016 22:38, Matthew Woehlke a =C3=A9crit :
>> Okay, after Vicente convinced me I should write this, I present to you
>> the start of a paper proposing a '[*]' operator (not pushed yet, and
>> just .rst for now; sorry).
> Hi, not that I'm against your proposal, but I believe you will need to
> justify why this operator that IMHO is almost equivalent to
> unpack()/unpacked<T> is more important than one that could replace
> ref()/reference_wrapper<T>.

Did I not address that directly?

- a std::unpacked is ambiguous; do I want to unpack it *now* (or
"ASAP"), or keep it together for the moment?

- std::unpack can't be used in initializer lists; e.g. this is
impossible: `double x[] =3D {[*]array_like};`.

....and of course, using unpack is a *lot* more unwieldy. While as has
been repeatedly pointed out, that's not necessarily a rationale, there's
a pretty big difference between:

  return std::allocate<Bar>(std::invoke(std::construct<Bar>,
std::unpack(tuple_like))); // or whatever

....and:

  return {[*]tuple_like};

> About the "require complicated specification" of a library solution, I
> believe that the language solution will not be simple neither.

That's hard to say without actually implementing it, and in fairness,
I'm maybe not comparing apples to apples. The language feature is pretty
easy to *specify*, however, and because it's a *language* feature,
compilers are allowed to employ any manner of shortcuts and other magic
to implement it efficiently. With a library solution, that, at best,
would require implementing compiler magic syntax to do essentially the
same thing...

> Would the operator be applicable to rvalue references? universal
> references? What would be its meaning?

Uh... yes? Why wouldn't it? It would work much like the RHS of a
range-based for.

range-based for:

  _c =3D <container expression>; // assign to temporary
  _e =3D end(_c)
  for (_i =3D begin(_c); _i !=3D _e; ++_i)
    <iterator expression> =3D *_i;

unpack operator:
  _t =3D <tuple-like value>
  get<0>(_t), get<1>(_t), ...

That is, the expression is evaluated into a temporary, and get<N>
operates on the temporary. Just like range-based for evaluates the
container expression into a temporary and operates on that.

> Could the tuple-like contains reference_wrapper<T> elements? How will
> the operator[*] take in account this specific elements?

Exactly as if you'd written `get<N>(tuple_like)` for such an element. I
don't see why this is complicated...

>> As described in the paper, there is at least one use case for this
>> language feature that cannot be (easily) accomplished otherwise:
>>
>>    template <type T>
>>    foo(T const& tuple_like)
>>    {
>>      new Bar{next_id(), [*]tuple_like};
>>    }
>>
>> If Bar cannot take a T directly (e.g. because it is an external library
>> type), but the 'tuple size' of T is not known, it is impossible to write
>> a single generic definition of foo() (and hard, or at least very
>> annoying, to write specializations).
>
> I guest that when you say that tuple size of T is not known, you mean
> that it is not fixed and that it depends on T (tuple_size<T>::value
> should give the number.

Correct (known to the generic definition of foo<T>()). If it were known,
the definition of foo() could just say `get<0>(tuple_like),
get<1>(tuple_like), ...`. Since it is not known, you would have to
specialize foo<T> for tuple_size<T>.

--=20
Matthew

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 20 Jan 2016 10:43:39 -0800 (PST)
Raw View
------=_Part_799_1396650987.1453315419682
Content-Type: multipart/alternative;
 boundary="----=_Part_800_1260772991.1453315419682"

------=_Part_800_1260772991.1453315419682
Content-Type: text/plain; charset=UTF-8

On Wednesday, January 20, 2016 at 10:28:52 AM UTC-5, Matthew Woehlke wrote:
>
> On 2016-01-20 01:50, Arthur O'Dwyer wrote:
> > Aren't you both (Nicol and Matthew) proposing language features? Matthew
> is
> > proposing `[*]`, and Nicol is proposing `[*]...`.  I don't see how
> either
> > of those can be implemented as a library-only feature.
>
> Yes, to all points. I feel like I've provided better examples, however,
> and that the specification of my version is significantly simpler. Maybe
> if Nicol will present a specification of his version, I will change my
> mind, but it still seems to me that his is more complicated and harder
> to use.
>

I presented a more formal description of the idea back in this post
<https://groups.google.com/a/isocpp.org/d/msg/std-proposals/KW2FcaRAasc/sNfCWcmxFwAJ>.
Is there something in particular missing from that?

It's obviously not a formal specification with standards wording or
whatever. But it is the equivalent of the "Proposal" section of your
document.

> Notice that in the previous parenthetical I had to write
> std::tuple_size_v<decltype(std::tie([*]x))>
> > - 1 to express the size of the "comma-separated sequence" [*]x under
> > Matthew's proposal. I think that's really the simplest thing that would
> > compile!
>
> Uh... why? What's wrong with std::tuple_size_v(x)? Recall that in the
> discussions of expanding the notion of "tuple-like", it's generally been
> implied that tuple_size would be defined, in addition to get<N>.
>

That there would be some kind of sized extension point for "tuple-like"
types is understandable. But using it directly is rather more verbose than
`sizeof...([*]x)`.


> > On Tuesday, January 19, 2016 at 12:23:25 PM UTC-8, Matthew Woehlke
> wrote:
> >> p.s. If we have genuine promotion of value sequences to parameter
> packs,
> >> why can't we do this?
> >>
> >>   auto&&... g_unpacked = g;
> >>   auto result = make_tuple(func([*]f, g_unpacked)...);
> >
> > Because you can't have variables of parameter-pack type. Parameter packs
> > aren't first-class citizens in C++.
>
> I think you missed the point; that is exactly what I meant by "If we
> have genuine promotion of value sequences to parameter packs". Note the
> "auto..." syntax.
>
> > - should tuples be convertible back into packs, or into some other kind
> of
> > entity?
>
> I'm not proposing "some other kind of entity". I'm proposing an
> immediate code (AST?) transform at point of use. Introducing some new
> (or even existing) "other kind of entity" is specifically something I
> want to *avoid*.
>
> > The questions of "why can't I declare a pack on the stack", or "why
> can't I
> > init-capture a pack", or "why can't I declare a class A<T...> that has
> > members of types T..." are all good questions, but are completely
> > orthogonal to the two questions above. And they'll still be there for
> the
> > solving later.
>
> But that's somewhat the point... the question is, if we want the ability
> as in the above example *anyway*, then what value is left in Nicol's
> proposal over mine (besides that it saves a little typing)?


Because however much "we want the ability as in the above example
*anyway*", there are *no proposals* for it. People have talked about it,
theorized about it. But nobody has actually taken it to the committee.

More importantly, if you try to do everything my proposal suggests in
separate pieces, then you're going to create incompatible APIs.

Let's say that we do what you want. We allow `[*]` to mean "immediately
unpack this expression." But after C++17 is in beta, someone proposes the
ability to turn tuple-like types into value sequences, which can be
unpacked identically to parameter packs. Well, you've already absconded
with valuable syntax that could have been used for that. Not only that,
since your syntax already covers some of that, someone such as yourself can
argue, "well, we already can immediately unpack them, so let's just leave
it there and add library functions to serve the needs of larger unpack
patterns."

Doing a half-job at fixing a problem makes it that much harder to justify
the eventual proper fix. Just look at uniform initialization. It's *almost*
uniform, yet nobody has made even the slightest effort to improve it and
fix the not-uniform problems with it. Why?

Because it's "good enough" as is.

It's one thing for a feature to be merely "good enough" due to an
oversight. It's another for it to be "good enough" due to an unwillingness
to actually fulfill the promise of the feature.

This would
>
make the common case (just want to unpack in place) easy and the
> uncommon case possible, vs. making both possible, but also both ugly.
>

"Ugly" is a matter of perspective and how used to a feature you are. As for
commonality, I can't prove that the many uses for generalized pack
creation/expansion number substantially greater than localized tuple
expansion.

However, the nice thing about having syntax that serves the uncommon cases
well is that we find out something about why those cases were uncommon.

The benefits of C++11 and 14 to template metaprogramming aren't just that
you can express more powerful constructs. It's that it is *easier* to
express those constructs. The power of concepts is not that it allows you
to do something you couldn't do before; it's that it takes something that
was exceedingly difficult to do (`std::enable_if` gymnastics) and turns it
into something trivial.

That's one of the benefits of structured binding, after all. One of the big
reasons *not* to use tuple to return multiple values is the painful syntax
of retrieving those values. With structured binding, that pain disappears.
If you give people easy-to-use MRVs, *they will use them*.

The same goes here. What might be considered uncommon today may well be
uncommon only *because it's hard*. The moment it becomes easy, we may find
ourselves typing `...` a whole lot more ;)

Don't pre-nerf a feature just because you don't think it'll be used as much.

--

---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_800_1260772991.1453315419682
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wednesday, January 20, 2016 at 10:28:52 AM UTC-5, Matth=
ew Woehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2016-01-20=
 01:50, Arthur O&#39;Dwyer wrote:
<br>&gt; Aren&#39;t you both (Nicol and Matthew) proposing language feature=
s? Matthew is=20
<br>&gt; proposing `[*]`, and Nicol is proposing `[*]...`. =C2=A0I don&#39;=
t see how either=20
<br>&gt; of those can be implemented as a library-only feature.
<br>
<br>Yes, to all points. I feel like I&#39;ve provided better examples, howe=
ver,
<br>and that the specification of my version is significantly simpler. Mayb=
e
<br>if Nicol will present a specification of his version, I will change my
<br>mind, but it still seems to me that his is more complicated and harder
<br>to use.
<br></blockquote><div><br>I presented a more formal description of the idea=
 <a href=3D"https://groups.google.com/a/isocpp.org/d/msg/std-proposals/KW2F=
caRAasc/sNfCWcmxFwAJ">back in this post</a>. Is there something in particul=
ar missing from that?<br><br>It&#39;s obviously not a formal specification =
with standards wording or whatever. But it is the equivalent of the &quot;P=
roposal&quot; section of your document.<br><br></div><blockquote class=3D"g=
mail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc sol=
id;padding-left: 1ex;">
&gt; Notice that in the previous parenthetical I had to write std::tuple_si=
ze_v&lt;decltype(<wbr>std::tie([*]x))&gt;=20
<br>&gt; - 1 to express the size of the &quot;comma-separated sequence&quot=
; [*]x under=20
<br>&gt; Matthew&#39;s proposal. I think that&#39;s really the simplest thi=
ng that would=20
<br>&gt; compile!
<br>
<br>Uh... why? What&#39;s wrong with std::tuple_size_v(x)? Recall that in t=
he
<br>discussions of expanding the notion of &quot;tuple-like&quot;, it&#39;s=
 generally been
<br>implied that tuple_size would be defined, in addition to get&lt;N&gt;.
<br></blockquote><div><br>That there would be some kind of sized extension =
point for &quot;tuple-like&quot; types is understandable. But using it dire=
ctly is rather more verbose than `sizeof...([*]x)`.<br>=C2=A0</div><blockqu=
ote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left=
: 1px #ccc solid;padding-left: 1ex;">
&gt; On Tuesday, January 19, 2016 at 12:23:25 PM UTC-8, Matthew Woehlke wro=
te:
<br>&gt;&gt; p.s. If we have genuine promotion of value sequences to parame=
ter packs,
<br>&gt;&gt; why can&#39;t we do this?=20
<br>&gt;&gt;
<br>&gt;&gt; =C2=A0 auto&amp;&amp;... g_unpacked =3D g;=20
<br>&gt;&gt; =C2=A0 auto result =3D make_tuple(func([*]f, g_unpacked)...);=
=20
<br>&gt;=20
<br>&gt; Because you can&#39;t have variables of parameter-pack type. Param=
eter packs=20
<br>&gt; aren&#39;t first-class citizens in C++.
<br>
<br>I think you missed the point; that is exactly what I meant by &quot;If =
we
<br>have genuine promotion of value sequences to parameter packs&quot;. Not=
e the
<br>&quot;auto...&quot; syntax.
<br>
<br>&gt; - should tuples be convertible back into packs, or into some other=
 kind of=20
<br>&gt; entity?
<br>
<br>I&#39;m not proposing &quot;some other kind of entity&quot;. I&#39;m pr=
oposing an
<br>immediate code (AST?) transform at point of use. Introducing some new
<br>(or even existing) &quot;other kind of entity&quot; is specifically som=
ething I
<br>want to *avoid*.
<br>
<br>&gt; The questions of &quot;why can&#39;t I declare a pack on the stack=
&quot;, or &quot;why can&#39;t I=20
<br>&gt; init-capture a pack&quot;, or &quot;why can&#39;t I declare a clas=
s A&lt;T...&gt; that has=20
<br>&gt; members of types T...&quot; are all good questions, but are comple=
tely=20
<br>&gt; orthogonal to the two questions above. And they&#39;ll still be th=
ere for the=20
<br>&gt; solving later.
<br>
<br>But that&#39;s somewhat the point... the question is, if we want the ab=
ility
<br>as in the above example *anyway*, then what value is left in Nicol&#39;=
s
<br>proposal over mine (besides that it saves a little typing)?</blockquote=
><div><br>Because however much &quot;we want the ability as in the above ex=
ample *anyway*&quot;, there are <i>no proposals</i> for it. People have tal=
ked about it, theorized about it. But nobody has actually taken it to the c=
ommittee.<br><br>More importantly, if you try to do everything my proposal =
suggests in separate pieces, then you&#39;re going to create incompatible A=
PIs.<br><br>Let&#39;s say that we do what you want. We allow `[*]` to mean =
&quot;immediately unpack this expression.&quot; But after C++17 is in beta,=
 someone proposes the ability to turn tuple-like types into value sequences=
, which can be unpacked identically to parameter packs. Well, you&#39;ve al=
ready absconded with valuable syntax that could have been used for that. No=
t only that, since your syntax already covers some of that, someone such as=
 yourself can argue, &quot;well, we already can immediately unpack them, so=
 let&#39;s just leave it there and add library functions to serve the needs=
 of larger unpack patterns.&quot;<br><br>Doing a half-job at fixing a probl=
em makes it that much harder to justify the eventual proper fix. Just look =
at uniform initialization. It&#39;s <i>almost</i> uniform, yet nobody has m=
ade even the slightest effort to improve it and fix the not-uniform problem=
s with it. Why?<br><br>Because it&#39;s &quot;good enough&quot; as is.<br><=
br>It&#39;s one thing for a feature to be merely &quot;good enough&quot; du=
e to an oversight. It&#39;s another for it to be &quot;good enough&quot; du=
e to an unwillingness to actually fulfill the promise of the feature.<br><b=
r><blockquote style=3D"margin: 0px 0px 0px 0.8ex; border-left: 1px solid rg=
b(204, 204, 204); padding-left: 1ex;" class=3D"gmail_quote">This would
<br></blockquote></div><blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">make th=
e common case (just want to unpack in place) easy and the
<br>uncommon case possible, vs. making both possible, but also both ugly.<b=
r></blockquote><div><br>&quot;Ugly&quot; is a matter of perspective and how=
 used to a feature you are. As for commonality, I can&#39;t prove that the =
many uses for generalized pack creation/expansion number substantially grea=
ter than localized tuple expansion.<br><br>However, the nice thing about ha=
ving syntax that serves the uncommon cases well is that we find out somethi=
ng about why those cases were uncommon.<br><br>The benefits of C++11 and 14=
 to template metaprogramming aren&#39;t just that you can express more powe=
rful constructs. It&#39;s that it is <i>easier</i> to express those constru=
cts. The power of concepts is not that it allows you to do something you co=
uldn&#39;t do before; it&#39;s that it takes something that was exceedingly=
 difficult to do (`std::enable_if` gymnastics) and turns it into something =
trivial.<br><br>That&#39;s one of the benefits of structured binding, after=
 all. One of the big reasons <i>not</i> to use tuple to return multiple val=
ues is the painful syntax of retrieving those values. With structured bindi=
ng, that pain disappears. If you give people easy-to-use MRVs, <i>they will=
 use them</i>.<br><br>The same goes here. What might be considered uncommon=
 today may well be uncommon only <i>because it&#39;s hard</i>. The moment i=
t becomes easy, we may find ourselves typing `...` a whole lot more ;)<br><=
br>Don&#39;t pre-nerf a feature just because you don&#39;t think it&#39;ll =
be used as much.<br></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

------=_Part_800_1260772991.1453315419682--
------=_Part_799_1396650987.1453315419682--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Wed, 20 Jan 2016 14:33:56 -0500
Raw View
On 2016-01-20 10:49, Matthew Woehlke wrote:
> On 2016-01-19 18:08, Vicente J. Botet Escriba wrote:
>> Le 18/01/2016 22:38, Matthew Woehlke a =C3=A9crit :
>>> Okay, after Vicente convinced me I should write this, I present to you
>>> the start of a paper proposing a '[*]' operator (not pushed yet, and
>>> just .rst for now; sorry).
>> Hi, not that I'm against your proposal, but I believe you will need to
>> justify why this operator that IMHO is almost equivalent to
>> unpack()/unpacked<T> is more important than one that could replace
>> ref()/reference_wrapper<T>.
>=20
> [...] using unpack is a *lot* more unwieldy. While as has been
> repeatedly pointed out, that's not necessarily a rationale, there's a
> pretty big difference between:
>=20
>   return std::allocate<Bar>(std::invoke(std::construct<Bar>,
> std::unpack(tuple_like))); // or whatever
>=20
> ...and:
>=20
>   return {[*]tuple_like};

Another example (using real, production code):

  // current code
  camera->SetCenter(loc[0], loc[1], loc[2]);

  // my proposal (add a '...' for Nicol's proposal)
  camera->SetCenter([*]loc);

  // your proposal
  std::invoke(camera.GetPointer(), &vtkCamera::SetCenter,
              std::unpack(loc));

Mine or Nicol's will probably win over what we have now (less typing).
Yours... almost certainly won't :-). It's nice for generic code, and
that's about it. Even for simpler examples, it's very unlikely I'd use
your unpack over just doing it longhand in most instances.

--=20
Matthew

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Wed, 20 Jan 2016 14:36:30 -0500
Raw View
On 2016-01-20 13:43, Nicol Bolas wrote:
> On Wednesday, January 20, 2016 at 10:28:52 AM UTC-5, Matthew Woehlke wrote:
>> What's wrong with std::tuple_size_v(x)? Recall that in the
>> discussions of expanding the notion of "tuple-like", it's generally been
>> implied that tuple_size would be defined, in addition to get<N>.
>
> That there would be some kind of sized extension point for "tuple-like"
> types is understandable. But using it directly is rather more verbose than
> `sizeof...([*]x)`.

`tuple_size_v(x)` is "rather more verbose" than `sizeof...(x)`? Only by
3 characters... and anyway I don't understand the relevance, since we're
talking about internal details, and not something that appears in user code.

> "Ugly" is a matter of perspective and how used to a feature you are. As for
> commonality, I can't prove that the many uses for generalized pack
> creation/expansion number substantially greater than localized tuple
> expansion.

Anecdotal, of course, but I can't think that I have *ever* wanted to
invoke a function for each member of a tuple-like. I'm having some
trouble even thinking of cases where I want `func(pack)...` (i.e. with
variadic templates). That suggests that they're rare (and is why I've
asked you to show realistic examples.)

Conversely, I *know* I often want to unpack tuple-likes into function
call arguments. It took barely a minute to turn up a handful of examples
in *real, production code* where I would have used the feature for that
purpose, if I could.

Okay, having said that, I *can* think of one case... can you show how
you would simplify this code?

  stream << "begin" << get<0>(x) << get<1>(x)
         << ... << get<N>(x) << "end";

(Rules: 'stream' must be named exactly once, and no fair creating a
helper function. Strong preference to avoid assigning 'stream' to a
scratch variable.)

For bonus points, include `", "` between each item of `x` (okay to
include after the last item also).

--
Matthew

--

---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Wed, 20 Jan 2016 14:11:57 -0600
Raw View
--089e01229aaa7bf1d90529c99baa
Content-Type: text/plain; charset=UTF-8

On 20 January 2016 at 13:36, Matthew Woehlke <mwoehlke.floss@gmail.com>
wrote:

> Anecdotal, of course, but I can't think that I have *ever* wanted to
> invoke a function for each member of a tuple-like.


Comparison, hashing, serialization, streaming just to name a few...


> That suggests that they're rare


No, it suggests your experience is limited.
--
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  +1-847-691-1404

--

---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

--089e01229aaa7bf1d90529c99baa
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On 20 January 2016 at 13:36, Matthew Woehlke <span dir=3D"=
ltr">&lt;<a href=3D"mailto:mwoehlke.floss@gmail.com" target=3D"_blank">mwoe=
hlke.floss@gmail.com</a>&gt;</span> wrote:<br><div class=3D"gmail_extra"><d=
iv class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:=
0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);=
border-left-style:solid;padding-left:1ex">Anecdotal, of course, but I can&#=
39;t think that I have *ever* wanted to<br>
invoke a function for each member of a tuple-like. </blockquote><div><br></=
div><div><div>Comparison, hashing, serialization, streaming just to name a =
few...</div></div><div>=C2=A0<br></div><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb=
(204,204,204);border-left-style:solid;padding-left:1ex">That suggests that =
they&#39;re rare</blockquote><div><br></div><div>No, it suggests your exper=
ience is limited.</div></div>-- <br><div class=3D"gmail_signature"><div dir=
=3D"ltr"><div><div dir=3D"ltr"><div>=C2=A0Nevin &quot;:-)&quot; Liber=C2=A0=
 &lt;mailto:<a href=3D"mailto:nevin@eviloverlord.com" target=3D"_blank">nev=
in@eviloverlord.com</a>&gt; =C2=A0+1-847-691-1404</div></div></div></div></=
div>
</div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

--089e01229aaa7bf1d90529c99baa--

.


Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Wed, 20 Jan 2016 15:13:23 -0800
Raw View
--001a11420926f2207b0529cc21d5
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Wed, Jan 20, 2016 at 7:28 AM, Matthew Woehlke <mwoehlke.floss@gmail.com>
wrote:

> On 2016-01-20 01:50, Arthur O'Dwyer wrote:
> > (Matthew doesn't really mean that literally anyway, unless he's proposi=
ng
> > to allow
> >
> >     [*]x;
>
> The non-complicated version of the proposal would indeed allow this; it
> would expand to `get<0>(x), get<1>x, ..., get<N>(x);`, which is valid
> code. Silly, but valid.
>

Parameter-pack expansion doesn't allow expansion-into-the-comma-operator
here. You're proposing to add a new "tuple-like-expansion" that *does*
allow expansion-into-the-comma-operator. That's weirder than just reusing
the existing language feature (parameter-pack expansion). Having two things
that do *almost* the same thing but behave subtly differently is bad UI
design *and* bad for the people who have to come up with the normative
wording.

> Notice that in the previous parenthetical I had to write
> std::tuple_size_v<decltype(std::tie([*]x))>
> > - 1 to express the size of the "comma-separated sequence" [*]x under
> > Matthew's proposal. I think that's really the simplest thing that would
> > compile!
>
> Uh... why? What's wrong with std::tuple_size_v(x)? Recall that in the
> discussions of expanding the notion of "tuple-like", it's generally been
> implied that tuple_size would be defined, in addition to get<N>.
>

Okay, std::tie([*]x) should just be x; that was my fault. But you still
have to write std::tuple_size_v<decltype(x)>. The entity std::tuple_size_v
is a variable template, not a constexpr function.

Off-topic but FYI, I'm still a little generally uncomfortable with the idea
of "tuple-like type". For example, in C++14 std::array<T,N> has become
"tuple-like", even though it has only one template type parameter. If we
were to standardize a "typelist" template (e.g. mpl::vector<T...>), would
it *not* be "tuple-like" because you couldn't use std::get<I> on it at
runtime? And if I-the-user want to define my own "tuple-like type", how
many customization points do I have to specialize, overload, or whatever,
before I can be sure that the STL will treat my type as "tuple-like"?
Admittedly we have had the same problems since 2011 with "container-like"
types and range-based for loops, and they don't really seem to be tripping
anybody up.


> On Tuesday, January 19, 2016 at 12:23:25 PM UTC-8, Matthew Woehlke wrote:
> >> p.s. If we have genuine promotion of value sequences to parameter pack=
s,
> >> why can't we do this?
> >>
> >>   auto&&... g_unpacked =3D g;
> >>   auto result =3D make_tuple(func([*]f, g_unpacked)...);
> >
> > Because you can't have variables of parameter-pack type. Parameter pack=
s
> > aren't first-class citizens in C++.
>
> I think you missed the point; that is exactly what I meant by "If we
> have genuine promotion of value sequences to parameter packs". Note the
> "auto..." syntax.
>

I probably misunderstood the combination of the "If" (namely: *what* are we
assuming we have?) and the "why can't we" (namely: is that a real question
or did you mean it rhetorically as "we definitely can"?).
Nicol's proposal involves a new way to get a parameter-pack into the middle
of an expression, but it doesn't change anything about the
first-class-citizen-ness of parameter-packs. You still can't have "values"
of "type" *parameter-pack*. Nor can you have named variables of "type"
*parameter-pack*, except for the (previously existing) very special case of
function parameters.

That is, I understood your question to mean "Does Nicol's proposal imply
that the following should compile?" and/or "Does Matthew's proposal imply
that the following should compile?". Both answers were "no".
You may have meant, "If (under some hypothetical(?) future(?) proposal) the
following code did compile, then it would definitely compile." If so, then
yes, I agree with that statement. ;)


> The questions of "why can't I declare a pack on the stack", or "why can't
> I
> > init-capture a pack", or "why can't I declare a class A<T...> that has
> > members of types T..." are all good questions, but are completely
> > orthogonal to the two questions above. And they'll still be there for t=
he
> > solving later.
>
> But that's somewhat the point... the question is, if we want the ability
> as in the above example *anyway*, then what value is left in Nicol's
> proposal over mine (besides that it saves a little typing)? This would
> make the common case (just want to unpack in place) easy and the
> uncommon case possible, vs. making both possible, but also both ugly.
>

Using "..." to unpack things isn't the ugly part of the proposal IMHO,
though!
The ugly part, and the part that's going to get bikeshedded to death, is
the choice of [*] as a prefix operator.
Especially since there's another proposal
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0018r0.html>
before the Committee (or was, at Kona) suggesting that [*](){ ... } should
be the syntax for "capture *this by copy".

Under Nicol's proposal, I now see a further difficulty with mixing [*] and
..... Nicol, Matthew, and I have all been writing sample code under Nicol's
proposal as if

    f([*]x...)

would naturally Do The Right Thing. But in fact, the operator precedence
there is wrong: the postfix ... binds more tightly than the prefix [*].
Under Nicol's proposal, the code would have to be

    f(([*]x)...)

which I now agree is horribly ugly. :)  However, the fix is simple: you
just need to change the "unpacking" operator from prefix to postfix. For
discussion purposes, I'll nominate postfix ~.

    f(x~...)

That's only one character longer than f([*]x), and arguably more readable.

    template<class Vec>
    auto dotproduct(const Vec& a, const Vec& b)
    {
        return (... + (a~ * b~));  // this is a C++17 fold-expression
    }

Not that I'm claiming above-average readability for that snippet, mind you!
:)  But IMHO it's better than

    template<class Vec>
    auto dotproduct(const Vec& a, const Vec& b)
    {
        auto f =3D [](auto&&... aibi){
            return (... + (aibi.first * aibi.second));
        };
        return f([*]my::tuple_zip(a, b));
    }

Keep in mind that I failed the simplicity test last time I tried to write
sample code according to Matthew's proposal, so my apologies if I've missed
something simpler again.  (Something simpler that still involves unpacking,
I mean!  My code above also relies on a made-up my::tuple_zip. If we
postulate a made-up my::tuple_foldl, though, the whole problem collapses
away and we don't need any language features at all:

    template<class Vec>
    auto dotproduct(const Vec& a, const Vec& b)
    {
        auto f =3D [](auto&& accumulator, auto&& ab) {
            return accumulator + (ab.first * ab.second);
        };
        return my::tuple_foldl(f, 0, my::tuple_zip(a, b)));
    }

=E2=80=93Arthur

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

--001a11420926f2207b0529cc21d5
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wed, Jan 20, 2016 at 7:28 AM, Matthew Woehlke <span dir=
=3D"ltr">&lt;<a href=3D"mailto:mwoehlke.floss@gmail.com" target=3D"_blank">=
mwoehlke.floss@gmail.com</a>&gt;</span> wrote:<br><div class=3D"gmail_extra=
"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,2=
04);border-left-style:solid;padding-left:1ex"><span class=3D"">On 2016-01-2=
0 01:50, Arthur O&#39;Dwyer wrote:<br></span><span class=3D"">&gt; (Matthew=
 doesn&#39;t really mean that literally anyway, unless he&#39;s proposing<b=
r>
&gt; to allow<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0[*]x;<br>
<br>
</span>The non-complicated version of the proposal would indeed allow this;=
 it<br>
would expand to `get&lt;0&gt;(x), get&lt;1&gt;x, ..., get&lt;N&gt;(x);`, wh=
ich is valid<br>
code. Silly, but valid.<br></blockquote><div><br></div><div>Parameter-pack =
expansion doesn&#39;t allow expansion-into-the-comma-operator here. You&#39=
;re proposing to add a new &quot;tuple-like-expansion&quot; that <i>does</i=
> allow expansion-into-the-comma-operator. That&#39;s weirder than just reu=
sing the existing language feature (parameter-pack expansion). Having two t=
hings that do <i>almost</i> the same thing but behave subtly differently is=
 bad UI design <i>and</i> bad for the people who have to come up with the n=
ormative wording.</div><div><br></div><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(=
204,204,204);border-left-style:solid;padding-left:1ex"><span class=3D"">&gt=
; Notice that in the previous parenthetical I had to write std::tuple_size_=
v&lt;decltype(std::tie([*]x))&gt;<br>
&gt; - 1 to express the size of the &quot;comma-separated sequence&quot; [*=
]x under<br>
&gt; Matthew&#39;s proposal. I think that&#39;s really the simplest thing t=
hat would<br>
&gt; compile!<br>
<br>
</span>Uh... why? What&#39;s wrong with std::tuple_size_v(x)? Recall that i=
n the<br>
discussions of expanding the notion of &quot;tuple-like&quot;, it&#39;s gen=
erally been<br>
implied that tuple_size would be defined, in addition to get&lt;N&gt;.<br><=
/blockquote><div><br></div><div>Okay, <font face=3D"monospace, monospace">s=
td::tie([*]x)</font> should just be <font face=3D"monospace, monospace">x</=
font>; that was my fault. But you still have to write <font face=3D"monospa=
ce, monospace">std::tuple_size_v&lt;decltype(x)&gt;</font>. The entity <fon=
t face=3D"monospace, monospace">std::tuple_size_v</font> is a variable temp=
late, not a constexpr function.</div><div><br></div><div>Off-topic but FYI,=
 I&#39;m still a little generally uncomfortable with the idea of &quot;tupl=
e-like type&quot;. For example, in C++14 <font face=3D"monospace, monospace=
">std::array&lt;T,N&gt;</font>=C2=A0has become &quot;tuple-like&quot;, even=
 though it has only one template type parameter. If we were to standardize =
a &quot;typelist&quot; template (e.g. <font face=3D"monospace, monospace">m=
pl::vector&lt;T...&gt;</font>), would it <i>not</i> be &quot;tuple-like&quo=
t; because you couldn&#39;t use <font face=3D"monospace, monospace">std::ge=
t&lt;I&gt;</font> on it at runtime? And if I-the-user want to define my own=
 &quot;tuple-like type&quot;, how many customization points do I have to sp=
ecialize, overload, or whatever, before I can be sure that the STL will tre=
at my type as &quot;tuple-like&quot;?</div><div>Admittedly we have had the =
same problems since 2011 with &quot;container-like&quot; types and range-ba=
sed for loops, and they don&#39;t really seem to be tripping anybody up.</d=
iv><div>=C2=A0</div><div><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(20=
4,204,204);border-left-style:solid;padding-left:1ex"><span class=3D"">&gt; =
On Tuesday, January 19, 2016 at 12:23:25 PM UTC-8, Matthew Woehlke wrote:<b=
r>
</span><span class=3D"">&gt;&gt; p.s. If we have genuine promotion of value=
 sequences to parameter packs,<br>
&gt;&gt; why can&#39;t we do this?<br>
&gt;&gt;<br>
&gt;&gt;=C2=A0 =C2=A0auto&amp;&amp;... g_unpacked =3D g;<br>
&gt;&gt;=C2=A0 =C2=A0auto result =3D make_tuple(func([*]f, g_unpacked)...);=
<br>
&gt;<br>
&gt; Because you can&#39;t have variables of parameter-pack type. Parameter=
 packs<br>
&gt; aren&#39;t first-class citizens in C++.<br>
<br>
</span>I think you missed the point; that is exactly what I meant by &quot;=
If we<br>
have genuine promotion of value sequences to parameter packs&quot;. Note th=
e<br>
&quot;auto...&quot; syntax.<br></blockquote><div><br></div><div>I probably =
misunderstood the combination of the &quot;If&quot; (namely: <i>what</i> ar=
e we assuming we have?) and the &quot;why can&#39;t we&quot; (namely: is th=
at a real question or did you mean it rhetorically as &quot;we definitely c=
an&quot;?).</div><div>Nicol&#39;s proposal involves a new way to get a para=
meter-pack into the middle of an expression, but it doesn&#39;t change anyt=
hing about the first-class-citizen-ness of parameter-packs. You still can&#=
39;t have &quot;values&quot; of &quot;type&quot; <i>parameter-pack</i>. Nor=
 can you have named variables of &quot;type&quot; <i>parameter-pack</i>, ex=
cept for the (previously existing) very special case of function parameters=
..</div><div><br></div><div>That is, I understood your question to mean &quo=
t;Does Nicol&#39;s proposal imply that the following should compile?&quot; =
and/or &quot;Does Matthew&#39;s proposal imply that the following should co=
mpile?&quot;. Both answers were &quot;no&quot;.</div><div>You may have mean=
t, &quot;If (under some hypothetical(?) future(?) proposal) the following c=
ode did compile, then it would definitely compile.&quot; If so, then yes, I=
 agree with that statement. ;)</div><div><br></div><div><br></div><blockquo=
te class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-widt=
h:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-le=
ft:1ex"><span class=3D"">&gt; The questions of &quot;why can&#39;t I declar=
e a pack on the stack&quot;, or &quot;why can&#39;t I<br>
&gt; init-capture a pack&quot;, or &quot;why can&#39;t I declare a class A&=
lt;T...&gt; that has<br>
&gt; members of types T...&quot; are all good questions, but are completely=
<br>
&gt; orthogonal to the two questions above. And they&#39;ll still be there =
for the<br>
&gt; solving later.<br>
<br>
</span>But that&#39;s somewhat the point... the question is, if we want the=
 ability<br>
as in the above example *anyway*, then what value is left in Nicol&#39;s<br=
>
proposal over mine (besides that it saves a little typing)? This would<br>
make the common case (just want to unpack in place) easy and the<br>
uncommon case possible, vs. making both possible, but also both ugly.<br></=
blockquote><div><br></div><div>Using &quot;...&quot; to unpack things isn&#=
39;t the ugly part of the proposal IMHO, though!</div><div>The ugly part, a=
nd the part that&#39;s going to get bikeshedded to death, is the choice of =
<font face=3D"monospace, monospace">[*]</font> as a prefix operator.</div><=
div>Especially since there&#39;s <a href=3D"http://www.open-std.org/jtc1/sc=
22/wg21/docs/papers/2015/p0018r0.html">another proposal</a> before the Comm=
ittee (or was, at Kona) suggesting that <font face=3D"monospace, monospace"=
>[*](){ </font><font face=3D"arial, helvetica, sans-serif">...</font><font =
face=3D"monospace, monospace"> }</font> should be the syntax for &quot;capt=
ure <font face=3D"monospace, monospace">*this</font> by copy&quot;.</div><d=
iv><br></div><div>Under Nicol&#39;s proposal, I now see a further difficult=
y with mixing <font face=3D"monospace, monospace">[*]</font> and <font face=
=3D"monospace, monospace">...</font>. Nicol, Matthew, and I have all been w=
riting sample code under Nicol&#39;s proposal as if</div><div><br></div><di=
v><font face=3D"monospace, monospace">=C2=A0 =C2=A0 f([*]x...)</font></div>=
<div><br></div><div>would naturally Do The Right Thing. But in fact, the op=
erator precedence there is wrong: the postfix <font face=3D"monospace, mono=
space">...</font> binds more tightly than the prefix <font face=3D"monospac=
e, monospace">[*]</font>. Under Nicol&#39;s proposal, the code would have t=
o be</div><div><br></div><div><font face=3D"monospace, monospace">=C2=A0 =
=C2=A0 f(([*]x)...)</font></div><div><br></div><div>which I now agree is ho=
rribly ugly. :) =C2=A0However, the fix is simple: you just need to change t=
he &quot;unpacking&quot; operator from prefix to postfix. For discussion pu=
rposes, I&#39;ll nominate postfix <font face=3D"monospace, monospace">~</fo=
nt>.</div><div><br></div><div><font face=3D"monospace, monospace">=C2=A0 =
=C2=A0 f(x~...)</font></div><div><br></div><div>That&#39;s only one charact=
er longer than f([*]x), and arguably more readable.</div><div><br></div><di=
v><span style=3D"font-family:monospace,monospace">=C2=A0 =C2=A0 template&lt=
;class Vec&gt;</span><br></div><div><font face=3D"monospace, monospace">=C2=
=A0 =C2=A0 auto dotproduct(const Vec&amp; a, const Vec&amp; b)</font></div>=
<div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 {</font></div><div><=
font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 return (... =
+ (a~ * b~)); =C2=A0// this is a C++17 fold-expression</font></div><div><fo=
nt face=3D"monospace, monospace">=C2=A0 =C2=A0 }</font></div><div><br></div=
><div>Not that I&#39;m claiming above-average readability for that snippet,=
 mind you! :) =C2=A0But IMHO it&#39;s better than</div><div><br></div><div>=
<div><span style=3D"font-family:monospace,monospace">=C2=A0 =C2=A0 template=
&lt;class Vec&gt;</span></div><div><span style=3D"font-family:monospace,mon=
ospace">=C2=A0 =C2=A0 auto dotproduct(const Vec&amp; a, const Vec&amp; b)</=
span><br></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 {</fo=
nt></div><div><span style=3D"font-family:monospace,monospace">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 auto f =3D [](auto&amp;&amp;... aibi){</span><br></div><div>=
<font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 return (... + (aibi.first * aibi.second));</font></div><div><font face=
=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 };</font></div><div><=
font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 return f([*]=
my</font><span style=3D"font-family:monospace,monospace">::tuple_zip(a, b)<=
/span><span style=3D"font-family:monospace,monospace">);</span></div><div><=
span style=3D"font-family:monospace,monospace">=C2=A0 =C2=A0 }</span><br></=
div></div><div><font face=3D"monospace, monospace"><br></font></div><div>Ke=
ep in mind that I failed the simplicity test last time I tried to write sam=
ple code according to Matthew&#39;s proposal, so my apologies if I&#39;ve m=
issed something simpler again. =C2=A0(Something simpler that still involves=
 unpacking, I mean!=C2=A0 My code above also relies on a made-up <font face=
=3D"monospace, monospace">my::tuple_zip</font>. If we postulate a made-up=
=C2=A0<font face=3D"monospace, monospace">my::tuple_foldl</font>, though, t=
he whole problem collapses away and we don&#39;t need any language features=
 at all:</div><div><br></div><div><div><span style=3D"font-family:monospace=
,monospace">=C2=A0 =C2=A0 template&lt;class Vec&gt;</span></div><div><span =
style=3D"font-family:monospace,monospace">=C2=A0 =C2=A0 auto dotproduct(con=
st Vec&amp; a, const Vec&amp; b)</span><br></div><div><font face=3D"monospa=
ce, monospace">=C2=A0 =C2=A0 {</font></div><div><font face=3D"monospace, mo=
nospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 auto f =3D=C2=A0</font><span style=3D"=
font-family:monospace,monospace">[](auto&amp;&amp; accumulator, auto&amp;&a=
mp; ab) {</span></div><div><span style=3D"font-family:monospace,monospace">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return accumulator + (ab.first * =
ab.second);</span></div><div><span style=3D"font-family:monospace,monospace=
">=C2=A0 =C2=A0 =C2=A0 =C2=A0 };</span></div><div><span style=3D"font-famil=
y:monospace,monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 return my::tuple_foldl(f=
</span><span style=3D"font-family:monospace,monospace">, 0, my::</span><spa=
n style=3D"font-family:monospace,monospace">tuple_zip(a, b)</span><span sty=
le=3D"font-family:monospace,monospace">));</span></div><div><span style=3D"=
font-family:monospace,monospace">=C2=A0 =C2=A0 }</span><br></div></div><div=
><span style=3D"font-family:monospace,monospace"><br></span></div><div>=E2=
=80=93Arthur</div></div></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

--001a11420926f2207b0529cc21d5--

.


Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Wed, 20 Jan 2016 15:41:55 -0800
Raw View
--001a1145ab580a67110529cc8816
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Wed, Jan 20, 2016 at 11:36 AM, Matthew Woehlke <mwoehlke.floss@gmail.com=
>
wrote:

>
> Okay, having said that, I *can* think of one case... can you show how
> you would simplify this code?
>
>   stream << "begin" << get<0>(x) << get<1>(x)
>          << ... << get<N>(x) << "end";
>
> (Rules: 'stream' must be named exactly once, and no fair creating a
> helper function. Strong preference to avoid assigning 'stream' to a
> scratch variable.)
>

Sure!

    // Nicol's syntax
    (stream << "begin" << ... << [*]x) << "end";
    // Arthur's syntax
    (stream << "begin" << ... << x~) << "end";


> For bonus points, include `", "` between each item of `x` (okay to
> include after the last item also).
>

This is significantly harder!  I think it would have to look something like
this:
http://melpon.org/wandbox/permlink/oLcM3ZjH45oTbI7T

template<class F>
auto operator<< (std::ostream& out, F&& f) -> decltype(f(out))  // SFINAE
{
    return f(out);  // maybe C++17 should provide this overload already
}

template<class TupleLike>
void print_to_stream(std::ostream& stream, const TupleLike& x)
{
    auto commaize =3D [](auto&& x) {
        return [&x](std::ostream& out) -> std::ostream& { return out << x
<< ", "; };
    };

    (stream << "begin, " << ... << commaize(x~)) << "end";
}

Messy, but not positively horrible. What would it look like in your
(Matthew's) proposal?

=E2=80=93Arthur

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

--001a1145ab580a67110529cc8816
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wed, Jan 20, 2016 at 11:36 AM, Matthew Woehlke <span di=
r=3D"ltr">&lt;<a href=3D"mailto:mwoehlke.floss@gmail.com" target=3D"_blank"=
>mwoehlke.floss@gmail.com</a>&gt;</span> wrote:<br><div class=3D"gmail_extr=
a"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,=
204);border-left-style:solid;padding-left:1ex"><br>
Okay, having said that, I *can* think of one case... can you show how<br>
you would simplify this code?<br>
<br>
=C2=A0 stream &lt;&lt; &quot;begin&quot; &lt;&lt; get&lt;0&gt;(x) &lt;&lt; =
get&lt;1&gt;(x)<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0&lt;&lt; ... &lt;&lt; get&lt;N&gt;(x) &lt=
;&lt; &quot;end&quot;;<br>
<br>
(Rules: &#39;stream&#39; must be named exactly once, and no fair creating a=
<br>
helper function. Strong preference to avoid assigning &#39;stream&#39; to a=
<br>
scratch variable.)<br></blockquote><div><br></div><div>Sure!</div><div><br>=
</div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 // Nicol&#39;s=
 syntax</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =
(stream &lt;&lt; &quot;begin&quot; &lt;&lt; ... &lt;&lt; [*]x) &lt;&lt; &qu=
ot;end&quot;;</font></div><div><font face=3D"monospace, monospace">=C2=A0 =
=C2=A0 // Arthur&#39;s syntax</font></div><div><font face=3D"monospace, mon=
ospace">=C2=A0 =C2=A0 (stream &lt;&lt; &quot;begin&quot; &lt;&lt; ... &lt;&=
lt; x~) &lt;&lt; &quot;end&quot;;</font></div><div>=C2=A0</div><blockquote =
class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1=
px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:=
1ex">For bonus points, include `&quot;, &quot;` between each item of `x` (o=
kay to<br>
include after the last item also).<br></blockquote><div><br></div><div>This=
 is significantly harder!=C2=A0 I think it would have to look something lik=
e this:</div><div></div><div><a href=3D"http://melpon.org/wandbox/permlink/=
oLcM3ZjH45oTbI7T">http://melpon.org/wandbox/permlink/oLcM3ZjH45oTbI7T<br></=
a></div><div><br></div><div><div><font face=3D"monospace, monospace">templa=
te&lt;class F&gt;</font></div><div><font face=3D"monospace, monospace">auto=
 operator&lt;&lt; (std::ostream&amp; out, F&amp;&amp; f) -&gt; decltype(f(o=
ut)) =C2=A0// SFINAE</font></div><div><font face=3D"monospace, monospace">{=
</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 return =
f(out); =C2=A0// maybe C++17 should provide this overload already</font></d=
iv><div><font face=3D"monospace, monospace">}</font></div><div><font face=
=3D"monospace, monospace"><br></font></div><div><font face=3D"monospace, mo=
nospace">template&lt;class TupleLike&gt;</font></div><div><font face=3D"mon=
ospace, monospace">void print_to_stream(std::ostream&amp; stream, const Tup=
leLike&amp; x)</font></div><div><font face=3D"monospace, monospace">{</font=
></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 auto commaize=
 =3D [](auto&amp;&amp; x) {</font></div><div><font face=3D"monospace, monos=
pace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 return [&amp;x](std::ostream&amp; out) -&=
gt; std::ostream&amp; { return out &lt;&lt; x &lt;&lt; &quot;, &quot;; };</=
font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 };</font>=
</div><div><font face=3D"monospace, monospace"><br></font></div><div><font =
face=3D"monospace, monospace">=C2=A0 =C2=A0 (stream &lt;&lt; &quot;begin, &=
quot; &lt;&lt; ... &lt;&lt; commaize(x~)) &lt;&lt; &quot;end&quot;;</font><=
/div><div><font face=3D"monospace, monospace">}</font></div></div><div><br>=
</div><div>Messy, but not positively horrible. What would it look like in y=
our (Matthew&#39;s) proposal?</div><div><br></div><div>=E2=80=93Arthur</div=
></div></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

--001a1145ab580a67110529cc8816--

.


Author: "T. C." <rs2740@gmail.com>
Date: Wed, 20 Jan 2016 16:03:45 -0800 (PST)
Raw View
------=_Part_4229_121054764.1453334625461
Content-Type: multipart/alternative;
 boundary="----=_Part_4230_1462948692.1453334625461"

------=_Part_4230_1462948692.1453334625461
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



On Wednesday, January 20, 2016 at 6:41:58 PM UTC-5, Arthur O'Dwyer wrote:
>
> On Wed, Jan 20, 2016 at 11:36 AM, Matthew Woehlke <mwoehlk...@gmail.com=
=20
> <javascript:>> wrote:
>
>>
>> For bonus points, include `", "` between each item of `x` (okay to
>> include after the last item also).
>>
>
> This is significantly harder!  I think it would have to look something=20
> like this:
> http://melpon.org/wandbox/permlink/oLcM3ZjH45oTbI7T
>
> template<class F>
> auto operator<< (std::ostream& out, F&& f) -> decltype(f(out))  // SFINAE
> {
>     return f(out);  // maybe C++17 should provide this overload already
> }
>
> template<class TupleLike>
> void print_to_stream(std::ostream& stream, const TupleLike& x)
> {
>     auto commaize =3D [](auto&& x) {
>         return [&x](std::ostream& out) -> std::ostream& { return out << x=
=20
> << ", "; };
>     };
>
>     (stream << "begin, " << ... << commaize(x~)) << "end";
> }
>
> Messy, but not positively horrible. What would it look like in your=20
> (Matthew's) proposal?
>
> =E2=80=93Arthur
>

If you can write stream twice, then a comma fold will do:

((stream << "begin, ") , ... , (stream << x~ << ", ")) << "end";

Also, I'm fairly sure you need to parenthesize stream << "begin, ". The=20
grammar only allows a cast-expression there.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

------=_Part_4230_1462948692.1453334625461
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<br><br>On Wednesday, January 20, 2016 at 6:41:58 PM UTC-5, Arthur O&#39;Dw=
yer wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">On =
Wed, Jan 20, 2016 at 11:36 AM, Matthew Woehlke <span dir=3D"ltr">&lt;<a hre=
f=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"DZWSFvsYGAAJ" =
rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#39;;return tr=
ue;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;">mwoehlk...@=
gmail.com</a>&gt;</span> wrote:<br><div><div class=3D"gmail_quote"><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-wid=
th:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-l=
eft:1ex"><br></blockquote><blockquote class=3D"gmail_quote" style=3D"margin=
:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204)=
;border-left-style:solid;padding-left:1ex">For bonus points, include `&quot=
;, &quot;` between each item of `x` (okay to<br>
include after the last item also).<br></blockquote><div><br></div><div>This=
 is significantly harder!=C2=A0 I think it would have to look something lik=
e this:</div><div></div><div><a href=3D"http://melpon.org/wandbox/permlink/=
oLcM3ZjH45oTbI7T" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.hr=
ef=3D&#39;http://www.google.com/url?q\75http%3A%2F%2Fmelpon.org%2Fwandbox%2=
Fpermlink%2FoLcM3ZjH45oTbI7T\46sa\75D\46sntz\0751\46usg\75AFQjCNGDnPiVJijWQ=
ML8ZoSqWaV9Qwjukw&#39;;return true;" onclick=3D"this.href=3D&#39;http://www=
..google.com/url?q\75http%3A%2F%2Fmelpon.org%2Fwandbox%2Fpermlink%2FoLcM3ZjH=
45oTbI7T\46sa\75D\46sntz\0751\46usg\75AFQjCNGDnPiVJijWQML8ZoSqWaV9Qwjukw&#3=
9;;return true;">http://melpon.org/wandbox/<wbr>permlink/oLcM3ZjH45oTbI7T<b=
r></a></div><div><br></div><div><div><font face=3D"monospace, monospace">te=
mplate&lt;class F&gt;</font></div><div><font face=3D"monospace, monospace">=
auto operator&lt;&lt; (std::ostream&amp; out, F&amp;&amp; f) -&gt; decltype=
(f(out)) =C2=A0// SFINAE</font></div><div><font face=3D"monospace, monospac=
e">{</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 ret=
urn f(out); =C2=A0// maybe C++17 should provide this overload already</font=
></div><div><font face=3D"monospace, monospace">}</font></div><div><font fa=
ce=3D"monospace, monospace"><br></font></div><div><font face=3D"monospace, =
monospace">template&lt;class TupleLike&gt;</font></div><div><font face=3D"m=
onospace, monospace">void print_to_stream(std::ostream&amp; stream, const T=
upleLike&amp; x)</font></div><div><font face=3D"monospace, monospace">{</fo=
nt></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 auto commai=
ze =3D [](auto&amp;&amp; x) {</font></div><div><font face=3D"monospace, mon=
ospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 return [&amp;x](std::ostream&amp; out) =
-&gt; std::ostream&amp; { return out &lt;&lt; x &lt;&lt; &quot;, &quot;; };=
</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 };</fon=
t></div><div><font face=3D"monospace, monospace"><br></font></div><div><fon=
t face=3D"monospace, monospace">=C2=A0 =C2=A0 (stream &lt;&lt; &quot;begin,=
 &quot; &lt;&lt; ... &lt;&lt; commaize(x~)) &lt;&lt; &quot;end&quot;;</font=
></div><div><font face=3D"monospace, monospace">}</font></div></div><div><b=
r></div><div>Messy, but not positively horrible. What would it look like in=
 your (Matthew&#39;s) proposal?</div><div><br></div><div>=E2=80=93Arthur</d=
iv></div></div></div></blockquote><div><br></div><div>If you can write=C2=
=A0<span style=3D"color: rgb(0, 0, 0); font-family: monospace; background-c=
olor: rgb(250, 250, 250);">stream=C2=A0</span>twice, then a comma fold will=
 do:</div><div><br></div><div class=3D"prettyprint" style=3D"border: 1px so=
lid rgb(187, 187, 187); word-wrap: break-word; background-color: rgb(250, 2=
50, 250);"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span =
style=3D"color: #660;" class=3D"styled-by-prettify">((</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">stream </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">&lt;&lt;</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #080;"=
 class=3D"styled-by-prettify">&quot;begin, &quot;</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"> </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">...</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><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;" class=3D"styled-by-prettify">(</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">stream </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">&lt;&lt;</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> x</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: #660;" class=3D"styled-by-pret=
tify">&lt;&lt;</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #080;" class=3D"styled-by-prettify">&quot=
;, &quot;</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;" class=3D"styled-by-prettify">&lt;&lt;</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #080;" class=3D"styled-by-prettify">&quot;end&quot;</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">;</span></div></code></=
div><div><br></div><div>Also, I&#39;m fairly sure you need to parenthesize=
=C2=A0<span style=3D"font-family: monospace, monospace;">stream &lt;&lt; &q=
uot;begin, &quot;</span>. The grammar only allows a cast-expression there.<=
br><br></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

------=_Part_4230_1462948692.1453334625461--
------=_Part_4229_121054764.1453334625461--

.


Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Wed, 20 Jan 2016 16:37:06 -0800
Raw View
--001a1145392c62f0930529cd4da9
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Wed, Jan 20, 2016 at 4:03 PM, T. C. <rs2740@gmail.com> wrote:

> On Wednesday, January 20, 2016 at 6:41:58 PM UTC-5, Arthur O'Dwyer wrote:
>
>>
>> template<class TupleLike>
>> void print_to_stream(std::ostream& stream, const TupleLike& x)
>> {
>>     auto commaize =3D [](auto&& x) {
>>         return [&x](std::ostream& out) -> std::ostream& { return out << =
x
>> << ", "; };
>>     };
>>
>>     (stream << "begin, " << ... << commaize(x~)) << "end";
>> }
>>
>>
> If you can write stream twice, then a comma fold will do:
>
> ((stream << "begin, ") , ... , (stream << x~ << ", ")) << "end";
>
> Also, I'm fairly sure you need to parenthesize stream << "begin, ". The
> grammar only allows a cast-expression there.
>

I bet you're right. :)  The above compiles with GCC 6.0 on Wandbox (if you
replace x~ with std::get<I>(x) of course) and fails for unrelated reasons
with Clang 3.9. But I can totally believe that GCC 6.0 has bugs and/or
helpful extensions in this area.

Personally, I was shocked that

    return (a * b) + ...;

failed to compile on either Clang or GCC =E2=80=94 and with a completely un=
helpful
syntax error! It took me tens of minutes to discover what I was doing wrong
(mostly spent trying to figure out if these compilers claimed to support
fold-expressions at all).

Is there a grammatical reason to *require* parentheses around every single
fold-expression, or was it just someone's idea of being "helpful"?

=E2=80=93Arthur

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

--001a1145392c62f0930529cd4da9
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wed, Jan 20, 2016 at 4:03 PM, T. C. <span dir=3D"ltr">&=
lt;<a href=3D"mailto:rs2740@gmail.com" target=3D"_blank">rs2740@gmail.com</=
a>&gt;</span> wrote:<br><div class=3D"gmail_extra"><div class=3D"gmail_quot=
e"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left=
:1px #ccc solid;padding-left:1ex">On Wednesday, January 20, 2016 at 6:41:58=
 PM UTC-5, Arthur O&#39;Dwyer wrote:<br><span class=3D""><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><div><di=
v><font face=3D"monospace, monospace"><br></font></div><div><font face=3D"m=
onospace, monospace">template&lt;class TupleLike&gt;</font></div><div><font=
 face=3D"monospace, monospace">void print_to_stream(std::ostream&amp; strea=
m, const TupleLike&amp; x)</font></div><div><font face=3D"monospace, monosp=
ace">{</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 a=
uto commaize =3D [](auto&amp;&amp; x) {</font></div><div><font face=3D"mono=
space, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 return [&amp;x](std::ostream&=
amp; out) -&gt; std::ostream&amp; { return out &lt;&lt; x &lt;&lt; &quot;, =
&quot;; };</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=
=A0 };</font></div><div><font face=3D"monospace, monospace"><br></font></di=
v><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 (stream &lt;&lt; &=
quot;begin, &quot; &lt;&lt; ... &lt;&lt; commaize(x~)) &lt;&lt; &quot;end&q=
uot;;</font></div><div><font face=3D"monospace, monospace">}</font></div></=
div><div><br></div></div></div></blockquote><div><br></div></span><div>If y=
ou can write=C2=A0<span style=3D"color:rgb(0,0,0);font-family:monospace;bac=
kground-color:rgb(250,250,250)">stream=C2=A0</span>twice, then a comma fold=
 will do:</div><div><br></div><div style=3D"border:1px solid rgb(187,187,18=
7);word-wrap:break-word;background-color:rgb(250,250,250)"><code><div><span=
 style=3D"color:#660">((</span><span style=3D"color:#000">stream </span><sp=
an style=3D"color:#660">&lt;&lt;</span><span style=3D"color:#000"> </span><=
span style=3D"color:#080">&quot;begin, &quot;</span><span style=3D"color:#6=
60">)</span><span style=3D"color:#000"> </span><span style=3D"color:#660">,=
</span><span style=3D"color:#000"> </span><span style=3D"color:#660">...</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#660">,</span><=
span style=3D"color:#000"> </span><span style=3D"color:#660">(</span><span =
style=3D"color:#000">stream </span><span style=3D"color:#660">&lt;&lt;</spa=
n><span style=3D"color:#000"> x</span><span style=3D"color:#660">~</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#660">&lt;&lt;</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#080">&quot;, &quot=
;</span><span style=3D"color:#660">))</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#660">&lt;&lt;</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#080">&quot;end&quot;</span><span style=3D"color=
:#660">;</span></div></code></div><div><br></div><div>Also, I&#39;m fairly =
sure you need to parenthesize=C2=A0<span style=3D"font-family:monospace,mon=
ospace">stream &lt;&lt; &quot;begin, &quot;</span>. The grammar only allows=
 a cast-expression there.<br></div></blockquote><div><br></div><div>I bet y=
ou&#39;re right. :) =C2=A0The above compiles with GCC 6.0 on Wandbox (if yo=
u replace <font face=3D"monospace, monospace">x~</font> with <font face=3D"=
monospace, monospace">std::get&lt;I&gt;(x)</font> of course) and fails for =
unrelated reasons with Clang 3.9. But I can totally believe that GCC 6.0 ha=
s bugs and/or helpful extensions in this area.</div><div><br></div><div>Per=
sonally, I was shocked that</div><div><br></div><div><font face=3D"monospac=
e, monospace">=C2=A0 =C2=A0 return (a * b) + ...;</font></div></div><br></d=
iv><div class=3D"gmail_extra">failed to compile on either Clang or GCC =E2=
=80=94 and with a completely unhelpful syntax error! It took me tens of min=
utes to discover what I was doing wrong (mostly spent trying to figure out =
if these compilers claimed to support fold-expressions at all).</div><div c=
lass=3D"gmail_extra"><br></div><div class=3D"gmail_extra">Is there a gramma=
tical reason to <i>require</i> parentheses around every single fold-express=
ion, or was it just someone&#39;s idea of being &quot;helpful&quot;?</div><=
div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">=E2=80=93Art=
hur</div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

--001a1145392c62f0930529cd4da9--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Thu, 21 Jan 2016 10:09:02 -0500
Raw View
On 2016-01-20 19:03, T. C. wrote:
> If you can write stream twice,

You can't. The specific use case in which I'd want to do this is with
QDebug:

  qDebug() << "stuff" << ...

The comma isn't terribly important, because QDebug will add spaces.
However, it will add blank lines which are NOT wanted if qDebug() is
called multiple times. Nor is using a scratch variable really an option,
because that would require adding an explicit scope to make the QDebug
instance destruct at the right place.

--
Matthew

--

---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Thu, 21 Jan 2016 10:40:25 -0500
Raw View
On 2016-01-20 18:13, Arthur O'Dwyer wrote:
> Off-topic but FYI, I'm still a little generally uncomfortable with the idea
> of "tuple-like type". For example, in C++14 std::array<T,N> has become
> "tuple-like", even though it has only one template type parameter.

So? The intent of "tuple-like" is that it is a sequence of a fixed
number of values. There is nothing saying that those values must be of
different types.

Most of the examples where I want something to be tuple-like are
actually arrays (typically, "vectors" in the linear algebra sense), e.g.
QPoint, Eigen::Vector<...>, etc.

> If we were to standardize a "typelist" template (e.g.
> mpl::vector<T...>), would it *not* be "tuple-like" because you
> couldn't use std::get<I> on it at runtime?

Yeees.... also because tuple_size wouldn't (couldn't) be constexpr. IOW,
it is not "tuple-like" if it is not fixed(-at-compile-time)-size.

This is of course why std::array is tuple-like and std::vector is not.

> And if I-the-user want to define my own "tuple-like type", how
> many customization points do I have to specialize, overload, or whatever,
> before I can be sure that the STL will treat my type as "tuple-like"?

That's an active question; see
https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/_dz9X2HVWl4.
I've repeatedly expressed the preference that the answer is 'get<N>' and
nothing else. Another opinion is 'get<N>' and 'tuple_size'. I don't
believe anyone is proposing additional requirements beyond those.

> On 2016-01-20 10:28, Matthew Woehlke wrote:
>> On 2016-01-20 01:50, Arthur O'Dwyer wrote:
>>> On Tuesday, January 19, 2016 at 12:23:25 PM UTC-8, Matthew Woehlke wrote:
>>>> p.s. If we have genuine promotion of value sequences to parameter packs,
>>>> why can't we do this?
>>>>
>>>>   auto&&... g_unpacked = g;
>>>>   auto result = make_tuple(func([*]f, g_unpacked)...);
>>>
>>> Because you can't have variables of parameter-pack type. Parameter packs
>>> aren't first-class citizens in C++.
>>
>> I think you missed the point; that is exactly what I meant by "If we
>> have genuine promotion of value sequences to parameter packs". Note the
>> "auto..." syntax.
>
> [...]
> That is, I understood your question to mean "Does Nicol's proposal imply
> that the following should compile?" and/or "Does Matthew's proposal imply
> that the following should compile?". Both answers were "no".

Ah, yes. I meant, "If <other feature> is something we also want anyway,
do we not have the same capabilities with <my version of the proposal>
and <other feature>? Would that not make <Nicol's version of the
proposal> unnecessary?"

I think Nicol addressed this adequately, so I won't rehash beyond
clarification of the original intended meaning.

> Using "..." to unpack things isn't the ugly part of the proposal IMHO,
> though!
> The ugly part, and the part that's going to get bikeshedded to death, is
> the choice of [*] as a prefix operator.
> Especially since there's another proposal
> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0018r0.html>
> before the Committee (or was, at Kona) suggesting that [*](){ ... } should
> be the syntax for "capture *this by copy".

I'm open to other (good) ideas... one reason I really like `[*]` however
is because it becomes natural to further extend it to slicing, e.g.
`[1]`, `[:3]`, `[2:4]`, `[1,2:4,5,8:]`, and so forth.

I think slicing is important; already with assignment unpacking, we have
the problem of how to deal with unwanted values. If we have slicing, we
can just write:

  auto {a, b} = [2,5]tuple_like;

> which I now agree is horribly ugly. :)  However, the fix is simple: you
> just need to change the "unpacking" operator from prefix to postfix. For
> discussion purposes, I'll nominate postfix ~.
>
>     f(x~...)

Per above, `[*]` wasn't chosen lightly. The use of `[]`s suggest the
indexing operator, which therefore implies something being extracted
from a container (and are extensible to multiple specifications of
"something"). The use of `*` is taken directly from Python, and per *my*
proposal, means the exact same thing. (Nicol's would make it... similar,
but less "exactly the same".)

`~` "comes out of nowhere", if you will... there is no existing use in
any language that would lead one to associate it with unpacking.

> If we postulate a made-up my::tuple_foldl, though, the whole problem
> collapses away and we don't need any language features at all:
>
>     template<class Vec>
>     auto dotproduct(const Vec& a, const Vec& b)
>     {
>         auto f = [](auto&& accumulator, auto&& ab) {
>             return accumulator + (ab.first * ab.second);
>         };
>         return my::tuple_foldl(f, 0, my::tuple_zip(a, b)));
>     }

Isn't that the same as `std::experimental::apply`? Yes, there are some
instances where a language feature would be just a shortcut. The places
where it's more useful, or *necessary* (initializer lists), have been
previously discussed.

--
Matthew

--

---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Thu, 21 Jan 2016 08:40:03 -0800
Raw View
On Thursday 21 January 2016 10:09:02 Matthew Woehlke wrote:
> Nor is using a scratch variable really an option,
> because that would require adding an explicit scope to make the QDebug
> instance destruct at the right place.

That's a choice and you can always choose differently.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--

---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Sat, 23 Jan 2016 11:48:58 -0800 (PST)
Raw View
------=_Part_4234_659674883.1453578538832
Content-Type: multipart/alternative;
 boundary="----=_Part_4235_616875723.1453578538833"

------=_Part_4235_616875723.1453578538833
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Thursday, January 21, 2016 at 7:40:35 AM UTC-8, Matthew Woehlke wrote:
>
> On 2016-01-20 18:13, Arthur O'Dwyer wrote:=20
> > Off-topic but FYI, I'm still a little generally uncomfortable with the=
=20
> idea=20
> > of "tuple-like type". For example, in C++14 std::array<T,N> has become=
=20
> > "tuple-like", even though it has only one template type parameter.=20
>
> So? The intent of "tuple-like" is that it is a sequence of a fixed=20
> number of values.

[...]=20

> > If we were to standardize a "typelist" template (e.g.=20
> > mpl::vector<T...>), would it *not* be "tuple-like" because you=20
> > couldn't use std::get<I> on it at runtime?=20
>
> Yeees.... also because tuple_size wouldn't (couldn't) be constexpr. IOW,=
=20
> it is not "tuple-like" if it is not fixed(-at-compile-time)-size.=20
>

Presumably tuple_size would be defined for mpl::vector the same way it is=
=20
for std::tuple.

template< class... Types >

class tuple_size< mpl::v <http://en.cppreference.com/w/cpp/utility/tuple>
ector<Types...> >
 : public std::integral_constant=20
<http://en.cppreference.com/w/cpp/types/integral_constant><std::size_t=20
<http://en.cppreference.com/w/cpp/types/size_t>, sizeof...(Types)> { };
=20

> This is of course why std::array is tuple-like and std::vector is not.=20
>

mpl::vector is not std::vector, though.


> Using "..." to unpack things isn't the ugly part of the proposal IMHO,=20
> > though!=20
> > The ugly part, and the part that's going to get bikeshedded to death, i=
s=20
> > the choice of [*] as a prefix operator.=20
> > Especially since there's another proposal=20
> > <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0018r0.html>=
=20
> > before the Committee (or was, at Kona) suggesting that [*](){ ... }=20
> should=20
> > be the syntax for "capture *this by copy".=20
>
> I'm open to other (good) ideas... one reason I really like `[*]` however=
=20
> is because it becomes natural to further extend it to slicing, e.g.=20
> `[1]`, `[:3]`, `[2:4]`, `[1,2:4,5,8:]`, and so forth.=20
>
> I think slicing is important; already with assignment unpacking, we have=
=20
> the problem of how to deal with unwanted values. If we have slicing, we=
=20
> can just write:=20
>
>   auto {a, b} =3D [2,5]tuple_like;=20
>

This seems like a non-starter because of the ambiguity of

    int x =3D 1;
    int y =3D 2;
    auto {a, b} =3D [x,y](std::array<int,3>(z));
    auto {a, b} =3D [x,y](std::array<int,3> z){ return z }();

Notice how many tokens deep you have to get into that expression before you=
=20
can figure out whether it's a lambda or a prefix-slice-expression.
The "prefix square brackets" syntax has been fully co-opted by lambdas at=
=20
this point; you won't be able to use it for a second major feature unless=
=20
you're *really* careful.


Per above, `[*]` wasn't chosen lightly. The use of `[]`s suggest the=20
> indexing operator, which therefore implies something being extracted=20
> from a container (and are extensible to multiple specifications of=20
> "something"). The use of `*` is taken directly from Python, and per *my*=
=20
> proposal, means the exact same thing. (Nicol's would make it... similar,=
=20
> but less "exactly the same".)=20
>

Yes, I recognized prefix * as being a Pythonism. Matching Python *would* be=
=20
nice. But, because prefix * already has a different meaning in C++, we've=
=20
got to change the syntax at least a little bit. We also have to change it=
=20
to fit in with the existing features of the language, such as=20
pack-expansion, fold-expressions, and so on.
=20

> `~` "comes out of nowhere", if you will... there is no existing use in=20
> any language that would lead one to associate it with unpacking.=20
>

Right; I picked it because it was obviously available (whereas other=20
constructs such as "postfix :" weren't obviously available). However, I=20
could teach it pretty easily. "If you want to unpack a tuple into its first=
=20
element, second ~, third ~, etc., you use postfix ~."
See http://www.merriam-webster.com/dictionary/swung%20dash =E2=80=94 and fo=
r those=20
who haven't heard of this usage in English, it's still not too far a step=
=20
from "postfix dot-dot-dot" to "postfix squiggle".
But again, the syntax will always be subject to bikeshedding. I'm not too=
=20
worried about that part. x~ is just what looks nicest for writing up=20
examples.
=20

> If we postulate a made-up my::tuple_foldl, though, the whole problem=20
> > collapses away and we don't need any language features at all:=20
> >=20
> >     template<class Vec>=20
> >     auto dotproduct(const Vec& a, const Vec& b)=20
> >     {=20
> >         auto f =3D [](auto&& accumulator, auto&& ab) {=20
> >             return accumulator + (ab.first * ab.second);=20
> >         };=20
> >         return my::tuple_foldl(f, 0, my::tuple_zip(a, b)));=20
> >     }=20
>
> Isn't that the same as `std::experimental::apply`?


No, not at all. foldl is one of the functional primitives we'd want a=20
tuple-functional-programming library to provide, along with tuple_map,=20
tuple_foldr, tuple_filter, tuple_zip... and probably lots more. But if we=
=20
get tuple-unpacking into the language, then we can use pack-expressions to=
=20
simulate all of those =E2=80=94 more readably and more efficiently.

=E2=80=93Arthur

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

------=_Part_4235_616875723.1453578538833
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Thursday, January 21, 2016 at 7:40:35 AM UTC-8, Matthew Woehlke wrote:<b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;">On 2016-01-20 18:13, Arthur O&#3=
9;Dwyer wrote:
<br>&gt; Off-topic but FYI, I&#39;m still a little generally uncomfortable =
with the idea
<br>&gt; of &quot;tuple-like type&quot;. For example, in C++14 std::array&l=
t;T,N&gt; has become
<br>&gt; &quot;tuple-like&quot;, even though it has only one template type =
parameter.
<br>
<br>So? The intent of &quot;tuple-like&quot; is that it is a sequence of a =
fixed
<br>number of values.</blockquote><div>[...]=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;">&gt; If we were to standardize a &quot;typelist=
&quot; template (e.g.
<br>&gt; mpl::vector&lt;T...&gt;), would it *not* be &quot;tuple-like&quot;=
 because you
<br>&gt; couldn&#39;t use std::get&lt;I&gt; on it at runtime?
<br>
<br>Yeees.... also because tuple_size wouldn&#39;t (couldn&#39;t) be conste=
xpr. IOW,
<br>it is not &quot;tuple-like&quot; if it is not fixed(-at-compile-time)-s=
ize.
<br></blockquote><div><br></div><div>Presumably tuple_size would be defined=
 for mpl::vector the same way it is for std::tuple.</div><div><br></div><sp=
an class=3D"kw1" style=3D"line-height: 1.1em; color: rgb(0, 0, 221); font-f=
amily: DejaVuSansMono, &#39;DejaVu Sans Mono&#39;, courier, monospace; whit=
e-space: nowrap;">template</span><span class=3D"sy1" style=3D"line-height: =
1.1em; color: rgb(0, 0, 128); font-family: DejaVuSansMono, &#39;DejaVu Sans=
 Mono&#39;, courier, monospace; white-space: nowrap;">&lt;</span><span styl=
e=3D"color: rgb(0, 0, 0); font-family: DejaVuSansMono, &#39;DejaVu Sans Mon=
o&#39;, courier, monospace; white-space: nowrap;">=C2=A0</span><span class=
=3D"kw1" style=3D"line-height: 1.1em; color: rgb(0, 0, 221); font-family: D=
ejaVuSansMono, &#39;DejaVu Sans Mono&#39;, courier, monospace; white-space:=
 nowrap;">class</span><span style=3D"color: rgb(0, 0, 0); font-family: Deja=
VuSansMono, &#39;DejaVu Sans Mono&#39;, courier, monospace; white-space: no=
wrap;">...=C2=A0</span><span class=3D"me1" style=3D"line-height: 1.1em; col=
or: rgb(0, 0, 0); font-family: DejaVuSansMono, &#39;DejaVu Sans Mono&#39;, =
courier, monospace; white-space: nowrap;">Types</span><span style=3D"color:=
 rgb(0, 0, 0); font-family: DejaVuSansMono, &#39;DejaVu Sans Mono&#39;, cou=
rier, monospace; white-space: nowrap;">=C2=A0</span><span class=3D"sy1" sty=
le=3D"line-height: 1.1em; color: rgb(0, 0, 128); font-family: DejaVuSansMon=
o, &#39;DejaVu Sans Mono&#39;, courier, monospace; white-space: nowrap;">&g=
t;</span><br style=3D"color: rgb(0, 0, 0); font-family: DejaVuSansMono, &#3=
9;DejaVu Sans Mono&#39;, courier, monospace; white-space: nowrap;"><p style=
=3D"line-height: 1.1em; color: rgb(0, 0, 0); font-family: DejaVuSansMono, &=
#39;DejaVu Sans Mono&#39;, courier, monospace; white-space: nowrap;"><span =
class=3D"kw1" style=3D"line-height: 1.1em; color: rgb(0, 0, 221);">class</s=
pan>=C2=A0tuple_size<span class=3D"sy1" style=3D"line-height: 1.1em; color:=
 rgb(0, 0, 128);">&lt;</span>=C2=A0<span class=3D"kw938" style=3D"color: rg=
b(0, 48, 128); background-image: none; line-height: 1.1em;"><a href=3D"http=
://en.cppreference.com/w/cpp/utility/tuple" style=3D"color: rgb(0, 48, 128)=
; background-image: none;">mpl::<span class=3D"me2" style=3D"line-height: 1=
..1em;">v</span></a>ector</span><span class=3D"sy1" style=3D"line-height: 1.=
1em; color: rgb(0, 0, 128);">&lt;</span>Types...<span class=3D"sy1" style=
=3D"line-height: 1.1em; color: rgb(0, 0, 128);">&gt;</span>=C2=A0<span clas=
s=3D"sy1" style=3D"line-height: 1.1em; color: rgb(0, 0, 128);">&gt;</span><=
br></p><div><span style=3D"color: rgb(0, 0, 0); font-family: DejaVuSansMono=
, &#39;DejaVu Sans Mono&#39;, courier, monospace; white-space: nowrap;">=C2=
=A0</span><span class=3D"sy4" style=3D"line-height: 1.1em; color: rgb(0, 12=
8, 128); font-family: DejaVuSansMono, &#39;DejaVu Sans Mono&#39;, courier, =
monospace; white-space: nowrap;">:</span><span style=3D"color: rgb(0, 0, 0)=
; font-family: DejaVuSansMono, &#39;DejaVu Sans Mono&#39;, courier, monospa=
ce; white-space: nowrap;">=C2=A0</span><span class=3D"kw1" style=3D"line-he=
ight: 1.1em; color: rgb(0, 0, 221); font-family: DejaVuSansMono, &#39;DejaV=
u Sans Mono&#39;, courier, monospace; white-space: nowrap;">public</span><s=
pan style=3D"color: rgb(0, 0, 0); font-family: DejaVuSansMono, &#39;DejaVu =
Sans Mono&#39;, courier, monospace; white-space: nowrap;">=C2=A0</span><a h=
ref=3D"http://en.cppreference.com/w/cpp/types/integral_constant" style=3D"c=
olor: rgb(0, 48, 128); background-image: none; font-family: DejaVuSansMono,=
 &#39;DejaVu Sans Mono&#39;, courier, monospace; white-space: nowrap;"><spa=
n class=3D"kw553" style=3D"line-height: 1.1em;">std::<span class=3D"me2" st=
yle=3D"line-height: 1.1em;">integral_constant</span></span></a><span class=
=3D"sy1" style=3D"line-height: 1.1em; color: rgb(0, 0, 128); font-family: D=
ejaVuSansMono, &#39;DejaVu Sans Mono&#39;, courier, monospace; white-space:=
 nowrap;">&lt;</span><a href=3D"http://en.cppreference.com/w/cpp/types/size=
_t" style=3D"color: rgb(0, 48, 128); background-image: none; font-family: D=
ejaVuSansMono, &#39;DejaVu Sans Mono&#39;, courier, monospace; white-space:=
 nowrap;"><span class=3D"kw100" style=3D"line-height: 1.1em;">std::<span cl=
ass=3D"me2" style=3D"line-height: 1.1em;">size_t</span></span></a><span sty=
le=3D"color: rgb(0, 0, 0); font-family: DejaVuSansMono, &#39;DejaVu Sans Mo=
no&#39;, courier, monospace; white-space: nowrap;">, sizeof...</span><span =
class=3D"br0" style=3D"line-height: 1.1em; color: rgb(0, 128, 0); font-fami=
ly: DejaVuSansMono, &#39;DejaVu Sans Mono&#39;, courier, monospace; white-s=
pace: nowrap;">(</span><span style=3D"color: rgb(0, 0, 0); font-family: Dej=
aVuSansMono, &#39;DejaVu Sans Mono&#39;, courier, monospace; white-space: n=
owrap;">Types</span><span class=3D"br0" style=3D"line-height: 1.1em; color:=
 rgb(0, 128, 0); font-family: DejaVuSansMono, &#39;DejaVu Sans Mono&#39;, c=
ourier, monospace; white-space: nowrap;">)</span><span class=3D"sy1" style=
=3D"line-height: 1.1em; color: rgb(0, 0, 128); font-family: DejaVuSansMono,=
 &#39;DejaVu Sans Mono&#39;, courier, monospace; white-space: nowrap;">&gt;=
</span><span style=3D"color: rgb(0, 0, 0); font-family: DejaVuSansMono, &#3=
9;DejaVu Sans Mono&#39;, courier, monospace; white-space: nowrap;">=C2=A0</=
span><span class=3D"br0" style=3D"line-height: 1.1em; color: rgb(0, 128, 0)=
; font-family: DejaVuSansMono, &#39;DejaVu Sans Mono&#39;, courier, monospa=
ce; white-space: nowrap;">{</span><span style=3D"color: rgb(0, 0, 0); font-=
family: DejaVuSansMono, &#39;DejaVu Sans Mono&#39;, courier, monospace; whi=
te-space: nowrap;">=C2=A0</span><span class=3D"br0" style=3D"line-height: 1=
..1em; color: rgb(0, 128, 0); font-family: DejaVuSansMono, &#39;DejaVu Sans =
Mono&#39;, courier, monospace; white-space: nowrap;">}</span><span class=3D=
"sy4" style=3D"line-height: 1.1em; color: rgb(0, 128, 128); font-family: De=
jaVuSansMono, &#39;DejaVu Sans Mono&#39;, courier, monospace; white-space: =
nowrap;">;</span></div><div>=C2=A0<br></div><blockquote class=3D"gmail_quot=
e" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddin=
g-left: 1ex;">This is of course why std::array is tuple-like and std::vecto=
r is not.
<br></blockquote><div><br></div><div>mpl::vector is not std::vector, though=
..</div><div><br></div><div><br></div><blockquote class=3D"gmail_quote" styl=
e=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left:=
 1ex;">&gt; Using &quot;...&quot; to unpack things isn&#39;t the ugly part =
of the proposal IMHO,
<br>&gt; though!
<br>&gt; The ugly part, and the part that&#39;s going to get bikeshedded to=
 death, is
<br>&gt; the choice of [*] as a prefix operator.
<br>&gt; Especially since there&#39;s another proposal
<br>&gt; &lt;<a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/=
2015/p0018r0.html" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.h=
ref=3D&#39;http://www.google.com/url?q\75http%3A%2F%2Fwww.open-std.org%2Fjt=
c1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2015%2Fp0018r0.html\46sa\75D\46sntz\0751=
\46usg\75AFQjCNEWxb4b9D-nRkelfhczkAcBLsNO_w&#39;;return true;" onclick=3D"t=
his.href=3D&#39;http://www.google.com/url?q\75http%3A%2F%2Fwww.open-std.org=
%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2015%2Fp0018r0.html\46sa\75D\46sntz=
\0751\46usg\75AFQjCNEWxb4b9D-nRkelfhczkAcBLsNO_w&#39;;return true;">http://=
www.open-std.org/jtc1/<wbr>sc22/wg21/docs/papers/2015/<wbr>p0018r0.html</a>=
&gt;
<br>&gt; before the Committee (or was, at Kona) suggesting that [*](){ ... =
} should
<br>&gt; be the syntax for &quot;capture *this by copy&quot;.
<br>
<br>I&#39;m open to other (good) ideas... one reason I really like `[*]` ho=
wever
<br>is because it becomes natural to further extend it to slicing, e.g.
<br>`[1]`, `[:3]`, `[2:4]`, `[1,2:4,5,8:]`, and so forth.
<br>
<br>I think slicing is important; already with assignment unpacking, we hav=
e
<br>the problem of how to deal with unwanted values. If we have slicing, we
<br>can just write:
<br>
<br>=C2=A0 auto {a, b} =3D [2,5]tuple_like;
<br></blockquote><div><br></div><div>This seems like a non-starter because =
of the ambiguity of</div><div><br></div><div>=C2=A0 =C2=A0 int x =3D 1;</di=
v><div>=C2=A0 =C2=A0 int y =3D 2;</div><div>=C2=A0 =C2=A0 auto {a, b} =3D [=
x,y](std::array&lt;int,3&gt;(z));</div><div>=C2=A0 =C2=A0 auto {a, b} =3D [=
x,y](std::array&lt;int,3&gt; z){ return z }();</div><div><br></div><div>Not=
ice how many tokens deep you have to get into that expression before you ca=
n figure out whether it&#39;s a lambda or a prefix-slice-expression.</div><=
div>The &quot;prefix square brackets&quot; syntax has been fully co-opted b=
y lambdas at this point; you won&#39;t be able to use it for a second major=
 feature unless you&#39;re <i>really</i> careful.</div><div><br></div><div>=
<br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Per above, `[*]` was=
n&#39;t chosen lightly. The use of `[]`s suggest the
<br>indexing operator, which therefore implies something being extracted
<br>from a container (and are extensible to multiple specifications of
<br>&quot;something&quot;). The use of `*` is taken directly from Python, a=
nd per *my*
<br>proposal, means the exact same thing. (Nicol&#39;s would make it... sim=
ilar,
<br>but less &quot;exactly the same&quot;.)
<br></blockquote><div><br></div><div>Yes, I recognized prefix <font face=3D=
"courier new, monospace">*</font> as being a Pythonism. Matching Python <i>=
would</i> be nice. But, because prefix <font face=3D"courier new, monospace=
">*</font> already has a different meaning in C++, we&#39;ve got to change =
the syntax at least a little bit. We also have to change it to fit in with =
the existing features of the language, such as pack-expansion, fold-express=
ions, and so on.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" st=
yle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-lef=
t: 1ex;">`~` &quot;comes out of nowhere&quot;, if you will... there is no e=
xisting use in
<br>any language that would lead one to associate it with unpacking.
<br></blockquote><div><br></div><div>Right; I picked it because it was obvi=
ously available (whereas other constructs such as &quot;postfix <font face=
=3D"courier new, monospace">:</font>&quot; weren&#39;t obviously available)=
.. However, I could teach it pretty easily. &quot;If you want to unpack a tu=
ple into its first element, second ~, third ~, etc., you use postfix <font =
face=3D"courier new, monospace">~</font>.&quot;</div><div>See <a href=3D"ht=
tp://www.merriam-webster.com/dictionary/swung%20dash">http://www.merriam-we=
bster.com/dictionary/swung%20dash</a> =E2=80=94 and for those who haven&#39=
;t heard of this usage in English, it&#39;s still not too far a step from &=
quot;postfix dot-dot-dot&quot; to &quot;postfix squiggle&quot;.<br></div><d=
iv>But again, the syntax will always be subject to bikeshedding. I&#39;m no=
t too worried about that part. <font face=3D"courier new, monospace">x~</fo=
nt> is just what looks nicest for writing up examples.</div><div>=C2=A0</di=
v><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">&gt; If we po=
stulate a made-up my::tuple_foldl, though, the whole problem
<br>&gt; collapses away and we don&#39;t need any language features at all:
<br>&gt;=20
<br>&gt; =C2=A0 =C2=A0 template&lt;class Vec&gt;
<br>&gt; =C2=A0 =C2=A0 auto dotproduct(const Vec&amp; a, const Vec&amp; b)
<br>&gt; =C2=A0 =C2=A0 {
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 auto f =3D [](auto&amp;&amp; accumulat=
or, auto&amp;&amp; ab) {
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return accumulator + (ab=
..first * ab.second);
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 };
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 return my::tuple_foldl(f, 0, my::tuple=
_zip(a, b)));
<br>&gt; =C2=A0 =C2=A0 }
<br>
<br>Isn&#39;t that the same as `std::experimental::apply`?</blockquote><div=
><br></div><div>No, not at all. <font face=3D"courier new, monospace">foldl=
</font> is one of the functional primitives we&#39;d want a tuple-functiona=
l-programming library to provide, along with tuple_map, tuple_foldr, tuple_=
filter, tuple_zip... and probably lots more. But if we get tuple-unpacking =
into the language, then we can use pack-expressions to simulate all of thos=
e =E2=80=94 more readably and more efficiently.</div><div><br></div><div>=
=E2=80=93Arthur</div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

------=_Part_4235_616875723.1453578538833--
------=_Part_4234_659674883.1453578538832--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 25 Jan 2016 09:26:23 -0500
Raw View
On 2016-01-23 14:48, Arthur O'Dwyer wrote:
> On Thursday, January 21, 2016 at 7:40:35 AM UTC-8, Matthew Woehlke wrote:
>>
>> On 2016-01-20 18:13, Arthur O'Dwyer wrote:
>>> Off-topic but FYI, I'm still a little generally uncomfortable with the
>> idea
>>> of "tuple-like type". For example, in C++14 std::array<T,N> has become
>>> "tuple-like", even though it has only one template type parameter.
>>
>> So? The intent of "tuple-like" is that it is a sequence of a fixed
>> number of values.
>
> [...]
>
>>> If we were to standardize a "typelist" template (e.g.
>>> mpl::vector<T...>), would it *not* be "tuple-like" because you
>>> couldn't use std::get<I> on it at runtime?
>>
>> Yeees.... also because tuple_size wouldn't (couldn't) be constexpr. IOW,
>> it is not "tuple-like" if it is not fixed(-at-compile-time)-size.
>
> Presumably tuple_size would be defined for mpl::vector the same way it is
> for std::tuple.

std::tuple *is fixed size*. I am not familiar with mpl::vector, but
looking at
http://www.boost.org/doc/libs/1_59_0/libs/mpl/doc/refmanual/vector.html,
it certainly does not appear to be fixed size.

Let me rephrase that: tuple_size *must be constexpr*. Unpacking code is
generated at compile time, which requires that the size be *constant*
and *known at compile time*, i.e. constexpr.

Unless I am completely misreading the doc, I don't see how that could be
true for mpl::vector.

Am I missing something?

>> This is of course why std::array is tuple-like and std::vector is not.
>
> mpl::vector is not std::vector, though.

They both have *dynamic size*.

>> I'm open to other (good) ideas... one reason I really like `[*]` however
>> is because it becomes natural to further extend it to slicing, e.g.
>> `[1]`, `[:3]`, `[2:4]`, `[1,2:4,5,8:]`, and so forth.
>>
>> I think slicing is important; already with assignment unpacking, we have
>> the problem of how to deal with unwanted values. If we have slicing, we
>> can just write:
>>
>>   auto {a, b} = [2,5]tuple_like;
>
> This seems like a non-starter because of the ambiguity of
>
>     int x = 1;
>     int y = 2;
>     auto {a, b} = [x,y](std::array<int,3>(z));
>     auto {a, b} = [x,y](std::array<int,3> z){ return z }();
>
> Notice how many tokens deep you have to get into that expression before you
> can figure out whether it's a lambda or a prefix-slice-expression.

I see that it took two characters:

 - '[': don't know yet
 - 'x': not an integer literal -> not a slice expression

Slicing (at least this form) would be permitted only with integer
literals. Since integer literals are not valid capture expressions, it
takes exactly two tokens, every time.

(Okay, we should probably allow template parameters and constexpr
expressions as slice arguments, but even those are fairly distinctive.)

For reasons similar to why mpl::vector is not tuple-like, slicing cannot
take non-constexpr indices.

>> Per above, `[*]` wasn't chosen lightly. The use of `[]`s suggest the
>> indexing operator, which therefore implies something being extracted
>> from a container (and are extensible to multiple specifications of
>> "something"). The use of `*` is taken directly from Python, and per *my*
>> proposal, means the exact same thing. (Nicol's would make it... similar,
>> but less "exactly the same".)
>
> Yes, I recognized prefix * as being a Pythonism. Matching Python *would* be
> nice. But, because prefix * already has a different meaning in C++, we've
> got to change the syntax at least a little bit.

What about `[:]`? Again, looking ahead to slicing, this can be seen as
an unbounded slice. (In fact, in Python, that's exactly what it is...)

Agreed it's somewhat bikeshedding, but I still have a fairly strong
preference for a syntax that will allow slicing.

--
Matthew

--

---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Mon, 25 Jan 2016 17:13:27 +0200
Raw View
On 25 January 2016 at 16:26, Matthew Woehlke <mwoehlke.floss@gmail.com> wrote:
>> Presumably tuple_size would be defined for mpl::vector the same way it is
>> for std::tuple.
>
> std::tuple *is fixed size*. I am not familiar with mpl::vector, but
> looking at
> http://www.boost.org/doc/libs/1_59_0/libs/mpl/doc/refmanual/vector.html,
> it certainly does not appear to be fixed size.

Zomg wtf, mpl::vector is not only fixed size, but also immutable.
You can't change its size, the way append works in mpl is that it
gives you a completely new type, that is, it's completely pure with
no side-effects.

>> mpl::vector is not std::vector, though.
> They both have *dynamic size*.

Nonsense.

--

---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 25 Jan 2016 10:32:34 -0500
Raw View
On 2016-01-25 10:13, Ville Voutilainen wrote:
> On 25 January 2016 at 16:26, Matthew Woehlke <mwoehlke.floss@gmail.com> wrote:
>>> Presumably tuple_size would be defined for mpl::vector the same way it is
>>> for std::tuple.
>>
>> std::tuple *is fixed size*. I am not familiar with mpl::vector, but
>> looking at
>> http://www.boost.org/doc/libs/1_59_0/libs/mpl/doc/refmanual/vector.html,
>> it certainly does not appear to be fixed size.
>
> Zomg wtf, mpl::vector is not only fixed size, but also immutable.
> You can't change its size, the way append works in mpl is that it
> gives you a completely new type, that is, it's completely pure with
> no side-effects.

Bah. Okay, that's what I get for skimming the doc :-). (Y'know, you
could be polite and reply to the "am I missing something" part of my
previous post...)

But if that's the case, then what's the problem here? Arthur originally
said:

On 2016-01-20 18:13, Arthur O'Dwyer wrote:
> would [mpl::vector] *not* be "tuple-like" because you couldn't use
> std::get<I> on it at runtime?

....but then, I don't understand why that would be true?

Back to that question, yes, the idea as I understand it is that
"tuple-like" <=> "can use get<N>". Why is that an issue?

--
Matthew

--

---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Mon, 25 Jan 2016 18:25:54 +0200
Raw View
On 25 January 2016 at 17:32, Matthew Woehlke <mwoehlke.floss@gmail.com> wrote:
> But if that's the case, then what's the problem here? Arthur originally
> said:
>
> On 2016-01-20 18:13, Arthur O'Dwyer wrote:
>> would [mpl::vector] *not* be "tuple-like" because you couldn't use
>> std::get<I> on it at runtime?
>
> ...but then, I don't understand why that would be true?
>
> Back to that question, yes, the idea as I understand it is that
> "tuple-like" <=> "can use get<N>". Why is that an issue?


mpl::vector is a container of types, not values. get<N> is a value-getter.

--

---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 25 Jan 2016 12:20:05 -0500
Raw View
On 2016-01-25 11:25, Ville Voutilainen wrote:
> On 25 January 2016 at 17:32, Matthew Woehlke <mwoehlke.floss@gmail.com> wrote:
>> But if that's the case, then what's the problem here? Arthur originally
>> said:
>>
>> On 2016-01-20 18:13, Arthur O'Dwyer wrote:
>>> would [mpl::vector] *not* be "tuple-like" because you couldn't use
>>> std::get<I> on it at runtime?
>>
>> ...but then, I don't understand why that would be true?
>>
>> Back to that question, yes, the idea as I understand it is that
>> "tuple-like" <=> "can use get<N>". Why is that an issue?
>
>
> mpl::vector is a container of types, not values. get<N> is a value-getter.

Ah. Um... how would you then *use* an mpl::vector in any context that
you would use a tuple-like? A std::tuple is certainly a value
collection. By extension, a tuple-like is also a value collection.

So... different premise, but same question; is there a problem here (and
if so, why)?

--
Matthew

--

---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Mon, 25 Jan 2016 19:25:55 +0200
Raw View
On 25 January 2016 at 19:20, Matthew Woehlke <mwoehlke.floss@gmail.com> wrote:
> On 2016-01-25 11:25, Ville Voutilainen wrote:
>> On 25 January 2016 at 17:32, Matthew Woehlke <mwoehlke.floss@gmail.com> wrote:
>>> But if that's the case, then what's the problem here? Arthur originally
>>> said:
>>>
>>> On 2016-01-20 18:13, Arthur O'Dwyer wrote:
>>>> would [mpl::vector] *not* be "tuple-like" because you couldn't use
>>>> std::get<I> on it at runtime?
>>>
>>> ...but then, I don't understand why that would be true?
>>>
>>> Back to that question, yes, the idea as I understand it is that
>>> "tuple-like" <=> "can use get<N>". Why is that an issue?
>>
>>
>> mpl::vector is a container of types, not values. get<N> is a value-getter.
>
> Ah. Um... how would you then *use* an mpl::vector in any context that
> you would use a tuple-like? A std::tuple is certainly a value
> collection. By extension, a tuple-like is also a value collection.
>
> So... different premise, but same question; is there a problem here (and
> if so, why)?


If your question is whether it's a problem that mpl::vector isn't
tuple-like, I would
be inclined to say that the answer is no. :)

--

---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Mon, 25 Jan 2016 11:37:51 -0800
Raw View
--047d7bb04ad6651425052a2db46c
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Mon, Jan 25, 2016 at 9:20 AM, Matthew Woehlke <mwoehlke.floss@gmail.com>
wrote:

> On 2016-01-25 11:25, Ville Voutilainen wrote:
> > On 25 January 2016 at 17:32, Matthew Woehlke <mwoehlke.floss@gmail.com>
> wrote:
> >> On 2016-01-20 18:13, Arthur O'Dwyer wrote:
> >>> would [mpl::vector] *not* be "tuple-like" because you couldn't use
> >>> std::get<I> on it at runtime?
> >>
> >> ...but then, I don't understand why that would be true?
> >>
> >> Back to that question, yes, the idea as I understand it is that
> >> "tuple-like" <=3D> "can use get<N>". Why is that an issue?
> >
> > mpl::vector is a container of types, not values. get<N> is a
> value-getter.
>
> Ah. Um... how would you then *use* an mpl::vector in any context that
> you would use a tuple-like? A std::tuple is certainly a value
> collection. By extension, a tuple-like is also a value collection.
>

As I explained in my original post, it seems obvious that we'd define

template< class... Types >

class tuple_size< mpl::v <http://en.cppreference.com/w/cpp/utility/tuple>
ector<Types...> >
 : public std::integral_constant
<http://en.cppreference.com/w/cpp/types/integral_constant><std::size_t
<http://en.cppreference.com/w/cpp/types/size_t>, sizeof...(Types)> { };

and also

// recursive casetemplate< std::size_t
<http://en.cppreference.com/w/cpp/types/size_t> I, class Head,
class... Tail >struct tuple_element<I, mpl::v
<http://en.cppreference.com/w/cpp/utility/tuple>ector<Head, Tail...>>
    : std::tuple_element<I-1, mpl::v
<http://en.cppreference.com/w/cpp/utility/tuple>ector<Tail...>> { };
// base casetemplate< class Head, class... Tail >struct
tuple_element<0, mpl::v
<http://en.cppreference.com/w/cpp/utility/tuple>ector<Head, Tail...>>
{
   typedef Head type;

};

The "Sprout" C++14 library includes these definitions today.
https://github.com/bolero-MURAKAMI/Sprout/blob/master/sprout/type/boost/mpl=
/vector.hpp

However, there's no such "obvious" definition for std::get.
The most plausible one would be

// please stifle all irrelevant comments re: overload sets and CV-qualifier=
s

template< std::size_t <http://en.cppreference.com/w/cpp/types/size_t> I,
class... Types >

auto get(const mpl::v <http://en.cppreference.com/w/cpp/utility/tuple>ector=
<
Types...>&)

   -> std::add_rvalue_reference
<http://en.cppreference.com/w/cpp/types/add_reference>_t<tuple_element_t<I,
mpl::v <http://en.cppreference.com/w/cpp/utility/tuple>ector<Types...>>>;

// deliberately left with no implementation, a la std::declval


So what we're left with is: mpl::vector is "not tuple-like", but it *does*
implement tuple_size_v and tuple_element_t.
The only part of the "tuple-like" contract that it fails to have an obvious
implementation for is the one part of the "tuple-like" contract *whose name
doesn't involve the word "tuple"*.
*That* is why the concept of "tuple-like" bothers me.

=E2=80=93Arthur

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

--047d7bb04ad6651425052a2db46c
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Mon, Jan 25, 2016 at 9:20 AM, Matthew Woehlke <span dir=
=3D"ltr">&lt;<a href=3D"mailto:mwoehlke.floss@gmail.com" target=3D"_blank">=
mwoehlke.floss@gmail.com</a>&gt;</span> wrote:<br><div class=3D"gmail_extra=
"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,2=
04);border-left-style:solid;padding-left:1ex"><span class=3D"">On 2016-01-2=
5 11:25, Ville Voutilainen wrote:<br>
&gt; On 25 January 2016 at 17:32, Matthew Woehlke &lt;<a href=3D"mailto:mwo=
ehlke.floss@gmail.com">mwoehlke.floss@gmail.com</a>&gt; wrote:<br>&gt;&gt; =
On 2016-01-20 18:13, Arthur O&#39;Dwyer wrote:<br>
&gt;&gt;&gt; would [mpl::vector] *not* be &quot;tuple-like&quot; because yo=
u couldn&#39;t use<br>
&gt;&gt;&gt; std::get&lt;I&gt; on it at runtime?<br>
&gt;&gt;<br>
&gt;&gt; ...but then, I don&#39;t understand why that would be true?<br>
&gt;&gt;<br>
&gt;&gt; Back to that question, yes, the idea as I understand it is that<br=
>
&gt;&gt; &quot;tuple-like&quot; &lt;=3D&gt; &quot;can use get&lt;N&gt;&quot=
;. Why is that an issue?<br>&gt;<br>
&gt; mpl::vector is a container of types, not values. get&lt;N&gt; is a val=
ue-getter.<br>
<br>
</span>Ah. Um... how would you then *use* an mpl::vector in any context tha=
t<br>
you would use a tuple-like? A std::tuple is certainly a value<br>
collection. By extension, a tuple-like is also a value collection.<br></blo=
ckquote><div><br></div><div>As I explained in my original post, it seems ob=
vious that we&#39;d define</div><div><br></div><div><span class=3D"" style=
=3D"line-height:1.1em;margin:0px;padding:0px;color:rgb(0,0,221);font-family=
:DejaVuSansMono,&#39;DejaVu Sans Mono&#39;,courier,monospace;font-size:13px=
;white-space:nowrap">template</span><span class=3D"" style=3D"line-height:1=
..1em;margin:0px;padding:0px;color:rgb(0,0,128);font-family:DejaVuSansMono,&=
#39;DejaVu Sans Mono&#39;,courier,monospace;font-size:13px;white-space:nowr=
ap">&lt;</span><span style=3D"color:rgb(0,0,0);font-family:DejaVuSansMono,&=
#39;DejaVu Sans Mono&#39;,courier,monospace;font-size:13px;white-space:nowr=
ap">=C2=A0</span><span class=3D"" style=3D"line-height:1.1em;margin:0px;pad=
ding:0px;color:rgb(0,0,221);font-family:DejaVuSansMono,&#39;DejaVu Sans Mon=
o&#39;,courier,monospace;font-size:13px;white-space:nowrap">class</span><sp=
an style=3D"color:rgb(0,0,0);font-family:DejaVuSansMono,&#39;DejaVu Sans Mo=
no&#39;,courier,monospace;font-size:13px;white-space:nowrap">...=C2=A0</spa=
n><span class=3D"" style=3D"line-height:1.1em;margin:0px;padding:0px;color:=
rgb(0,0,0);font-family:DejaVuSansMono,&#39;DejaVu Sans Mono&#39;,courier,mo=
nospace;font-size:13px;white-space:nowrap">Types</span><span style=3D"color=
:rgb(0,0,0);font-family:DejaVuSansMono,&#39;DejaVu Sans Mono&#39;,courier,m=
onospace;font-size:13px;white-space:nowrap">=C2=A0</span><span class=3D"" s=
tyle=3D"line-height:1.1em;margin:0px;padding:0px;color:rgb(0,0,128);font-fa=
mily:DejaVuSansMono,&#39;DejaVu Sans Mono&#39;,courier,monospace;font-size:=
13px;white-space:nowrap">&gt;</span><br style=3D"color:rgb(0,0,0);font-fami=
ly:DejaVuSansMono,&#39;DejaVu Sans Mono&#39;,courier,monospace;font-size:13=
px;white-space:nowrap"><p style=3D"margin:0px;line-height:1.1em;padding:0px=
;color:rgb(0,0,0);font-family:DejaVuSansMono,&#39;DejaVu Sans Mono&#39;,cou=
rier,monospace;font-size:13px;white-space:nowrap"><span class=3D"" style=3D=
"line-height:1.1em;margin:0px;padding:0px;color:rgb(0,0,221)">class</span>=
=C2=A0tuple_size<span class=3D"" style=3D"line-height:1.1em;margin:0px;padd=
ing:0px;color:rgb(0,0,128)">&lt;</span>=C2=A0<span class=3D"" style=3D"text=
-decoration:none;color:rgb(0,48,128);background-image:none;line-height:1.1e=
m;margin:0px;padding:0px"><a href=3D"http://en.cppreference.com/w/cpp/utili=
ty/tuple" style=3D"text-decoration:none;color:rgb(0,48,128);background-imag=
e:none">mpl::<span class=3D"" style=3D"line-height:1.1em;margin:0px;padding=
:0px">v</span></a>ector</span><span class=3D"" style=3D"line-height:1.1em;m=
argin:0px;padding:0px;color:rgb(0,0,128)">&lt;</span>Types...<span class=3D=
"" style=3D"line-height:1.1em;margin:0px;padding:0px;color:rgb(0,0,128)">&g=
t;</span>=C2=A0<span class=3D"" style=3D"line-height:1.1em;margin:0px;paddi=
ng:0px;color:rgb(0,0,128)">&gt;</span><br></p><span style=3D"color:rgb(0,0,=
0);font-family:DejaVuSansMono,&#39;DejaVu Sans Mono&#39;,courier,monospace;=
font-size:13px;white-space:nowrap">=C2=A0</span><span class=3D"" style=3D"l=
ine-height:1.1em;margin:0px;padding:0px;color:rgb(0,128,128);font-family:De=
jaVuSansMono,&#39;DejaVu Sans Mono&#39;,courier,monospace;font-size:13px;wh=
ite-space:nowrap">:</span><span style=3D"color:rgb(0,0,0);font-family:DejaV=
uSansMono,&#39;DejaVu Sans Mono&#39;,courier,monospace;font-size:13px;white=
-space:nowrap">=C2=A0</span><span class=3D"" style=3D"line-height:1.1em;mar=
gin:0px;padding:0px;color:rgb(0,0,221);font-family:DejaVuSansMono,&#39;Deja=
Vu Sans Mono&#39;,courier,monospace;font-size:13px;white-space:nowrap">publ=
ic</span><span style=3D"color:rgb(0,0,0);font-family:DejaVuSansMono,&#39;De=
jaVu Sans Mono&#39;,courier,monospace;font-size:13px;white-space:nowrap">=
=C2=A0</span><a href=3D"http://en.cppreference.com/w/cpp/types/integral_con=
stant" style=3D"text-decoration:none;color:rgb(0,48,128);background-image:n=
one;font-family:DejaVuSansMono,&#39;DejaVu Sans Mono&#39;,courier,monospace=
;font-size:13px;white-space:nowrap"><span class=3D"" style=3D"line-height:1=
..1em;margin:0px;padding:0px">std::<span class=3D"" style=3D"line-height:1.1=
em;margin:0px;padding:0px">integral_constant</span></span></a><span class=
=3D"" style=3D"line-height:1.1em;margin:0px;padding:0px;color:rgb(0,0,128);=
font-family:DejaVuSansMono,&#39;DejaVu Sans Mono&#39;,courier,monospace;fon=
t-size:13px;white-space:nowrap">&lt;</span><a href=3D"http://en.cppreferenc=
e.com/w/cpp/types/size_t" style=3D"text-decoration:none;color:rgb(0,48,128)=
;background-image:none;font-family:DejaVuSansMono,&#39;DejaVu Sans Mono&#39=
;,courier,monospace;font-size:13px;white-space:nowrap"><span class=3D"" sty=
le=3D"line-height:1.1em;margin:0px;padding:0px">std::<span class=3D"" style=
=3D"line-height:1.1em;margin:0px;padding:0px">size_t</span></span></a><span=
 style=3D"color:rgb(0,0,0);font-family:DejaVuSansMono,&#39;DejaVu Sans Mono=
&#39;,courier,monospace;font-size:13px;white-space:nowrap">, sizeof...</spa=
n><span class=3D"" style=3D"line-height:1.1em;margin:0px;padding:0px;color:=
rgb(0,128,0);font-family:DejaVuSansMono,&#39;DejaVu Sans Mono&#39;,courier,=
monospace;font-size:13px;white-space:nowrap">(</span><span style=3D"color:r=
gb(0,0,0);font-family:DejaVuSansMono,&#39;DejaVu Sans Mono&#39;,courier,mon=
ospace;font-size:13px;white-space:nowrap">Types</span><span class=3D"" styl=
e=3D"line-height:1.1em;margin:0px;padding:0px;color:rgb(0,128,0);font-famil=
y:DejaVuSansMono,&#39;DejaVu Sans Mono&#39;,courier,monospace;font-size:13p=
x;white-space:nowrap">)</span><span class=3D"" style=3D"line-height:1.1em;m=
argin:0px;padding:0px;color:rgb(0,0,128);font-family:DejaVuSansMono,&#39;De=
jaVu Sans Mono&#39;,courier,monospace;font-size:13px;white-space:nowrap">&g=
t;</span><span style=3D"color:rgb(0,0,0);font-family:DejaVuSansMono,&#39;De=
jaVu Sans Mono&#39;,courier,monospace;font-size:13px;white-space:nowrap">=
=C2=A0</span><span class=3D"" style=3D"line-height:1.1em;margin:0px;padding=
:0px;color:rgb(0,128,0);font-family:DejaVuSansMono,&#39;DejaVu Sans Mono&#3=
9;,courier,monospace;font-size:13px;white-space:nowrap">{</span><span style=
=3D"color:rgb(0,0,0);font-family:DejaVuSansMono,&#39;DejaVu Sans Mono&#39;,=
courier,monospace;font-size:13px;white-space:nowrap">=C2=A0</span><span cla=
ss=3D"" style=3D"line-height:1.1em;margin:0px;padding:0px;color:rgb(0,128,0=
);font-family:DejaVuSansMono,&#39;DejaVu Sans Mono&#39;,courier,monospace;f=
ont-size:13px;white-space:nowrap">}</span><span class=3D"" style=3D"line-he=
ight:1.1em;margin:0px;padding:0px;color:rgb(0,128,128);font-family:DejaVuSa=
nsMono,&#39;DejaVu Sans Mono&#39;,courier,monospace;font-size:13px;white-sp=
ace:nowrap">;</span><br></div><div><br></div><div>and also</div><div><br></=
div><pre class=3D"" style=3D"padding:0px;border:0px none white;color:rgb(0,=
0,0);line-height:1.2em;border-top-left-radius:5px;border-top-right-radius:5=
px;border-bottom-right-radius:5px;border-bottom-left-radius:5px;margin-top:=
0px;margin-bottom:0px;width:55em;overflow:auto;font-size:13px;background-im=
age:none;vertical-align:top;font-family:DejaVuSansMono,&#39;DejaVu Sans Mon=
o&#39;,courier,monospace!important"><span class=3D"" style=3D"color:rgb(144=
,144,144)">// recursive case</span>
<span class=3D"" style=3D"color:rgb(0,0,221)">template</span><span class=3D=
"" style=3D"color:rgb(0,0,128)">&lt;</span> <a href=3D"http://en.cppreferen=
ce.com/w/cpp/types/size_t" style=3D"text-decoration:none;color:rgb(0,48,128=
);background-image:none"><span class=3D"">std::<span class=3D"">size_t</spa=
n></span></a> I, <span class=3D"" style=3D"color:rgb(0,0,221)">class</span>=
 Head, <span class=3D"" style=3D"color:rgb(0,0,221)">class</span>... <span =
class=3D"">Tail</span> <span class=3D"" style=3D"color:rgb(0,0,128)">&gt;</=
span>
<span class=3D"" style=3D"color:rgb(0,0,221)">struct</span> tuple_element<s=
pan class=3D"" style=3D"color:rgb(0,0,128)">&lt;</span>I, <a href=3D"http:/=
/en.cppreference.com/w/cpp/utility/tuple" style=3D"color:rgb(0,48,128);whit=
e-space:nowrap;text-decoration:none;background-image:none">mpl::<span class=
=3D"" style=3D"line-height:1.1em;margin:0px;padding:0px">v</span></a><span =
style=3D"color:rgb(0,48,128);white-space:nowrap">ector</span><span class=3D=
"" style=3D"color:rgb(0,0,128)">&lt;</span>Head, Tail...<span class=3D"" st=
yle=3D"color:rgb(0,0,128)">&gt;&gt;</span>
    <span class=3D"" style=3D"color:rgb(0,128,128)">:</span> std<span class=
=3D"" style=3D"color:rgb(0,128,128)">::</span><span class=3D"">tuple_elemen=
t</span><span class=3D"" style=3D"color:rgb(0,0,128)">&lt;</span>I<span cla=
ss=3D"" style=3D"color:rgb(0,0,64)">-</span><span class=3D"" style=3D"color=
:rgb(0,0,128)">1</span>, <a href=3D"http://en.cppreference.com/w/cpp/utilit=
y/tuple" style=3D"color:rgb(0,48,128);white-space:nowrap;text-decoration:no=
ne;background-image:none">mpl::<span class=3D"" style=3D"line-height:1.1em;=
margin:0px;padding:0px">v</span></a><span style=3D"color:rgb(0,48,128);whit=
e-space:nowrap">ector</span><span class=3D"" style=3D"color:rgb(0,0,128)">&=
lt;</span>Tail...<span class=3D"" style=3D"color:rgb(0,0,128)">&gt;&gt;</sp=
an> <span class=3D"" style=3D"color:rgb(0,128,0)">{</span> <span class=3D""=
 style=3D"color:rgb(0,128,0)">}</span><span class=3D"" style=3D"color:rgb(0=
,128,128)">;</span>

<span class=3D"" style=3D"color:rgb(144,144,144)">// base case</span>
<span class=3D"" style=3D"color:rgb(0,0,221)">template</span><span class=3D=
"" style=3D"color:rgb(0,0,128)">&lt;</span> <span class=3D"" style=3D"color=
:rgb(0,0,221)">class</span> Head, <span class=3D"" style=3D"color:rgb(0,0,2=
21)">class</span>... <span class=3D"">Tail</span> <span class=3D"" style=3D=
"color:rgb(0,0,128)">&gt;</span>
<span class=3D"" style=3D"color:rgb(0,0,221)">struct</span> tuple_element<s=
pan class=3D"" style=3D"color:rgb(0,0,128)">&lt;</span><span class=3D"" sty=
le=3D"color:rgb(0,0,128)">0</span>, <a href=3D"http://en.cppreference.com/w=
/cpp/utility/tuple" style=3D"color:rgb(0,48,128);white-space:nowrap;text-de=
coration:none;background-image:none">mpl::<span class=3D"" style=3D"line-he=
ight:1.1em;margin:0px;padding:0px">v</span></a><span style=3D"color:rgb(0,4=
8,128);white-space:nowrap">ector</span><span class=3D"" style=3D"color:rgb(=
0,0,128)">&lt;</span>Head, Tail...<span class=3D"" style=3D"color:rgb(0,0,1=
28)">&gt;&gt;</span> <span class=3D"" style=3D"color:rgb(0,128,0)">{</span>
   <span class=3D"" style=3D"color:rgb(0,0,221)">typedef</span> Head type<s=
pan class=3D"" style=3D"color:rgb(0,128,128)">;=C2=A0</span>
</pre><div><span class=3D"" style=3D"font-family:DejaVuSansMono,&#39;DejaVu=
 Sans Mono&#39;,courier,monospace;font-size:13px;color:rgb(0,128,0)">}</spa=
n><span class=3D"" style=3D"font-family:DejaVuSansMono,&#39;DejaVu Sans Mon=
o&#39;,courier,monospace;font-size:13px;color:rgb(0,128,128)">;</span></div=
><div><br></div><div>The &quot;Sprout&quot; C++14 library includes these de=
finitions today.</div><div><a href=3D"https://github.com/bolero-MURAKAMI/Sp=
rout/blob/master/sprout/type/boost/mpl/vector.hpp">https://github.com/boler=
o-MURAKAMI/Sprout/blob/master/sprout/type/boost/mpl/vector.hpp<br></a></div=
><div><br></div><div>However, there&#39;s no such &quot;obvious&quot; defin=
ition for std::get.</div><div>The most plausible one would be</div><div><br=
></div><div><pre class=3D"" style=3D"font-size:13px;padding:0px;border:0px =
none white;color:rgb(0,0,0);line-height:1.2em;border-top-left-radius:5px;bo=
rder-top-right-radius:5px;border-bottom-right-radius:5px;border-bottom-left=
-radius:5px;margin-top:0px;margin-bottom:0px;width:55em;overflow:auto;backg=
round-image:none;vertical-align:top;font-family:DejaVuSansMono,&#39;DejaVu =
Sans Mono&#39;,courier,monospace!important"><span class=3D"" style=3D"color=
:rgb(144,144,144)">// please stifle all irrelevant comments re: overload se=
ts and CV-qualifiers</span>
</pre><div><span class=3D"" style=3D"line-height:1.1em;margin:0px;padding:0=
px;color:rgb(0,0,221);font-family:DejaVuSansMono,&#39;DejaVu Sans Mono&#39;=
,courier,monospace;font-size:13px;white-space:nowrap">template</span><span =
class=3D"" style=3D"line-height:1.1em;margin:0px;padding:0px;color:rgb(0,0,=
128);font-family:DejaVuSansMono,&#39;DejaVu Sans Mono&#39;,courier,monospac=
e;font-size:13px;white-space:nowrap">&lt;=C2=A0</span><span class=3D"" styl=
e=3D"font-family:DejaVuSansMono,&#39;DejaVu Sans Mono&#39;,courier,monospac=
e;font-size:13px;color:rgb(0,48,128);text-decoration:none;background-image:=
none"><a href=3D"http://en.cppreference.com/w/cpp/types/size_t" style=3D"fo=
nt-family:DejaVuSansMono,&#39;DejaVu Sans Mono&#39;,courier,monospace;font-=
size:13px;color:rgb(0,48,128);text-decoration:none;background-image:none">s=
td::<span class=3D"">size_t</span></a></span><span class=3D"" style=3D"font=
-size:13px;line-height:1.1em;margin:0px;padding:0px;color:rgb(0,0,128);font=
-family:DejaVuSansMono,&#39;DejaVu Sans Mono&#39;,courier,monospace;white-s=
pace:nowrap">=C2=A0<span style=3D"color:rgb(0,0,0)">I</span><span class=3D"=
" style=3D"line-height:1.1em;margin:0px;padding:0px">,</span><span style=3D=
"color:rgb(0,0,0)">=C2=A0</span><span class=3D"" style=3D"line-height:1.1em=
;margin:0px;padding:0px;color:rgb(0,0,221)">class</span><span style=3D"colo=
r:rgb(0,0,0)">...=C2=A0</span><span class=3D"" style=3D"line-height:1.1em;m=
argin:0px;padding:0px;color:rgb(0,0,0)">Types</span><span style=3D"color:rg=
b(0,0,0)">=C2=A0</span><span class=3D"" style=3D"line-height:1.1em;margin:0=
px;padding:0px">&gt;</span><br></span></div><div><p style=3D"margin:0px;lin=
e-height:1.1em;padding:0px;font-family:DejaVuSansMono,&#39;DejaVu Sans Mono=
&#39;,courier,monospace;font-size:13px;white-space:nowrap"><span style=3D"c=
olor:rgb(0,0,0)"><span class=3D"" style=3D"line-height:1.1em;margin:0px;pad=
ding:0px;color:rgb(0,0,221)">auto</span>=C2=A0get</span><font color=3D"#000=
080">(</font><font color=3D"#000000">const=C2=A0</font><span class=3D"" sty=
le=3D"color:rgb(0,48,128);background-image:none;line-height:1.1em;margin:0p=
x;padding:0px"><a href=3D"http://en.cppreference.com/w/cpp/utility/tuple" s=
tyle=3D"color:rgb(0,48,128);text-decoration:none;background-image:none">mpl=
::<span class=3D"" style=3D"line-height:1.1em;margin:0px;padding:0px">v</sp=
an></a>ector</span><span class=3D"" style=3D"color:rgb(0,0,128);line-height=
:1.1em;margin:0px;padding:0px">&lt;</span><font color=3D"#000000">Types...<=
/font><span class=3D"" style=3D"color:rgb(0,0,128);line-height:1.1em;margin=
:0px;padding:0px">&gt;&amp;</span><span class=3D"" style=3D"color:rgb(0,0,1=
28);line-height:1.1em;margin:0px;padding:0px">)</span></p><p style=3D"margi=
n:0px;line-height:1.1em;padding:0px;font-family:DejaVuSansMono,&#39;DejaVu =
Sans Mono&#39;,courier,monospace;font-size:13px;white-space:nowrap"><span c=
lass=3D"" style=3D"color:rgb(0,0,128);line-height:1.1em;margin:0px;padding:=
0px">=C2=A0 =C2=A0-&gt;=C2=A0</span><span class=3D"" style=3D"text-decorati=
on:none;color:rgb(0,48,128);background-image:none;line-height:1.1em;margin:=
0px;padding:0px"><a href=3D"http://en.cppreference.com/w/cpp/types/add_refe=
rence" style=3D"text-decoration:none;color:rgb(0,48,128);background-image:n=
one">std::<span class=3D"" style=3D"line-height:1.1em;margin:0px;padding:0p=
x">add_rvalue_reference</span></a>_t</span><span class=3D"" style=3D"line-h=
eight:1.1em;margin:0px;padding:0px;color:rgb(0,0,128)">&lt;</span><span cla=
ss=3D"" style=3D"line-height:1.1em;margin:0px;padding:0px"><font color=3D"#=
000000">tuple_element_t&lt;I,</font></span><span class=3D"" style=3D"color:=
rgb(0,48,128);background-image:none;line-height:1.1em;margin:0px;padding:0p=
x"><a href=3D"http://en.cppreference.com/w/cpp/utility/tuple" style=3D"colo=
r:rgb(0,48,128);text-decoration:none;background-image:none">mpl::<span clas=
s=3D"" style=3D"line-height:1.1em;margin:0px;padding:0px">v</span></a>ector=
</span><span class=3D"" style=3D"color:rgb(0,0,128);line-height:1.1em;margi=
n:0px;padding:0px">&lt;</span><font color=3D"#000000">Types...</font><span =
class=3D"" style=3D"color:rgb(0,0,128);line-height:1.1em;margin:0px;padding=
:0px">&gt;</span><span class=3D"" style=3D"line-height:1.1em;margin:0px;pad=
ding:0px"><font color=3D"#000000">&gt;</font></span><span class=3D"" style=
=3D"line-height:1.1em;margin:0px;padding:0px;color:rgb(0,0,128)">&gt;</span=
><span class=3D"" style=3D"line-height:1.1em;margin:0px;padding:0px;color:r=
gb(0,0,0)">;</span></p><pre class=3D"" style=3D"font-size:13px;padding:0px;=
border:0px none white;color:rgb(0,0,0);line-height:1.2em;border-top-left-ra=
dius:5px;border-top-right-radius:5px;border-bottom-right-radius:5px;border-=
bottom-left-radius:5px;margin-top:0px;margin-bottom:0px;width:55em;overflow=
:auto;background-image:none;vertical-align:top;font-family:DejaVuSansMono,&=
#39;DejaVu Sans Mono&#39;,courier,monospace!important"><span class=3D"" sty=
le=3D"color:rgb(144,144,144)">// deliberately left with no implementation, =
a la std::declval</span>
</pre></div></div><div><span class=3D"" style=3D"color:rgb(144,144,144)"><b=
r></span></div><div>So what we&#39;re left with is: <font face=3D"monospace=
, monospace">mpl::vector</font> is &quot;not tuple-like&quot;, but it <i>do=
es</i> implement <font face=3D"monospace, monospace">tuple_size_v</font> an=
d <font face=3D"monospace, monospace">tuple_element_t</font>.</div><div>The=
 only part of the &quot;tuple-like&quot; contract that it fails to have an =
obvious implementation for is the one part of the &quot;tuple-like&quot; co=
ntract <i>whose name doesn&#39;t involve the word &quot;tuple&quot;</i>.</d=
iv><div><i>That</i> is why the concept of &quot;tuple-like&quot; bothers me=
..</div><div><br></div><div>=E2=80=93Arthur</div></div></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

--047d7bb04ad6651425052a2db46c--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 25 Jan 2016 14:58:43 -0500
Raw View
On 2016-01-25 14:37, Arthur O'Dwyer wrote:
> However, there's no such "obvious" definition for [mpl::vector] std::get.
>=20
> So what we're left with is: mpl::vector is "not tuple-like", but it *does=
*
> implement tuple_size_v and tuple_element_t.
> The only part of the "tuple-like" contract that it fails to have an obvio=
us
> implementation for is the one part of the "tuple-like" contract *whose na=
me
> doesn't involve the word "tuple"*.
> *That* is why the concept of "tuple-like" bothers me.

LOL :-). (Note: not at you, at the observed absurdity of the situation=C2=
=B9.)

Thanks for explaining; I understand now.

Per my earlier comment, I don't see how you would use an mpl::vector in
most of the contexts in which you care about something being
"tuple-like" (i.e. unpacking, conversion to/from std::tuple). Ergo,
while I understand (and to an extent agree with) your concern now, I'm
also thinking that it may just be one of those unfortunate facts of life.

I think the problem is that we have a few related but
not-quite-identical concepts, all of which are being called "tuple" (and
all of which can make a reasonable argument that "tuple is the correct
term, darn it").

I am open to suggestions? (Maybe we just avoid using the actual phrase
"tuple-like" in the standard?)

(=C2=B9 Interesting and at-least-partly applicable factoid: according to
Scott Adams, laughter is sometimes a tell that you have just changed
your mind on a subject.)

--=20
Matthew

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 25 Jan 2016 13:23:49 -0800 (PST)
Raw View
------=_Part_2445_1713585197.1453757029552
Content-Type: multipart/alternative;
 boundary="----=_Part_2446_1216339924.1453757029553"

------=_Part_2446_1216339924.1453757029553
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Monday, January 25, 2016 at 2:58:52 PM UTC-5, Matthew Woehlke wrote:
>
> On 2016-01-25 14:37, Arthur O'Dwyer wrote:=20
> > However, there's no such "obvious" definition for [mpl::vector]=20
> std::get.=20
> >=20
> > So what we're left with is: mpl::vector is "not tuple-like", but it=20
> *does*=20
> > implement tuple_size_v and tuple_element_t.=20
> > The only part of the "tuple-like" contract that it fails to have an=20
> obvious=20
> > implementation for is the one part of the "tuple-like" contract *whose=
=20
> name=20
> > doesn't involve the word "tuple"*.=20
> > *That* is why the concept of "tuple-like" bothers me.=20
>
> LOL :-). (Note: not at you, at the observed absurdity of the situation=C2=
=B9.)=20
>
> Thanks for explaining; I understand now.=20
>
> Per my earlier comment, I don't see how you would use an mpl::vector in=
=20
> most of the contexts in which you care about something being=20
> "tuple-like" (i.e. unpacking, conversion to/from std::tuple).


I made the analogy that a tuple-like type is analogous to a non-type=20
template parameter pack or a function parameter pack. Therefore, an=20
`mpl::vector` is like a *type* template parameter pack. So:

template<typename Typelist, typename ...Ts>
void func(Ts ... ts)
{
  return make_tuple(Typelist~(std::forward<Ts>(ts))...);
}

Transforms the `ts` parameters in accord with the `mpl::vector` typelist.

This would also work with a tuple parameter:

template<typename Typelist>
void func(tuple<whatever> ts)
{
  return make_tuple(Typelist~(ts~)...);
}

Now, I'm not saying we ought to do that. But that's the general idea.
=20

> Ergo,=20
> while I understand (and to an extent agree with) your concern now, I'm=20
> also thinking that it may just be one of those unfortunate facts of life.=
=20
>
> I think the problem is that we have a few related but=20
> not-quite-identical concepts, all of which are being called "tuple" (and=
=20
> all of which can make a reasonable argument that "tuple is the correct=20
> term, darn it").=20
>
> I am open to suggestions? (Maybe we just avoid using the actual phrase=20
> "tuple-like" in the standard?)
>

There needs to be a recognition between what is a tuple-like type and what=
=20
is a tuple-like *value*.

You can access the number of elements in a tuple-like type, and you can=20
access the types of each of those elements. But types obviously don't have=
=20
values, so that is a *third* operation only applicable to values of=20
tuple-like types.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

------=_Part_2446_1216339924.1453757029553
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Monday, January 25, 2016 at 2:58:52 PM UTC-5, Matthew Woehlke wrote:<blo=
ckquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-=
left: 1px #ccc solid;padding-left: 1ex;">On 2016-01-25 14:37, Arthur O&#39;=
Dwyer wrote:
<br>&gt; However, there&#39;s no such &quot;obvious&quot; definition for [m=
pl::vector] std::get.
<br>&gt;=20
<br>&gt; So what we&#39;re left with is: mpl::vector is &quot;not tuple-lik=
e&quot;, but it *does*
<br>&gt; implement tuple_size_v and tuple_element_t.
<br>&gt; The only part of the &quot;tuple-like&quot; contract that it fails=
 to have an obvious
<br>&gt; implementation for is the one part of the &quot;tuple-like&quot; c=
ontract *whose name
<br>&gt; doesn&#39;t involve the word &quot;tuple&quot;*.
<br>&gt; *That* is why the concept of &quot;tuple-like&quot; bothers me.
<br>
<br>LOL :-). (Note: not at you, at the observed absurdity of the situation=
=C2=B9.)
<br>
<br>Thanks for explaining; I understand now.
<br>
<br>Per my earlier comment, I don&#39;t see how you would use an mpl::vecto=
r in
<br>most of the contexts in which you care about something being
<br>&quot;tuple-like&quot; (i.e. unpacking, conversion to/from std::tuple).=
</blockquote><div><br>I made the analogy that a tuple-like type is analogou=
s to a non-type template parameter pack or a function parameter pack. There=
fore, an `mpl::vector` is like a <i>type</i> template parameter pack. So:<b=
r><br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 2=
50); border-color: rgb(187, 187, 187); border-style: solid; border-width: 1=
px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subpr=
ettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">templa=
te</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">typename</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #606;" class=3D"styled-by-prettify">Typelist</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;"=
 class=3D"styled-by-prettify">typename</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"s=
tyled-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">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r></span><span style=3D"color: #008;" class=3D"styled-by-prettify">void</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> func</span><s=
pan 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"colo=
r: #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"> ts</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><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: #008;" class=3D"styled-by-prettify">return=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> make_tupl=
e</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><=
span style=3D"color: #606;" class=3D"styled-by-prettify">Typelist</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">~(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">std</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">forward</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #606;" class=
=3D"styled-by-prettify">Ts</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">&gt;(</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">=
<br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</spa=
n></div></code></div><br>Transforms the `ts` parameters in accord with the =
`mpl::vector` typelist.<br><br>This would also work with a tuple parameter:=
<br><br><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"sub=
prettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">temp=
late</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">typename</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #606;" class=3D"styled-by-prettify">Typelist</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><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;" cl=
ass=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">tuple</span><span style=3D"color: #080;" class=3D"styled-=
by-prettify">&lt;whatever&gt;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> ts</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><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: #008;" class=3D"styled-by-prettify">return</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> make_tuple</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span =
style=3D"color: #606;" class=3D"styled-by-prettify">Typelist</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">~(</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">ts</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">~)...);</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br></span></div></code></div></div><div><br>Now, I&#39;m n=
ot saying we ought to do that. But that&#39;s the general idea.<br>=C2=A0</=
div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;">Ergo,
<br>while I understand (and to an extent agree with) your concern now, I&#3=
9;m
<br>also thinking that it may just be one of those unfortunate facts of lif=
e.
<br>
<br>I think the problem is that we have a few related but
<br>not-quite-identical concepts, all of which are being called &quot;tuple=
&quot; (and
<br>all of which can make a reasonable argument that &quot;tuple is the cor=
rect
<br>term, darn it&quot;).
<br>
<br>I am open to suggestions? (Maybe we just avoid using the actual phrase
<br>&quot;tuple-like&quot; in the standard?)<br></blockquote><div><br>There=
 needs to be a recognition between what is a tuple-like type and what is a =
tuple-like <i>value</i>.<br><br>You can access the number of elements in a =
tuple-like type, and you can access the types of each of those elements. Bu=
t types obviously don&#39;t have values, so that is a <i>third</i> operatio=
n only applicable to values of tuple-like types.<br></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

------=_Part_2446_1216339924.1453757029553--
------=_Part_2445_1713585197.1453757029552--

.


Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Fri, 29 Jan 2016 11:20:57 -0800
Raw View
--001a1142092651a2f7052a7def23
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Mon, Jan 25, 2016 at 1:23 PM, Nicol Bolas <jmckesson@gmail.com> wrote:

>
> I made the analogy that a tuple-like type is analogous to a non-type
> template parameter pack or a function parameter pack. Therefore, an
> `mpl::vector` is like a *type* template parameter pack. So:
>
> template<typename Typelist, typename ...Ts>
> void func(Ts ... ts)
> {
>   return make_tuple(Typelist~(std::forward<Ts>(ts))...);
> }
>
> Transforms the `ts` parameters in accord with the `mpl::vector` typelist.
>

(Using the "postfix twiddle" notation for de-tupling, I see. I'm flattered.
:))

IIUC, you're proposing that
- postfix-twiddle on a value V expands to a pack of std::get<i>(V)
- postfix-twiddle on a type T expands to a pack of std::tuple_element_t<i,T=
>
So, std::tuple<A,B,C> would be both tuple-like and typelist-like, because
it supports both of the above operations; but mpl::vector<A,B,C> (without
std::get) would be only typelist-like; is that right?

That makes sense.

There needs to be a recognition between what is a tuple-like type and what
> is a tuple-like *value*.
>
> You can access the number of elements in a tuple-like type, and you can
> access the types of each of those elements. But types obviously don't hav=
e
> values, so that is a *third* operation only applicable to values of
> tuple-like types.
>

I tend to disagree with the above statement, because I tend to disagree
with any statement that treats "operations on types" and "operations on
values" as fundamentally different, ever since I saw Louis Dionne speak for
the first time. :)
As of C++11, we have decltype(E) =E2=80=94 which takes the value E and prod=
uces its
type =E2=80=94 and we have std::declval<T>() =E2=80=94 which takes a type T=
 and produces a
value of that type. And they compose, so I can do a bunch of "value-space"
computations and then take the decltype of the resulting expression. Any
construct that gets in the way of my doing that is objectionable.
In other words, rather than saying that mpl::vector<Ts...> doesn't have a
value and so std::get<I>(mplvec) should be ill-formed, I would prefer we
simply say that std::get<I>(mplvec) doesn't have a *value* =E2=80=94 but it=
 should
still have a *type*!
In short, I'd strongly prefer that every "typelist-like" type *also* be
"tuple-like", at least from the point of view of the type system, even if
that means leaving some "tuple-like operations" declared-but-not-defined.


Having said all that, this "postfix twiddle means std::get<> (and/or
std::tuple_element_t<>)" thing still feels too ad-hoc to me. If we could
come up with a nice syntax for it, I'd prefer to have the std::get<>
written out and just build a simple syntax for getting a
parameter-pack of *integer
indices*.  I have no idea what that syntax would look like, though, or how
it would end up remotely as clean as this seductive example:

    template<class Vec>
    auto dotproduct(const Vec& a, const Vec& b)
    {
        return (... + (a~ * b~));  // this is a C++17 fold-expression
    }

The only thing I can think to do is to introduce first-class parameter
packs, and write

    template<size_t I, class... Ts>
    auto getp(const std::tuple<Ts...>&) -> Ts...;  // "return a pack"

    template<class Vec>
    auto dotproduct(const Vec& a, const Vec& b)
    {
        return (... + (getp(a) * getp(b)));
    }

But first-class parameter packs seem like a nightmare to specify, don't
they?
Plus, at that point we're definitely turning C++ into a vector language, in
which "packs of values" are first-class citizens and packwise (i.e. vector)
arithmetic is built into the language; and maybe some of the folks who
actually do vectorization stuff ought to weigh in and say "this is how we
want vector operations to work, for performance or usability reasons."

=E2=80=93Arthur

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

--001a1142092651a2f7052a7def23
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Mon, Jan 25, 2016 at 1:23 PM, Nicol Bolas <span dir=3D"=
ltr">&lt;<a href=3D"mailto:jmckesson@gmail.com" target=3D"_blank">jmckesson=
@gmail.com</a>&gt;</span> wrote:<br><div class=3D"gmail_extra"><div class=
=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px =
0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-l=
eft-style:solid;padding-left:1ex"><br><div>I made the analogy that a tuple-=
like type is analogous to a non-type template parameter pack or a function =
parameter pack. Therefore, an `mpl::vector` is like a <i>type</i> template =
parameter pack. So:<br><br><div style=3D"background-color:rgb(250,250,250);=
border:1px solid rgb(187,187,187);word-wrap:break-word"><code><div><span st=
yle=3D"color:rgb(0,0,136)">template</span><span style=3D"color:rgb(102,102,=
0)">&lt;</span><span style=3D"color:rgb(0,0,136)">typename</span><span styl=
e=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">Typelis=
t</span><span style=3D"color:rgb(102,102,0)">,</span><span style=3D"color:r=
gb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">typename</span><span =
style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">...=
</span><span style=3D"color:rgb(102,0,102)">Ts</span><span style=3D"color:r=
gb(102,102,0)">&gt;</span><span style=3D"color:rgb(0,0,0)"><br></span><span=
 style=3D"color:rgb(0,0,136)">void</span><span style=3D"color:rgb(0,0,0)"> =
func</span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"colo=
r:rgb(102,0,102)">Ts</span><span style=3D"color:rgb(0,0,0)"> </span><span s=
tyle=3D"color:rgb(102,102,0)">...</span><span style=3D"color:rgb(0,0,0)"> t=
s</span><span style=3D"color:rgb(102,102,0)">)</span><span style=3D"color:r=
gb(0,0,0)"><br></span><span style=3D"color:rgb(102,102,0)">{</span><span st=
yle=3D"color:rgb(0,0,0)"><br>=C2=A0 </span><span style=3D"color:rgb(0,0,136=
)">return</span><span style=3D"color:rgb(0,0,0)"> make_tuple</span><span st=
yle=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(102,0,102)">T=
ypelist</span><span style=3D"color:rgb(102,102,0)">~(</span><span style=3D"=
color:rgb(0,0,0)">std</span><span style=3D"color:rgb(102,102,0)">::</span><=
span style=3D"color:rgb(0,0,0)">forward</span><span style=3D"color:rgb(102,=
102,0)">&lt;</span><span style=3D"color:rgb(102,0,102)">Ts</span><span styl=
e=3D"color:rgb(102,102,0)">&gt;(</span><span style=3D"color:rgb(0,0,0)">ts<=
/span><span style=3D"color:rgb(102,102,0)">))...);</span><span style=3D"col=
or:rgb(0,0,0)"><br></span><span style=3D"color:rgb(102,102,0)">}</span></di=
v></code></div><br>Transforms the `ts` parameters in accord with the `mpl::=
vector` typelist.<br></div></blockquote><div><br></div><div>(Using the &quo=
t;postfix twiddle&quot; notation for de-tupling, I see. I&#39;m flattered. =
:))</div><div><br></div><div>IIUC, you&#39;re proposing that<br></div><div>=
- postfix-twiddle on a value V expands to a pack of std::get&lt;i&gt;(V)</d=
iv><div>- postfix-twiddle on a type T expands to a pack of std::tuple_eleme=
nt_t&lt;i,T&gt;</div><div>So, std::tuple&lt;A,B,C&gt; would be both tuple-l=
ike and typelist-like, because it supports both of the above operations; bu=
t mpl::vector&lt;A,B,C&gt; (without std::get) would be only typelist-like; =
is that right?</div><div><br></div><div>That makes sense.</div><div><br></d=
iv><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bord=
er-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:soli=
d;padding-left:1ex"><div>There needs to be a recognition between what is a =
tuple-like type and what is a tuple-like <i>value</i>.<br><br>You can acces=
s the number of elements in a tuple-like type, and you can access the types=
 of each of those elements. But types obviously don&#39;t have values, so t=
hat is a <i>third</i> operation only applicable to values of tuple-like typ=
es.<br></div></blockquote><div><br></div><div>I tend to disagree with the a=
bove statement, because I tend to disagree with any statement that treats &=
quot;operations on types&quot; and &quot;operations on values&quot; as fund=
amentally different, ever since I saw Louis Dionne speak for the first time=
.. :)</div><div>As of C++11, we have decltype(E) =E2=80=94 which takes the v=
alue E and produces its type =E2=80=94 and we have std::declval&lt;T&gt;() =
=E2=80=94 which takes a type T and produces a value of that type. And they =
compose, so I can do a bunch of &quot;value-space&quot; computations and th=
en take the decltype of the resulting expression. Any construct that gets i=
n the way of my doing that is objectionable.</div><div>In other words, rath=
er than saying that <font face=3D"monospace, monospace">mpl::vector&lt;Ts..=
..&gt;</font> doesn&#39;t have a value and so <font face=3D"monospace, monos=
pace">std::get&lt;I&gt;(mplvec)</font> should be ill-formed, I would prefer=
 we simply say that <font face=3D"monospace, monospace">std::get&lt;I&gt;(m=
plvec)</font> doesn&#39;t have a <i>value</i> =E2=80=94 but it should still=
 have a <i>type</i>!</div><div>In short, I&#39;d strongly prefer that every=
 &quot;typelist-like&quot; type <i>also</i> be &quot;tuple-like&quot;, at l=
east from the point of view of the type system, even if that means leaving =
some &quot;tuple-like operations&quot; declared-but-not-defined.</div><div>=
<br></div><div><br></div><div>Having said all that, this &quot;postfix twid=
dle means std::get&lt;&gt; (and/or std::tuple_element_t&lt;&gt;)&quot; thin=
g still feels too ad-hoc to me. If we could come up with a nice syntax for =
it, I&#39;d prefer to have the std::get&lt;&gt; written out and just build =
a simple syntax for getting a parameter-pack of <i>integer indices</i>.=C2=
=A0 I have no idea what that syntax would look like, though, or how it woul=
d end up remotely as clean as this seductive example:</div><div><br></div><=
div><div style=3D"font-size:13px"><span style=3D"font-family:monospace,mono=
space">=C2=A0 =C2=A0 template&lt;class Vec&gt;</span><br></div><div style=
=3D"font-size:13px"><font face=3D"monospace, monospace">=C2=A0 =C2=A0 auto =
dotproduct(const Vec&amp; a, const Vec&amp; b)</font></div><div style=3D"fo=
nt-size:13px"><font face=3D"monospace, monospace">=C2=A0 =C2=A0 {</font></d=
iv><div style=3D"font-size:13px"><font face=3D"monospace, monospace">=C2=A0=
 =C2=A0 =C2=A0 =C2=A0 return (... + (a~ * b~)); =C2=A0// this is a C++17 fo=
ld-expression</font></div><div style=3D"font-size:13px"><font face=3D"monos=
pace, monospace">=C2=A0 =C2=A0 }</font></div></div><div><br></div><div>The =
only thing I can think to do is to introduce first-class parameter packs, a=
nd write</div><div><br></div><div><div><div style=3D"font-size:13px"><span =
style=3D"font-family:monospace,monospace">=C2=A0 =C2=A0 template&lt;size_t =
I, class... Ts&gt;</span><br></div><div style=3D"font-size:13px"><font face=
=3D"monospace, monospace">=C2=A0 =C2=A0 auto getp(const std::tuple&lt;Ts...=
&gt;&amp;) -&gt; Ts...; =C2=A0// &quot;return a pack&quot;</font></div><div=
 style=3D"font-size:13px"><span style=3D"font-family:monospace,monospace"><=
br></span></div><div style=3D"font-size:13px"><span style=3D"font-family:mo=
nospace,monospace">=C2=A0 =C2=A0 template&lt;class Vec&gt;</span><br></div>=
<div style=3D"font-size:13px"><font face=3D"monospace, monospace">=C2=A0 =
=C2=A0 auto dotproduct(const Vec&amp; a, const Vec&amp; b)</font></div><div=
 style=3D"font-size:13px"><font face=3D"monospace, monospace">=C2=A0 =C2=A0=
 {</font></div><div style=3D"font-size:13px"><font face=3D"monospace, monos=
pace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 return (... + (getp(a) * getp(b)));</font=
></div><div style=3D"font-size:13px"><font face=3D"monospace, monospace">=
=C2=A0 =C2=A0 }</font></div></div></div><div><br></div><div>But first-class=
 parameter packs seem like a nightmare to specify, don&#39;t they?</div><di=
v>Plus, at that point we&#39;re definitely turning C++ into a vector langua=
ge, in which &quot;packs of values&quot; are first-class citizens and packw=
ise (i.e. vector) arithmetic is built into the language; and maybe some of =
the folks who actually do vectorization stuff ought to weigh in and say &qu=
ot;this is how we want vector operations to work, for performance or usabil=
ity reasons.&quot;</div><div><br></div><div>=E2=80=93Arthur</div></div></di=
v></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

--001a1142092651a2f7052a7def23--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Fri, 29 Jan 2016 16:03:46 -0500
Raw View
On 2016-01-29 14:20, Arthur O'Dwyer wrote:
> Having said all that, this "postfix twiddle means std::get<> (and/or
> std::tuple_element_t<>)" thing still feels too ad-hoc to me. If we
> could come up with a nice syntax for it, I'd prefer to have the
> std::get<> written out and just build a simple syntax for getting a
> parameter-pack of *integer indices*.

Ugh, please no :-). I'm already not happy about writing:

  auto t = get_tuple_like();
  foo(t~...); // or whatever; I still don't like '~'

If I have to write:

  foo(get<MAGIC...>(t));

....instead (for presumably some not-very-short spelling of "MAGIC"
likely involving a `decltype(t)`), I am not going to be happy. And I am
also going to think we have entirely missed the point.

--
Matthew

--

---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 29 Jan 2016 13:08:26 -0800 (PST)
Raw View
------=_Part_1733_247287122.1454101706956
Content-Type: multipart/alternative;
 boundary="----=_Part_1734_1689372135.1454101706956"

------=_Part_1734_1689372135.1454101706956
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Friday, January 29, 2016 at 2:21:00 PM UTC-5, Arthur O'Dwyer wrote:
>
> On Mon, Jan 25, 2016 at 1:23 PM, Nicol Bolas <jmck...@gmail.com=20
> <javascript:>> wrote:
>
>>
>> There needs to be a recognition between what is a tuple-like type and=20
>>> what is a tuple-like *value*.
>>>
>>> You can access the number of elements in a tuple-like type, and you can=
=20
>>> access the types of each of those elements. But types obviously don't h=
ave=20
>>> values, so that is a *third* operation only applicable to values of=20
>>> tuple-like types.
>>>
>>
>> I tend to disagree with the above statement, because I tend to disagree=
=20
>> with any statement that treats "operations on types" and "operations on=
=20
>> values" as fundamentally different, ever since I saw Louis Dionne speak =
for=20
>> the first time. :)
>>
> As of C++11, we have decltype(E) =E2=80=94 which takes the value E and pr=
oduces=20
> its type =E2=80=94 and we have std::declval<T>() =E2=80=94 which takes a =
type T and=20
> produces a value of that type. And they compose, so I can do a bunch of=
=20
> "value-space" computations and then take the decltype of the resulting=20
> expression. Any construct that gets in the way of my doing that is=20
> objectionable.
> In other words, rather than saying that mpl::vector<Ts...> doesn't have a=
=20
> value and so std::get<I>(mplvec) should be ill-formed, I would prefer we=
=20
> simply say that std::get<I>(mplvec) doesn't have a *value* =E2=80=94 but =
it=20
> should still have a *type*!
>

You can want whatever you want, but the fact is that in C++, types and=20
values are different things. And we have different mechanisms for dealing=
=20
with each.

Functions take values and return them. Template metafunctions take types=20
and can evaluate to types. `declval` doesn't really generate a value in any=
=20
meaningful way, since it can only exist in a non-evaluated context. And=20
while `decltype` does evaluate to a type, that type is not based on a=20
value, since the expression itself is never actually evaluated.

Maybe sometimes these things will be equivalent someday. But until then,=20
C++ is what it is. Values and types are different, and we shouldn't pretend=
=20
that they're not.

In short, I'd strongly prefer that every "typelist-like" type *also* be=20
> "tuple-like", at least from the point of view of the type system, even if=
=20
> that means leaving some "tuple-like operations" declared-but-not-defined.
>

I dislike things that are "declared but not defined". The concept is based=
=20
on various minutiae of C++'s declaration and definition syntax that people=
=20
shouldn't have to know.

We added `=3Ddelete` syntax so that we wouldn't have to rely on such things=
=20
as much. Similarly, concepts includes a whole mechanism that *avoids*=20
having to deal with `declval` and a host of other "declared but not=20
defined" constructs associated with `enable_if`.

Also, I rather suspect that `tuple_element_t<Type, I>` takes less time to=
=20
compile than `decltype(get<I>(declval<Type>()))`. And it's a heck of a lot=
=20
easier to understand and implement for the user.

Having said all that, this "postfix twiddle means std::get<> (and/or=20
> std::tuple_element_t<>)" thing still feels too ad-hoc to me.
>

It's no more ad-hoc than range-based for using `std::begin` and `std::end`.=
=20
You have to have some customization point for user-defined types.

If we could come up with a nice syntax for it, I'd prefer to have the=20
> std::get<> written out and just build a simple syntax for getting a=20
> parameter-pack of *integer indices*.  I have no idea what that syntax=20
> would look like, though, or how it would end up remotely as clean as this=
=20
> seductive example:
>
>     template<class Vec>
>     auto dotproduct(const Vec& a, const Vec& b)
>     {
>         return (... + (a~ * b~));  // this is a C++17 fold-expression
>     }
>
>
That example seems to be missing what the return value is supposed to be.=
=20
Presumably it's some `Vec` object, but you don't use the typename anywhere.

The only thing I can think to do is to introduce first-class parameter=20
> packs, and write
>
>     template<size_t I, class... Ts>
>     auto getp(const std::tuple<Ts...>&) -> Ts...;  // "return a pack"
>
>     template<class Vec>
>     auto dotproduct(const Vec& a, const Vec& b)
>     {
>         return (... + (getp(a) * getp(b)));
>     }
>
> But first-class parameter packs seem like a nightmare to specify, don't=
=20
> they?
>

Um, how exactly is that easier than the user implementing the appropriate=
=20
interfaces? It certainly isn't easier for the reader to understand.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

------=_Part_1734_1689372135.1454101706956
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Friday, January 29, 2016 at 2:21:00 PM UTC-5, Arthur O&=
#39;Dwyer wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"lt=
r">On Mon, Jan 25, 2016 at 1:23 PM, Nicol Bolas <span dir=3D"ltr">&lt;<a hr=
ef=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"aio3m_bNGgAJ"=
 rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#39;;return t=
rue;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;">jmck...@gm=
ail.com</a>&gt;</span> wrote:<br><div><div class=3D"gmail_quote"><blockquot=
e class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width=
:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-lef=
t:1ex"><br><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(=
204,204,204);border-left-style:solid;padding-left:1ex"><div>There needs to =
be a recognition between what is a tuple-like type and what is a tuple-like=
 <i>value</i>.<br><br>You can access the number of elements in a tuple-like=
 type, and you can access the types of each of those elements. But types ob=
viously don&#39;t have values, so that is a <i>third</i> operation only app=
licable to values of tuple-like types.<br></div></blockquote><div><br></div=
><div>I tend to disagree with the above statement, because I tend to disagr=
ee with any statement that treats &quot;operations on types&quot; and &quot=
;operations on values&quot; as fundamentally different, ever since I saw Lo=
uis Dionne speak for the first time. :)</div></div></blockquote></div></div=
></div></blockquote><div></div><blockquote class=3D"gmail_quote" style=3D"m=
argin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"=
><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div>As of C++11, we have=
 decltype(E) =E2=80=94 which takes the value E and produces its type =E2=80=
=94 and we have std::declval&lt;T&gt;() =E2=80=94 which takes a type T and =
produces a value of that type. And they compose, so I can do a bunch of &qu=
ot;value-space&quot; computations and then take the decltype of the resulti=
ng expression. Any construct that gets in the way of my doing that is objec=
tionable.</div><div>In other words, rather than saying that <font face=3D"m=
onospace, monospace">mpl::vector&lt;Ts...&gt;</font> doesn&#39;t have a val=
ue and so <font face=3D"monospace, monospace">std::get&lt;I&gt;(mplvec)</fo=
nt> should be ill-formed, I would prefer we simply say that <font face=3D"m=
onospace, monospace">std::get&lt;I&gt;(mplvec)</font> doesn&#39;t have a <i=
>value</i> =E2=80=94 but it should still have a <i>type</i>!</div></div></d=
iv></div></blockquote><div><br>You can want whatever you want, but the fact=
 is that in C++, types and=20
values are different things. And we have different mechanisms for=20
dealing with each.<br><br>Functions take values and return them.=20
Template metafunctions take types and can evaluate to types. `declval`=20
doesn&#39;t really generate a value in any meaningful way, since it can onl=
y
 exist in a non-evaluated context. And while `decltype` does evaluate to
 a type, that type is not based on a value, since the expression itself=20
is never actually evaluated.<br><br>Maybe sometimes these things will be
 equivalent someday. But until then, C++ is what it is. Values and types ar=
e=20
different, and we shouldn&#39;t pretend that they&#39;re not.<br><br></div>=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div cla=
ss=3D"gmail_quote"><div>In short, I&#39;d strongly prefer that every &quot;=
typelist-like&quot; type <i>also</i> be &quot;tuple-like&quot;, at least fr=
om the point of view of the type system, even if that means leaving some &q=
uot;tuple-like operations&quot; declared-but-not-defined.</div></div></div>=
</div></blockquote><div><br>I dislike things that are &quot;declared but no=
t defined&quot;. The concept is based on various minutiae of C++&#39;s decl=
aration and definition syntax that people shouldn&#39;t have to know.<br><b=
r>We added `=3Ddelete` syntax so that we wouldn&#39;t have to rely on such =
things as much. Similarly, concepts includes a whole mechanism that <i>avoi=
ds</i> having to deal with `declval` and a host of other &quot;declared but=
 not defined&quot; constructs associated with `enable_if`.<br><br>Also, I r=
ather suspect that `tuple_element_t&lt;Type, I&gt;` takes=20
less time to compile than=20
`decltype(get&lt;I&gt;(declval&lt;Type&gt;()))`. And it&#39;s a heck of a=
=20
lot easier to understand and implement for the user.<br><br></div><blockquo=
te class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left:=
 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gma=
il_quote"><div></div><div>Having said all that, this &quot;postfix twiddle =
means std::get&lt;&gt; (and/or std::tuple_element_t&lt;&gt;)&quot; thing st=
ill feels too ad-hoc to me.</div></div></div></div></blockquote><div><br>It=
&#39;s no more ad-hoc than range-based for using `std::begin` and `std::end=
`. You have to have some customization point for user-defined types.<br><br=
></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><=
div class=3D"gmail_quote"><div>If we could come up with a nice syntax for i=
t, I&#39;d prefer to have the std::get&lt;&gt; written out and just build a=
 simple syntax for getting a parameter-pack of <i>integer indices</i>.=C2=
=A0 I have no idea what that syntax would look like, though, or how it woul=
d end up remotely as clean as this seductive example:</div><div><br></div><=
div><div style=3D"font-size:13px"><span style=3D"font-family:monospace,mono=
space">=C2=A0 =C2=A0 template&lt;class Vec&gt;</span><br></div><div style=
=3D"font-size:13px"><font face=3D"monospace, monospace">=C2=A0 =C2=A0 auto =
dotproduct(const Vec&amp; a, const Vec&amp; b)</font></div><div style=3D"fo=
nt-size:13px"><font face=3D"monospace, monospace">=C2=A0 =C2=A0 {</font></d=
iv><div style=3D"font-size:13px"><font face=3D"monospace, monospace">=C2=A0=
 =C2=A0 =C2=A0 =C2=A0 return (... + (a~ * b~)); =C2=A0// this is a C++17 fo=
ld-expression</font></div><div style=3D"font-size:13px"><font face=3D"monos=
pace, monospace">=C2=A0 =C2=A0 }</font></div></div><div><br></div></div></d=
iv></div></blockquote><div><br>That example seems to be missing what the re=
turn value is supposed to be. Presumably it&#39;s some `Vec` object, but yo=
u don&#39;t use the typename anywhere.<br><br></div><blockquote class=3D"gm=
ail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc soli=
d;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div=
></div><div>The only thing I can think to do is to introduce first-class pa=
rameter packs, and write</div><div><br></div><div><div><div style=3D"font-s=
ize:13px"><span style=3D"font-family:monospace,monospace">=C2=A0 =C2=A0 tem=
plate&lt;size_t I, class... Ts&gt;</span><br></div><div style=3D"font-size:=
13px"><font face=3D"monospace, monospace">=C2=A0 =C2=A0 auto getp(const std=
::tuple&lt;Ts...&gt;&amp;) -&gt; Ts...; =C2=A0// &quot;return a pack&quot;<=
/font></div><div style=3D"font-size:13px"><span style=3D"font-family:monosp=
ace,monospace"><br></span></div><div style=3D"font-size:13px"><span style=
=3D"font-family:monospace,monospace">=C2=A0 =C2=A0 template&lt;class Vec&gt=
;</span><br></div><div style=3D"font-size:13px"><font face=3D"monospace, mo=
nospace">=C2=A0 =C2=A0 auto dotproduct(const Vec&amp; a, const Vec&amp; b)<=
/font></div><div style=3D"font-size:13px"><font face=3D"monospace, monospac=
e">=C2=A0 =C2=A0 {</font></div><div style=3D"font-size:13px"><font face=3D"=
monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 return (... + (getp(a) * =
getp(b)));</font></div><div style=3D"font-size:13px"><font face=3D"monospac=
e, monospace">=C2=A0 =C2=A0 }</font></div></div></div><div><br></div><div>B=
ut first-class parameter packs seem like a nightmare to specify, don&#39;t =
they?</div></div></div></div></blockquote><div><br>Um, how exactly is that =
easier than the user implementing the appropriate interfaces? It certainly =
isn&#39;t easier for the reader to understand.</div><br></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

------=_Part_1734_1689372135.1454101706956--
------=_Part_1733_247287122.1454101706956--

.


Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Fri, 29 Jan 2016 17:59:19 -0800
Raw View
--001a1145b8d8f94465052a837f23
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Fri, Jan 29, 2016 at 1:08 PM, Nicol Bolas <jmckesson@gmail.com> wrote:

> On Friday, January 29, 2016 at 2:21:00 PM UTC-5, Arthur O'Dwyer wrote:
>>
>>
>> As of C++11, we have decltype(E) =E2=80=94 which takes the value E and p=
roduces
>> its type =E2=80=94 and we have std::declval<T>() =E2=80=94 which takes a=
 type T and
>> produces a value of that type. And they compose, so I can do a bunch of
>> "value-space" computations and then take the decltype of the resulting
>> expression. Any construct that gets in the way of my doing that is
>> objectionable.
>> In other words, rather than saying that mpl::vector<Ts...> doesn't have
>> a value and so std::get<I>(mplvec) should be ill-formed, I would prefer
>> we simply say that std::get<I>(mplvec) doesn't have a *value* =E2=80=94 =
but it
>> should still have a *type*!
>>
>
> You can want whatever you want, but the fact is that in C++, types and
> values are different things. And we have different mechanisms for dealing
> with each.
>
> Functions take values and return them. Template metafunctions take types
> and can evaluate to types. `declval` doesn't really generate a value in a=
ny
> meaningful way, since it can only exist in a non-evaluated context. And
> while `decltype` does evaluate to a type, that type is not based on a
> value, since the expression itself is never actually evaluated.
>
> Maybe sometimes these things will be equivalent someday. But until then,
> C++ is what it is. Values and types are different, and we shouldn't prete=
nd
> that they're not.
>

That's one point of view, but I tend to think that it's outdated (as of
C++11). We don't need template metafunctions anymore (well, not so many of
them), now that we have constexpr and heterogeneous function templates at
our disposal. For example, where in C++03 we *did* often have to write
template metafunctions such as

*template<class T, class U>*
*struct result_of_plus {*
*    typedef __typeof(T()+U()) type;*
*};*

struct plus {
    template<class T, class U>
    *typename result_of_plus<T,U>::type* operator(T t, U u) { return t + u;
}
};

as of C++14 we no longer need to write any of that metafunction machinery;
we can use decltype to get the compiler to do the meta-lifting on our
behalf, and all we need to worry about are *expressions*, which generally
have both a type and a value.

struct plus {
    template<class T, class U>
    *auto* operator(T t, U u) *-> decltype(t + u)* { return t + u; }
};

(and we don't even need the -> decltype stuff unless we want SFINAE!)
Values and types *are* different, but they are still intimately related
(for example, every value has a type), and while we *can* use different
mechanisms to deal with each, we no longer *need* to.


Having said all that, this "postfix twiddle means std::get<> (and/or
>> std::tuple_element_t<>)" thing still feels too ad-hoc to me.
>>
>
> It's no more ad-hoc than range-based for using `std::begin` and
> `std::end`. You have to have some customization point for user-defined
> types.
>

Agreed, I think, grudgingly, reluctantly, in practice.  In other words, I
agree that's the current state of the world, but I don't *like* it. It
feels much too ad-hoc. begin and end "work" as well as they do because they
had a couple of decades of implementation experience behind them before
people started making up syntactic sugar for them. Right now we have maybe
5 years of experience using std::get and probably even less with
std::tuple_element_t. Are those *exactly* the primitives we want to
syntactic-sugar up, or will we regret the decision in another 5 years when
we realize "how tuples *should* have been done"?

I mean, imagine if instead of iostreams using operator overloading, we had
gotten a syntactic sugar where << in certain contexts expanded to a call to
std::printf(). Makes sense, right? But it would have been horrible for the
flexibility and symmetry of the language as a whole. *And even
iostreams-as-is suck!*  Basically I'm worried that postfix-twiddle and
tuples-as-is are in an analogous situation right now. We might not *want*
to immortalize std::get<I> in language syntax.



> If we could come up with a nice syntax for it, I'd prefer to have the
>> std::get<> written out and just build a simple syntax for getting a
>> parameter-pack of *integer indices*.  I have no idea what that syntax
>> would look like, though, or how it would end up remotely as clean as thi=
s
>> seductive example:
>>
>>     template<class Vec>
>>     auto dotproduct(const Vec& a, const Vec& b)
>>     {
>>         return (... + (a~ * b~));  // this is a C++17 fold-expression
>>     }
>>
>>
> That example seems to be missing what the return value is supposed to be.
> Presumably it's some `Vec` object, but you don't use the typename anywher=
e.
>

The return type is exactly decltype((... + (a~ * b~))). Starting in C++14,
we don't have to write it out; auto suffices for return type deduction.
For example, if Vec is std::tuple<int, double, char>, then decltype((... +
(a~ * b~))) is double.


The only thing I can think to do is to introduce first-class parameter
>> packs, and write
>>
>>     template<size_t I, class... Ts>
>>     auto getp(const std::tuple<Ts...>&) -> Ts...;  // "return a pack"
>>
>>     template<class Vec>
>>     auto dotproduct(const Vec& a, const Vec& b)
>>     {
>>         return (... + (getp(a) * getp(b)));
>>     }
>>
>> But first-class parameter packs seem like a nightmare to specify, don't
>> they?
>>
>
> Um, how exactly is that easier than the user implementing the appropriate
> interfaces? It certainly isn't easier for the reader to understand.
>

My idea was that std::getp would probably be standardized as the "packful"
version of std::get, so the user wouldn't have to actually write out the
implementation of getp in practice.
I agree that the syntax inside this version of dotproduct is much more
off-putting than the postfix-twiddle syntax. *It is uglier.* However,
it is *conceptually
cleaner*, because it doesn't introduce any significantly new grammar (no
postfix-twiddle operator) and it doesn't introduce any new "magic
names" (no hard-coding of the names get and tuple_element_t into the
compiler).  This is a trade-off, and I'm honestly not sure which way would
be better for the language.  It's quite possible (IMHO) that the best
course of action for now would be *not doing either one*.

=E2=80=93Arthur

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

--001a1145b8d8f94465052a837f23
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Fri, Jan 29, 2016 at 1:08 PM, Nicol Bolas <span dir=3D"=
ltr">&lt;<a href=3D"mailto:jmckesson@gmail.com" target=3D"_blank">jmckesson=
@gmail.com</a>&gt;</span> wrote:<br><div class=3D"gmail_extra"><div class=
=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px =
0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-l=
eft-style:solid;padding-left:1ex"><div dir=3D"ltr">On Friday, January 29, 2=
016 at 2:21:00 PM UTC-5, Arthur O&#39;Dwyer wrote:<span class=3D""><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-wid=
th:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-l=
eft:1ex"><div dir=3D"ltr"><br></div></blockquote><div></div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;=
border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex=
"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div>As of C++11, we hav=
e decltype(E) =E2=80=94 which takes the value E and produces its type =E2=
=80=94 and we have std::declval&lt;T&gt;() =E2=80=94 which takes a type T a=
nd produces a value of that type. And they compose, so I can do a bunch of =
&quot;value-space&quot; computations and then take the decltype of the resu=
lting expression. Any construct that gets in the way of my doing that is ob=
jectionable.</div><div>In other words, rather than saying that <font face=
=3D"monospace, monospace">mpl::vector&lt;Ts...&gt;</font> doesn&#39;t have =
a value and so <font face=3D"monospace, monospace">std::get&lt;I&gt;(mplvec=
)</font> should be ill-formed, I would prefer we simply say that <font face=
=3D"monospace, monospace">std::get&lt;I&gt;(mplvec)</font> doesn&#39;t have=
 a <i>value</i> =E2=80=94 but it should still have a <i>type</i>!</div></di=
v></div></div></blockquote></span><div><br>You can want whatever you want, =
but the fact is that in C++, types and=20
values are different things. And we have different mechanisms for=20
dealing with each.<br><br>Functions take values and return them.=20
Template metafunctions take types and can evaluate to types. `declval`=20
doesn&#39;t really generate a value in any meaningful way, since it can onl=
y
 exist in a non-evaluated context. And while `decltype` does evaluate to
 a type, that type is not based on a value, since the expression itself=20
is never actually evaluated.<br><br>Maybe sometimes these things will be
 equivalent someday. But until then, C++ is what it is. Values and types ar=
e=20
different, and we shouldn&#39;t pretend that they&#39;re not.<br></div></di=
v></blockquote><div><br></div><div>That&#39;s one point of view, but I tend=
 to think that it&#39;s outdated (as of C++11). We don&#39;t need template =
metafunctions anymore (well, not so many of them), now that we have constex=
pr and heterogeneous function templates at our disposal. For example, where=
 in C++03 we <i>did</i>=C2=A0often have to write template metafunctions suc=
h as</div><div><br></div><div><b><font face=3D"monospace, monospace">templa=
te&lt;class T, class U&gt;</font></b></div><div><b><font face=3D"monospace,=
 monospace">struct result_of_plus {</font></b></div><div><b><font face=3D"m=
onospace, monospace">=C2=A0 =C2=A0 typedef __typeof(T()+U()) type;</font></=
b></div><div><b><font face=3D"monospace, monospace">};</font></b></div><div=
><font face=3D"monospace, monospace"><br></font></div><div><font face=3D"mo=
nospace, monospace">struct plus {</font></div><div><font face=3D"monospace,=
 monospace">=C2=A0 =C2=A0 template&lt;class T, class U&gt;</font></div><div=
><font face=3D"monospace, monospace">=C2=A0 =C2=A0 <b>typename result_of_pl=
us&lt;T,U&gt;::type</b> operator(T t, U u) { return t + u; }</font></div><d=
iv><font face=3D"monospace, monospace">};</font></div><div><br></div><div>a=
s of C++14 we no longer need to write any of that metafunction machinery; w=
e can use <font face=3D"monospace, monospace">decltype</font>=C2=A0to get t=
he compiler to do the meta-lifting on our behalf, and all we need to worry =
about are <i>expressions</i>, which generally have both a type and a value.=
</div><div><br></div><div><div><font face=3D"monospace, monospace">struct p=
lus {</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 te=
mplate&lt;class T, class U&gt;</font></div><div><font face=3D"monospace, mo=
nospace">=C2=A0 =C2=A0=C2=A0<b>auto</b>=C2=A0operator(T t, U u) <b>-&gt; de=
cltype(t + u)</b> { return t + u; }</font></div><div><font face=3D"monospac=
e, monospace">};</font></div></div><div><font face=3D"monospace, monospace"=
><br></font></div><div>(and we don&#39;t even need the <font face=3D"monosp=
ace, monospace">-&gt; decltype</font> stuff unless we want SFINAE!)</div><d=
iv>Values and types <i>are</i> different, but they are still intimately rel=
ated (for example, every value has a type), and while we <i>can</i> use dif=
ferent mechanisms to deal with each, we no longer <i>need</i> to.</div><div=
><br></div><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin=
:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204)=
;border-left-style:solid;padding-left:1ex"><div dir=3D"ltr"><span class=3D"=
"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;borde=
r-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid=
;padding-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div>Ha=
ving said all that, this &quot;postfix twiddle means std::get&lt;&gt; (and/=
or std::tuple_element_t&lt;&gt;)&quot; thing still feels too ad-hoc to me.<=
/div></div></div></div></blockquote></span><div><br>It&#39;s no more ad-hoc=
 than range-based for using `std::begin` and `std::end`. You have to have s=
ome customization point for user-defined types.<br></div></div></blockquote=
><div><br></div><div>Agreed, I think, grudgingly, reluctantly, in practice.=
=C2=A0 In other words, I agree that&#39;s the current state of the world, b=
ut I don&#39;t <i>like</i> it. It feels much too ad-hoc. begin and end &quo=
t;work&quot; as well as they do because they had a couple of decades of imp=
lementation experience behind them before people started making up syntacti=
c sugar for them. Right now we have maybe 5 years of experience using std::=
get and probably even less with std::tuple_element_t. Are those <i>exactly<=
/i> the primitives we want to syntactic-sugar up, or will we regret the dec=
ision in another 5 years when we realize &quot;how tuples <i>should</i> hav=
e been done&quot;?</div><div><br></div><div>I mean, imagine if instead of i=
ostreams using operator overloading, we had gotten a syntactic sugar where =
<font face=3D"monospace, monospace">&lt;&lt;</font> in certain contexts exp=
anded to a call to <font face=3D"monospace, monospace">std::printf()</font>=
.. Makes sense, right? But it would have been horrible for the flexibility a=
nd symmetry of the language as a whole. <i>And even iostreams-as-is suck!</=
i> =C2=A0Basically I&#39;m worried that postfix-twiddle and tuples-as-is ar=
e in an analogous situation right now. We might not <i>want</i> to immortal=
ize <font face=3D"monospace, monospace">std::get&lt;I&gt;</font> in languag=
e syntax.</div><div><br></div><div>=C2=A0</div><blockquote class=3D"gmail_q=
uote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-c=
olor:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir=3D=
"ltr"><span class=3D""><blockquote class=3D"gmail_quote" style=3D"margin:0p=
x 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);bo=
rder-left-style:solid;padding-left:1ex"><div dir=3D"ltr"><div><div class=3D=
"gmail_quote"><div>If we could come up with a nice syntax for it, I&#39;d p=
refer to have the std::get&lt;&gt; written out and just build a simple synt=
ax for getting a parameter-pack of <i>integer indices</i>.=C2=A0 I have no =
idea what that syntax would look like, though, or how it would end up remot=
ely as clean as this seductive example:</div><div><br></div><div><div style=
=3D"font-size:13px"><span style=3D"font-family:monospace,monospace">=C2=A0 =
=C2=A0 template&lt;class Vec&gt;</span><br></div><div style=3D"font-size:13=
px"><font face=3D"monospace, monospace">=C2=A0 =C2=A0 auto dotproduct(const=
 Vec&amp; a, const Vec&amp; b)</font></div><div style=3D"font-size:13px"><f=
ont face=3D"monospace, monospace">=C2=A0 =C2=A0 {</font></div><div style=3D=
"font-size:13px"><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 return (... + (a~ * b~)); =C2=A0// this is a C++17 fold-expression</=
font></div><div style=3D"font-size:13px"><font face=3D"monospace, monospace=
">=C2=A0 =C2=A0 }</font></div></div><div><br></div></div></div></div></bloc=
kquote></span><div><br>That example seems to be missing what the return val=
ue is supposed to be. Presumably it&#39;s some `Vec` object, but you don&#3=
9;t use the typename anywhere.<br></div></div></blockquote><div><br></div><=
div>The return type is exactly <font face=3D"monospace, monospace">decltype=
((... + (a~ * b~)))</font>. Starting in C++14, we don&#39;t have to write i=
t out; <font face=3D"monospace, monospace">auto</font> suffices for return =
type deduction.</div><div>For example, if <font face=3D"monospace, monospac=
e">Vec</font> is <font face=3D"monospace, monospace">std::tuple&lt;int, dou=
ble, char&gt;</font>, then=C2=A0<span style=3D"font-family:monospace,monosp=
ace">decltype((... + (a~ * b~)))</span>=C2=A0is <font face=3D"monospace, mo=
nospace">double</font>.</div><div><br></div><div><br></div><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;b=
order-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"=
><div dir=3D"ltr"><span class=3D""><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(20=
4,204,204);border-left-style:solid;padding-left:1ex"><div dir=3D"ltr"><div>=
<div class=3D"gmail_quote"><div>The only thing I can think to do is to intr=
oduce first-class parameter packs, and write</div><div><br></div><div><div>=
<div style=3D"font-size:13px"><span style=3D"font-family:monospace,monospac=
e">=C2=A0 =C2=A0 template&lt;size_t I, class... Ts&gt;</span><br></div><div=
 style=3D"font-size:13px"><font face=3D"monospace, monospace">=C2=A0 =C2=A0=
 auto getp(const std::tuple&lt;Ts...&gt;&amp;) -&gt; Ts...; =C2=A0// &quot;=
return a pack&quot;</font></div><div style=3D"font-size:13px"><span style=
=3D"font-family:monospace,monospace"><br></span></div><div style=3D"font-si=
ze:13px"><span style=3D"font-family:monospace,monospace">=C2=A0 =C2=A0 temp=
late&lt;class Vec&gt;</span><br></div><div style=3D"font-size:13px"><font f=
ace=3D"monospace, monospace">=C2=A0 =C2=A0 auto dotproduct(const Vec&amp; a=
, const Vec&amp; b)</font></div><div style=3D"font-size:13px"><font face=3D=
"monospace, monospace">=C2=A0 =C2=A0 {</font></div><div style=3D"font-size:=
13px"><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 retur=
n (... + (getp(a) * getp(b)));</font></div><div style=3D"font-size:13px"><f=
ont face=3D"monospace, monospace">=C2=A0 =C2=A0 }</font></div></div></div><=
div><br></div><div>But first-class parameter packs seem like a nightmare to=
 specify, don&#39;t they?</div></div></div></div></blockquote></span><div><=
br>Um, how exactly is that easier than the user implementing the appropriat=
e interfaces? It certainly isn&#39;t easier for the reader to understand.</=
div></div></blockquote><div><br></div><div>My idea was that <font face=3D"m=
onospace, monospace">std::getp</font> would probably be standardized as the=
 &quot;packful&quot; version of <font face=3D"monospace, monospace">std::ge=
t</font>, so the user wouldn&#39;t have to actually write out the implement=
ation of <font face=3D"monospace, monospace">getp</font> in practice.</div>=
<div>I agree that the syntax inside this version of <font face=3D"monospace=
, monospace">dotproduct</font> is much more off-putting than the postfix-tw=
iddle syntax. <b>It is uglier.</b> However, it is <b>conceptually cleaner</=
b>, because it doesn&#39;t introduce any significantly new grammar (no post=
fix-twiddle operator) and it doesn&#39;t introduce any new &quot;magic name=
s&quot;=C2=A0(no hard-coding of the names=C2=A0<font face=3D"monospace, mon=
ospace">get</font>=C2=A0and=C2=A0<font face=3D"monospace, monospace">tuple_=
element_t</font>=C2=A0into the compiler).=C2=A0 This is a trade-off, and I&=
#39;m honestly not sure which way would be better for the language.=C2=A0 I=
t&#39;s quite possible (IMHO) that the best course of action for now would =
be=C2=A0<b>not doing either one</b>.</div><div><br></div><div>=E2=80=93Arth=
ur</div></div></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

--001a1145b8d8f94465052a837f23--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 30 Jan 2016 08:33:21 -0800 (PST)
Raw View
------=_Part_401_995972821.1454171601816
Content-Type: multipart/alternative;
 boundary="----=_Part_402_1356464816.1454171601817"

------=_Part_402_1356464816.1454171601817
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Friday, January 29, 2016 at 8:59:22 PM UTC-5, Arthur O'Dwyer wrote:
>
> On Fri, Jan 29, 2016 at 1:08 PM, Nicol Bolas <jmck...@gmail.com=20
> <javascript:>> wrote:
>
>> On Friday, January 29, 2016 at 2:21:00 PM UTC-5, Arthur O'Dwyer wrote:
>>>
>>>
>>> As of C++11, we have decltype(E) =E2=80=94 which takes the value E and =
produces=20
>>> its type =E2=80=94 and we have std::declval<T>() =E2=80=94 which takes =
a type T and=20
>>> produces a value of that type. And they compose, so I can do a bunch of=
=20
>>> "value-space" computations and then take the decltype of the resulting=
=20
>>> expression. Any construct that gets in the way of my doing that is=20
>>> objectionable.
>>> In other words, rather than saying that mpl::vector<Ts...> doesn't have=
=20
>>> a value and so std::get<I>(mplvec) should be ill-formed, I would prefer=
=20
>>> we simply say that std::get<I>(mplvec) doesn't have a *value* =E2=80=94=
 but it=20
>>> should still have a *type*!
>>>
>>
>> You can want whatever you want, but the fact is that in C++, types and=
=20
>> values are different things. And we have different mechanisms for dealin=
g=20
>> with each.
>>
>> Functions take values and return them. Template metafunctions take types=
=20
>> and can evaluate to types. `declval` doesn't really generate a value in =
any=20
>> meaningful way, since it can only exist in a non-evaluated context. And=
=20
>> while `decltype` does evaluate to a type, that type is not based on a=20
>> value, since the expression itself is never actually evaluated.
>>
>> Maybe sometimes these things will be equivalent someday. But until then,=
=20
>> C++ is what it is. Values and types are different, and we shouldn't pret=
end=20
>> that they're not.
>>
>
> That's one point of view, but I tend to think that it's outdated (as of=
=20
> C++11). We don't need template metafunctions anymore (well, not so many o=
f=20
> them),
>

No, there's a *huge difference* between "we don't need X anymore" and "we=
=20
don't need X quite as much anymore".

Expression type deduction is useful, and I never claimed that it wasn't.=20
But it should not be *abused* by declaring functions you don't intend to=20
actually call, just so that you can turn what should be a metafunction=20
invocation into `decltype(function)`.
=20

> Values and types *are* different, but they are still intimately related=
=20
> (for example, every value has a type), and while we *can* use different=
=20
> mechanisms to deal with each, we no longer *need* to.
>

And that way lies highly unclear code. If a template function has access to=
=20
a type that provides a type sequence (just a sequence like mpl::vector),=20
and you want to access one of the types in that type sequence, you have to=
=20
do something like this:

decltype(get<I>(declval<TypeSeq>()))

Compare that to:

tuple_element_t<TypeSeq, I>

Which one of these is more clear to the reader what is going on?

So yes, if you want to blur the distinction between types and values in=20
C++, you can. But I can't say much for the *consequences* of that.
=20

> Having said all that, this "postfix twiddle means std::get<> (and/or=20
>>> std::tuple_element_t<>)" thing still feels too ad-hoc to me.
>>>
>>
>> It's no more ad-hoc than range-based for using `std::begin` and=20
>> `std::end`. You have to have some customization point for user-defined=
=20
>> types.
>>
>
> Agreed, I think, grudgingly, reluctantly, in practice.  In other words, I=
=20
> agree that's the current state of the world, but I don't *like* it. It=20
> feels much too ad-hoc. begin and end "work" as well as they do because th=
ey=20
> had a couple of decades of implementation experience behind them before=
=20
> people started making up syntactic sugar for them. Right now we have mayb=
e=20
> 5 years of experience using std::get and probably even less with=20
> std::tuple_element_t. Are those *exactly* the primitives we want to=20
> syntactic-sugar up, or will we regret the decision in another 5 years whe=
n=20
> we realize "how tuples *should* have been done"?
>

I hate using principles as bludgeons, but "perfect is the enemy of good".

Sure, in 10 years, someone might come up with a better idea. But right now,=
=20
*today*, this is a reasonable choice. Waiting around for 10 years for the=
=20
best possible choice to present itself makes no sense. We have problems=20
using tuples and tuple-like types, and we need solutions to those problems.=
=20
*Now*.

Unless you have a specific, actual *problem* with the syntax, something=20
that clearly makes it less effective or useful than it could be, then=20
you're saying nothing more than "don't do this, it might not be good." Yes,=
=20
we know it might not work out. That's not a good enough reason to stop=20
trying.

Equally importantly, the language can *change*. Look at the Ranges TS,=20
which changes iterator pairs into iterator+sentinel. C++14 range-based for=
=20
loops assume that the type that `begin` and `end` return for the same range=
=20
is the same. But all it takes is one small language change (the definition=
=20
of how range-for transforms itself) to remove that requirement.

If we find a better way to handle tuples, a better entrypoint or whatever,=
=20
we can always modify the meaning of the operator. You simply have to make=
=20
the change in a non-code-breaking way.

I mean, imagine if instead of iostreams using operator overloading, we had=
=20
> gotten a syntactic sugar where << in certain contexts expanded to a call=
=20
> to std::printf(). Makes sense, right? But it would have been horrible for=
=20
> the flexibility and symmetry of the language as a whole.
>

Um... what's so bad about that?

Ignoring the silliness of changing what `<<` means, using `printf` as an=20
extension point for formatting types makes *far more sense* than=20
`operator<<`. Why? Because `operator<<` only gets two parameters, while a=
=20
regular function can get however many parameters you want.

Regular printf allows you to do things like cap the width of a formatted=20
integer or fill it out with zeros or whatever. These are encoded in the=20
formatting string, but they are still effectively *parameters* to the=20
formatter.

Iostreams provides equivalent functionality, but only by storing them in=20
the formatter itself. Which means that they continue to apply until another=
=20
command changes them; they're not bound to a specific value being=20
formatted. This makes the construct exceedingly painful, on pretty much=20
everyone:

1. It makes it harder to write a formatter. You have to extract your=20
formatting parameters from the stream and then generate your data based on=
=20
them.
2. Every stream must have the capacity to store such parameters, so streams=
=20
have to do more stuff.
3. Users have to use Godawful syntax to turn such parameters on and off.

In short, `operator<<` does a *crappy* job of providing extensibility for=
=20
formatting operations.

The *only* problem I have with this suggestion of having `<<` become=20
`printf`is that you used a pre-existing operator that already has a=20
well-defined meaning. If you had suggested using a new operator (which is=
=20
what we're suggesting here), I'd be more-or-less OK with it.

Or at least less hostile (I personally despise using *any* operator for=20
formatting).

The only thing I can think to do is to introduce first-class parameter=20
>>> packs, and write
>>>
>>>     template<size_t I, class... Ts>
>>>     auto getp(const std::tuple<Ts...>&) -> Ts...;  // "return a pack"
>>>
>>>     template<class Vec>
>>>     auto dotproduct(const Vec& a, const Vec& b)
>>>     {
>>>         return (... + (getp(a) * getp(b)));
>>>     }
>>>
>>> But first-class parameter packs seem like a nightmare to specify, don't=
=20
>>> they?
>>>
>>
>> Um, how exactly is that easier than the user implementing the appropriat=
e=20
>> interfaces? It certainly isn't easier for the reader to understand.
>>
>
> My idea was that std::getp would probably be standardized as the=20
> "packful" version of std::get, so the user wouldn't have to actually=20
> write out the implementation of getp in practice.
> I agree that the syntax inside this version of dotproduct is much more=20
> off-putting than the postfix-twiddle syntax. *It is uglier.* However, it=
=20
> is *conceptually cleaner*, because it doesn't introduce any significantly=
=20
> new grammar (no postfix-twiddle operator)
>

It does introduce new grammar; just not at the cite of *use*. You have to=
=20
have new grammar to have multiple return values.

and it doesn't introduce any new "magic names" (no hard-coding of the names=
=20
> get and tuple_element_t into the compiler).  This is a trade-off, and I'm=
=20
> honestly not sure which way would be better for the language.  It's quite=
=20
> possible (IMHO) that the best course of action for now would be *not=20
> doing either one*.
>

No, it would not. Irrational fear is not a good reason to not do something.=
=20
Especially if it is an exceedingly useful something, which will make a pain=
=20
point of the language far less painful.

Equally importantly, it's not a tradeoff. The reason being that you cannot=
=20
*store* arbitrary value sequences. They're not types, after all. You can't=
=20
pass around a value sequence. These are all things that don't make sense=20
because value sequences are not objects (they're multiple objects, each=20
with their own type and so forth).

Tuples *are* objects. You can stick them in classes with well-defined=20
behavior. You can pass them around intact, unbroadcasted. You can=20
introspect them arbitrarily, fetching out a specific element. You can=20
*modify* them in-situ. And so forth. Even with language-level multiple=20
return values, tuples are still extremely useful constructs.

Which means that the desire to broadcast them, to transform tuples into=20
value sequences, *is still useful*. So even if you have MRVs as a=20
language-feature, you still want the tuple-to-value-sequence transformation=
..

So it isn't a tradeoff; the two features have some overlap, but they are=20
also different and each are useful in their own rights.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

------=_Part_402_1356464816.1454171601817
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Friday, January 29, 2016 at 8:59:22 PM UTC-5, Arthur O&=
#39;Dwyer wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"lt=
r">On Fri, Jan 29, 2016 at 1:08 PM, Nicol Bolas <span dir=3D"ltr">&lt;<a hr=
ef=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"05KaqrPjGgAJ"=
 rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#39;;return t=
rue;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;">jmck...@gm=
ail.com</a>&gt;</span> wrote:<br><div><div class=3D"gmail_quote"><blockquot=
e class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width=
:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-lef=
t:1ex"><div dir=3D"ltr">On Friday, January 29, 2016 at 2:21:00 PM UTC-5, Ar=
thur O&#39;Dwyer wrote:<span><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,2=
04);border-left-style:solid;padding-left:1ex"><div dir=3D"ltr"><br></div></=
blockquote><div></div><blockquote class=3D"gmail_quote" style=3D"margin:0px=
 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);bor=
der-left-style:solid;padding-left:1ex"><div dir=3D"ltr"><div><div class=3D"=
gmail_quote"><div>As of C++11, we have decltype(E) =E2=80=94 which takes th=
e value E and produces its type =E2=80=94 and we have std::declval&lt;T&gt;=
() =E2=80=94 which takes a type T and produces a value of that type. And th=
ey compose, so I can do a bunch of &quot;value-space&quot; computations and=
 then take the decltype of the resulting expression. Any construct that get=
s in the way of my doing that is objectionable.</div><div>In other words, r=
ather than saying that <font face=3D"monospace, monospace">mpl::vector&lt;T=
s...&gt;</font> doesn&#39;t have a value and so <font face=3D"monospace, mo=
nospace">std::get&lt;I&gt;(mplvec)</font> should be ill-formed, I would pre=
fer we simply say that <font face=3D"monospace, monospace">std::get&lt;I&gt=
;(mplvec)</font> doesn&#39;t have a <i>value</i> =E2=80=94 but it should st=
ill have a <i>type</i>!</div></div></div></div></blockquote></span><div><br=
>You can want whatever you want, but the fact is that in C++, types and=20
values are different things. And we have different mechanisms for=20
dealing with each.<br><br>Functions take values and return them.=20
Template metafunctions take types and can evaluate to types. `declval`=20
doesn&#39;t really generate a value in any meaningful way, since it can onl=
y
 exist in a non-evaluated context. And while `decltype` does evaluate to
 a type, that type is not based on a value, since the expression itself=20
is never actually evaluated.<br><br>Maybe sometimes these things will be
 equivalent someday. But until then, C++ is what it is. Values and types ar=
e=20
different, and we shouldn&#39;t pretend that they&#39;re not.<br></div></di=
v></blockquote><div><br></div><div>That&#39;s one point of view, but I tend=
 to think that it&#39;s outdated (as of C++11). We don&#39;t need template =
metafunctions anymore (well, not so many of them),</div></div></div></div><=
/blockquote><div><br>No, there&#39;s a <i>huge difference</i> between &quot=
;we don&#39;t need X anymore&quot; and &quot;we don&#39;t need X quite as m=
uch anymore&quot;.<br><br>Expression type deduction is useful, and I never =
claimed that it wasn&#39;t. But it should not be <i>abused</i> by declaring=
 functions you don&#39;t intend to actually call, just so that you can turn=
 what should be a metafunction invocation into `decltype(function)`.<br>=C2=
=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div=
><div class=3D"gmail_quote"><div>Values and types <i>are</i> different, but=
 they are still intimately related (for example, every value has a type), a=
nd while we <i>can</i> use different mechanisms to deal with each, we no lo=
nger <i>need</i> to.</div></div></div></div></blockquote><div><br>And that =
way lies highly unclear code. If a template function has access to a type t=
hat provides a type sequence (just a sequence like mpl::vector), and you wa=
nt to access one of the types in that type sequence, you have to do somethi=
ng like this:<br><br><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"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">decltype</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">ge=
t</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">I</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">&gt;(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">declval</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color=
: #606;" class=3D"styled-by-prettify">TypeSeq</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">&gt;()))</span></div></code></div><br>Co=
mpare that to:<br><br><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"><di=
v class=3D"subprettyprint"><span style=3D"color: #000;" class=3D"styled-by-=
prettify">tuple_element_t</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&lt;</span><span style=3D"color: #606;" class=3D"styled-by-p=
rettify">TypeSeq</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> I<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span>=
</div></code></div><br>Which one of these is more clear to the reader what =
is going on?<br><br>So yes, if you want to blur the distinction between typ=
es and values in C++, you can. But I can&#39;t say much for the <i>conseque=
nces</i> of that.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D=
"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex=
;"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div></div><blockquote =
class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1=
px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:=
1ex"><div dir=3D"ltr"><span><blockquote class=3D"gmail_quote" style=3D"marg=
in:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,20=
4);border-left-style:solid;padding-left:1ex"><div dir=3D"ltr"><div><div cla=
ss=3D"gmail_quote"><div>Having said all that, this &quot;postfix twiddle me=
ans std::get&lt;&gt; (and/or std::tuple_element_t&lt;&gt;)&quot; thing stil=
l feels too ad-hoc to me.</div></div></div></div></blockquote></span><div><=
br>It&#39;s no more ad-hoc than range-based for using `std::begin` and `std=
::end`. You have to have some customization point for user-defined types.<b=
r></div></div></blockquote><div><br></div><div>Agreed, I think, grudgingly,=
 reluctantly, in practice.=C2=A0 In other words, I agree that&#39;s the cur=
rent state of the world, but I don&#39;t <i>like</i> it. It feels much too =
ad-hoc. begin and end &quot;work&quot; as well as they do because they had =
a couple of decades of implementation experience behind them before people =
started making up syntactic sugar for them. Right now we have maybe 5 years=
 of experience using std::get and probably even less with std::tuple_elemen=
t_t. Are those <i>exactly</i> the primitives we want to syntactic-sugar up,=
 or will we regret the decision in another 5 years when we realize &quot;ho=
w tuples <i>should</i> have been done&quot;?</div></div></div></div></block=
quote><div><br>I hate using principles as bludgeons, but &quot;perfect is t=
he enemy of good&quot;.<br><br>Sure, in 10 years, someone might come up wit=
h a better idea. But right now, <i>today</i>, this is a reasonable choice. =
Waiting around for 10 years for the best possible choice to present itself =
makes no sense. We have problems using tuples and tuple-like types, and we =
need solutions to those problems. <i>Now</i>.<br><br>Unless you have a spec=
ific, actual <i>problem</i> with the syntax, something that clearly makes i=
t less effective or useful than it could be, then you&#39;re saying nothing=
 more than &quot;don&#39;t do this, it might not be good.&quot; Yes, we kno=
w it might not work out. That&#39;s not a good enough reason to stop trying=
..<br><br>Equally importantly, the language can <i>change</i>. Look at the R=
anges TS, which changes iterator pairs into iterator+sentinel. C++14 range-=
based for loops assume that the type that `begin` and `end` return for the =
same range is the same. But all it takes is one small language change (the =
definition of how range-for transforms itself) to remove that requirement.<=
br><br>If we find a better way to handle tuples, a better entrypoint or wha=
tever, we can always modify the meaning of the operator. You simply have to=
 make the change in a non-code-breaking way.<br><br></div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quote=
"><div></div><div>I mean, imagine if instead of iostreams using operator ov=
erloading, we had gotten a syntactic sugar where <font face=3D"monospace, m=
onospace">&lt;&lt;</font> in certain contexts expanded to a call to <font f=
ace=3D"monospace, monospace">std::printf()</font>. Makes sense, right? But =
it would have been horrible for the flexibility and symmetry of the languag=
e as a whole.</div></div></div></div></blockquote><div><br>Um... what&#39;s=
 so bad about that?<br><br>Ignoring the silliness of changing what `&lt;&lt=
;` means, using `printf` as an extension point for formatting types makes <=
i>far more sense</i> than `operator&lt;&lt;`. Why? Because `operator&lt;&lt=
;` only gets two parameters, while a regular function can get however many =
parameters you want.<br><br>Regular printf allows you to do things like cap=
 the width of a formatted integer or fill it out with zeros or whatever. Th=
ese are encoded in the formatting string, but they are still effectively <i=
>parameters</i> to the formatter.<br><br>Iostreams provides equivalent func=
tionality, but only by storing them in the formatter itself. Which means th=
at they continue to apply until another command changes them; they&#39;re n=
ot bound to a specific value being formatted. This makes the construct exce=
edingly painful, on pretty much everyone:<br><br>1. It makes it harder to w=
rite a formatter. You have to extract your formatting parameters from the s=
tream and then generate your data based on them.<br>2. Every stream must ha=
ve the capacity to store such parameters, so streams have to do more stuff.=
<br>3. Users have to use Godawful syntax to turn such parameters on and off=
..<br><br>In short, `operator&lt;&lt;` does a <i>crappy</i> job of providing=
 extensibility for formatting operations.<br><br>The <i>only</i> problem I =
have with this suggestion of having `&lt;&lt;` become `printf`is that you u=
sed a pre-existing operator that already has a well-defined meaning. If you=
 had suggested using a new operator (which is what we&#39;re suggesting her=
e), I&#39;d be more-or-less OK with it.<br><br>Or at least less hostile (I =
personally despise using <i>any</i> operator for formatting).<br><br></div>=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div cla=
ss=3D"gmail_quote"><div></div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,=
204);border-left-style:solid;padding-left:1ex"><div dir=3D"ltr"><span><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-=
width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;paddin=
g-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div>The only =
thing I can think to do is to introduce first-class parameter packs, and wr=
ite</div><div><br></div><div><div><div style=3D"font-size:13px"><span style=
=3D"font-family:monospace,monospace">=C2=A0 =C2=A0 template&lt;size_t I, cl=
ass... Ts&gt;</span><br></div><div style=3D"font-size:13px"><font face=3D"m=
onospace, monospace">=C2=A0 =C2=A0 auto getp(const std::tuple&lt;Ts...&gt;&=
amp;) -&gt; Ts...; =C2=A0// &quot;return a pack&quot;</font></div><div styl=
e=3D"font-size:13px"><span style=3D"font-family:monospace,monospace"><br></=
span></div><div style=3D"font-size:13px"><span style=3D"font-family:monospa=
ce,monospace">=C2=A0 =C2=A0 template&lt;class Vec&gt;</span><br></div><div =
style=3D"font-size:13px"><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =
auto dotproduct(const Vec&amp; a, const Vec&amp; b)</font></div><div style=
=3D"font-size:13px"><font face=3D"monospace, monospace">=C2=A0 =C2=A0 {</fo=
nt></div><div style=3D"font-size:13px"><font face=3D"monospace, monospace">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return (... + (getp(a) * getp(b)));</font></div=
><div style=3D"font-size:13px"><font face=3D"monospace, monospace">=C2=A0 =
=C2=A0 }</font></div></div></div><div><br></div><div>But first-class parame=
ter packs seem like a nightmare to specify, don&#39;t they?</div></div></di=
v></div></blockquote></span><div><br>Um, how exactly is that easier than th=
e user implementing the appropriate interfaces? It certainly isn&#39;t easi=
er for the reader to understand.</div></div></blockquote><div><br></div><di=
v>My idea was that <font face=3D"monospace, monospace">std::getp</font> wou=
ld probably be standardized as the &quot;packful&quot; version of <font fac=
e=3D"monospace, monospace">std::get</font>, so the user wouldn&#39;t have t=
o actually write out the implementation of <font face=3D"monospace, monospa=
ce">getp</font> in practice.</div><div>I agree that the syntax inside this =
version of <font face=3D"monospace, monospace">dotproduct</font> is much mo=
re off-putting than the postfix-twiddle syntax. <b>It is uglier.</b> Howeve=
r, it is <b>conceptually cleaner</b>, because it doesn&#39;t introduce any =
significantly new grammar (no postfix-twiddle operator)</div></div></div></=
div></blockquote><div><br>It does introduce new grammar; just not at the ci=
te of <i>use</i>. You have to have new grammar to have multiple return valu=
es.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr"><div><div class=3D"gmail_quote"><div> and it doesn&#39;t introduce any =
new &quot;magic names&quot;=C2=A0(no hard-coding of the names=C2=A0<font fa=
ce=3D"monospace, monospace">get</font>=C2=A0and=C2=A0<font face=3D"monospac=
e, monospace">tuple_element_t</font>=C2=A0<wbr>into the compiler).=C2=A0 Th=
is is a trade-off, and I&#39;m honestly not sure which way would be better =
for the language.=C2=A0 It&#39;s quite possible (IMHO) that the best course=
 of action for now would be=C2=A0<b>not doing either one</b>.</div></div></=
div></div></blockquote><div><br>No, it would not. Irrational fear is not a =
good reason to not do something. Especially if it is an exceedingly useful =
something, which will make a pain point of the language far less painful.<b=
r><br>Equally importantly, it&#39;s not a tradeoff. The reason being that y=
ou cannot <i>store</i> arbitrary value sequences. They&#39;re not types, af=
ter all. You can&#39;t pass around a value sequence. These are all things t=
hat don&#39;t make sense because value sequences are not objects (they&#39;=
re multiple objects, each with their own type and so forth).<br><br>Tuples =
<i>are</i> objects. You can stick them in classes with well-defined behavio=
r. You can pass them around intact, unbroadcasted. You can introspect them =
arbitrarily, fetching out a specific element. You can <i>modify</i> them in=
-situ. And so forth. Even with language-level multiple return values, tuple=
s are still extremely useful constructs.<br><br>Which means that the desire=
 to broadcast them, to transform tuples into value sequences, <i>is still u=
seful</i>. So even if you have MRVs as a language-feature, you still want t=
he tuple-to-value-sequence transformation.<br><br>So it isn&#39;t a tradeof=
f; the two features have some overlap, but they are also different and each=
 are useful in their own rights.<br></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

------=_Part_402_1356464816.1454171601817--
------=_Part_401_995972821.1454171601816--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sat, 30 Jan 2016 18:39:10 +0200
Raw View
On 30 January 2016 at 18:33, Nicol Bolas <jmckesson@gmail.com> wrote:
>> That's one point of view, but I tend to think that it's outdated (as of
>> C++11). We don't need template metafunctions anymore (well, not so many of
>> them),
> No, there's a huge difference between "we don't need X anymore" and "we
> don't need X quite as much anymore".
> Expression type deduction is useful, and I never claimed that it wasn't. But
> it should not be abused by declaring functions you don't intend to actually
> call, just so that you can turn what should be a metafunction invocation
> into `decltype(function)`.


Well, you may call it abuse, but most existing traits internally
declare functions
that are not intended to be called. Which means that declaring but not defining
functions is a fairly common metaprogramming technique.

--

---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Tony V E <tvaneerd@gmail.com>
Date: Sat, 30 Jan 2016 12:35:53 -0500
Raw View
<html><head></head><body lang=3D"en-US" style=3D"background-color: rgb(255,=
 255, 255); line-height: initial;">                                        =
                                              <div style=3D"width: 100%; fo=
nt-size: initial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif=
; color: rgb(31, 73, 125); text-align: initial; background-color: rgb(255, =
255, 255);">IMO</div><div style=3D"width: 100%; font-size: initial; font-fa=
mily: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, 125)=
; text-align: initial; background-color: rgb(255, 255, 255);"><br></div><di=
v style=3D"width: 100%; font-size: initial; font-family: Calibri, 'Slate Pr=
o', sans-serif, sans-serif; color: rgb(31, 73, 125); text-align: initial; b=
ackground-color: rgb(255, 255, 255);">mpl::vector is a "type-list"</div><di=
v style=3D"width: 100%; font-size: initial; font-family: Calibri, 'Slate Pr=
o', sans-serif, sans-serif; color: rgb(31, 73, 125); text-align: initial; b=
ackground-color: rgb(255, 255, 255);">std::tuple is a "tuple-like"=E2=80=8E=
 (and also a type-list) - a typelist with values</div><div style=3D"width: =
100%; font-size: initial; font-family: Calibri, 'Slate Pro', sans-serif, sa=
ns-serif; color: rgb(31, 73, 125); text-align: initial; background-color: r=
gb(255, 255, 255);"><br></div><div style=3D"width: 100%; font-size: initial=
; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31,=
 73, 125); text-align: initial; background-color: rgb(255, 255, 255);">Can =
we use those terms going forward?</div><div style=3D"width: 100%; font-size=
: initial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif; color=
: rgb(31, 73, 125); text-align: initial; background-color: rgb(255, 255, 25=
5);"><br></div><div style=3D"width: 100%; font-size: initial; font-family: =
Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); text=
-align: initial; background-color: rgb(255, 255, 255);"><br></div><div styl=
e=3D"width: 100%; font-size: initial; font-family: Calibri, 'Slate Pro', sa=
ns-serif, sans-serif; color: rgb(31, 73, 125); text-align: initial; backgro=
und-color: rgb(255, 255, 255);">Any place you are doing meta-programming an=
d need a type-list you _could_ use std::tuple, and the value part of tuple =
is ignored without penalty, as you are just doing compile-time type stuff. =
</div><div style=3D"width: 100%; font-size: initial; font-family: Calibri, =
'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); text-align: i=
nitial; background-color: rgb(255, 255, 255);"><br></div><div style=3D"widt=
h: 100%; font-size: initial; font-family: Calibri, 'Slate Pro', sans-serif,=
 sans-serif; color: rgb(31, 73, 125); text-align: initial; background-color=
: rgb(255, 255, 255);">HOWEVER, it is confusing to the reader. We need an a=
ctual std::typelist</div><div style=3D"width: 100%; font-size: initial; fon=
t-family: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, =
125); text-align: initial; background-color: rgb(255, 255, 255);"><br></div=
><div style=3D"width: 100%; font-size: initial; font-family: Calibri, 'Slat=
e Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); text-align: initia=
l; background-color: rgb(255, 255, 255);">At which point mpl::vector become=
s "typelist-like" :-(</div><div style=3D"width: 100%; font-size: initial; f=
ont-family: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73=
, 125); text-align: initial; background-color: rgb(255, 255, 255);">(ie we =
need to be careful about naming our types and our concepts the same thing o=
r not)</div><div style=3D"width: 100%; font-size: initial; font-family: Cal=
ibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); text-al=
ign: initial; background-color: rgb(255, 255, 255);"><br></div><div style=
=3D"width: 100%; font-size: initial; font-family: Calibri, 'Slate Pro', san=
s-serif, sans-serif; color: rgb(31, 73, 125); text-align: initial; backgrou=
nd-color: rgb(255, 255, 255);">And I hate std::get. I wish it was called tu=
ple_get. Particularly if we start to use it as a syntax-sugar extension poi=
nt (like range-for and begin/end)</div><div style=3D"width: 100%; font-size=
: initial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif; color=
: rgb(31, 73, 125); text-align: initial; background-color: rgb(255, 255, 25=
5);"><br></div><div style=3D"width: 100%; font-size: initial; font-family: =
Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); text=
-align: initial; background-color: rgb(255, 255, 255);">=E2=80=8EJust my tw=
o cents. Carry on.&nbsp;</div><div style=3D"width: 100%; font-size: initial=
; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31,=
 73, 125); text-align: initial; background-color: rgb(255, 255, 255);">Tony=
</div><div style=3D"width: 100%; font-size: initial; font-family: Calibri, =
'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); text-align: i=
nitial; background-color: rgb(255, 255, 255);"><br></div>                  =
                                                                           =
                                        <div style=3D"width: 100%; font-siz=
e: initial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif; colo=
r: rgb(31, 73, 125); text-align: initial; background-color: rgb(255, 255, 2=
55);"><br style=3D"display:initial"></div>                                 =
                                                                           =
                                                                           =
            <div style=3D"font-size: initial; font-family: Calibri, 'Slate =
Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); text-align: initial;=
 background-color: rgb(255, 255, 255);">Sent&nbsp;from&nbsp;my&nbsp;BlackBe=
rry&nbsp;portable&nbsp;Babbage&nbsp;Device</div>                           =
                                                                           =
                                                                           =
 <table width=3D"100%" style=3D"background-color:white;border-spacing:0px;"=
> <tbody><tr><td colspan=3D"2" style=3D"font-size: initial; text-align: ini=
tial; background-color: rgb(255, 255, 255);">                           <di=
v style=3D"border-style: solid none none; border-top-color: rgb(181, 196, 2=
23); border-top-width: 1pt; padding: 3pt 0in 0in; font-family: Tahoma, 'BB =
Alpha Sans', 'Slate Pro'; font-size: 10pt;">  <div><b>From: </b>Arthur O'Dw=
yer</div><div><b>Sent: </b>Monday, January 25, 2016 2:37 PM</div><div><b>To=
: </b>std-proposals@isocpp.org</div><div><b>Reply To: </b>std-proposals@iso=
cpp.org</div><div><b>Subject: </b>Re: [std-proposals] Re: RFC: Unpacking tu=
ples to value sequences</div></div></td></tr></tbody></table><div style=3D"=
border-style: solid none none; border-top-color: rgb(186, 188, 209); border=
-top-width: 1pt; font-size: initial; text-align: initial; background-color:=
 rgb(255, 255, 255);"></div><br><div id=3D"_originalContent" style=3D""><di=
v dir=3D"ltr">On Mon, Jan 25, 2016 at 9:20 AM, Matthew Woehlke <span dir=3D=
"ltr">&lt;<a href=3D"mailto:mwoehlke.floss@gmail.com" target=3D"_blank">mwo=
ehlke.floss@gmail.com</a>&gt;</span> wrote:<br><div class=3D"gmail_extra"><=
div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin=
:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204)=
;border-left-style:solid;padding-left:1ex"><span class=3D"">On 2016-01-25 1=
1:25, Ville Voutilainen wrote:<br>
&gt; On 25 January 2016 at 17:32, Matthew Woehlke &lt;<a href=3D"mailto:mwo=
ehlke.floss@gmail.com">mwoehlke.floss@gmail.com</a>&gt; wrote:<br>&gt;&gt; =
On 2016-01-20 18:13, Arthur O'Dwyer wrote:<br>
&gt;&gt;&gt; would [mpl::vector] *not* be "tuple-like" because you couldn't=
 use<br>
&gt;&gt;&gt; std::get&lt;I&gt; on it at runtime?<br>
&gt;&gt;<br>
&gt;&gt; ...but then, I don't understand why that would be true?<br>
&gt;&gt;<br>
&gt;&gt; Back to that question, yes, the idea as I understand it is that<br=
>
&gt;&gt; "tuple-like" &lt;=3D&gt; "can use get&lt;N&gt;". Why is that an is=
sue?<br>&gt;<br>
&gt; mpl::vector is a container of types, not values. get&lt;N&gt; is a val=
ue-getter.<br>
<br>
</span>Ah. Um... how would you then *use* an mpl::vector in any context tha=
t<br>
you would use a tuple-like? A std::tuple is certainly a value<br>
collection. By extension, a tuple-like is also a value collection.<br></blo=
ckquote><div><br></div><div>As I explained in my original post, it seems ob=
vious that we'd define</div><div><br></div><div><span class=3D"" style=3D"l=
ine-height:1.1em;margin:0px;padding:0px;color:rgb(0,0,221);font-family:Deja=
VuSansMono,'DejaVu Sans Mono',courier,monospace;font-size:13px;white-space:=
nowrap">template</span><span class=3D"" style=3D"line-height:1.1em;margin:0=
px;padding:0px;color:rgb(0,0,128);font-family:DejaVuSansMono,'DejaVu Sans M=
ono',courier,monospace;font-size:13px;white-space:nowrap">&lt;</span><span =
style=3D"color:rgb(0,0,0);font-family:DejaVuSansMono,'DejaVu Sans Mono',cou=
rier,monospace;font-size:13px;white-space:nowrap">&nbsp;</span><span class=
=3D"" style=3D"line-height:1.1em;margin:0px;padding:0px;color:rgb(0,0,221);=
font-family:DejaVuSansMono,'DejaVu Sans Mono',courier,monospace;font-size:1=
3px;white-space:nowrap">class</span><span style=3D"color:rgb(0,0,0);font-fa=
mily:DejaVuSansMono,'DejaVu Sans Mono',courier,monospace;font-size:13px;whi=
te-space:nowrap">...&nbsp;</span><span class=3D"" style=3D"line-height:1.1e=
m;margin:0px;padding:0px;color:rgb(0,0,0);font-family:DejaVuSansMono,'DejaV=
u Sans Mono',courier,monospace;font-size:13px;white-space:nowrap">Types</sp=
an><span style=3D"color:rgb(0,0,0);font-family:DejaVuSansMono,'DejaVu Sans =
Mono',courier,monospace;font-size:13px;white-space:nowrap">&nbsp;</span><sp=
an class=3D"" style=3D"line-height:1.1em;margin:0px;padding:0px;color:rgb(0=
,0,128);font-family:DejaVuSansMono,'DejaVu Sans Mono',courier,monospace;fon=
t-size:13px;white-space:nowrap">&gt;</span><br style=3D"color:rgb(0,0,0);fo=
nt-family:DejaVuSansMono,'DejaVu Sans Mono',courier,monospace;font-size:13p=
x;white-space:nowrap"><p style=3D"margin:0px;line-height:1.1em;padding:0px;=
color:rgb(0,0,0);font-family:DejaVuSansMono,'DejaVu Sans Mono',courier,mono=
space;font-size:13px;white-space:nowrap"><span class=3D"" style=3D"line-hei=
ght:1.1em;margin:0px;padding:0px;color:rgb(0,0,221)">class</span>&nbsp;tupl=
e_size<span class=3D"" style=3D"line-height:1.1em;margin:0px;padding:0px;co=
lor:rgb(0,0,128)">&lt;</span>&nbsp;<span class=3D"" style=3D"text-decoratio=
n:none;color:rgb(0,48,128);background-image:none;line-height:1.1em;margin:0=
px;padding:0px"><a href=3D"http://en.cppreference.com/w/cpp/utility/tuple" =
style=3D"text-decoration:none;color:rgb(0,48,128);background-image:none">mp=
l::<span class=3D"" style=3D"line-height:1.1em;margin:0px;padding:0px">v</s=
pan></a>ector</span><span class=3D"" style=3D"line-height:1.1em;margin:0px;=
padding:0px;color:rgb(0,0,128)">&lt;</span>Types...<span class=3D"" style=
=3D"line-height:1.1em;margin:0px;padding:0px;color:rgb(0,0,128)">&gt;</span=
>&nbsp;<span class=3D"" style=3D"line-height:1.1em;margin:0px;padding:0px;c=
olor:rgb(0,0,128)">&gt;</span><br></p><span style=3D"color:rgb(0,0,0);font-=
family:DejaVuSansMono,'DejaVu Sans Mono',courier,monospace;font-size:13px;w=
hite-space:nowrap">&nbsp;</span><span class=3D"" style=3D"line-height:1.1em=
;margin:0px;padding:0px;color:rgb(0,128,128);font-family:DejaVuSansMono,'De=
jaVu Sans Mono',courier,monospace;font-size:13px;white-space:nowrap">:</spa=
n><span style=3D"color:rgb(0,0,0);font-family:DejaVuSansMono,'DejaVu Sans M=
ono',courier,monospace;font-size:13px;white-space:nowrap">&nbsp;</span><spa=
n class=3D"" style=3D"line-height:1.1em;margin:0px;padding:0px;color:rgb(0,=
0,221);font-family:DejaVuSansMono,'DejaVu Sans Mono',courier,monospace;font=
-size:13px;white-space:nowrap">public</span><span style=3D"color:rgb(0,0,0)=
;font-family:DejaVuSansMono,'DejaVu Sans Mono',courier,monospace;font-size:=
13px;white-space:nowrap">&nbsp;</span><a href=3D"http://en.cppreference.com=
/w/cpp/types/integral_constant" style=3D"text-decoration:none;color:rgb(0,4=
8,128);background-image:none;font-family:DejaVuSansMono,'DejaVu Sans Mono',=
courier,monospace;font-size:13px;white-space:nowrap"><span class=3D"" style=
=3D"line-height:1.1em;margin:0px;padding:0px">std::<span class=3D"" style=
=3D"line-height:1.1em;margin:0px;padding:0px">integral_constant</span></spa=
n></a><span class=3D"" style=3D"line-height:1.1em;margin:0px;padding:0px;co=
lor:rgb(0,0,128);font-family:DejaVuSansMono,'DejaVu Sans Mono',courier,mono=
space;font-size:13px;white-space:nowrap">&lt;</span><a href=3D"http://en.cp=
preference.com/w/cpp/types/size_t" style=3D"text-decoration:none;color:rgb(=
0,48,128);background-image:none;font-family:DejaVuSansMono,'DejaVu Sans Mon=
o',courier,monospace;font-size:13px;white-space:nowrap"><span class=3D"" st=
yle=3D"line-height:1.1em;margin:0px;padding:0px">std::<span class=3D"" styl=
e=3D"line-height:1.1em;margin:0px;padding:0px">size_t</span></span></a><spa=
n style=3D"color:rgb(0,0,0);font-family:DejaVuSansMono,'DejaVu Sans Mono',c=
ourier,monospace;font-size:13px;white-space:nowrap">, sizeof...</span><span=
 class=3D"" style=3D"line-height:1.1em;margin:0px;padding:0px;color:rgb(0,1=
28,0);font-family:DejaVuSansMono,'DejaVu Sans Mono',courier,monospace;font-=
size:13px;white-space:nowrap">(</span><span style=3D"color:rgb(0,0,0);font-=
family:DejaVuSansMono,'DejaVu Sans Mono',courier,monospace;font-size:13px;w=
hite-space:nowrap">Types</span><span class=3D"" style=3D"line-height:1.1em;=
margin:0px;padding:0px;color:rgb(0,128,0);font-family:DejaVuSansMono,'DejaV=
u Sans Mono',courier,monospace;font-size:13px;white-space:nowrap">)</span><=
span class=3D"" style=3D"line-height:1.1em;margin:0px;padding:0px;color:rgb=
(0,0,128);font-family:DejaVuSansMono,'DejaVu Sans Mono',courier,monospace;f=
ont-size:13px;white-space:nowrap">&gt;</span><span style=3D"color:rgb(0,0,0=
);font-family:DejaVuSansMono,'DejaVu Sans Mono',courier,monospace;font-size=
:13px;white-space:nowrap">&nbsp;</span><span class=3D"" style=3D"line-heigh=
t:1.1em;margin:0px;padding:0px;color:rgb(0,128,0);font-family:DejaVuSansMon=
o,'DejaVu Sans Mono',courier,monospace;font-size:13px;white-space:nowrap">{=
</span><span style=3D"color:rgb(0,0,0);font-family:DejaVuSansMono,'DejaVu S=
ans Mono',courier,monospace;font-size:13px;white-space:nowrap">&nbsp;</span=
><span class=3D"" style=3D"line-height:1.1em;margin:0px;padding:0px;color:r=
gb(0,128,0);font-family:DejaVuSansMono,'DejaVu Sans Mono',courier,monospace=
;font-size:13px;white-space:nowrap">}</span><span class=3D"" style=3D"line-=
height:1.1em;margin:0px;padding:0px;color:rgb(0,128,128);font-family:DejaVu=
SansMono,'DejaVu Sans Mono',courier,monospace;font-size:13px;white-space:no=
wrap">;</span><br></div><div><br></div><div>and also</div><div><br></div><p=
re class=3D"" style=3D"padding:0px;border:0px none white;color:rgb(0,0,0);l=
ine-height:1.2em;border-top-left-radius:5px;border-top-right-radius:5px;bor=
der-bottom-right-radius:5px;border-bottom-left-radius:5px;margin-top:0px;ma=
rgin-bottom:0px;width:55em;overflow:auto;font-size:13px;background-image:no=
ne;vertical-align:top;font-family:DejaVuSansMono,'DejaVu Sans Mono',courier=
,monospace!important"><span class=3D"" style=3D"color:rgb(144,144,144)">// =
recursive case</span>
<span class=3D"" style=3D"color:rgb(0,0,221)">template</span><span class=3D=
"" style=3D"color:rgb(0,0,128)">&lt;</span> <a href=3D"http://en.cppreferen=
ce.com/w/cpp/types/size_t" style=3D"text-decoration:none;color:rgb(0,48,128=
);background-image:none"><span class=3D"">std::<span class=3D"">size_t</spa=
n></span></a> I, <span class=3D"" style=3D"color:rgb(0,0,221)">class</span>=
 Head, <span class=3D"" style=3D"color:rgb(0,0,221)">class</span>... <span =
class=3D"">Tail</span> <span class=3D"" style=3D"color:rgb(0,0,128)">&gt;</=
span>
<span class=3D"" style=3D"color:rgb(0,0,221)">struct</span> tuple_element<s=
pan class=3D"" style=3D"color:rgb(0,0,128)">&lt;</span>I, <a href=3D"http:/=
/en.cppreference.com/w/cpp/utility/tuple" style=3D"color:rgb(0,48,128);whit=
e-space:nowrap;text-decoration:none;background-image:none">mpl::<span class=
=3D"" style=3D"line-height:1.1em;margin:0px;padding:0px">v</span></a><span =
style=3D"color:rgb(0,48,128);white-space:nowrap">ector</span><span class=3D=
"" style=3D"color:rgb(0,0,128)">&lt;</span>Head, Tail...<span class=3D"" st=
yle=3D"color:rgb(0,0,128)">&gt;&gt;</span>
    <span class=3D"" style=3D"color:rgb(0,128,128)">:</span> std<span class=
=3D"" style=3D"color:rgb(0,128,128)">::</span><span class=3D"">tuple_elemen=
t</span><span class=3D"" style=3D"color:rgb(0,0,128)">&lt;</span>I<span cla=
ss=3D"" style=3D"color:rgb(0,0,64)">-</span><span class=3D"" style=3D"color=
:rgb(0,0,128)">1</span>, <a href=3D"http://en.cppreference.com/w/cpp/utilit=
y/tuple" style=3D"color:rgb(0,48,128);white-space:nowrap;text-decoration:no=
ne;background-image:none">mpl::<span class=3D"" style=3D"line-height:1.1em;=
margin:0px;padding:0px">v</span></a><span style=3D"color:rgb(0,48,128);whit=
e-space:nowrap">ector</span><span class=3D"" style=3D"color:rgb(0,0,128)">&=
lt;</span>Tail...<span class=3D"" style=3D"color:rgb(0,0,128)">&gt;&gt;</sp=
an> <span class=3D"" style=3D"color:rgb(0,128,0)">{</span> <span class=3D""=
 style=3D"color:rgb(0,128,0)">}</span><span class=3D"" style=3D"color:rgb(0=
,128,128)">;</span>

<span class=3D"" style=3D"color:rgb(144,144,144)">// base case</span>
<span class=3D"" style=3D"color:rgb(0,0,221)">template</span><span class=3D=
"" style=3D"color:rgb(0,0,128)">&lt;</span> <span class=3D"" style=3D"color=
:rgb(0,0,221)">class</span> Head, <span class=3D"" style=3D"color:rgb(0,0,2=
21)">class</span>... <span class=3D"">Tail</span> <span class=3D"" style=3D=
"color:rgb(0,0,128)">&gt;</span>
<span class=3D"" style=3D"color:rgb(0,0,221)">struct</span> tuple_element<s=
pan class=3D"" style=3D"color:rgb(0,0,128)">&lt;</span><span class=3D"" sty=
le=3D"color:rgb(0,0,128)">0</span>, <a href=3D"http://en.cppreference.com/w=
/cpp/utility/tuple" style=3D"color:rgb(0,48,128);white-space:nowrap;text-de=
coration:none;background-image:none">mpl::<span class=3D"" style=3D"line-he=
ight:1.1em;margin:0px;padding:0px">v</span></a><span style=3D"color:rgb(0,4=
8,128);white-space:nowrap">ector</span><span class=3D"" style=3D"color:rgb(=
0,0,128)">&lt;</span>Head, Tail...<span class=3D"" style=3D"color:rgb(0,0,1=
28)">&gt;&gt;</span> <span class=3D"" style=3D"color:rgb(0,128,0)">{</span>
   <span class=3D"" style=3D"color:rgb(0,0,221)">typedef</span> Head type<s=
pan class=3D"" style=3D"color:rgb(0,128,128)">;&nbsp;</span>
</pre><div><span class=3D"" style=3D"font-family:DejaVuSansMono,'DejaVu San=
s Mono',courier,monospace;font-size:13px;color:rgb(0,128,0)">}</span><span =
class=3D"" style=3D"font-family:DejaVuSansMono,'DejaVu Sans Mono',courier,m=
onospace;font-size:13px;color:rgb(0,128,128)">;</span></div><div><br></div>=
<div>The "Sprout" C++14 library includes these definitions today.</div><div=
><a href=3D"https://github.com/bolero-MURAKAMI/Sprout/blob/master/sprout/ty=
pe/boost/mpl/vector.hpp">https://github.com/bolero-MURAKAMI/Sprout/blob/mas=
ter/sprout/type/boost/mpl/vector.hpp<br></a></div><div><br></div><div>Howev=
er, there's no such "obvious" definition for std::get.</div><div>The most p=
lausible one would be</div><div><br></div><div><pre class=3D"" style=3D"fon=
t-size:13px;padding:0px;border:0px none white;color:rgb(0,0,0);line-height:=
1.2em;border-top-left-radius:5px;border-top-right-radius:5px;border-bottom-=
right-radius:5px;border-bottom-left-radius:5px;margin-top:0px;margin-bottom=
:0px;width:55em;overflow:auto;background-image:none;vertical-align:top;font=
-family:DejaVuSansMono,'DejaVu Sans Mono',courier,monospace!important"><spa=
n class=3D"" style=3D"color:rgb(144,144,144)">// please stifle all irreleva=
nt comments re: overload sets and CV-qualifiers</span>
</pre><div><span class=3D"" style=3D"line-height:1.1em;margin:0px;padding:0=
px;color:rgb(0,0,221);font-family:DejaVuSansMono,'DejaVu Sans Mono',courier=
,monospace;font-size:13px;white-space:nowrap">template</span><span class=3D=
"" style=3D"line-height:1.1em;margin:0px;padding:0px;color:rgb(0,0,128);fon=
t-family:DejaVuSansMono,'DejaVu Sans Mono',courier,monospace;font-size:13px=
;white-space:nowrap">&lt;&nbsp;</span><span class=3D"" style=3D"font-family=
:DejaVuSansMono,'DejaVu Sans Mono',courier,monospace;font-size:13px;color:r=
gb(0,48,128);text-decoration:none;background-image:none"><a href=3D"http://=
en.cppreference.com/w/cpp/types/size_t" style=3D"font-family:DejaVuSansMono=
,'DejaVu Sans Mono',courier,monospace;font-size:13px;color:rgb(0,48,128);te=
xt-decoration:none;background-image:none">std::<span class=3D"">size_t</spa=
n></a></span><span class=3D"" style=3D"font-size:13px;line-height:1.1em;mar=
gin:0px;padding:0px;color:rgb(0,0,128);font-family:DejaVuSansMono,'DejaVu S=
ans Mono',courier,monospace;white-space:nowrap">&nbsp;<span style=3D"color:=
rgb(0,0,0)">I</span><span class=3D"" style=3D"line-height:1.1em;margin:0px;=
padding:0px">,</span><span style=3D"color:rgb(0,0,0)">&nbsp;</span><span cl=
ass=3D"" style=3D"line-height:1.1em;margin:0px;padding:0px;color:rgb(0,0,22=
1)">class</span><span style=3D"color:rgb(0,0,0)">...&nbsp;</span><span clas=
s=3D"" style=3D"line-height:1.1em;margin:0px;padding:0px;color:rgb(0,0,0)">=
Types</span><span style=3D"color:rgb(0,0,0)">&nbsp;</span><span class=3D"" =
style=3D"line-height:1.1em;margin:0px;padding:0px">&gt;</span><br></span></=
div><div><p style=3D"margin:0px;line-height:1.1em;padding:0px;font-family:D=
ejaVuSansMono,'DejaVu Sans Mono',courier,monospace;font-size:13px;white-spa=
ce:nowrap"><span style=3D"color:rgb(0,0,0)"><span class=3D"" style=3D"line-=
height:1.1em;margin:0px;padding:0px;color:rgb(0,0,221)">auto</span>&nbsp;ge=
t</span><font color=3D"#000080">(</font><font color=3D"#000000">const&nbsp;=
</font><span class=3D"" style=3D"color:rgb(0,48,128);background-image:none;=
line-height:1.1em;margin:0px;padding:0px"><a href=3D"http://en.cppreference=
..com/w/cpp/utility/tuple" style=3D"color:rgb(0,48,128);text-decoration:none=
;background-image:none">mpl::<span class=3D"" style=3D"line-height:1.1em;ma=
rgin:0px;padding:0px">v</span></a>ector</span><span class=3D"" style=3D"col=
or:rgb(0,0,128);line-height:1.1em;margin:0px;padding:0px">&lt;</span><font =
color=3D"#000000">Types...</font><span class=3D"" style=3D"color:rgb(0,0,12=
8);line-height:1.1em;margin:0px;padding:0px">&gt;&amp;</span><span class=3D=
"" style=3D"color:rgb(0,0,128);line-height:1.1em;margin:0px;padding:0px">)<=
/span></p><p style=3D"margin:0px;line-height:1.1em;padding:0px;font-family:=
DejaVuSansMono,'DejaVu Sans Mono',courier,monospace;font-size:13px;white-sp=
ace:nowrap"><span class=3D"" style=3D"color:rgb(0,0,128);line-height:1.1em;=
margin:0px;padding:0px">&nbsp; &nbsp;-&gt;&nbsp;</span><span class=3D"" sty=
le=3D"text-decoration:none;color:rgb(0,48,128);background-image:none;line-h=
eight:1.1em;margin:0px;padding:0px"><a href=3D"http://en.cppreference.com/w=
/cpp/types/add_reference" style=3D"text-decoration:none;color:rgb(0,48,128)=
;background-image:none">std::<span class=3D"" style=3D"line-height:1.1em;ma=
rgin:0px;padding:0px">add_rvalue_reference</span></a>_t</span><span class=
=3D"" style=3D"line-height:1.1em;margin:0px;padding:0px;color:rgb(0,0,128)"=
>&lt;</span><span class=3D"" style=3D"line-height:1.1em;margin:0px;padding:=
0px"><font color=3D"#000000">tuple_element_t&lt;I,</font></span><span class=
=3D"" style=3D"color:rgb(0,48,128);background-image:none;line-height:1.1em;=
margin:0px;padding:0px"><a href=3D"http://en.cppreference.com/w/cpp/utility=
/tuple" style=3D"color:rgb(0,48,128);text-decoration:none;background-image:=
none">mpl::<span class=3D"" style=3D"line-height:1.1em;margin:0px;padding:0=
px">v</span></a>ector</span><span class=3D"" style=3D"color:rgb(0,0,128);li=
ne-height:1.1em;margin:0px;padding:0px">&lt;</span><font color=3D"#000000">=
Types...</font><span class=3D"" style=3D"color:rgb(0,0,128);line-height:1.1=
em;margin:0px;padding:0px">&gt;</span><span class=3D"" style=3D"line-height=
:1.1em;margin:0px;padding:0px"><font color=3D"#000000">&gt;</font></span><s=
pan class=3D"" style=3D"line-height:1.1em;margin:0px;padding:0px;color:rgb(=
0,0,128)">&gt;</span><span class=3D"" style=3D"line-height:1.1em;margin:0px=
;padding:0px;color:rgb(0,0,0)">;</span></p><pre class=3D"" style=3D"font-si=
ze:13px;padding:0px;border:0px none white;color:rgb(0,0,0);line-height:1.2e=
m;border-top-left-radius:5px;border-top-right-radius:5px;border-bottom-righ=
t-radius:5px;border-bottom-left-radius:5px;margin-top:0px;margin-bottom:0px=
;width:55em;overflow:auto;background-image:none;vertical-align:top;font-fam=
ily:DejaVuSansMono,'DejaVu Sans Mono',courier,monospace!important"><span cl=
ass=3D"" style=3D"color:rgb(144,144,144)">// deliberately left with no impl=
ementation, a la std::declval</span>
</pre></div></div><div><span class=3D"" style=3D"color:rgb(144,144,144)"><b=
r></span></div><div>So what we're left with is: <font face=3D"monospace, mo=
nospace">mpl::vector</font> is "not tuple-like", but it <i>does</i> impleme=
nt <font face=3D"monospace, monospace">tuple_size_v</font> and <font face=
=3D"monospace, monospace">tuple_element_t</font>.</div><div>The only part o=
f the "tuple-like" contract that it fails to have an obvious implementation=
 for is the one part of the "tuple-like" contract <i>whose name doesn't inv=
olve the word "tuple"</i>.</div><div><i>That</i> is why the concept of "tup=
le-like" bothers me.</div><div><br></div><div>=E2=80=93Arthur</div></div></=
div></div>

<p></p>

-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups "=
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>
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br>
<br><!--end of _originalContent --></div></body></html>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Wed, 03 Feb 2016 11:03:04 -0500
Raw View
On 2016-01-30 11:33, Nicol Bolas wrote:
> On Friday, January 29, 2016 at 8:59:22 PM UTC-5, Arthur O'Dwyer wrote:
>> My idea was that std::getp would probably be standardized as the=20
>> "packful" version of std::get, so the user wouldn't have to actually=20
>> write out the implementation of getp in practice.
>> I agree that the syntax inside this version of dotproduct is much more=
=20
>> off-putting than the postfix-twiddle syntax. *It is uglier.* However, it=
=20
>> is *conceptually cleaner*, because it doesn't introduce any significantl=
y=20
>> new grammar (no postfix-twiddle operator)
>=20
> It does introduce new grammar; just not at the cite of *use*. You have to=
=20
> have new grammar to have multiple return values.

Not only that, but you're no longer returning a tuple-like, you're
returning *an actual parameter pack*. This implies, by extension, that
you can do things like assign that pack to a variable:

  auto p =3D getp(t);

....which in turn implies:

  template <typename... Ts>
  foo(Ts const&... args)
  {
    auto x =3D args;
    bar(x...);
  }

This of course has all sorts of interesting implications... what is
`decltype(x)`? Can I pass `x` as a "single" parameter to a function? Can
I pass multiple packs as distinct entities (i.e. and still know on the
other side what belongs to which pack)?

You can weasel out of this by claiming that getp only works in certain
contexts, but then... you've invented a grammar disguised as a function.
In any case, I don't see an improvement over something that's a grammar
and not trying to pretend otherwise.

Also, I still want slicing.

>> and it doesn't introduce any new "magic names" (no hard-coding of the na=
mes=20
>> get and tuple_element_t into the compiler).

....which is completely irrelevant. In light of P0144, we *already have
that*. Inventing a new mechanism to do *the exact same thing*=C2=B9 is idio=
cy.

(=C2=B9 Both P0144 and this are value unpacking. This unpacks into a
parameter pack, P0144 into a variable assignment, but before those
happen, both involve the same conceptual decomposition of a tuple-like
into a sequence of values.)

--=20
Matthew

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

.


Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Wed, 3 Feb 2016 16:28:17 -0800
Raw View
--001a1145392ca0fafc052ae6cf6c
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Wed, Feb 3, 2016 at 8:03 AM, Matthew Woehlke <mwoehlke.floss@gmail.com>
wrote:

> On 2016-01-30 11:33, Nicol Bolas wrote:
> > On Friday, January 29, 2016 at 8:59:22 PM UTC-5, Arthur O'Dwyer wrote:
> >> My idea was that std::getp would probably be standardized as the
> >> "packful" version of std::get, so the user wouldn't have to actually
> >> write out the implementation of getp in practice.
> >> I agree that the syntax inside this version of dotproduct is much more
> >> off-putting than the postfix-twiddle syntax. *It is uglier.* However, =
it
> >> is *conceptually cleaner*, because it doesn't introduce any
> significantly
> >> new grammar (no postfix-twiddle operator)
> >
> > It does introduce new grammar; just not at the cite of *use*. You have =
to
> > have new grammar to have multiple return values.
>
> Not only that, but you're no longer returning a tuple-like, you're
> returning *an actual parameter pack*. This implies, by extension, [...]
> all sorts of interesting implications...


Right. Adding "first-class parameter packs" would definitely open many cans
of worms, which is why the Committee hasn't done it yet. It adds many
interesting *language* issues (as opposed to *library* issues). However, I
stand by my assertion that it doesn't add any new *grammar* issues.


> what is `decltype(x)`?


Well, since x is a *pattern*, decltype(x) would also be a *pattern*. You
could turn it into a *pack expansion* by adding ... on the end.


> Can I pass `x` as a "single" parameter to a function? Can
> I pass multiple packs as distinct entities (i.e. and still know on the
> other side what belongs to which pack)?
>

There's no existing grammar to allow that, so I guess not.

>> and it doesn't introduce any new "magic names" (no hard-coding of the
> names
> >> get and tuple_element_t into the compiler).
>
> ...which is completely irrelevant. In light of P0144, we *already have
> that*. Inventing a new mechanism to do *the exact same thing*=C2=B9 is id=
iocy.
>

You're right. If P0144 is adopted, it will show that the Committee is
friendly to the idea of hard-coding the name "std::get" into the compiler.
If that happens, then my objection to "magic names" will clearly have been
overruled, and I'll happily shut up about it. The reason I'm harping on it
right now is that I'm not aware that the Committee *has* shown significant
friendliness toward P0144 yet.
In other words: Ranged for-loop syntax is a minor, but IMHO inconclusive,
precedent in favor of hard-coding magic names. Adoption of P0144 would be a
*major* precedent in favor =E2=80=94 I'm just not aware that P0144 has in f=
act
*been* adopted. :)

=E2=80=93Arthur

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

--001a1145392ca0fafc052ae6cf6c
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wed, Feb 3, 2016 at 8:03 AM, Matthew Woehlke <span dir=
=3D"ltr">&lt;<a href=3D"mailto:mwoehlke.floss@gmail.com" target=3D"_blank">=
mwoehlke.floss@gmail.com</a>&gt;</span> wrote:<br><div class=3D"gmail_extra=
"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=3D"=
">On 2016-01-30 11:33, Nicol Bolas wrote:<br>
&gt; On Friday, January 29, 2016 at 8:59:22 PM UTC-5, Arthur O&#39;Dwyer wr=
ote:<br>
</span><span class=3D"">&gt;&gt; My idea was that std::getp would probably =
be standardized as the<br>
&gt;&gt; &quot;packful&quot; version of std::get, so the user wouldn&#39;t =
have to actually<br>
&gt;&gt; write out the implementation of getp in practice.<br>
&gt;&gt; I agree that the syntax inside this version of dotproduct is much =
more<br>
</span>&gt;&gt; off-putting than the postfix-twiddle syntax. *It is uglier.=
* However, it<br>
&gt;&gt; is *conceptually cleaner*, because it doesn&#39;t introduce any si=
gnificantly<br>
<span class=3D"">&gt;&gt; new grammar (no postfix-twiddle operator)<br>
&gt;<br>
</span>&gt; It does introduce new grammar; just not at the cite of *use*. Y=
ou have to<br>
<span class=3D"">&gt; have new grammar to have multiple return values.<br>
<br>
</span>Not only that, but you&#39;re no longer returning a tuple-like, you&=
#39;re<br>
returning *an actual parameter pack*. This implies, by extension, [...]<br>=
all sorts of interesting implications...</blockquote><div><br></div><div>Ri=
ght. Adding &quot;first-class parameter packs&quot; would definitely open m=
any cans of worms, which is why the Committee hasn&#39;t done it yet. It ad=
ds many interesting <i>language</i> issues (as opposed to <i>library</i> is=
sues). However, I stand by my assertion that it doesn&#39;t add any new=C2=
=A0<i>grammar</i> issues.</div><div>=C2=A0</div><blockquote class=3D"gmail_=
quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1=
ex"> what is=C2=A0`decltype(x)`?</blockquote><div><br></div><div>Well, sinc=
e <font face=3D"monospace, monospace">x</font> is a <i>pattern</i>, <font f=
ace=3D"monospace, monospace">decltype(x)</font> would also be a <i>pattern<=
/i>. You could turn it into a <i>pack expansion</i> by adding <font face=3D=
"monospace, monospace">...</font> on the end.</div><div>=C2=A0</div><blockq=
uote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc =
solid;padding-left:1ex"> Can I pass `x` as a &quot;single&quot; parameter t=
o a function? Can<br>
I pass multiple packs as distinct entities (i.e. and still know on the<br>
other side what belongs to which pack)?<br></blockquote><div><br></div><div=
>There&#39;s no existing grammar to allow that, so I guess not.</div><div><=
br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;borde=
r-left:1px #ccc solid;padding-left:1ex"><span class=3D"">&gt;&gt; and it do=
esn&#39;t introduce any new &quot;magic names&quot; (no hard-coding of the =
names<br>
&gt;&gt; get and tuple_element_t into the compiler).<br>
<br>
</span>...which is completely irrelevant. In light of P0144, we *already ha=
ve<br>
that*. Inventing a new mechanism to do *the exact same thing*=C2=B9 is idio=
cy.<br></blockquote><div><br></div><div>You&#39;re right. If P0144 is adopt=
ed, it will show that the Committee is friendly to the idea of hard-coding =
the name &quot;std::get&quot; into the compiler. If that happens, then my o=
bjection to &quot;magic names&quot; will clearly have been overruled, and I=
&#39;ll happily shut up about it. The reason I&#39;m harping on it right no=
w is that I&#39;m not aware that the Committee <i>has</i> shown significant=
 friendliness toward P0144 yet.</div><div>In other words: Ranged for-loop s=
yntax is a minor, but IMHO inconclusive, precedent in favor of hard-coding =
magic names. Adoption of P0144 would be a <i>major</i> precedent in favor =
=E2=80=94 I&#39;m just not aware that P0144 has in fact <i>been</i> adopted=
.. :)</div><div><br></div><div>=E2=80=93Arthur</div></div><br></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

--001a1145392ca0fafc052ae6cf6c--

.