Topic: String interpolation


Author: Jake Arkinstall <jake.arkinstall@gmail.com>
Date: Thu, 8 Feb 2018 17:41:16 -0800 (PST)
Raw View
------=_Part_3859_1149588477.1518140476992
Content-Type: multipart/alternative;
 boundary="----=_Part_3860_917082784.1518140476993"

------=_Part_3860_917082784.1518140476993
Content-Type: text/plain; charset="UTF-8"

Hello everyone,

This one is light-hearted, but will be controversial. It is not related to
the language itself, and is an effort to add syntactic sugar to C++
concatenation/streaming.

Before I start, let me set the scene with an axiom: *Not all of the code
you write during early development is designed to end up in the final
product.* One logical conclusion to this is that *some of the code you
write during development doesn't need to be streamlined*, which leads to *having
to write more code, simply because user-friendly approaches would be less
efficient, is sometimes a waste of time.* During the initial development
phase of a project, or at least in my case, some throwaway code is put into
place just to get *something* happening - some output in certain events you
want to monitor, some variables you want to keep track of. Apart from the
big decisions such as application flow, efficiency of the code that just
exists to show that the cogs are moving is (effectively) irrelevant. This
is the basis of this post; the solution isn't going to end up (I hope)
being used in a production-level stock market tick feed, or in the logging
code for a time-sensitive process. It's aiming for the more casual
occasion, where baseball caps are acceptable and cumberbands and pocket
watches are a social faux pas - but everyone has brought their cumberbands
and pocket watches along to the party, stored in their bag, ready to wear
when the time is right.

The crude reason that this is the basis for the post is that I cannot
forsee a efficient implementation and, in this specific circumstance, that
doesn't concern me.

Now the scene is set, on we go.

Some programming languages allow direct string interpolation, i.e. the
injection of variables into what otherwise appears to be a string literal.
For example, in bash:
recipient="World"
echo "Hello, ${recipient}!"

Similar syntaxes are used in a wide variety of languages - see
https://en.wikipedia.org/wiki/String_interpolation . These languages are
higher level, and do not compete directly with C++, so there are good
reasons for them have some user-friendly features that aren't really
accessible to us. But this is something that isn't too hard to implement if
we allow some concessions.

I fully understand that we *do* have the ability to inject values into
strings using Boost's format library, the fmt library, printf, and friends.
With these we get a lot of flexibility, great performance in some cases -
but the code on the user's side is slightly more cryptic because variables
are placed after the format string, and it is up to the code reader to do
*find* which variable coincides with which *token*, rather than it being
effortless. Effortless is nice. Of course, we also have streams, but
writing these up explicitly gets tedious.

So here's what I'm suggesting: a syntax similar to - but obviously not the
same as - that of a string literal, which enables interpolation through the
use of stream operations, performed during translation phase 4.

We can use something similar to the C# syntax, using the dollar symbol
preceding the opening quotation mark to differentiate between string
literals and interpolation-enabled strings, but using the bash/perl/php
approach to inserting variables, using the dollar symbol and curly braces
(minimising confusion when we actually *want* braces).

T recipient;
// operator<<(std::ostream&, T) defined, or we naturally get an undefined
operator<< error later on

string message = $"Hello, ${recipient}!"

// becomes, internally, equivalent to:
// string message;
// {
//     std::stringstream TMP_;
//     TMP_ << "Hello " << recipient << "!";
//     message = TMP_.str()
// }

std::cout << $"The message is ${message}\n";

// becomes, internally, equivalent to:
// {
//     std::cout << "The message is " << message << "\n";
// }
// // braces not really necessary, but it makes generalisation easier:
// // Trade a dollar for a pair of braces every time.
//
// // If we REALLY don't care about performance, this could use the
// // string approach and send the resulting string to std::cout. *shudder*

This is designed to be a gentler, quick-and-easy way of using streams, not
the most flexible nor the fastest approach; obviously, if you want speed
and flexibility, you're often going to have to do things the long way
around. But if you don't want that, and just want to get that code down as
quickly as possible before future optimisations, I think this approach has
merit. There is potential to add some extra decoration, which is seen in
bash when a quick and easy operation is needed:
recipient="Worm";
echo "Hello, ${recipient/m/ld}!"

I'm definitely not suggesting that we have a string replacement feature
(that would be pointless), but it demonstrates that operations upon the
variables output is possible, and these can be implemented in a
backwards-compatible manner. For example, if we use the above syntax as the
default, erring out if there exists invalid syntax inside the curly braces,
we could in future allow shortcuts to <iomanip> functionality (such that
type doesn't even come into it - [set precision, send a string, unset
precision] is not an error, it's just pointless):
double pi = std::acos(-1);
std::cout << $"Pi to 3 s.f. is ${pi:3}, but it is ${pi} by default\n";
// becomes, internally, equivalent to:
// {
//     std::streamsize TMP_ = std::cout.precision();
//     std::cout << "Pi to 3 s.f. is "
//               << std::setprecision(3) << pi << std::setprecision(TMP_)
//               << ", but in full is " << pi << "by default\n";
// }

The idea is that this will be an optional inclusion, through a flag, so
there is negligible compilation overhead for those who don't want, or are
maybe even offended by, this functionality.

This is not much of a proposal as yet, mainly because I am aware that this
idea might not be incredibly popular; most proposals tend to aim for more
efficient, more flexible code at the optional expense of adding *more*
code, and this is doing the exact opposite of that. As such, going further
with this without probing for opinions is a waste of time.

Regards,
Jake Arkinstall

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/356d5835-f1bf-4699-94f5-0b2d3d0b9c0e%40isocpp.org.

------=_Part_3860_917082784.1518140476993
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hello everyone,<br><br>This one is light-hearted, but will=
 be controversial. It is not related to the language itself, and is an effo=
rt to add syntactic sugar to C++ concatenation/streaming.<br><br>Before I s=
tart, let me set the scene with an axiom: <i>Not all of the code you write =
during early development is designed to end up in the final product.</i> On=
e logical conclusion to this is that <i>some of the code you write during d=
evelopment doesn&#39;t need to be streamlined</i>, which leads to <i>having=
 to write more code, simply because user-friendly approaches would be less =
efficient, is sometimes a waste of time.</i><i> </i>During the initial deve=
lopment phase of a project, or at least in my case, some throwaway code is =
put into place just to get *something* happening - some output in certain e=
vents you want to monitor, some variables you want to keep track of. Apart =
from the big decisions such as application flow, efficiency of the code tha=
t just exists to show that the cogs are moving is (effectively) irrelevant.=
 This is the basis of this post; the solution isn&#39;t going to end up (I =
hope) being used in a production-level stock market tick feed, or in the lo=
gging code for a time-sensitive process. It&#39;s aiming for the more casua=
l occasion, where baseball caps are acceptable and cumberbands and pocket w=
atches are a social faux pas - but everyone has brought their cumberbands a=
nd pocket watches along to the party, stored in their bag, ready to wear wh=
en the time is right.<br><br>The crude reason that this is the basis for th=
e post is that I cannot forsee a efficient implementation and, in this spec=
ific circumstance, that doesn&#39;t concern me.<br><br>Now the scene is set=
, on we go.<br><br>Some programming languages allow direct string interpola=
tion, i.e. the injection of variables into what otherwise appears to be a s=
tring literal. For example, in bash:<br><div style=3D"background-color: rgb=
(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; bor=
der-width: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code cla=
ss=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #000=
;" class=3D"styled-by-prettify">recipient</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #080;" class=
=3D"styled-by-prettify">&quot;World&quot;</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br>echo </span><span style=3D"color: #080;"=
 class=3D"styled-by-prettify">&quot;Hello, ${recipient}!&quot;</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div></code=
></div><br>Similar syntaxes are used in a wide variety of languages - see h=
ttps://en.wikipedia.org/wiki/String_interpolation . These languages are hig=
her level, and do not compete directly with C++, so there are good reasons =
for them have some user-friendly features that aren&#39;t really accessible=
 to us. But this is something that isn&#39;t too hard to implement if we al=
low some concessions.<br><br>I fully understand that we <b>do</b> have the =
ability to inject values into strings using Boost&#39;s format library, the=
 fmt library, printf, and friends. With these we get a lot of flexibility, =
great performance in some cases - but the code on the user&#39;s side is sl=
ightly more cryptic because variables are placed after the format string, a=
nd it is up to the code reader to do <i>find</i> which variable coincides w=
ith which <i>token</i>, rather than it being effortless. Effortless is nice=
.. Of course, we also have streams, but writing these up explicitly gets ted=
ious.<br><br>So here&#39;s what I&#39;m suggesting: a syntax similar to - b=
ut obviously not the same as - that of a string literal, which enables inte=
rpolation through the use of stream operations, performed during translatio=
n phase 4.<br><br>We can use something similar to the C# syntax, using the =
dollar symbol preceding the opening quotation mark to differentiate between=
 string literals and interpolation-enabled strings, but using the bash/perl=
/php approach to inserting variables, using the dollar symbol and curly bra=
ces (minimising confusion when we actually <b>want</b> braces).<br><br><div=
 style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187,=
 187); border-style: solid; border-width: 1px; overflow-wrap: break-word;" =
class=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subprettypr=
int"><span style=3D"color: #000;" class=3D"styled-by-prettify">T recipient<=
/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><span sty=
le=3D"color: #800;" class=3D"styled-by-prettify">// operator&lt;&lt;(std::o=
stream&amp;, T) defined, or we naturally get an undefined operator&lt;&lt; =
error later on</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">string</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> m=
essage </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: #080;" class=3D"styled-by-prettify">&quot;Hello, ${rec=
ipient}!&quot;</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br><br></span><span style=3D"color: #800;" class=3D"styled-by-prettify=
">// becomes, internally, equivalent to:</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br></span><span style=3D"color: #800;" class=
=3D"styled-by-prettify">// string message;</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #800;" cla=
ss=3D"styled-by-prettify">// {</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br></span><span style=3D"color: #800;" class=3D"styled=
-by-prettify">// =C2=A0 =C2=A0 std::stringstream TMP_;</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color=
: #800;" class=3D"styled-by-prettify">// =C2=A0 =C2=A0 TMP_ &lt;&lt; &quot;=
Hello &quot; &lt;&lt; recipient &lt;&lt; &quot;!&quot;;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #800;" class=3D"styled-by-prettify">// =C2=A0 =C2=A0 message =3D TMP_.=
str()</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><=
/span><span style=3D"color: #800;" class=3D"styled-by-prettify">// }</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>std</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">cout </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&lt;&lt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> $</span><span style=3D"colo=
r: #080;" class=3D"styled-by-prettify">&quot;The message is ${message}\n&qu=
ot;</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><=
span style=3D"color: #800;" class=3D"styled-by-prettify">// becomes, intern=
ally, equivalent to:</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br></span><span style=3D"color: #800;" class=3D"styled-by-pretti=
fy">// {</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r></span><span style=3D"color: #800;" class=3D"styled-by-prettify">// =C2=
=A0 =C2=A0 std::cout &lt;&lt; &quot;The message is &quot; &lt;&lt; message =
&lt;&lt; &quot;\n&quot;;</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"><br></span><span style=3D"color: #800;" class=3D"styled-by-pr=
ettify">// }</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br></span><span style=3D"color: #800;" class=3D"styled-by-prettify">// /=
/ braces not really necessary, but it makes generalisation easier:</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span st=
yle=3D"color: #800;" class=3D"styled-by-prettify">// // Trade a dollar for =
a pair of braces every time.</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br></span><span style=3D"color: #800;" class=3D"styled-b=
y-prettify">//</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br></span><span style=3D"color: #800;" class=3D"styled-by-prettify">//=
 // If we REALLY don&#39;t care about performance, this could use the</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span=
 style=3D"color: #800;" class=3D"styled-by-prettify">// // string approach =
and send the resulting string to std::cout. *shudder*</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br></span></div></code></div><b=
r>This is designed to be a gentler, quick-and-easy way of using streams, no=
t the most flexible nor the fastest approach; obviously, if you want speed =
and flexibility, you&#39;re often going to have to do things the long way a=
round. But if you don&#39;t want that, and just want to get that code down =
as quickly as possible before future optimisations, I think this approach h=
as merit. There is potential to add some extra decoration, which is seen in=
 bash when a quick and easy operation is needed:<code></code><br><div style=
=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187);=
 border-style: solid; border-width: 1px; overflow-wrap: break-word;" class=
=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subprettyprint">=
<span style=3D"color: #000;" class=3D"styled-by-prettify">recipient</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span st=
yle=3D"color: #080;" class=3D"styled-by-prettify">&quot;Worm&quot;</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>echo </span><span style=
=3D"color: #080;" class=3D"styled-by-prettify">&quot;Hello, ${recipient/m/l=
d}!&quot;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br></span></div></code></div><br>I&#39;m definitely not suggesting that we =
have a string replacement feature (that would be pointless), but it demonst=
rates that operations upon the variables output is possible, and these can =
be implemented in a backwards-compatible manner. For example, if we use the=
 above syntax as the default, erring out if there exists invalid syntax ins=
ide the curly braces, we could in future allow shortcuts to &lt;iomanip&gt;=
 functionality (such that type doesn&#39;t even come into it - [set precisi=
on, send a string, unset precision] is not an error, it&#39;s just pointles=
s):<br><div style=3D"background-color: rgb(250, 250, 250); border-color: rg=
b(187, 187, 187); border-style: solid; border-width: 1px; overflow-wrap: br=
eak-word;" class=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"=
subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">d=
ouble</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> pi <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">acos</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">(-</span><span style=3D"color: #066;" =
class=3D"styled-by-prettify">1</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br>std</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>cout </span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;=
&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> $</sp=
an><span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;Pi to 3 =
s.f. is ${pi:3}, but it is ${pi} by default\n&quot;</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #800;" cla=
ss=3D"styled-by-prettify">// becomes, internally, equivalent to:</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span styl=
e=3D"color: #800;" class=3D"styled-by-prettify">// {</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: =
#800;" class=3D"styled-by-prettify">// =C2=A0 =C2=A0 std::streamsize TMP_ =
=3D std::cout.precision();</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br></span><span style=3D"color: #800;" class=3D"styled-by-=
prettify">// =C2=A0 =C2=A0 std::cout &lt;&lt; &quot;Pi to 3 s.f. is &quot;<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span>=
<span style=3D"color: #800;" class=3D"styled-by-prettify">// =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 &lt;&lt; std::setprecision(3) &lt;&lt; p=
i &lt;&lt; std::setprecision(TMP_)</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #800;" class=3D"st=
yled-by-prettify">// =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 &lt;&=
lt; &quot;, but in full is &quot; &lt;&lt; pi &lt;&lt; &quot;by default\n&q=
uot;;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><=
/span><span style=3D"color: #800;" class=3D"styled-by-prettify">// }</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div>=
</code></div><br>The idea is that this will be an optional inclusion, throu=
gh a flag, so there is negligible compilation overhead for those who don&#3=
9;t want, or are maybe even offended by, this functionality.<br><br>This is=
 not much of a proposal as yet, mainly because I am aware that this idea mi=
ght not be incredibly popular; most proposals tend to aim for more efficien=
t, more flexible code at the optional expense of adding <i>more</i> code, a=
nd this is doing the exact opposite of that. As such, going further with th=
is without probing for opinions is a waste of time.<br><br>Regards,<br>Jake=
 Arkinstall<br></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/356d5835-f1bf-4699-94f5-0b2d3d0b9c0e%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/356d5835-f1bf-4699-94f5-0b2d3d0b9c0e=
%40isocpp.org</a>.<br />

------=_Part_3860_917082784.1518140476993--

------=_Part_3859_1149588477.1518140476992--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 8 Feb 2018 19:38:05 -0800 (PST)
Raw View
------=_Part_4088_1261355947.1518147486041
Content-Type: multipart/alternative;
 boundary="----=_Part_4089_2121902617.1518147486044"

------=_Part_4089_2121902617.1518147486044
Content-Type: text/plain; charset="UTF-8"

On Thursday, February 8, 2018 at 8:41:17 PM UTC-5, Jake Arkinstall wrote:
>
> T recipient;
> // operator<<(std::ostream&, T) defined, or we naturally get an undefined
> operator<< error later on
>
> string message = $"Hello, ${recipient}!"
>
> // becomes, internally, equivalent to:
> // string message;
> // {
> //     std::stringstream TMP_;
> //     TMP_ << "Hello " << recipient << "!";
> //     message = TMP_.str()
> // }
>
> std::cout << $"The message is ${message}\n";
>
> // becomes, internally, equivalent to:
> // {
> //     std::cout << "The message is " << message << "\n";
> // }
> // // braces not really necessary, but it makes generalisation easier:
> // // Trade a dollar for a pair of braces every time.
> //
> // // If we REALLY don't care about performance, this could use the
> // // string approach and send the resulting string to std::cout. *shudder*
>
> This is designed to be a gentler, quick-and-easy way of using streams, not
> the most flexible nor the fastest approach; obviously, if you want speed
> and flexibility, you're often going to have to do things the long way
> around. But if you don't want that, and just want to get that code down as
> quickly as possible before future optimisations, I think this approach has
> merit.
>

And that is precisely the flaw in your proposal. There is no reason why I
should have to choose between "slow and convenient" and "fast and
hard-to-use". The evolution of modern C++ has been to take "fast and
hard-to-use" and turn it into "fast and easy-to-use". `constexpr` makes an
entire branch of template metaprogramming look like normal code. Variadic
templates make many things that were out of reach for the average
programmer into much easier metaprogramming techniques. Concepts take the
`enable_if` hack and makes it into a real, extensible part of the language.
And so forth.

When you're building library components, it's OK to make a library-based
system that perhaps has some deficiencies in performance in order to allow
it to be easier to use (note: this does not excuse iostreams). When you're
building something into the *language*, you can't just do that. Language
features should not generate bad code by default. And I submit that the
above is bad code. Or at the very least, it could very easily be better
code if it didn't use a terrible system like iostream.

See, the problem is that iostream is: 1) the only extensible, type-safe
formatting system available to standard C++, and 2) terrible in pretty much
every other way.

If you want to incorporate something like this into the language, then you
*first* needs to come up with an underlying model which isn't terrible.
That is, an extensible, type-safe system for converting objects to strings.
And there's absolutely no excuse for this not being `constexpr` aware. It
should not be based on virtual functions.

Once you have that, then you can go about suggesting using that as the
basis for "string interpolation". But what you're doing is putting the cart
before the horse. Or at the very least, asking a cart to be driven by a
very lame horse.

If "string interpolation" is to be worthwhile, I shouldn't have to think
about whether it's performant enough to use it in my code. Just like I
don't have to worry that range-based `for` loops will copy values into a
temporary `vector` or something before iterating over them.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/2806d759-b4b1-4e8a-8ed4-9d4fdf4844a1%40isocpp.org.

------=_Part_4089_2121902617.1518147486044
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Thursday, February 8, 2018 at 8:41:17 PM UTC-5, Jake Ar=
kinstall 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=
"><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,=
187);border-style:solid;border-width:1px"><code><div><span style=3D"color:#=
000">T recipient</span><span style=3D"color:#660">;</span><span style=3D"co=
lor:#000"><br></span><span style=3D"color:#800">// operator&lt;&lt;(std::os=
tream&amp;, T) defined, or we naturally get an undefined operator&lt;&lt; e=
rror later on</span><span style=3D"color:#000"><br><br></span><span style=
=3D"color:#008">string</span><span style=3D"color:#000"> message </span><sp=
an style=3D"color:#660">=3D</span><span style=3D"color:#000"> $</span><span=
 style=3D"color:#080">&quot;Hello, ${recipient}!&quot;</span><span style=3D=
"color:#000"><br><br></span><span style=3D"color:#800">// becomes, internal=
ly, equivalent to:</span><span style=3D"color:#000"><br></span><span style=
=3D"color:#800">// string message;</span><span style=3D"color:#000"><br></s=
pan><span style=3D"color:#800">// {</span><span style=3D"color:#000"><br></=
span><span style=3D"color:#800">// =C2=A0 =C2=A0 std::stringstream TMP_;</s=
pan><span style=3D"color:#000"><br></span><span style=3D"color:#800">// =C2=
=A0 =C2=A0 TMP_ &lt;&lt; &quot;Hello &quot; &lt;&lt; recipient &lt;&lt; &qu=
ot;!&quot;;</span><span style=3D"color:#000"><br></span><span style=3D"colo=
r:#800">// =C2=A0 =C2=A0 message =3D TMP_.str()</span><span style=3D"color:=
#000"><br></span><span style=3D"color:#800">// }</span><span style=3D"color=
:#000"><br><br>std</span><span style=3D"color:#660">::</span><span style=3D=
"color:#000">cout </span><span style=3D"color:#660">&lt;&lt;</span><span st=
yle=3D"color:#000"> $</span><span style=3D"color:#080">&quot;The message is=
 ${message}\n&quot;</span><span style=3D"color:#660">;</span><span style=3D=
"color:#000"><br><br></span><span style=3D"color:#800">// becomes, internal=
ly, equivalent to:</span><span style=3D"color:#000"><br></span><span style=
=3D"color:#800">// {</span><span style=3D"color:#000"><br></span><span styl=
e=3D"color:#800">// =C2=A0 =C2=A0 std::cout &lt;&lt; &quot;The message is &=
quot; &lt;&lt; message &lt;&lt; &quot;\n&quot;;</span><span style=3D"color:=
#000"><br></span><span style=3D"color:#800">// }</span><span style=3D"color=
:#000"><br></span><span style=3D"color:#800">// // braces not really necess=
ary, but it makes generalisation easier:</span><span style=3D"color:#000"><=
br></span><span style=3D"color:#800">// // Trade a dollar for a pair of bra=
ces every time.</span><span style=3D"color:#000"><br></span><span style=3D"=
color:#800">//</span><span style=3D"color:#000"><br></span><span style=3D"c=
olor:#800">// // If we REALLY don&#39;t care about performance, this could =
use the</span><span style=3D"color:#000"><br></span><span style=3D"color:#8=
00">// // string approach and send the resulting string to std::cout. *shud=
der*</span><span style=3D"color:#000"><br></span></div></code></div><br>Thi=
s is designed to be a gentler, quick-and-easy way of using streams, not the=
 most flexible nor the fastest approach; obviously, if you want speed and f=
lexibility, you&#39;re often going to have to do things the long way around=
.. But if you don&#39;t want that, and just want to get that code down as qu=
ickly as possible before future optimisations, I think this approach has me=
rit.</div></blockquote><div><br>And that is precisely the flaw in your prop=
osal. There is no reason why I should have to choose between &quot;slow and=
=20
convenient&quot; and &quot;fast and hard-to-use&quot;. The evolution of mod=
ern C++ has=20
been to take &quot;fast and hard-to-use&quot; and turn it into &quot;fast a=
nd=20
easy-to-use&quot;. `constexpr` makes an entire branch of template=20
metaprogramming look like normal code. Variadic templates make many=20
things that were out of reach for the average programmer into much easier m=
etaprogramming techniques.=20
Concepts take the `enable_if` hack and makes it into a real, extensible=20
part of the language. And so forth.<br><br>When you&#39;re building library=
 components, it&#39;s OK to make a library-based system that perhaps has so=
me deficiencies in performance in order to allow it to be easier to use (no=
te: this does not excuse iostreams). When you&#39;re building something int=
o the <i>language</i>, you can&#39;t just do that. Language features should=
 not generate bad code by default. And I submit that the above is bad code.=
 Or at the very least, it could very easily be better code if it didn&#39;t=
 use a terrible system like iostream.<br><br>See, the problem is that iostr=
eam is: 1) the only extensible, type-safe formatting system available to st=
andard C++, and 2) terrible in pretty much every other way.<br><br>If you w=
ant to incorporate something like this into the language, then you <i>first=
</i> needs to come up with an underlying model which isn&#39;t terrible. Th=
at is, an extensible, type-safe system for converting objects to strings. A=
nd there&#39;s absolutely no excuse for this not being `constexpr` aware. I=
t should not be based on virtual functions.<br><br>Once you have that, then=
 you can go about suggesting using that as the basis for &quot;string inter=
polation&quot;. But what you&#39;re doing is putting the cart before the ho=
rse. Or at the very least, asking a cart to be driven by a very lame horse.=
<br><br>If &quot;string interpolation&quot; is to be worthwhile, I shouldn&=
#39;t have to think
 about whether it&#39;s performant enough to use it in my code. Just like I=
 don&#39;t have to worry that range-based `for` loops will copy values into=
 a temporary `vector` or something before iterating over them.<br></div><br=
></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/2806d759-b4b1-4e8a-8ed4-9d4fdf4844a1%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/2806d759-b4b1-4e8a-8ed4-9d4fdf4844a1=
%40isocpp.org</a>.<br />

------=_Part_4089_2121902617.1518147486044--

------=_Part_4088_1261355947.1518147486041--

.


Author: Jake Arkinstall <jake.arkinstall@gmail.com>
Date: Fri, 9 Feb 2018 06:06:38 +0000
Raw View
--94eb2c1c1adcde7b9f0564c154c8
Content-Type: text/plain; charset="UTF-8"

On 9 Feb 2018 03:38, "Nicol Bolas" <jmckesson@gmail.com> wrote:

There is no reason why I should have to choose between "slow and
convenient" and "fast and hard-to-use". The evolution of modern C++ has
been to take "fast and hard-to-use" and turn it into "fast and
easy-to-use". `constexpr` makes an entire branch of template
metaprogramming look like normal code. Variadic templates make many things
that were out of reach for the average programmer into much easier
metaprogramming techniques. Concepts take the `enable_if` hack and makes it
into a real, extensible part of the language. And so forth.


The conflict I am facing is that (a) C++ handling of injecting variables
into strings is a choice of ugly, ugly, or ugly, and (b) there is no
efficient way (that I can think of) of changing that. But there are
situations, as I set out in the beginning, where (a) takes priority over
(b). It is not everyone's cup of tea, granted.

See, the problem is that iostream is: 1) the only extensible, type-safe
formatting system available to standard C++, and 2) terrible in pretty much
every other way.


iostream is what we have, iostream is the de-facto approach that most
people use when outputting a variety of objects in non-time-critical code.
The fact is that people are *already* using them, they already have their
stream operators defined for built-in types and for any kind of custom type
that is supposed to be output in the first place. All this does is make
their lives easier in doing so. This is the reason I chose this approach -
it gives people a smoother way of doing what they are already doing without
all the fuss of adding in other code.


If you want to incorporate something like this into the language, then you
*first* needs to come up with an underlying model which isn't terrible.
That is, an extensible, type-safe system for converting objects to strings.
And there's absolutely no excuse for this not being `constexpr` aware. It
should not be based on virtual functions.


Converting objects to strings and then doing what? That's the problem. We
could always use a typecast to string (in many-member objects these methods
often end up using stringstreams in the first place) then concatenating the
result to the preceding literal, followed by further concatenations. Copies
everywhere. We could come up with a mechanism by which the result is
sequentially added to the existing string, but that's iostream in a
nutshell. Introducing something new would be a much bigger change, and
requires convincing the community to change their habits and legacy code.
Syntactic sugar is not worth all that. I'm aiming for something that is
*less* demanding on the user.

I will see if I can find out how it is implemented in the other languages
and report back. I cannot imagine that they use anything that is
inaccessible to us, but instead I believe that they are just more accepting
of the small cost involved.

Once you have that, then you can go about suggesting using that as the
basis for "string interpolation". But what you're doing is putting the cart
before the horse. Or at the very least, asking a cart to be driven by a
very lame horse.


A very lame horse that is trusty enough to pull the community thus far, and
a cart that is used extensively in other (ditching the metaphor here)
languages because it is incredibly easy to use.

If "string interpolation" is to be worthwhile, I shouldn't have to think
about whether it's performant enough to use it in my code. Just like I
don't have to worry that range-based `for` loops will copy values into a
temporary `vector` or something before iterating over them.


Ideally, this would be nice. If you can think of such a thing, here is the
perfect place to discuss it. My focus here is very much on the cart. As for
the horse, I don't much have a preference, except that ease of use is vital.

But I find it damaging for us to refuse to have nice things simply based on
one metric - there are multiple costs involved in a project, and
development time and ease of use is one of them. Creating a way of making
things easier on developers in the times that they aren't looking for the
fastest solution is useful in that regard. Of course, the question would
then be why they are using C++ in the first place. But it would be wrong to
suggest that 100% of the time that you're writing C++ you're thinking
purely about the performance of each run, especially during a debug session
or in the early stages as I mentioned. And, for your layman who isn't
concerned about the cost of building a string in an iostream and copying
the result to a string - from beginners, to people who are testing out an
idea, or demonstrating functionality, doing old-school debugging, or who
just aren't concerned about performance at that stage - it costs them
nothing, but gives them a nicer language to work with.

There may be an alternative, and that's improved and standardised
preprocessor functionality so that people can have more flexibility. The
fact that we can't even have control of state, e.g. defines inside macros,
is extremely limiting (otherwise this would be doable in some form via
macros). I guess it is perfectly possible to make a pre-preprocessor to run
the code through pre-translation, but that adds its own complications.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCNK9JpR74Wmngnqrqt4AT5O%3DjB_CcmEzXvaPLFS0Y6o%2BQ%40mail.gmail.com.

--94eb2c1c1adcde7b9f0564c154c8
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"auto"><br><div class=3D"gmail_extra" dir=3D"auto"><div class=3D=
"gmail_quote">On 9 Feb 2018 03:38, &quot;Nicol Bolas&quot; &lt;<a href=3D"m=
ailto:jmckesson@gmail.com">jmckesson@gmail.com</a>&gt; wrote:<br type=3D"at=
tribution"><blockquote class=3D"quote" style=3D"margin:0 0 0 .8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"quoted-t=
ext">There is no reason why I should have to choose between &quot;slow and=
=20
convenient&quot; and &quot;fast and hard-to-use&quot;. The evolution of mod=
ern C++ has=20
been to take &quot;fast and hard-to-use&quot; and turn it into &quot;fast a=
nd=20
easy-to-use&quot;. `constexpr` makes an entire branch of template=20
metaprogramming look like normal code. Variadic templates make many=20
things that were out of reach for the average programmer into much easier m=
etaprogramming techniques.=20
Concepts take the `enable_if` hack and makes it into a real, extensible=20
part of the language. And so forth.<br></div></div></blockquote></div></div=
><div dir=3D"auto"><br></div><div dir=3D"auto">The conflict I am facing is =
that (a) C++ handling of injecting variables into strings is a choice of ug=
ly, ugly, or ugly, and (b) there is no efficient way (that I can think of) =
of changing that. But there are situations, as I set out in the beginning, =
where (a) takes priority over (b). It is not everyone&#39;s cup of tea, gra=
nted.</div><div dir=3D"auto"><br></div><div class=3D"gmail_extra" dir=3D"au=
to"><div class=3D"gmail_quote"><blockquote class=3D"quote" style=3D"margin:=
0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><d=
iv class=3D"quoted-text"></div><div>See, the problem is that iostream is: 1=
) the only extensible, type-safe formatting system available to standard C+=
+, and 2) terrible in pretty much every other way.<br></div></div></blockqu=
ote></div></div><div dir=3D"auto"><br></div><div dir=3D"auto">iostream is w=
hat we have, iostream is the de-facto approach that most people use when ou=
tputting a variety of objects in non-time-critical code. The fact is that p=
eople are <b>already</b> using them, they already have their stream operato=
rs defined for built-in types and for any kind of custom type that is suppo=
sed to be output in the first place. All this does is make their lives easi=
er in doing so. This is the reason I chose this approach - it gives people =
a smoother way of doing what they are already doing without all the fuss of=
 adding in other code.</div><div dir=3D"auto">=C2=A0</div><div class=3D"gma=
il_extra" dir=3D"auto"><div class=3D"gmail_quote"><blockquote class=3D"quot=
e" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">=
<div dir=3D"ltr"><div>If you want to incorporate something like this into t=
he language, then you <i>first</i> needs to come up with an underlying mode=
l which isn&#39;t terrible. That is, an extensible, type-safe system for co=
nverting objects to strings. And there&#39;s absolutely no excuse for this =
not being `constexpr` aware. It should not be based on virtual functions.<b=
r></div></div></blockquote></div></div><div dir=3D"auto"><br></div><div dir=
=3D"auto">Converting objects to strings and then doing what? That&#39;s the=
 problem. We could always use a typecast to string (in many-member objects =
these methods often end up using stringstreams in the first place) then con=
catenating the result to the preceding literal, followed by further concate=
nations. Copies everywhere. We could come up with a mechanism by which the =
result is sequentially added to the existing string, but that&#39;s iostrea=
m in a nutshell. Introducing something new would be a much bigger change, a=
nd requires convincing the community to change their habits and legacy code=
.. Syntactic sugar is not worth all that. I&#39;m aiming for something that =
is <i>less</i> demanding on the user.</div><div dir=3D"auto"><br></div><div=
 dir=3D"auto">I will see if I can find out how it is implemented in the oth=
er languages and report back. I cannot imagine that they use anything that =
is inaccessible to us, but instead I believe that they are just more accept=
ing of the small cost involved.</div><div dir=3D"auto"><br></div><div class=
=3D"gmail_extra" dir=3D"auto"><div class=3D"gmail_quote"><blockquote class=
=3D"quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div dir=3D"ltr"><div>Once you have that, then you can go about sug=
gesting using that as the basis for &quot;string interpolation&quot;. But w=
hat you&#39;re doing is putting the cart before the horse. Or at the very l=
east, asking a cart to be driven by a very lame horse.</div></div></blockqu=
ote></div></div><div dir=3D"auto"><br></div><div dir=3D"auto">A very lame h=
orse that is trusty enough to pull the community thus far, and a cart that =
is used extensively in other (ditching the metaphor here) languages because=
 it is incredibly easy to use.</div><div dir=3D"auto"><br></div><div class=
=3D"gmail_extra" dir=3D"auto"></div><div class=3D"gmail_extra" dir=3D"auto"=
><div class=3D"gmail_quote"><blockquote class=3D"quote" style=3D"margin:0 0=
 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>=
If &quot;string interpolation&quot; is to be worthwhile, I shouldn&#39;t ha=
ve to think
 about whether it&#39;s performant enough to use it in my code. Just like I=
 don&#39;t have to worry that range-based `for` loops will copy values into=
 a temporary `vector` or something before iterating over them.<br></div></d=
iv></blockquote></div></div><div dir=3D"auto"><br></div><div dir=3D"auto">I=
deally, this would be nice. If you can think of such a thing, here is the p=
erfect place to discuss it. My focus here is very much on the cart. As for =
the horse, I don&#39;t much have a preference, except that ease of use is v=
ital.</div><div dir=3D"auto"><br></div><div dir=3D"auto">But I find it dama=
ging for us to refuse to have nice things simply based on one metric - ther=
e are multiple costs involved in a project, and development time and ease o=
f use is one of them. Creating a way of making things easier on developers =
in the times that they aren&#39;t looking for the fastest solution is usefu=
l in that regard. Of course, the question would then be why they are using =
C++ in the first place. But it would be wrong to suggest that 100% of the t=
ime that you&#39;re writing C++ you&#39;re thinking purely about the perfor=
mance of each run, especially during a debug session or in the early stages=
 as I mentioned. And, for your layman who isn&#39;t concerned about the cos=
t of building a string in an iostream and copying the result to a string - =
from beginners, to people who are testing out an idea, or demonstrating fun=
ctionality, doing old-school debugging, or who just aren&#39;t concerned ab=
out performance at that stage - it costs them nothing, but gives them a nic=
er language to work with.</div><div dir=3D"auto"><br></div><div dir=3D"auto=
">There may be an alternative, and that&#39;s improved and standardised pre=
processor functionality so that people can have more flexibility. The fact =
that we can&#39;t even have control of state, e.g. defines inside macros, i=
s extremely limiting (otherwise this would be doable in some form via macro=
s). I guess it is perfectly possible to make a pre-preprocessor to run the =
code through pre-translation, but that adds its own complications.</div></d=
iv>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCNK9JpR74Wmngnqrqt4AT5O%3DjB_=
CcmEzXvaPLFS0Y6o%2BQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCNK=
9JpR74Wmngnqrqt4AT5O%3DjB_CcmEzXvaPLFS0Y6o%2BQ%40mail.gmail.com</a>.<br />

--94eb2c1c1adcde7b9f0564c154c8--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Thu, 08 Feb 2018 22:18:05 -0800
Raw View
On Thursday, 8 February 2018 17:41:16 PST Jake Arkinstall wrote:
> T recipient;
> // operator<<(std::ostream&, T) defined, or we naturally get an undefined
> operator<< error later on

Considering iostreams are somewhat slow, because of all the virtuals and
multiple inheritance, how can I make your proposal work with something other
than it?

Explain how it would work with an arbitrary other class.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center



--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1731062.NdW3nXAon1%40tjmaciei-mobl1.

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 8 Feb 2018 23:50:33 -0800 (PST)
Raw View
------=_Part_4338_1994671980.1518162633154
Content-Type: multipart/alternative;
 boundary="----=_Part_4339_68324471.1518162633154"

------=_Part_4339_68324471.1518162633154
Content-Type: text/plain; charset="UTF-8"

On Friday, February 9, 2018 at 1:06:40 AM UTC-5, Jake Arkinstall wrote:
>
> On 9 Feb 2018 03:38, "Nicol Bolas" <jmck...@gmail.com <javascript:>>
> wrote:
>
> There is no reason why I should have to choose between "slow and
> convenient" and "fast and hard-to-use". The evolution of modern C++ has
> been to take "fast and hard-to-use" and turn it into "fast and
> easy-to-use". `constexpr` makes an entire branch of template
> metaprogramming look like normal code. Variadic templates make many things
> that were out of reach for the average programmer into much easier
> metaprogramming techniques. Concepts take the `enable_if` hack and makes it
> into a real, extensible part of the language. And so forth.
>
>
> The conflict I am facing is that (a) C++ handling of injecting variables
> into strings is a choice of ugly, ugly, or ugly, and (b) there is no
> efficient way (that I can think of) of changing that.
>

There is an efficient way. There are plenty of better solutions than using
`iostreams` for string formatting. They may not be part of the standard
library yet, but there have been proposals for some of them
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0645r0.html>.

But there are situations, as I set out in the beginning, where (a) takes
> priority over (b). It is not everyone's cup of tea, granted.
>

Show me another C++ language feature that is fundamentally rooted in doing
things the slow way. Other than exceptions. Or things related to virtual
functions/dynamic_casting of multiple inheritance.

Here's the thing. `iostreams`, for all of its failures, is ephemeral. It
can be replaced; it can go away. A language feature cannot just "go away".
If we add a better way of doing text formatting, then "string
interpolation" will not be able to use it, unless it can be made to do so
in a backwards compatible way.

That's bad. Language features *have to* get it right the first time. Just
look at "uniform initialization" to see what happens when you screw that up.

See, the problem is that iostream is: 1) the only extensible, type-safe
> formatting system available to standard C++, and 2) terrible in pretty much
> every other way.
>
>
> iostream is what we have, iostream is the de-facto approach that most
> people use when outputting a variety of objects in non-time-critical code.
> The fact is that people are *already* using them, they already have their
> stream operators defined for built-in types and for any kind of custom type
> that is supposed to be output in the first place. All this does is make
> their lives easier in doing so. This is the reason I chose this approach -
> it gives people a smoother way of doing what they are already doing without
> all the fuss of adding in other code.
>
>
> If you want to incorporate something like this into the language, then you
> *first* needs to come up with an underlying model which isn't terrible.
> That is, an extensible, type-safe system for converting objects to strings.
> And there's absolutely no excuse for this not being `constexpr` aware. It
> should not be based on virtual functions.
>
>
> Converting objects to strings and then doing what? That's the problem. We
> could always use a typecast to string (in many-member objects these methods
> often end up using stringstreams in the first place) then concatenating the
> result to the preceding literal, followed by further concatenations. Copies
> everywhere. We could come up with a mechanism by which the result is
> sequentially added to the existing string, but that's iostream in a
> nutshell.
>

It is? `iostream` is rooted in virtual calls. I see nothing about "a
mechanism by which the result is sequentially added to the existing string"
that *requires* virtual calls. That's a design choice, not a fundamental
requirement.

Introducing something new would be a much bigger change, and requires
> convincing the community to change their habits and legacy code. Syntactic
> sugar is not worth all that.
>

But "all that" is worthwhile in and of itself. Getting a better string
formatting system would be a great proposal; adding "string interpolation"
to that would merely be icing on the cake.

I'm aiming for something that is *less* demanding on the user.
>
> I will see if I can find out how it is implemented in the other languages
> and report back. I cannot imagine that they use anything that is
> inaccessible to us, but instead I believe that they are just more accepting
> of the small cost involved.
>
> Once you have that, then you can go about suggesting using that as the
> basis for "string interpolation". But what you're doing is putting the cart
> before the horse. Or at the very least, asking a cart to be driven by a
> very lame horse.
>
>
> A very lame horse that is trusty enough to pull the community thus far,
>

If that were truly the case, why do we have `to/from_chars`? No, "the
community" has needed a replacement for iostreams for a long time. We
simply don't have one at present.

and a cart that is used extensively in other (ditching the metaphor here)
> languages because it is incredibly easy to use.
>
> If "string interpolation" is to be worthwhile, I shouldn't have to think
> about whether it's performant enough to use it in my code. Just like I
> don't have to worry that range-based `for` loops will copy values into a
> temporary `vector` or something before iterating over them.
>
>
> Ideally, this would be nice. If you can think of such a thing, here is the
> perfect place to discuss it. My focus here is very much on the cart. As for
> the horse, I don't much have a preference, except that ease of use is vital.
>

If the options are "no string interpolation" and "bad string
interpolation", I'll take the former over the latter. Better to have no
feature than to have one that you have to think about whether it's
reasonable to use it when it is otherwise entirely appropriate. Again, look
to my range-based `for` analogy; that syntactic sugar doesn't get in the
way.

But I find it damaging for us to refuse to have nice things simply based on
> one metric - there are multiple costs involved in a project, and
> development time and ease of use is one of them. Creating a way of making
> things easier on developers in the times that they aren't looking for the
> fastest solution is useful in that regard.
>

Why do you assume that a non-iostreams solution would not have "ease of
use"? Your entire argument is predicated on the notion that you have to
choose between "easy to use" and "fast".

Take P0645, mentioned above. Its customization point is a non-member
function, just like iostream, which will be looked up through ADL. The only
real difference between it and iostream (besides the performance) is that
the function isn't named `operator<<`. There is nothing about this which is
particularly difficult to use.

Just because iostreams exists today doesn't mean that there's not a better
solution that would be no more difficult to use than that.

Of course, the question would then be why they are using C++ in the first
> place. But it would be wrong to suggest that 100% of the time that you're
> writing C++ you're thinking purely about the performance of each run,
> especially during a debug session or in the early stages as I mentioned.
> And, for your layman who isn't concerned about the cost of building a
> string in an iostream and copying the result to a string - from beginners,
> to people who are testing out an idea, or demonstrating functionality,
> doing old-school debugging, or who just aren't concerned about performance
> at that stage - it costs them nothing, but gives them a nicer language to
> work with.
>
> There may be an alternative, and that's improved and standardised
> preprocessor functionality so that people can have more flexibility. The
> fact that we can't even have control of state, e.g. defines inside macros,
> is extremely limiting (otherwise this would be doable in some form via
> macros). I guess it is perfectly possible to make a pre-preprocessor to run
> the code through pre-translation, but that adds its own complications.
>

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/d404b982-04e5-4520-8384-25632af83d96%40isocpp.org.

------=_Part_4339_68324471.1518162633154
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Friday, February 9, 2018 at 1:06:40 AM UTC-5, Jake Arki=
nstall wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"auto"=
><div dir=3D"auto"><div class=3D"gmail_quote">On 9 Feb 2018 03:38, &quot;Ni=
col Bolas&quot; &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscate=
d-mailto=3D"qAQ36lRrCQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;=
javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;=
;return true;">jmck...@gmail.com</a>&gt; wrote:<br type=3D"attribution"><bl=
ockquote style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left=
:1ex"><div dir=3D"ltr"><div>There is no reason why I should have to choose =
between &quot;slow and=20
convenient&quot; and &quot;fast and hard-to-use&quot;. The evolution of mod=
ern C++ has=20
been to take &quot;fast and hard-to-use&quot; and turn it into &quot;fast a=
nd=20
easy-to-use&quot;. `constexpr` makes an entire branch of template=20
metaprogramming look like normal code. Variadic templates make many=20
things that were out of reach for the average programmer into much easier m=
etaprogramming techniques.=20
Concepts take the `enable_if` hack and makes it into a real, extensible=20
part of the language. And so forth.<br></div></div></blockquote></div></div=
><div dir=3D"auto"><br></div><div dir=3D"auto">The conflict I am facing is =
that (a) C++ handling of injecting variables into strings is a choice of ug=
ly, ugly, or ugly, and (b) there is no efficient way (that I can think of) =
of changing that.</div></div></blockquote><div><br>There is an efficient wa=
y. There are plenty of better solutions than using `iostreams` for string f=
ormatting. They may not be part of the standard library yet, but there <a h=
ref=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0645r0.html=
">have been proposals for some of them</a>.<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"auto"><div dir=3D"auto">But there a=
re situations, as I set out in the beginning, where (a) takes priority over=
 (b). It is not everyone&#39;s cup of tea, granted.</div></div></blockquote=
><div><br>Show me another C++ language feature that is fundamentally rooted=
 in doing things the slow way. Other than exceptions. Or things related to =
virtual functions/dynamic_casting of multiple inheritance.<br><br>Here&#39;=
s the thing. `iostreams`, for all of its failures, is ephemeral. It can be =
replaced; it can go away. A language feature cannot just &quot;go away&quot=
;. If we add a better way of doing text formatting, then &quot;string inter=
polation&quot; will not be able to use it, unless it can be made to do so i=
n a backwards compatible way.<br><br>That&#39;s bad. Language features <i>h=
ave to</i> get it right the first time. Just look at &quot;uniform initiali=
zation&quot; to see what happens when you screw that up.<br><br></div><bloc=
kquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-l=
eft: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"auto"><div dir=3D"auto"=
></div><div dir=3D"auto"><div class=3D"gmail_quote"><blockquote style=3D"ma=
rgin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"lt=
r"><div></div><div>See, the problem is that iostream is: 1) the only extens=
ible, type-safe formatting system available to standard C++, and 2) terribl=
e in pretty much every other way.<br></div></div></blockquote></div></div><=
div dir=3D"auto"><br></div><div dir=3D"auto">iostream is what we have, iost=
ream is the de-facto approach that most people use when outputting a variet=
y of objects in non-time-critical code. The fact is that people are <b>alre=
ady</b> using them, they already have their stream operators defined for bu=
ilt-in types and for any kind of custom type that is supposed to be output =
in the first place. All this does is make their lives easier in doing so. T=
his is the reason I chose this approach - it gives people a smoother way of=
 doing what they are already doing without all the fuss of adding in other =
code.</div><div dir=3D"auto">=C2=A0</div><div dir=3D"auto"><div class=3D"gm=
ail_quote"><blockquote style=3D"margin:0 0 0 .8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"ltr"><div>If you want to incorporate someth=
ing like this into the language, then you <i>first</i> needs to come up wit=
h an underlying model which isn&#39;t terrible. That is, an extensible, typ=
e-safe system for converting objects to strings. And there&#39;s absolutely=
 no excuse for this not being `constexpr` aware. It should not be based on =
virtual functions.<br></div></div></blockquote></div></div><div dir=3D"auto=
"><br></div><div dir=3D"auto">Converting objects to strings and then doing =
what? That&#39;s the problem. We could always use a typecast to string (in =
many-member objects these methods often end up using stringstreams in the f=
irst place) then concatenating the result to the preceding literal, followe=
d by further concatenations. Copies everywhere. We could come up with a mec=
hanism by which the result is sequentially added to the existing string, bu=
t that&#39;s iostream in a nutshell.</div></div></blockquote><div><br>It is=
? `iostream` is rooted in virtual calls. I see nothing about &quot;a mechan=
ism by which the result is sequentially added to the existing string&quot; =
that <i>requires</i> virtual calls. That&#39;s a design choice, not a funda=
mental requirement.<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"auto"><div dir=3D"auto">Introducing something new would be a=
 much bigger change, and requires convincing the community to change their =
habits and legacy code. Syntactic sugar is not worth all that.</div></div><=
/blockquote><div><br>But &quot;all that&quot; is worthwhile in and of itsel=
f. Getting a better string formatting system would be a great proposal; add=
ing &quot;string interpolation&quot; to that would merely be icing on the c=
ake.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"=
auto"><div dir=3D"auto">I&#39;m aiming for something that is <i>less</i> de=
manding on the user.</div><div dir=3D"auto"><br></div><div dir=3D"auto">I w=
ill see if I can find out how it is implemented in the other languages and =
report back. I cannot imagine that they use anything that is inaccessible t=
o us, but instead I believe that they are just more accepting of the small =
cost involved.</div><div dir=3D"auto"><br></div><div dir=3D"auto"><div clas=
s=3D"gmail_quote"><blockquote style=3D"margin:0 0 0 .8ex;border-left:1px #c=
cc solid;padding-left:1ex"><div dir=3D"ltr"><div>Once you have that, then y=
ou can go about suggesting using that as the basis for &quot;string interpo=
lation&quot;. But what you&#39;re doing is putting the cart before the hors=
e. Or at the very least, asking a cart to be driven by a very lame horse.</=
div></div></blockquote></div></div><div dir=3D"auto"><br></div><div dir=3D"=
auto">A very lame horse that is trusty enough to pull the community thus fa=
r,</div></div></blockquote><div><br>If that were truly the case, why do we =
have `to/from_chars`? No, &quot;the community&quot; has needed a replacemen=
t for iostreams for a long time. We simply don&#39;t have one at present.<b=
r><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"auto">=
<div dir=3D"auto">and a cart that is used extensively in other (ditching th=
e metaphor here) languages because it is incredibly easy to use.</div><div =
dir=3D"auto"><br></div><div dir=3D"auto"></div><div dir=3D"auto"><div class=
=3D"gmail_quote"><blockquote style=3D"margin:0 0 0 .8ex;border-left:1px #cc=
c solid;padding-left:1ex"><div dir=3D"ltr"><div>If &quot;string interpolati=
on&quot; is to be worthwhile, I shouldn&#39;t have to think
 about whether it&#39;s performant enough to use it in my code. Just like I=
 don&#39;t have to worry that range-based `for` loops will copy values into=
 a temporary `vector` or something before iterating over them.<br></div></d=
iv></blockquote></div></div><div dir=3D"auto"><br></div><div dir=3D"auto">I=
deally, this would be nice. If you can think of such a thing, here is the p=
erfect place to discuss it. My focus here is very much on the cart. As for =
the horse, I don&#39;t much have a preference, except that ease of use is v=
ital.</div></div></blockquote><div><br>If the options are &quot;no string i=
nterpolation&quot; and &quot;bad string interpolation&quot;, I&#39;ll take =
the former over the latter. Better to have no feature than to have one that=
 you have to think about whether it&#39;s reasonable to use it when it is o=
therwise entirely appropriate. Again, look to my range-based `for` analogy;=
 that syntactic sugar doesn&#39;t get in the way.<br><br></div><blockquote =
class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1p=
x #ccc solid;padding-left: 1ex;"><div dir=3D"auto"><div dir=3D"auto"></div>=
<div dir=3D"auto">But I find it damaging for us to refuse to have nice thin=
gs simply based on one metric - there are multiple costs involved in a proj=
ect, and development time and ease of use is one of them. Creating a way of=
 making things easier on developers in the times that they aren&#39;t looki=
ng for the fastest solution is useful in that regard.</div></div></blockquo=
te><div><br>Why do you assume that a non-iostreams solution would not have =
&quot;ease of use&quot;? Your entire argument is predicated on the notion t=
hat you have to choose between &quot;easy to use&quot; and &quot;fast&quot;=
..<br><br>Take P0645, mentioned above. Its customization point is a non-memb=
er function, just like iostream, which will be looked up through ADL. The o=
nly real difference between it and iostream (besides the performance) is th=
at the function isn&#39;t named `operator&lt;&lt;`. There is nothing about =
this which is particularly difficult to use.<br><br>Just because iostreams =
exists today doesn&#39;t mean that there&#39;s not a better solution that w=
ould be no more difficult to use than that.<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"auto"><div dir=3D"auto">Of course, =
the question would then be why they are using C++ in the first place. But i=
t would be wrong to suggest that 100% of the time that you&#39;re writing C=
++ you&#39;re thinking purely about the performance of each run, especially=
 during a debug session or in the early stages as I mentioned. And, for you=
r layman who isn&#39;t concerned about the cost of building a string in an =
iostream and copying the result to a string - from beginners, to people who=
 are testing out an idea, or demonstrating functionality, doing old-school =
debugging, or who just aren&#39;t concerned about performance at that stage=
 - it costs them nothing, but gives them a nicer language to work with.</di=
v><div dir=3D"auto"><br></div><div dir=3D"auto">There may be an alternative=
, and that&#39;s improved and standardised preprocessor functionality so th=
at people can have more flexibility. The fact that we can&#39;t even have c=
ontrol of state, e.g. defines inside macros, is extremely limiting (otherwi=
se this would be doable in some form via macros). I guess it is perfectly p=
ossible to make a pre-preprocessor to run the code through pre-translation,=
 but that adds its own complications.</div></div>
</blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/d404b982-04e5-4520-8384-25632af83d96%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/d404b982-04e5-4520-8384-25632af83d96=
%40isocpp.org</a>.<br />

------=_Part_4339_68324471.1518162633154--

------=_Part_4338_1994671980.1518162633154--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Fri, 09 Feb 2018 00:05:44 -0800
Raw View
On Thursday, 8 February 2018 23:50:33 PST Nicol Bolas wrote:
> Show me another C++ language feature that is fundamentally rooted in doing
> things the slow way. Other than exceptions. Or things related to virtual
> functions/dynamic_casting of multiple inheritance.

I should point out that neither exceptions nor dynamic casting are slow when
used properly. Exceptions, when used only in exceptional cases, do not affect
the performance of the main program and, in many benchmarks, show that they
actually improve performance. They're only slow when thrown.

Part of the reason for that is also the dynamic casting. There aren't many
ways of skinning this particular cat, not without removing the multiple
inheritance feature from the language. It just is what it is. But most
applications and frameworks don't abuse the feature too badly, so the feature
isn't slow for them.

And here's an example of a framework that does abuse virtuals and multiple
inheritance: iostreams.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center



--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1755463.eZGoRBFS42%40tjmaciei-mobl1.

.


Author: Richard Hodges <hodges.r@gmail.com>
Date: Fri, 9 Feb 2018 09:05:44 +0100
Raw View
--001a113fb94ed913420564c2fea0
Content-Type: text/plain; charset="UTF-8"

It's a great idea. Naysayers talk of performance concerns as a result of
virtual functions. These are irrelevant.

Firstly, the cost of turning numeric values into strings far outweighs the
cost of a virtual call

Second, fixing iostream to make it more efficient is a separate concern.

The general idea is a great one, and very welcome.

I have recently taught iostream formatting to a new developer. His reaction
was incredulity that it was so hard and unintuitive. Particularly the
formatting of UDTs.

It is a travesty that in 2018, c++ remains impenetrable to beginners. It
drives people into the waiting arms of awful non-languages like java, c#
and swift.




On 9 Feb 2018 6:18 am, "Thiago Macieira" <thiago@macieira.org> wrote:

On Thursday, 8 February 2018 17:41:16 PST Jake Arkinstall wrote:
> T recipient;
> // operator<<(std::ostream&, T) defined, or we naturally get an undefined
> operator<< error later on

Considering iostreams are somewhat slow, because of all the virtuals and
multiple inheritance, how can I make your proposal work with something other
than it?

Explain how it would work with an arbitrary other class.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center



--
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/
isocpp.org/d/msgid/std-proposals/1731062.NdW3nXAon1%40tjmaciei-mobl1.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3haDVWHLQ4MJfEjeFWoh%3DJduvANZ%2BG61M9_x8H9%2BbU-xpA%40mail.gmail.com.

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

<div dir=3D"auto"><div>It&#39;s a great idea. Naysayers talk of performance=
 concerns as a result of virtual functions. These are irrelevant.</div><div=
 dir=3D"auto"><br></div><div dir=3D"auto">Firstly, the cost of turning nume=
ric values into strings far outweighs the cost of a virtual call=C2=A0</div=
><div dir=3D"auto"><br></div><div dir=3D"auto">Second, fixing iostream to m=
ake it more efficient is a separate concern.=C2=A0</div><div dir=3D"auto"><=
br></div><div dir=3D"auto">The general idea is a great one, and very welcom=
e.=C2=A0</div><div dir=3D"auto"><br></div><div dir=3D"auto">I have recently=
 taught iostream formatting to a new developer. His reaction was incredulit=
y that it was so hard and unintuitive. Particularly the formatting of UDTs.=
=C2=A0</div><div dir=3D"auto"><br></div><div dir=3D"auto"><span style=3D"fo=
nt-family:sans-serif">It is a travesty that in 2018, c++ remains impenetrab=
le to beginners. It drives people into the waiting arms of awful non-langua=
ges like java, c# and swift.=C2=A0</span></div><div dir=3D"auto"><font face=
=3D"sans-serif"><br></font></div><div dir=3D"auto"><font face=3D"sans-serif=
"><br></font></div><div dir=3D"auto"><font face=3D"sans-serif"><br></font><=
div class=3D"gmail_extra" dir=3D"auto"><br><div class=3D"gmail_quote">On 9 =
Feb 2018 6:18 am, &quot;Thiago Macieira&quot; &lt;<a href=3D"mailto:thiago@=
macieira.org">thiago@macieira.org</a>&gt; wrote:<br type=3D"attribution"><b=
lockquote class=3D"quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div class=3D"quoted-text">On Thursday, 8 February 2=
018 17:41:16 PST Jake Arkinstall wrote:<br>
&gt; T recipient;<br>
&gt; // operator&lt;&lt;(std::ostream&amp;, T) defined, or we naturally get=
 an undefined<br>
&gt; operator&lt;&lt; error later on<br>
<br>
</div>Considering iostreams are somewhat slow, because of all the virtuals =
and<br>
multiple inheritance, how can I make your proposal work with something othe=
r<br>
than it?<br>
<br>
Explain how it would work with an arbitrary other class.<br>
<br>
--<br>
Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" rel=3D"noref=
errer" target=3D"_blank">macieira.info</a> - thiago (AT) <a href=3D"http://=
kde.org" rel=3D"noreferrer" target=3D"_blank">kde.org</a><br>
=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center<br>
<div class=3D"quoted-text"><br>
<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%2Bunsubscribe@isocpp.org">std-propo=
sals+unsubscribe@<wbr>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>
</div>To view this discussion on the web visit <a href=3D"https://groups.go=
ogle.com/a/isocpp.org/d/msgid/std-proposals/1731062.NdW3nXAon1%40tjmaciei-m=
obl1" rel=3D"noreferrer" target=3D"_blank">https://groups.google.com/a/<wbr=
>isocpp.org/d/msgid/std-<wbr>proposals/1731062.NdW3nXAon1%<wbr>40tjmaciei-m=
obl1</a>.<br>
</blockquote></div><br></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CALvx3haDVWHLQ4MJfEjeFWoh%3DJduvANZ%2=
BG61M9_x8H9%2BbU-xpA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3haDVW=
HLQ4MJfEjeFWoh%3DJduvANZ%2BG61M9_x8H9%2BbU-xpA%40mail.gmail.com</a>.<br />

--001a113fb94ed913420564c2fea0--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Fri, 09 Feb 2018 00:24:36 -0800
Raw View
On Friday, 9 February 2018 00:05:44 PST Richard Hodges wrote:
> It's a great idea. Naysayers talk of performance concerns as a result of
> virtual functions. These are irrelevant.
>
> Firstly, the cost of turning numeric values into strings far outweighs the
> cost of a virtual call

That depends on a lot. The cost of a virtual call could easily get to 5% total
time of a conversion, which is non-negligible, if there's no memory allocation
involved.

> Second, fixing iostream to make it more efficient is a separate concern.

More than likely, doing that means replacing it entirely, which in turn means
this feature cannot depend on iostreams. It must be generic, if it exists at
all.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center



--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/14112472.AvYaaQfdXc%40tjmaciei-mobl1.

.


Author: Richard Hodges <hodges.r@gmail.com>
Date: Fri, 9 Feb 2018 09:27:03 +0000
Raw View
> That depends on a lot. The cost of a virtual call could easily get to 5% =
total=20
time of a conversion, which is non-negligible, if there's no memory allocat=
ion=20
involved.

When no new projects are choosing to use your language, the cost of a call =
is an utter irrelevance. C++=E2=80=99s problem is not a performance one - i=
t=E2=80=99s an adoption one.

This is because no matter how much you or I enjoy the the language, it rema=
ins without essential features such as automatic object printing, packaging=
, reflection, standard graphics/human interface libraries and so on.

After 40 years, writing c++ still requires an intimate knowledge of operati=
ng systems, development toolchains, processor internals and all the other b=
lockers to adoption. Even the trivial task of teaching my son c++ through t=
he writing of a simple portable game requires a week-long lecture on librar=
ies, differences between windows and linux toolchains (let=E2=80=99s not ev=
en get started on cygwin and mingw!), compilation of a graphics engine (req=
uiring the gathering and compilation of all dependent libraries) and all th=
e other nastiness that makes the entire enterprise a waste of everyone=E2=
=80=99s time.

C++ will not die because of a virtual call - that has not killed any other =
language. It will die because it is impossible to start a project using it =
without 20+ years of experience.




> On 9 Feb 2018, at 08:24, Thiago Macieira <thiago@macieira.org> wrote:
>=20
> On Friday, 9 February 2018 00:05:44 PST Richard Hodges wrote:
>> It's a great idea. Naysayers talk of performance concerns as a result of
>> virtual functions. These are irrelevant.
>>=20
>> Firstly, the cost of turning numeric values into strings far outweighs t=
he
>> cost of a virtual call
>=20
> That depends on a lot. The cost of a virtual call could easily get to 5% =
total=20
> time of a conversion, which is non-negligible, if there's no memory alloc=
ation=20
> involved.
>=20
>> Second, fixing iostream to make it more efficient is a separate concern.
>=20
> More than likely, doing that means replacing it entirely, which in turn m=
eans=20
> this feature cannot depend on iostreams. It must be generic, if it exists=
 at=20
> all.
>=20
> --=20
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
>   Software Architect - Intel Open Source Technology Center
>=20
>=20
>=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=
 email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit https://groups.google.com/a/isoc=
pp.org/d/msgid/std-proposals/14112472.AvYaaQfdXc%40tjmaciei-mobl1.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/3DD8D4BE-1472-4AE9-8295-74BCD282DEC5%40gmail.com=
..

.


Author: Jake Arkinstall <jake.arkinstall@gmail.com>
Date: Fri, 9 Feb 2018 13:51:29 +0000
Raw View
--001a11c0327a4b35720564c7d391
Content-Type: text/plain; charset="UTF-8"

On 9 Feb 2018 08:24, "Thiago Macieira" <thiago@macieira.org> wrote:

On Friday, 9 February 2018 00:05:44 PST Richard Hodges wrote:
> It's a great idea. Naysayers talk of performance concerns as a result of
> virtual functions. These are irrelevant.
>
> Firstly, the cost of turning numeric values into strings far outweighs the
> cost of a virtual call

That depends on a lot. The cost of a virtual call could easily get to 5%
total
time of a conversion, which is non-negligible, if there's no memory
allocation
involved.


5% during a debug stage is no big deal. I set the scene for a good reason:
not all code is production code. My focus here is making C++ friendlier
until performance is a goal. There is absolutely no reason, that I can see,
to treat early development with the same fine-tooth comb as the final
product.


> Second, fixing iostream to make it more efficient is a separate concern.

More than likely, doing that means replacing it entirely, which in turn
means
this feature cannot depend on iostreams. It must be generic, if it exists at
all.


That would be nice, but generic is a royal pain in the backside in this
circumstance. This is not something that can be written in the current
language because it requires interpetation of the strings. How on earth
that is supposed to generalise to choices of fmt, string conversion and
concatenation, stringstreams, and whatever magical solution we're waiting
on to make string manipulation efficient, I have no idea, especially in the
general situation where the different approaches - e.g. to_string and
operator<< - are not equivalent.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCOKumW2SOvUEAPR4LdQfJDBXT7jvXPB0eMiznJ_6gCYhw%40mail.gmail.com.

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

<div dir=3D"auto"><div><br><div class=3D"gmail_extra"><br><div class=3D"gma=
il_quote">On 9 Feb 2018 08:24, &quot;Thiago Macieira&quot; &lt;<a href=3D"m=
ailto:thiago@macieira.org">thiago@macieira.org</a>&gt; wrote:<br type=3D"at=
tribution"><blockquote class=3D"quote" style=3D"margin:0 0 0 .8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div class=3D"quoted-text">On Friday, 9=
 February 2018 00:05:44 PST Richard Hodges wrote:<br>
&gt; It&#39;s a great idea. Naysayers talk of performance concerns as a res=
ult of<br>
&gt; virtual functions. These are irrelevant.<br>
&gt;<br>
&gt; Firstly, the cost of turning numeric values into strings far outweighs=
 the<br>
&gt; cost of a virtual call<br>
<br>
</div>That depends on a lot. The cost of a virtual call could easily get to=
 5% total<br>
time of a conversion, which is non-negligible, if there&#39;s no memory all=
ocation<br>
involved.<br></blockquote></div></div></div><div dir=3D"auto"><br></div><di=
v dir=3D"auto">5% during a debug stage is no big deal. I set the scene for =
a good reason: not all code is production code. My focus here is making C++=
 friendlier until performance is a goal. There is absolutely no reason, tha=
t I can see, to treat early development with the same fine-tooth comb as th=
e final product.</div><div dir=3D"auto"><br></div><div dir=3D"auto"><div cl=
ass=3D"gmail_extra"><div class=3D"gmail_quote"><blockquote class=3D"quote" =
style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class=3D"quoted-text"><br>
&gt; Second, fixing iostream to make it more efficient is a separate concer=
n.<br>
<br>
</div>More than likely, doing that means replacing it entirely, which in tu=
rn means<br>
this feature cannot depend on iostreams. It must be generic, if it exists a=
t<br>
all.</blockquote></div></div></div><div dir=3D"auto"><br></div><div dir=3D"=
auto">That would be nice, but generic is a royal pain in the backside in th=
is circumstance. This is not something that can be written in the current l=
anguage because it requires interpetation of the strings. How on earth that=
 is supposed to generalise to choices of fmt, string conversion and concate=
nation, stringstreams, and whatever magical solution we&#39;re waiting on t=
o make string manipulation efficient, I have no idea, especially in the gen=
eral situation where the different approaches - e.g. to_string and operator=
&lt;&lt; - are not equivalent.</div><div dir=3D"auto"></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCOKumW2SOvUEAPR4LdQfJDBXT7jvX=
PB0eMiznJ_6gCYhw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCOKumW2=
SOvUEAPR4LdQfJDBXT7jvXPB0eMiznJ_6gCYhw%40mail.gmail.com</a>.<br />

--001a11c0327a4b35720564c7d391--

.


Author: =?UTF-8?Q?Marcel_F=2E_Kr=C3=BCger?= <zauguin@gmail.com>
Date: Fri, 09 Feb 2018 14:07:17 +0000
Raw View
--94eb2c1a16a86fce4b0564c80cf9
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Jake Arkinstall <jake.arkinstall@gmail.com> schrieb am Fr., 9. Feb. 2018 um
14:51 Uhr:

>
> That would be nice, but generic is a royal pain in the backside in this
> circumstance. This is not something that can be written in the current
> language because it requires interpetation of the strings. How on earth
> that is supposed to generalise to choices of fmt, string conversion and
> concatenation, stringstreams, and whatever magical solution we're waiting
> on to make string manipulation efficient, I have no idea, especially in t=
he
> general situation where the different approaches - e.g. to_string and
> operator<< - are not equivalent.
>

Maybe this could be based on user-defined literals:
If for example `operator""_sth` accepts more than two parameters, the
expression "abc{def}ghij"_sth could be rewritten to `operator""_sth("abc",
3, def, "ghij", 4)`.
Then the standard library could include a literal suffix based on iostreams
and it should be generic enough to be supported by most libraries.

Best regards
Marcel Kr=C3=BCger

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CAE1xPfd5X7_e9D4Xk%3DZMKCF0WEEN%2Bvw5xCW4FFXLkz_=
AcXSfPA%40mail.gmail.com.

--94eb2c1a16a86fce4b0564c80cf9
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_quote"><div dir=3D"ltr">Jake Arkinstal=
l &lt;<a href=3D"mailto:jake.arkinstall@gmail.com">jake.arkinstall@gmail.co=
m</a>&gt; schrieb am Fr., 9. Feb. 2018 um 14:51=C2=A0Uhr:</div><blockquote =
class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid=
;padding-left:1ex"><div dir=3D"auto"><div dir=3D"auto"><br></div></div><div=
 dir=3D"auto"><div dir=3D"auto">That would be nice, but generic is a royal =
pain in the backside in this circumstance. This is not something that can b=
e written in the current language because it requires interpetation of the =
strings. How on earth that is supposed to generalise to choices of fmt, str=
ing conversion and concatenation, stringstreams, and whatever magical solut=
ion we&#39;re waiting on to make string manipulation efficient, I have no i=
dea, especially in the general situation where the different approaches - e=
..g. to_string and operator&lt;&lt; - are not equivalent.</div></div></block=
quote><div><br></div><div>Maybe this could be based on user-defined literal=
s:</div><div>If for example `operator&quot;&quot;_sth` accepts more than tw=
o parameters, the expression &quot;abc{def}ghij&quot;_sth could be rewritte=
n to `operator&quot;&quot;_sth(&quot;abc&quot;, 3, def, &quot;ghij&quot;, 4=
)`.</div><div>Then the standard library could include a literal suffix base=
d on iostreams and it should be generic enough to be supported by most libr=
aries.</div><div><br></div><div>Best regards</div><div>Marcel Kr=C3=BCger</=
div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAE1xPfd5X7_e9D4Xk%3DZMKCF0WEEN%2Bvw5=
xCW4FFXLkz_AcXSfPA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAE1xPfd5X7_e=
9D4Xk%3DZMKCF0WEEN%2Bvw5xCW4FFXLkz_AcXSfPA%40mail.gmail.com</a>.<br />

--94eb2c1a16a86fce4b0564c80cf9--

.


Author: Jake Arkinstall <jake.arkinstall@gmail.com>
Date: Fri, 9 Feb 2018 14:16:57 +0000
Raw View
--001a113d5a725d2d200564c82ebc
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

I like this approach.

On 9 Feb 2018 14:07, "Marcel F. Kr=C3=BCger" <zauguin@gmail.com> wrote:

> Jake Arkinstall <jake.arkinstall@gmail.com> schrieb am Fr., 9. Feb. 2018
> um 14:51 Uhr:
>
>>
>> That would be nice, but generic is a royal pain in the backside in this
>> circumstance. This is not something that can be written in the current
>> language because it requires interpetation of the strings. How on earth
>> that is supposed to generalise to choices of fmt, string conversion and
>> concatenation, stringstreams, and whatever magical solution we're waitin=
g
>> on to make string manipulation efficient, I have no idea, especially in =
the
>> general situation where the different approaches - e.g. to_string and
>> operator<< - are not equivalent.
>>
>
> Maybe this could be based on user-defined literals:
> If for example `operator""_sth` accepts more than two parameters, the
> expression "abc{def}ghij"_sth could be rewritten to `operator""_sth("abc"=
,
> 3, def, "ghij", 4)`.
> Then the standard library could include a literal suffix based on
> iostreams and it should be generic enough to be supported by most librari=
es.
>
> Best regards
> Marcel Kr=C3=BCger
>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit https://groups.google.com/a/
> isocpp.org/d/msgid/std-proposals/CAE1xPfd5X7_e9D4Xk%
> 3DZMKCF0WEEN%2Bvw5xCW4FFXLkz_AcXSfPA%40mail.gmail.com
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAE1xPfd5X7=
_e9D4Xk%3DZMKCF0WEEN%2Bvw5xCW4FFXLkz_AcXSfPA%40mail.gmail.com?utm_medium=3D=
email&utm_source=3Dfooter>
> .
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CAC%2B0CCNSW%2B2QekrWHumD9NAPca0qeQxFZ7KtL%3DdOh=
Po7o4hC%2Bg%40mail.gmail.com.

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

<div dir=3D"auto">I like this approach.</div><div class=3D"gmail_extra"><br=
><div class=3D"gmail_quote">On 9 Feb 2018 14:07, &quot;Marcel F. Kr=C3=BCge=
r&quot; &lt;<a href=3D"mailto:zauguin@gmail.com">zauguin@gmail.com</a>&gt; =
wrote:<br type=3D"attribution"><blockquote class=3D"gmail_quote" style=3D"m=
argin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr"><div class=3D"gmail_quote"><div dir=3D"ltr">Jake Arkinstall &lt;<a href=
=3D"mailto:jake.arkinstall@gmail.com" target=3D"_blank">jake.arkinstall@gma=
il.com</a>&gt; schrieb am Fr., 9. Feb. 2018 um 14:51=C2=A0Uhr:</div><blockq=
uote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc =
solid;padding-left:1ex"><div dir=3D"auto"><div dir=3D"auto"><br></div></div=
><div dir=3D"auto"><div dir=3D"auto">That would be nice, but generic is a r=
oyal pain in the backside in this circumstance. This is not something that =
can be written in the current language because it requires interpetation of=
 the strings. How on earth that is supposed to generalise to choices of fmt=
, string conversion and concatenation, stringstreams, and whatever magical =
solution we&#39;re waiting on to make string manipulation efficient, I have=
 no idea, especially in the general situation where the different approache=
s - e.g. to_string and operator&lt;&lt; - are not equivalent.</div></div></=
blockquote><div><br></div><div>Maybe this could be based on user-defined li=
terals:</div><div>If for example `operator&quot;&quot;_sth` accepts more th=
an two parameters, the expression &quot;abc{def}ghij&quot;_sth could be rew=
ritten to `operator&quot;&quot;_sth(&quot;abc&quot;, 3, def, &quot;ghij&quo=
t;, 4)`.</div><div>Then the standard library could include a literal suffix=
 based on iostreams and it should be generic enough to be supported by most=
 libraries.</div><div><br></div><div>Best regards</div><div>Marcel Kr=C3=BC=
ger</div></div></div>

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAE1xPfd5X7_e9D4Xk%3DZMKCF0WEEN%2Bvw5=
xCW4FFXLkz_AcXSfPA%40mail.gmail.com?utm_medium=3Demail&amp;utm_source=3Dfoo=
ter" target=3D"_blank">https://groups.google.com/a/<wbr>isocpp.org/d/msgid/=
std-<wbr>proposals/CAE1xPfd5X7_e9D4Xk%<wbr>3DZMKCF0WEEN%2Bvw5xCW4FFXLkz_<wb=
r>AcXSfPA%40mail.gmail.com</a>.<br>
</blockquote></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCNSW%2B2QekrWHumD9NAPca0qeQxF=
Z7KtL%3DdOhPo7o4hC%2Bg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CC=
NSW%2B2QekrWHumD9NAPca0qeQxFZ7KtL%3DdOhPo7o4hC%2Bg%40mail.gmail.com</a>.<br=
 />

--001a113d5a725d2d200564c82ebc--

.


Author: Richard Hodges <hodges.r@gmail.com>
Date: Fri, 9 Feb 2018 14:38:20 +0000
Raw View
--Apple-Mail=_47B0B0FA-B8C9-4359-A43D-3980E9746DF1
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="UTF-8"

> I like this approach.

I do too. I was engaged in a boost discussion along these lines - imagine t=
hat this variadic suffix operator was a synonym for:

template<class=E2=80=A6Things>
auto concat(Things&&=E2=80=A6things) -> concatenated_data<Things=E2=80=A6>;

concatenated_data would essentially contain a tuple of data references/copi=
es as appropriate.

Now a concatenated_data<> can have a friend overload for=20

template<class Stream, class=E2=80=A6Things>
Stream& operator<<(Stream&, concatenated_data<Things=E2=80=A6> const&)

And an overload for to_string

Efficiency concerns can now be allayed by providing appropriate customisati=
on of the stream operator and/or to_string overloads, or the default basic_=
ostream implementation can be accepted.






> On 9 Feb 2018, at 14:16, Jake Arkinstall <jake.arkinstall@gmail.com> wrot=
e:
>=20
> I like this approach.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/3A3B07EE-ADE5-46BB-8CC8-DFA8E9EDEBF6%40gmail.com=
..

--Apple-Mail=_47B0B0FA-B8C9-4359-A43D-3980E9746DF1
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset="UTF-8"

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><div class=3D"">&g=
t; I like this approach.</div><div class=3D""><br class=3D""></div><div cla=
ss=3D"">I do too. I was engaged in a boost discussion along these lines - i=
magine that this variadic suffix operator was a synonym for:</div><div clas=
s=3D""><br class=3D""></div><div class=3D""><font face=3D"Courier New" clas=
s=3D"">template&lt;class=E2=80=A6Things&gt;</font></div><div class=3D""><fo=
nt face=3D"Courier New" class=3D"">auto concat(Things&amp;&amp;=E2=80=A6thi=
ngs) -&gt; concatenated_data&lt;Things=E2=80=A6&gt;;</font></div><div class=
=3D""><br class=3D""></div><div class=3D"">concatenated_data would essentia=
lly contain a tuple of data references/copies as appropriate.</div><div cla=
ss=3D""><br class=3D""></div><div class=3D"">Now a concatenated_data&lt;&gt=
; can have a friend overload for&nbsp;</div><div class=3D""><br class=3D"">=
</div><div class=3D""><font face=3D"Courier New" class=3D"">template&lt;cla=
ss Stream, class=E2=80=A6Things&gt;</font></div><div class=3D""><font face=
=3D"Courier New" class=3D"">Stream&amp; operator&lt;&lt;(Stream&amp;, conca=
tenated_data&lt;Things=E2=80=A6&gt; const&amp;)</font></div><div class=3D""=
><br class=3D""></div><div class=3D"">And an overload for <font face=3D"Cou=
rier New" class=3D"">to_string</font></div><div class=3D""><br class=3D""><=
/div><div class=3D"">Efficiency concerns can now be allayed by providing ap=
propriate customisation of the stream operator and/or to_string overloads, =
or the default <font face=3D"Courier New" class=3D"">basic_ostream</font> i=
mplementation can be accepted.</div><div class=3D""><br class=3D""></div><d=
iv class=3D""><br class=3D""></div><div class=3D""><br class=3D""></div><di=
v class=3D""><br class=3D""></div><div class=3D""><br class=3D""></div><br =
class=3D""><div><blockquote type=3D"cite" class=3D""><div class=3D"">On 9 F=
eb 2018, at 14:16, Jake Arkinstall &lt;<a href=3D"mailto:jake.arkinstall@gm=
ail.com" class=3D"">jake.arkinstall@gmail.com</a>&gt; wrote:</div><br class=
=3D"Apple-interchange-newline"><div class=3D""><span style=3D"font-family: =
Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; =
font-weight: normal; letter-spacing: normal; text-align: start; text-indent=
: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webki=
t-text-stroke-width: 0px; float: none; display: inline !important;" class=
=3D"">I like this approach.</span></div></blockquote></div><br class=3D""><=
/body></html>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/3A3B07EE-ADE5-46BB-8CC8-DFA8E9EDEBF6%=
40gmail.com?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/3A3B07EE-ADE5-46BB-8CC8-DFA8E9EDEBF6%=
40gmail.com</a>.<br />

--Apple-Mail=_47B0B0FA-B8C9-4359-A43D-3980E9746DF1--

.


Author: Avi Kivity <avi@scylladb.com>
Date: Fri, 9 Feb 2018 17:42:18 +0200
Raw View
This is a multi-part message in MIME format.
--------------428CDA8FCA99C3502D21690F
Content-Type: text/plain; charset="UTF-8"; format=flowed
Content-Transfer-Encoding: quoted-printable

On 02/09/2018 04:07 PM, Marcel F. Kr=C3=BCger wrote:
> Jake Arkinstall <jake.arkinstall@gmail.com=20
> <mailto:jake.arkinstall@gmail.com>> schrieb am Fr., 9. Feb. 2018 um=20
> 14:51=C2=A0Uhr:
>
>
>     That would be nice, but generic is a royal pain in the backside in
>     this circumstance. This is not something that can be written in
>     the current language because it requires interpetation of the
>     strings. How on earth that is supposed to generalise to choices of
>     fmt, string conversion and concatenation, stringstreams, and
>     whatever magical solution we're waiting on to make string
>     manipulation efficient, I have no idea, especially in the general
>     situation where the different approaches - e.g. to_string and
>     operator<< - are not equivalent.
>
>
> Maybe this could be based on user-defined literals:
> If for example `operator""_sth` accepts more than two parameters, the=20
> expression "abc{def}ghij"_sth could be rewritten to=20
> `operator""_sth("abc", 3, def, "ghij", 4)`.
> Then the standard library could include a literal suffix based on=20
> iostreams and it should be generic enough to be supported by most=20
> libraries.
>

I hate myself for suggesting it, but what about code injection?

 =C2=A0=C2=A0=C2=A0 constexpr std::injected_code operator""v(const char* li=
teral) { ... }

The "std::injected_code" return type is a string that gets injected into=20
the code, replacing the literal.

This could be abused in so many wonderful ways.


--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/33eb3ce3-12a5-800d-9c4d-2a362fb139d6%40scylladb.=
com.

--------------428CDA8FCA99C3502D21690F
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<html>
  <head>
    <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-8=
">
  </head>
  <body text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div class=3D"moz-cite-prefix">On 02/09/2018 04:07 PM, Marcel F.
      Kr=C3=BCger wrote:<br>
    </div>
    <blockquote type=3D"cite"
cite=3D"mid:CAE1xPfd5X7_e9D4Xk=3DZMKCF0WEEN+vw5xCW4FFXLkz_AcXSfPA@mail.gmai=
l.com">
      <div dir=3D"ltr">
        <div class=3D"gmail_quote">
          <div dir=3D"ltr">Jake Arkinstall &lt;<a
              href=3D"mailto:jake.arkinstall@gmail.com"
              moz-do-not-send=3D"true">jake.arkinstall@gmail.com</a>&gt;
            schrieb am Fr., 9. Feb. 2018 um 14:51=C2=A0Uhr:</div>
          <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0
            .8ex;border-left:1px #ccc solid;padding-left:1ex">
            <div dir=3D"auto">
              <div dir=3D"auto"><br>
              </div>
            </div>
            <div dir=3D"auto">
              <div dir=3D"auto">That would be nice, but generic is a royal
                pain in the backside in this circumstance. This is not
                something that can be written in the current language
                because it requires interpetation of the strings. How on
                earth that is supposed to generalise to choices of fmt,
                string conversion and concatenation, stringstreams, and
                whatever magical solution we're waiting on to make
                string manipulation efficient, I have no idea,
                especially in the general situation where the different
                approaches - e.g. to_string and operator&lt;&lt; - are
                not equivalent.</div>
            </div>
          </blockquote>
          <div><br>
          </div>
          <div>Maybe this could be based on user-defined literals:</div>
          <div>If for example `operator""_sth` accepts more than two
            parameters, the expression "abc{def}ghij"_sth could be
            rewritten to `operator""_sth("abc", 3, def, "ghij", 4)`.</div>
          <div>Then the standard library could include a literal suffix
            based on iostreams and it should be generic enough to be
            supported by most libraries.</div>
          <div><br>
          </div>
        </div>
      </div>
    </blockquote>
    <br>
    I hate myself for suggesting it, but what about code injection?<br>
    <br>
    =C2=A0=C2=A0=C2=A0 constexpr std::injected_code operator""v(const char*=
 literal) {
    ... }<br>
    <br>
    The "std::injected_code" return type is a string that gets injected
    into the code, replacing the literal.<br>
    <br>
    This could be abused in so many wonderful ways.<br>
    <br>
    =C2=A0=C2=A0=C2=A0 <br>
  </body>
</html>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/33eb3ce3-12a5-800d-9c4d-2a362fb139d6%=
40scylladb.com?utm_medium=3Demail&utm_source=3Dfooter">https://groups.googl=
e.com/a/isocpp.org/d/msgid/std-proposals/33eb3ce3-12a5-800d-9c4d-2a362fb139=
d6%40scylladb.com</a>.<br />

--------------428CDA8FCA99C3502D21690F--

.


Author: Jake Arkinstall <jake.arkinstall@gmail.com>
Date: Fri, 9 Feb 2018 16:14:44 +0000
Raw View
--f4f5e808d750a0ac1c0564c9d331
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

So an approach to eval() in a compiled language?

There are many dangers here, but also a lot of flexibility. It allows
libraries to change the language, opens up the potential for more advanced
preprocessing (especially given that they could have state).

It could very well be worth considering.

On 9 Feb 2018 15:42, "Avi Kivity" <avi@scylladb.com> wrote:

> On 02/09/2018 04:07 PM, Marcel F. Kr=C3=BCger wrote:
>
> Jake Arkinstall <jake.arkinstall@gmail.com> schrieb am Fr., 9. Feb. 2018
> um 14:51 Uhr:
>
>>
>> That would be nice, but generic is a royal pain in the backside in this
>> circumstance. This is not something that can be written in the current
>> language because it requires interpetation of the strings. How on earth
>> that is supposed to generalise to choices of fmt, string conversion and
>> concatenation, stringstreams, and whatever magical solution we're waitin=
g
>> on to make string manipulation efficient, I have no idea, especially in =
the
>> general situation where the different approaches - e.g. to_string and
>> operator<< - are not equivalent.
>>
>
> Maybe this could be based on user-defined literals:
> If for example `operator""_sth` accepts more than two parameters, the
> expression "abc{def}ghij"_sth could be rewritten to `operator""_sth("abc"=
,
> 3, def, "ghij", 4)`.
> Then the standard library could include a literal suffix based on
> iostreams and it should be generic enough to be supported by most librari=
es.
>
>
> I hate myself for suggesting it, but what about code injection?
>
>     constexpr std::injected_code operator""v(const char* literal) { ... }
>
> The "std::injected_code" return type is a string that gets injected into
> the code, replacing the literal.
>
> This could be abused in so many wonderful ways.
>
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit https://groups.google.com/a/
> isocpp.org/d/msgid/std-proposals/33eb3ce3-12a5-800d-
> 9c4d-2a362fb139d6%40scylladb.com
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/33eb3ce3-12=
a5-800d-9c4d-2a362fb139d6%40scylladb.com?utm_medium=3Demail&utm_source=3Dfo=
oter>
> .
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CAC%2B0CCPvOW5KdxWjbWr3BUPrE9PU9A3nkoZKgE687ySzp=
%2BJ%2BBw%40mail.gmail.com.

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

<div dir=3D"auto">So an approach to eval() in a compiled language?<div dir=
=3D"auto"><br></div><div dir=3D"auto">There are many dangers here, but also=
 a lot of flexibility. It allows libraries to change the language, opens up=
 the potential for more advanced preprocessing (especially given that they =
could have state).</div><div dir=3D"auto"><br></div><div dir=3D"auto">It co=
uld very well be worth considering.</div></div><div class=3D"gmail_extra"><=
br><div class=3D"gmail_quote">On 9 Feb 2018 15:42, &quot;Avi Kivity&quot; &=
lt;<a href=3D"mailto:avi@scylladb.com">avi@scylladb.com</a>&gt; wrote:<br t=
ype=3D"attribution"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0=
 .8ex;border-left:1px #ccc solid;padding-left:1ex">
 =20
   =20
 =20
  <div text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div class=3D"m_-3260905452705745034moz-cite-prefix">On 02/09/2018 04:0=
7 PM, Marcel F.
      Kr=C3=BCger wrote:<br>
    </div>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div class=3D"gmail_quote">
          <div dir=3D"ltr">Jake Arkinstall &lt;<a href=3D"mailto:jake.arkin=
stall@gmail.com" target=3D"_blank">jake.arkinstall@gmail.com</a>&gt;
            schrieb am Fr., 9. Feb. 2018 um 14:51=C2=A0Uhr:</div>
          <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bord=
er-left:1px #ccc solid;padding-left:1ex">
            <div dir=3D"auto">
              <div dir=3D"auto"><br>
              </div>
            </div>
            <div dir=3D"auto">
              <div dir=3D"auto">That would be nice, but generic is a royal
                pain in the backside in this circumstance. This is not
                something that can be written in the current language
                because it requires interpetation of the strings. How on
                earth that is supposed to generalise to choices of fmt,
                string conversion and concatenation, stringstreams, and
                whatever magical solution we&#39;re waiting on to make
                string manipulation efficient, I have no idea,
                especially in the general situation where the different
                approaches - e.g. to_string and operator&lt;&lt; - are
                not equivalent.</div>
            </div>
          </blockquote>
          <div><br>
          </div>
          <div>Maybe this could be based on user-defined literals:</div>
          <div>If for example `operator&quot;&quot;_sth` accepts more than =
two
            parameters, the expression &quot;abc{def}ghij&quot;_sth could b=
e
            rewritten to `operator&quot;&quot;_sth(&quot;abc&quot;, 3, def,=
 &quot;ghij&quot;, 4)`.</div>
          <div>Then the standard library could include a literal suffix
            based on iostreams and it should be generic enough to be
            supported by most libraries.</div>
          <div><br>
          </div>
        </div>
      </div>
    </blockquote>
    <br>
    I hate myself for suggesting it, but what about code injection?<br>
    <br>
    =C2=A0=C2=A0=C2=A0 constexpr std::injected_code operator&quot;&quot;v(c=
onst char* literal) {
    ... }<br>
    <br>
    The &quot;std::injected_code&quot; return type is a string that gets in=
jected
    into the code, replacing the literal.<br>
    <br>
    This could be abused in so many wonderful ways.<br>
    <br>
    =C2=A0=C2=A0=C2=A0 <br>
  </div>


<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/33eb3ce3-12a5-800d-9c4d-2a362fb139d6%=
40scylladb.com?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank=
">https://groups.google.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/33=
eb3ce3-12a5-800d-<wbr>9c4d-2a362fb139d6%40scylladb.<wbr>com</a>.<br>
</blockquote></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCPvOW5KdxWjbWr3BUPrE9PU9A3nko=
ZKgE687ySzp%2BJ%2BBw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCPv=
OW5KdxWjbWr3BUPrE9PU9A3nkoZKgE687ySzp%2BJ%2BBw%40mail.gmail.com</a>.<br />

--f4f5e808d750a0ac1c0564c9d331--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Fri, 09 Feb 2018 08:38:09 -0800
Raw View
On Friday, 9 February 2018 01:27:03 PST Richard Hodges wrote:
> > That depends on a lot. The cost of a virtual call could easily get to 5=
%
> > total
> time of a conversion, which is non-negligible, if there's no memory
> allocation involved.
>=20
> When no new projects are choosing to use your language, the cost of a cal=
l
> is an utter irrelevance. C++=E2=80=99s problem is not a performance one -=
 it=E2=80=99s an
> adoption one.

Fortunately, we don't have an adoption problem.

--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center



--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/11056799.JelVoZn1UV%40tjmaciei-mobl1.

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Fri, 09 Feb 2018 08:38:59 -0800
Raw View
On Friday, 9 February 2018 05:51:29 PST Jake Arkinstall wrote:
> That would be nice, but generic is a royal pain in the backside in this
> circumstance. This is not something that can be written in the current
> language because it requires interpetation of the strings. How on earth
> that is supposed to generalise to choices of fmt, string conversion and
> concatenation, stringstreams, and whatever magical solution we're waiting
> on to make string manipulation efficient, I have no idea, especially in the
> general situation where the different approaches - e.g. to_string and
> operator<< - are not equivalent.

And that's exactly I feel this proposal has no future.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center



--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/3073671.g2Bv754bdN%40tjmaciei-mobl1.

.


Author: Jake Arkinstall <jake.arkinstall@gmail.com>
Date: Fri, 9 Feb 2018 16:40:32 +0000
Raw View
--001a113d5a72dbb2950564ca2f4f
Content-Type: text/plain; charset="UTF-8"

Okay, so a feature which exists in many languages, with considerably wide
use, cannot possibly be used in C++ because it isn't good enough for us.

This is why we cannot have nice things.

On 9 Feb 2018 16:39, "Thiago Macieira" <thiago@macieira.org> wrote:

> On Friday, 9 February 2018 05:51:29 PST Jake Arkinstall wrote:
> > That would be nice, but generic is a royal pain in the backside in this
> > circumstance. This is not something that can be written in the current
> > language because it requires interpetation of the strings. How on earth
> > that is supposed to generalise to choices of fmt, string conversion and
> > concatenation, stringstreams, and whatever magical solution we're waiting
> > on to make string manipulation efficient, I have no idea, especially in
> the
> > general situation where the different approaches - e.g. to_string and
> > operator<< - are not equivalent.
>
> And that's exactly I feel this proposal has no future.
>
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
>    Software Architect - Intel Open Source Technology Center
>
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit https://groups.google.com/a/
> isocpp.org/d/msgid/std-proposals/3073671.g2Bv754bdN%40tjmaciei-mobl1.
>

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCNhZf8ZP8HSCy-Ua31uggNhJnUz3-iSz8bP8EEph5nTeQ%40mail.gmail.com.

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

<div dir=3D"auto">Okay, so a feature which exists in many languages, with c=
onsiderably wide use, cannot possibly be used in C++ because it isn&#39;t g=
ood enough for us.<div dir=3D"auto"><br></div><div dir=3D"auto">This is why=
 we cannot have nice things.</div></div><div class=3D"gmail_extra"><br><div=
 class=3D"gmail_quote">On 9 Feb 2018 16:39, &quot;Thiago Macieira&quot; &lt=
;<a href=3D"mailto:thiago@macieira.org">thiago@macieira.org</a>&gt; wrote:<=
br type=3D"attribution"><blockquote class=3D"gmail_quote" style=3D"margin:0=
 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Friday, 9 Februar=
y 2018 05:51:29 PST Jake Arkinstall wrote:<br>
&gt; That would be nice, but generic is a royal pain in the backside in thi=
s<br>
&gt; circumstance. This is not something that can be written in the current=
<br>
&gt; language because it requires interpetation of the strings. How on eart=
h<br>
&gt; that is supposed to generalise to choices of fmt, string conversion an=
d<br>
&gt; concatenation, stringstreams, and whatever magical solution we&#39;re =
waiting<br>
&gt; on to make string manipulation efficient, I have no idea, especially i=
n the<br>
&gt; general situation where the different approaches - e.g. to_string and<=
br>
&gt; operator&lt;&lt; - are not equivalent.<br>
<br>
And that&#39;s exactly I feel this proposal has no future.<br>
<br>
--<br>
Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" rel=3D"noref=
errer" target=3D"_blank">macieira.info</a> - thiago (AT) <a href=3D"http://=
kde.org" rel=3D"noreferrer" target=3D"_blank">kde.org</a><br>
=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center<br>
<br>
<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%2Bunsubscribe@isocpp.org">std-propo=
sals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/3073671.g2Bv754bdN%40tjmaciei-mobl1" =
rel=3D"noreferrer" target=3D"_blank">https://groups.google.com/a/<wbr>isocp=
p.org/d/msgid/std-<wbr>proposals/3073671.g2Bv754bdN%<wbr>40tjmaciei-mobl1</=
a>.<br>
</blockquote></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCNhZf8ZP8HSCy-Ua31uggNhJnUz3-=
iSz8bP8EEph5nTeQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCNhZf8Z=
P8HSCy-Ua31uggNhJnUz3-iSz8bP8EEph5nTeQ%40mail.gmail.com</a>.<br />

--001a113d5a72dbb2950564ca2f4f--

.


Author: Ren Industries <renindustries@gmail.com>
Date: Fri, 9 Feb 2018 13:11:49 -0500
Raw View
--f403045c548050ea250564cb76c4
Content-Type: text/plain; charset="UTF-8"

On Fri, Feb 9, 2018 at 11:40 AM, Jake Arkinstall <jake.arkinstall@gmail.com>
wrote:

> Okay, so a feature which exists in many languages, with considerably wide
> use, cannot possibly be used in C++ because it isn't good enough for us.
>
> This is why we cannot have nice things.
>

Or because what you are proposing is not a nice thing, as several
knowledgable people have told you.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAMD6iD_9wmiL3_kyah7YFVHuXiXw4oT8jyA8NGWvZjfSPuVJcQ%40mail.gmail.com.

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On F=
ri, Feb 9, 2018 at 11:40 AM, Jake Arkinstall <span dir=3D"ltr">&lt;<a href=
=3D"mailto:jake.arkinstall@gmail.com" target=3D"_blank">jake.arkinstall@gma=
il.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"=
margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"=
auto">Okay, so a feature which exists in many languages, with considerably =
wide use, cannot possibly be used in C++ because it isn&#39;t good enough f=
or us.<div dir=3D"auto"><br></div><div dir=3D"auto">This is why we cannot h=
ave nice things.</div></div></blockquote><div><br></div><div>Or because wha=
t you are proposing is not a nice thing, as several knowledgable people hav=
e told you.=C2=A0</div></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAMD6iD_9wmiL3_kyah7YFVHuXiXw4oT8jyA8=
NGWvZjfSPuVJcQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAMD6iD_9wmiL3_ky=
ah7YFVHuXiXw4oT8jyA8NGWvZjfSPuVJcQ%40mail.gmail.com</a>.<br />

--f403045c548050ea250564cb76c4--

.


Author: Richard Hodges <hodges.r@gmail.com>
Date: Fri, 9 Feb 2018 18:35:23 +0000
Raw View
--001a114197d29e35820564cbcaf2
Content-Type: text/plain; charset="UTF-8"

> Or because what you are proposing is not a nice thing, as several
knowledgable people have told you.

Or alternatively,

It would be a nice thing, and the usual naysayers seem still to be trying
to prevent the language from becoming easy to use, portable and powerful.

Why they would seek to do this is a mystery to me. Perhaps their use case
for this language, and their vision of how it is used is a narrow one?

Honestly, since when was the easy printing of debug information "not a nice
thing?"



On 9 February 2018 at 18:11, Ren Industries <renindustries@gmail.com> wrote:

> On Fri, Feb 9, 2018 at 11:40 AM, Jake Arkinstall <
> jake.arkinstall@gmail.com> wrote:
>
>> Okay, so a feature which exists in many languages, with considerably wide
>> use, cannot possibly be used in C++ because it isn't good enough for us.
>>
>> This is why we cannot have nice things.
>>
>
> Or because what you are proposing is not a nice thing, as several
> knowledgable people have told you.
>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit https://groups.google.com/a/
> isocpp.org/d/msgid/std-proposals/CAMD6iD_9wmiL3_
> kyah7YFVHuXiXw4oT8jyA8NGWvZjfSPuVJcQ%40mail.gmail.com
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAMD6iD_9wmiL3_kyah7YFVHuXiXw4oT8jyA8NGWvZjfSPuVJcQ%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3hY%2BzDmVb-4eyRdTH9%2Bp8GhDB7WTnFM-RTfpjkYt4rxAPQ%40mail.gmail.com.

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

<div dir=3D"ltr">&gt;=C2=A0<span style=3D"color:rgb(34,34,34);font-family:a=
rial,sans-serif;font-size:12.8px;font-style:normal;font-variant-ligatures:n=
ormal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-a=
lign:start;text-indent:0px;text-transform:none;white-space:normal;word-spac=
ing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;tex=
t-decoration-color:initial;float:none;display:inline">Or because what you a=
re proposing is not a nice thing, as several knowledgable people have told =
you.</span><div><span style=3D"color:rgb(34,34,34);font-family:arial,sans-s=
erif;font-size:12.8px;font-style:normal;font-variant-ligatures:normal;font-=
variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;=
text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;bac=
kground-color:rgb(255,255,255);text-decoration-style:initial;text-decoratio=
n-color:initial;float:none;display:inline"><br></span></div><div><span styl=
e=3D"color:rgb(34,34,34);font-family:arial,sans-serif;font-size:12.8px;font=
-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-w=
eight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-trans=
form:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,=
255);text-decoration-style:initial;text-decoration-color:initial;float:none=
;display:inline">Or alternatively,</span></div><div><span style=3D"color:rg=
b(34,34,34);font-family:arial,sans-serif;font-size:12.8px;font-style:normal=
;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;let=
ter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;whi=
te-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-dec=
oration-style:initial;text-decoration-color:initial;float:none;display:inli=
ne"><br></span></div><div><span style=3D"color:rgb(34,34,34);font-family:ar=
ial,sans-serif;font-size:12.8px;font-style:normal;font-variant-ligatures:no=
rmal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-al=
ign:start;text-indent:0px;text-transform:none;white-space:normal;word-spaci=
ng:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text=
-decoration-color:initial;float:none;display:inline">It would be a nice thi=
ng, and the usual naysayers seem still to be trying to prevent the language=
 from becoming easy to use, portable and powerful.</span></div><div><span s=
tyle=3D"color:rgb(34,34,34);font-family:arial,sans-serif;font-size:12.8px;f=
ont-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;fon=
t-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-tr=
ansform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,2=
55,255);text-decoration-style:initial;text-decoration-color:initial;float:n=
one;display:inline"><br></span></div><div><span style=3D"color:rgb(34,34,34=
);font-family:arial,sans-serif;font-size:12.8px;font-style:normal;font-vari=
ant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacin=
g:normal;text-align:start;text-indent:0px;text-transform:none;white-space:n=
ormal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-st=
yle:initial;text-decoration-color:initial;float:none;display:inline">Why th=
ey would seek to do this is a mystery to me. Perhaps their use case for thi=
s language, and their vision of how it is used is a narrow one?</span></div=
><div><br></div><div>Honestly, since when was the easy printing of debug in=
formation &quot;not a nice thing?&quot;</div><div><br></div><div><span styl=
e=3D"color:rgb(34,34,34);font-family:arial,sans-serif;font-size:12.8px;font=
-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-w=
eight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-trans=
form:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,=
255);text-decoration-style:initial;text-decoration-color:initial;float:none=
;display:inline"><br></span></div></div><div class=3D"gmail_extra"><br><div=
 class=3D"gmail_quote">On 9 February 2018 at 18:11, Ren Industries <span di=
r=3D"ltr">&lt;<a href=3D"mailto:renindustries@gmail.com" target=3D"_blank">=
renindustries@gmail.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail=
_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:=
1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"=
><span class=3D"">On Fri, Feb 9, 2018 at 11:40 AM, Jake Arkinstall <span di=
r=3D"ltr">&lt;<a href=3D"mailto:jake.arkinstall@gmail.com" target=3D"_blank=
">jake.arkinstall@gmail.com</a>&gt;</span> wrote:<br><blockquote class=3D"g=
mail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"auto">Okay, so a feature which exists in many language=
s, with considerably wide use, cannot possibly be used in C++ because it is=
n&#39;t good enough for us.<div dir=3D"auto"><br></div><div dir=3D"auto">Th=
is is why we cannot have nice things.</div></div></blockquote><div><br></di=
v></span><div>Or because what you are proposing is not a nice thing, as sev=
eral knowledgable people have told you.=C2=A0</div></div></div></div><span =
class=3D"">

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&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" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></span>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAMD6iD_9wmiL3_kyah7YFVHuXiXw4oT8jyA8=
NGWvZjfSPuVJcQ%40mail.gmail.com?utm_medium=3Demail&amp;utm_source=3Dfooter"=
 target=3D"_blank">https://groups.google.com/a/<wbr>isocpp.org/d/msgid/std-=
<wbr>proposals/CAMD6iD_9wmiL3_<wbr>kyah7YFVHuXiXw4oT8jyA8NGWvZjfS<wbr>PuVJc=
Q%40mail.gmail.com</a>.<br>
</blockquote></div><br></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CALvx3hY%2BzDmVb-4eyRdTH9%2Bp8GhDB7WT=
nFM-RTfpjkYt4rxAPQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3hY%2BzD=
mVb-4eyRdTH9%2Bp8GhDB7WTnFM-RTfpjkYt4rxAPQ%40mail.gmail.com</a>.<br />

--001a114197d29e35820564cbcaf2--

.


Author: Ren Industries <renindustries@gmail.com>
Date: Fri, 9 Feb 2018 13:38:26 -0500
Raw View
--089e08210da87fec0a0564cbd503
Content-Type: text/plain; charset="UTF-8"

On Fri, Feb 9, 2018 at 1:35 PM, Richard Hodges <hodges.r@gmail.com> wrote:

> > Or because what you are proposing is not a nice thing, as several
> knowledgable people have told you.
>
> Or alternatively,
>
> It would be a nice thing, and the usual naysayers seem still to be trying
> to prevent the language from becoming easy to use, portable and powerful.
>
> Why they would seek to do this is a mystery to me. Perhaps their use case
> for this language, and their vision of how it is used is a narrow one?
>
> Honestly, since when was the easy printing of debug information "not a
> nice thing?"
>
>
If it costs too much to do, it's not a nice thing. The fact you consider it
easier to use, portable, and more powerful does not make it so.
It's a pretty big mystery to me why anyone would want something built on
iostreams in 2018.

Honestly, since when is making one of the worst parts of the language MORE
vital a nice thing?

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAMD6iD9aT26x8GQHnQL%2Bkuj3Rq8fVQSfYYFtvTnFidkf6jU_ag%40mail.gmail.com.

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On F=
ri, Feb 9, 2018 at 1:35 PM, Richard Hodges <span dir=3D"ltr">&lt;<a href=3D=
"mailto:hodges.r@gmail.com" target=3D"_blank">hodges.r@gmail.com</a>&gt;</s=
pan> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex=
;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><span class=
=3D"">&gt;=C2=A0<span style=3D"color:rgb(34,34,34);font-family:arial,sans-s=
erif;font-size:12.8px;font-style:normal;font-variant-ligatures:normal;font-=
variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;=
text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;bac=
kground-color:rgb(255,255,255);text-decoration-style:initial;text-decoratio=
n-color:initial;float:none;display:inline">Or because what you are proposin=
g is not a nice thing, as several knowledgable people have told you.</span>=
<div><span style=3D"color:rgb(34,34,34);font-family:arial,sans-serif;font-s=
ize:12.8px;font-style:normal;font-variant-ligatures:normal;font-variant-cap=
s:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent=
:0px;text-transform:none;white-space:normal;word-spacing:0px;background-col=
or:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:ini=
tial;float:none;display:inline"><br></span></div></span><div><span style=3D=
"color:rgb(34,34,34);font-family:arial,sans-serif;font-size:12.8px;font-sty=
le:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weigh=
t:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform=
:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255)=
;text-decoration-style:initial;text-decoration-color:initial;float:none;dis=
play:inline">Or alternatively,</span></div><div><span style=3D"color:rgb(34=
,34,34);font-family:arial,sans-serif;font-size:12.8px;font-style:normal;fon=
t-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-=
spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-s=
pace:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decorat=
ion-style:initial;text-decoration-color:initial;float:none;display:inline">=
<br></span></div><div><span style=3D"color:rgb(34,34,34);font-family:arial,=
sans-serif;font-size:12.8px;font-style:normal;font-variant-ligatures:normal=
;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:=
start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0=
px;background-color:rgb(255,255,255);text-decoration-style:initial;text-dec=
oration-color:initial;float:none;display:inline">It would be a nice thing, =
and the usual naysayers seem still to be trying to prevent the language fro=
m becoming easy to use, portable and powerful.</span></div><div><span style=
=3D"color:rgb(34,34,34);font-family:arial,sans-serif;font-size:12.8px;font-=
style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-we=
ight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transf=
orm:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,2=
55);text-decoration-style:initial;text-decoration-color:initial;float:none;=
display:inline"><br></span></div><div><span style=3D"color:rgb(34,34,34);fo=
nt-family:arial,sans-serif;font-size:12.8px;font-style:normal;font-variant-=
ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:no=
rmal;text-align:start;text-indent:0px;text-transform:none;white-space:norma=
l;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:=
initial;text-decoration-color:initial;float:none;display:inline">Why they w=
ould seek to do this is a mystery to me. Perhaps their use case for this la=
nguage, and their vision of how it is used is a narrow one?</span></div><di=
v><br></div><div>Honestly, since when was the easy printing of debug inform=
ation &quot;not a nice thing?&quot;</div><div><br></div></div></blockquote>=
<div><br></div><div>If it costs too much to do, it&#39;s not a nice thing. =
The fact you consider it easier to use, portable, and more powerful does no=
t make it so.</div><div>It&#39;s a pretty big mystery to me why anyone woul=
d want something built on iostreams in 2018.=C2=A0</div><div><br></div><div=
>Honestly, since when is making one of the worst parts of the language MORE=
 vital a nice thing?</div></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAMD6iD9aT26x8GQHnQL%2Bkuj3Rq8fVQSfYY=
FtvTnFidkf6jU_ag%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAMD6iD9aT26x8G=
QHnQL%2Bkuj3Rq8fVQSfYYFtvTnFidkf6jU_ag%40mail.gmail.com</a>.<br />

--089e08210da87fec0a0564cbd503--

.


Author: Richard Hodges <hodges.r@gmail.com>
Date: Fri, 9 Feb 2018 18:43:41 +0000
Raw View
--Apple-Mail=_7CFBF7B3-22CC-44F4-8BB9-1339ECBFA177
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="UTF-8"

> It's a pretty big mystery to me why anyone would want something built on =
iostreams in 2018.=20

With ADL customisation points the default behaviour could be easily changed=
..

No-one is advocating cementing in iostreams, merely using it for convenienc=
e.

Please kindly read my (presumably poorly worded) post again.

R


> On 9 Feb 2018, at 18:38, Ren Industries <renindustries@gmail.com> wrote:
>=20
> On Fri, Feb 9, 2018 at 1:35 PM, Richard Hodges <hodges.r@gmail.com <mailt=
o:hodges.r@gmail.com>> wrote:
> > Or because what you are proposing is not a nice thing, as several knowl=
edgable people have told you.
>=20
> Or alternatively,
>=20
> It would be a nice thing, and the usual naysayers seem still to be trying=
 to prevent the language from becoming easy to use, portable and powerful.
>=20
> Why they would seek to do this is a mystery to me. Perhaps their use case=
 for this language, and their vision of how it is used is a narrow one?
>=20
> Honestly, since when was the easy printing of debug information "not a ni=
ce thing?"
>=20
>=20
> If it costs too much to do, it's not a nice thing. The fact you consider =
it easier to use, portable, and more powerful does not make it so.
> It's a pretty big mystery to me why anyone would want something built on =
iostreams in 2018.=20
>=20
> Honestly, since when is making one of the worst parts of the language MOR=
E vital a nice thing?
>=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=
 email to std-proposals+unsubscribe@isocpp.org <mailto:std-proposals+unsubs=
cribe@isocpp.org>.
> To post to this group, send email to std-proposals@isocpp.org <mailto:std=
-proposals@isocpp.org>.
> To view this discussion on the web visit https://groups.google.com/a/isoc=
pp.org/d/msgid/std-proposals/CAMD6iD9aT26x8GQHnQL%2Bkuj3Rq8fVQSfYYFtvTnFidk=
f6jU_ag%40mail.gmail.com <https://groups.google.com/a/isocpp.org/d/msgid/st=
d-proposals/CAMD6iD9aT26x8GQHnQL%2Bkuj3Rq8fVQSfYYFtvTnFidkf6jU_ag%40mail.gm=
ail.com?utm_medium=3Demail&utm_source=3Dfooter>.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/25CCF885-86AD-4D51-8F5C-C46376D34DE0%40gmail.com=
..

--Apple-Mail=_7CFBF7B3-22CC-44F4-8BB9-1339ECBFA177
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset="UTF-8"

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dus-ascii"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode=
: space; -webkit-line-break: after-white-space;" class=3D""><div class=3D""=
>&gt; It's a pretty big mystery to me why anyone would want something built=
 on iostreams in 2018.&nbsp;</div><div class=3D""><br class=3D""></div><div=
 class=3D"">With ADL customisation points the default behaviour could be ea=
sily changed.</div><div class=3D""><br class=3D""></div><div class=3D"">No-=
one is advocating cementing in iostreams, merely using it for convenience.<=
/div><div class=3D""><br class=3D""></div><div class=3D"">Please kindly rea=
d my (presumably poorly worded) post again.</div><div class=3D""><br class=
=3D""></div><div class=3D"">R</div><div class=3D""><br class=3D""></div><br=
 class=3D""><div><blockquote type=3D"cite" class=3D""><div class=3D"">On 9 =
Feb 2018, at 18:38, Ren Industries &lt;<a href=3D"mailto:renindustries@gmai=
l.com" class=3D"">renindustries@gmail.com</a>&gt; wrote:</div><br class=3D"=
Apple-interchange-newline"><div class=3D""><div dir=3D"ltr" class=3D""><div=
 class=3D"gmail_extra"><div class=3D"gmail_quote">On Fri, Feb 9, 2018 at 1:=
35 PM, Richard Hodges <span dir=3D"ltr" class=3D"">&lt;<a href=3D"mailto:ho=
dges.r@gmail.com" target=3D"_blank" class=3D"">hodges.r@gmail.com</a>&gt;</=
span> wrote:<br class=3D""><blockquote class=3D"gmail_quote" style=3D"margi=
n:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr" =
class=3D""><span class=3D"">&gt;&nbsp;<span style=3D"color:rgb(34,34,34);fo=
nt-family:arial,sans-serif;font-size:12.8px;font-style:normal;font-variant-=
ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:no=
rmal;text-align:start;text-indent:0px;text-transform:none;white-space:norma=
l;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:=
initial;text-decoration-color:initial;float:none;display:inline" class=3D""=
>Or because what you are proposing is not a nice thing, as several knowledg=
able people have told you.</span><div class=3D""><span style=3D"color:rgb(3=
4,34,34);font-family:arial,sans-serif;font-size:12.8px;font-style:normal;fo=
nt-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter=
-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-=
space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decora=
tion-style:initial;text-decoration-color:initial;float:none;display:inline"=
 class=3D""><br class=3D""></span></div></span><div class=3D""><span style=
=3D"color:rgb(34,34,34);font-family:arial,sans-serif;font-size:12.8px;font-=
style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-we=
ight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transf=
orm:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,2=
55);text-decoration-style:initial;text-decoration-color:initial;float:none;=
display:inline" class=3D"">Or alternatively,</span></div><div class=3D""><s=
pan style=3D"color:rgb(34,34,34);font-family:arial,sans-serif;font-size:12.=
8px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:norma=
l;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;te=
xt-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(=
255,255,255);text-decoration-style:initial;text-decoration-color:initial;fl=
oat:none;display:inline" class=3D""><br class=3D""></span></div><div class=
=3D""><span style=3D"color:rgb(34,34,34);font-family:arial,sans-serif;font-=
size:12.8px;font-style:normal;font-variant-ligatures:normal;font-variant-ca=
ps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-inden=
t:0px;text-transform:none;white-space:normal;word-spacing:0px;background-co=
lor:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:in=
itial;float:none;display:inline" class=3D"">It would be a nice thing, and t=
he usual naysayers seem still to be trying to prevent the language from bec=
oming easy to use, portable and powerful.</span></div><div class=3D""><span=
 style=3D"color:rgb(34,34,34);font-family:arial,sans-serif;font-size:12.8px=
;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;f=
ont-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-=
transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255=
,255,255);text-decoration-style:initial;text-decoration-color:initial;float=
:none;display:inline" class=3D""><br class=3D""></span></div><div class=3D"=
"><span style=3D"color:rgb(34,34,34);font-family:arial,sans-serif;font-size=
:12.8px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:n=
ormal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0p=
x;text-transform:none;white-space:normal;word-spacing:0px;background-color:=
rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initia=
l;float:none;display:inline" class=3D"">Why they would seek to do this is a=
 mystery to me. Perhaps their use case for this language, and their vision =
of how it is used is a narrow one?</span></div><div class=3D""><br class=3D=
""></div><div class=3D"">Honestly, since when was the easy printing of debu=
g information "not a nice thing?"</div><div class=3D""><br class=3D""></div=
></div></blockquote><div class=3D""><br class=3D""></div><div class=3D"">If=
 it costs too much to do, it's not a nice thing. The fact you consider it e=
asier to use, portable, and more powerful does not make it so.</div><div cl=
ass=3D"">It's a pretty big mystery to me why anyone would want something bu=
ilt on iostreams in 2018.&nbsp;</div><div class=3D""><br class=3D""></div><=
div class=3D"">Honestly, since when is making one of the worst parts of the=
 language MORE vital a nice thing?</div></div></div></div><div class=3D""><=
br class=3D"webkit-block-placeholder"></div>

-- <br class=3D"">
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.<br class=3D"">
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" class=3D"">=
std-proposals+unsubscribe@isocpp.org</a>.<br class=3D"">
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" class=3D"">std-proposals@isocpp.org</a>.<br class=3D"">
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAMD6iD9aT26x8GQHnQL%2Bkuj3Rq8fVQSfYY=
FtvTnFidkf6jU_ag%40mail.gmail.com?utm_medium=3Demail&amp;utm_source=3Dfoote=
r" class=3D"">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/=
CAMD6iD9aT26x8GQHnQL%2Bkuj3Rq8fVQSfYYFtvTnFidkf6jU_ag%40mail.gmail.com</a>.=
<br class=3D"">
</div></blockquote></div><br class=3D""></body></html>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/25CCF885-86AD-4D51-8F5C-C46376D34DE0%=
40gmail.com?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/25CCF885-86AD-4D51-8F5C-C46376D34DE0%=
40gmail.com</a>.<br />

--Apple-Mail=_7CFBF7B3-22CC-44F4-8BB9-1339ECBFA177--

.


Author: inkwizytoryankes@gmail.com
Date: Fri, 9 Feb 2018 10:47:35 -0800 (PST)
Raw View
------=_Part_5165_1945678765.1518202055226
Content-Type: multipart/alternative;
 boundary="----=_Part_5166_375610758.1518202055226"

------=_Part_5166_375610758.1518202055226
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



On Friday, February 9, 2018 at 3:07:32 PM UTC+1, Marcel Kr=C3=BCger wrote:
>
> Jake Arkinstall <jake.ar...@gmail.com <javascript:>> schrieb am Fr., 9.=
=20
> Feb. 2018 um 14:51 Uhr:
>
>>
>> That would be nice, but generic is a royal pain in the backside in this=
=20
>> circumstance. This is not something that can be written in the current=
=20
>> language because it requires interpetation of the strings. How on earth=
=20
>> that is supposed to generalise to choices of fmt, string conversion and=
=20
>> concatenation, stringstreams, and whatever magical solution we're waitin=
g=20
>> on to make string manipulation efficient, I have no idea, especially in =
the=20
>> general situation where the different approaches - e.g. to_string and=20
>> operator<< - are not equivalent.
>>
>
> Maybe this could be based on user-defined literals:
> If for example `operator""_sth` accepts more than two parameters, the=20
> expression "abc{def}ghij"_sth could be rewritten to `operator""_sth("abc"=
,=20
> 3, def, "ghij", 4)`.
> Then the standard library could include a literal suffix based on=20
> iostreams and it should be generic enough to be supported by most librari=
es.
>
> Best regards
> Marcel Kr=C3=BCger
>
=20
When reflection hit we can have this syntax:
auto f =3D "test {0.a} test {0.b} test"_str;
auto r1 =3D f(ArgType{ .a =3D 4, .b =3D 3 }); //"test 4 test 3 test"
auto r2 =3D f(OtherType{ .a =3D "zzz", .b =3D 42f, .c =3D true }); //"test =
zzz test=20
42.00 test"
auto r3 =3D f(5); //compile error! `int` do not have `a`

This is only matter of finding member address using compile time string.


--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/e71cfa25-b8f8-472b-b887-fdafd908145b%40isocpp.or=
g.

------=_Part_5166_375610758.1518202055226
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Friday, February 9, 2018 at 3:07:32 PM UTC+1, M=
arcel Kr=C3=BCger wrote:<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div d=
ir=3D"ltr"><div class=3D"gmail_quote"><div dir=3D"ltr">Jake Arkinstall &lt;=
<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"gYIuhJKF=
CQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#39;;ret=
urn true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;">jake.=
ar...@gmail.com</a>&gt; schrieb am Fr., 9. Feb. 2018 um 14:51=C2=A0Uhr:</di=
v><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:=
1px #ccc solid;padding-left:1ex"><div dir=3D"auto"><div dir=3D"auto"><br></=
div></div><div dir=3D"auto"><div dir=3D"auto">That would be nice, but gener=
ic is a royal pain in the backside in this circumstance. This is not someth=
ing that can be written in the current language because it requires interpe=
tation of the strings. How on earth that is supposed to generalise to choic=
es of fmt, string conversion and concatenation, stringstreams, and whatever=
 magical solution we&#39;re waiting on to make string manipulation efficien=
t, I have no idea, especially in the general situation where the different =
approaches - e.g. to_string and operator&lt;&lt; - are not equivalent.</div=
></div></blockquote><div><br></div><div>Maybe this could be based on user-d=
efined literals:</div><div>If for example `operator&quot;&quot;_sth` accept=
s more than two parameters, the expression &quot;abc{def}ghij&quot;_sth cou=
ld be rewritten to `operator&quot;&quot;_sth(&quot;abc&quot;, 3, def, &quot=
;ghij&quot;, 4)`.</div><div>Then the standard library could include a liter=
al suffix based on iostreams and it should be generic enough to be supporte=
d by most libraries.</div><div><br></div><div>Best regards</div><div>Marcel=
 Kr=C3=BCger</div></div></div></blockquote><div>=C2=A0<br>When reflection h=
it we can have this syntax:<br><div style=3D"background-color: rgb(250, 250=
, 250); border-color: rgb(187, 187, 187); border-style: solid; border-width=
: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"pre=
ttyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=
=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"st=
yled-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-pretti=
fy"> </span><span style=3D"color: #080;" class=3D"styled-by-prettify">&quot=
;test {0.a} test {0.b} test&quot;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">_str</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> r1=
 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> f</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"c=
olor: #606;" class=3D"styled-by-prettify">ArgType</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">a </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #066;" class=3D"styled-by-prettify">4</span><spa=
n 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">b </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: #066;" class=3D"styled-by-prett=
ify">3</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">});</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">//&quot;test 4 test 3 test&q=
uot;</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"> r2 </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> f</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #606;" cl=
ass=3D"styled-by-prettify">OtherType</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">a=
 </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 st=
yle=3D"color: #080;" class=3D"styled-by-prettify">&quot;zzz&quot;</span><sp=
an 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">b </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: #066;" class=3D"styled-by-prett=
ify">42f</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">c </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">true</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">});</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">//&quot=
;test zzz test 42.00 test&quot;</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"> r3 </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> f</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><spa=
n style=3D"color: #066;" class=3D"styled-by-prettify">5</span><span style=
=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">//compile error! `int` do not have `a`</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div>=
</code></div><br>This is only matter of finding member address using compil=
e time string.<br><br><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/e71cfa25-b8f8-472b-b887-fdafd908145b%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/e71cfa25-b8f8-472b-b887-fdafd908145b=
%40isocpp.org</a>.<br />

------=_Part_5166_375610758.1518202055226--

------=_Part_5165_1945678765.1518202055226--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Fri, 09 Feb 2018 10:55:47 -0800
Raw View
On Friday, 9 February 2018 10:43:41 PST Richard Hodges wrote:
> With ADL customisation points the default behaviour could be easily changed.
>
> No-one is advocating cementing in iostreams, merely using it for
> convenience.
>
> Please kindly read my (presumably poorly worded) post again.

Then please reword it and talk about how it would work with the not-yet-
existent std2::iostreams and QTextStream.

I'm not saying your idea has no merit. I said that the proposal, as it was
posted, has no future. Improve it.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center



--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/4890431.TR9UepuQra%40tjmaciei-mobl1.

.


Author: Hyman Rosen <hyman.rosen@gmail.com>
Date: Fri, 9 Feb 2018 13:55:24 -0500
Raw View
--001a1143b2f66c11440564cc138f
Content-Type: text/plain; charset="UTF-8"

On Fri, Feb 9, 2018 at 1:38 PM, Ren Industries <renindustries@gmail.com>
wrote:
>
> It's a pretty big mystery to me why anyone would want something built on
> iostreams in 2018.
> Honestly, since when is making one of the worst parts of the language MORE
> vital a nice thing?
>

What's wrong with iostreams?  Is it that virtual functions aren't good
enough for optimizationists?

From more recent C++  standardization, we have
    { std::vector<int>         v{3}; } // v.size() == 1
    { std::vector<std::string> v{3}; } // v.size() == 3
    { std::vector<int>         v{0}; } // v.size() == 1
    { std::vector<std::string> v{0}; } // undefined behavior

That does not inspire the greatest confidence that new designs emerging
from the
standardization process are going to be any better than what we already
have.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAHSYqdYebVsQT3vbK%3DmV-D0qmcYTWbboTqkCWO-r%3D5n3DyzrCQ%40mail.gmail.com.

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On F=
ri, Feb 9, 2018 at 1:38 PM, Ren Industries <span dir=3D"ltr">&lt;<a href=3D=
"mailto:renindustries@gmail.com" target=3D"_blank">renindustries@gmail.com<=
/a>&gt;</span> wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0 0 =
0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div c=
lass=3D"gmail_extra"><div class=3D"gmail_quote"><div>It&#39;s a pretty big =
mystery to me why anyone would want something built on iostreams in 2018.=
=C2=A0</div><div>Honestly, since when is making one of the worst parts of t=
he language MORE vital a nice thing?</div></div></div></div></blockquote><d=
iv><br>What&#39;s wrong with iostreams?=C2=A0 Is it that virtual functions =
aren&#39;t good enough for optimizationists?<br><br>From more recent C++=C2=
=A0 standardization, we have<br><font face=3D"monospace, monospace">=C2=A0 =
=C2=A0 { std::vector&lt;int&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0v{3}; } //=
 v.size() =3D=3D 1<br>=C2=A0 =C2=A0 { std::vector&lt;std::string&gt; v{3}; =
} // v.size() =3D=3D 3

<br style=3D"color:rgb(34,34,34);font-size:small;font-style:normal;font-var=
iant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spaci=
ng:normal;text-align:start;text-indent:0px;text-transform:none;white-space:=
normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-s=
tyle:initial;text-decoration-color:initial"><span style=3D"color:rgb(34,34,=
34);font-size:small;font-style:normal;font-variant-ligatures:normal;font-va=
riant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;te=
xt-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;backg=
round-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-=
color:initial;float:none;display:inline">=C2=A0 =C2=A0 { std::vector&lt;int=
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0v{0}; } // v.size() =3D=3D 1</span><b=
r style=3D"color:rgb(34,34,34);font-size:small;font-style:normal;font-varia=
nt-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing=
:normal;text-align:start;text-indent:0px;text-transform:none;white-space:no=
rmal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-sty=
le:initial;text-decoration-color:initial"></font><span style=3D"color:rgb(3=
4,34,34);font-size:small;font-style:normal;font-variant-ligatures:normal;fo=
nt-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:sta=
rt;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;=
background-color:rgb(255,255,255);text-decoration-style:initial;text-decora=
tion-color:initial;float:none;display:inline"><font face=3D"monospace, mono=
space">=C2=A0 =C2=A0 { std::vector&lt;std::string&gt; v{0}; } // undefined =
behavior</font><br><br>That does not inspire the greatest confidence that n=
ew designs emerging from the<br>standardization process are going to be any=
 better than what we already have.</span></div></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAHSYqdYebVsQT3vbK%3DmV-D0qmcYTWbboTq=
kCWO-r%3D5n3DyzrCQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAHSYqdYebVsQ=
T3vbK%3DmV-D0qmcYTWbboTqkCWO-r%3D5n3DyzrCQ%40mail.gmail.com</a>.<br />

--001a1143b2f66c11440564cc138f--

.


Author: inkwizytoryankes@gmail.com
Date: Fri, 9 Feb 2018 11:04:23 -0800 (PST)
Raw View
------=_Part_5433_1269882007.1518203063962
Content-Type: multipart/alternative;
 boundary="----=_Part_5434_1922072075.1518203063962"

------=_Part_5434_1922072075.1518203063962
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



On Friday, February 9, 2018 at 3:07:32 PM UTC+1, Marcel Kr=C3=BCger wrote:
>
> Jake Arkinstall <jake.ar...@gmail.com <javascript:>> schrieb am Fr., 9.=
=20
> Feb. 2018 um 14:51 Uhr:
>
>>
>> That would be nice, but generic is a royal pain in the backside in this=
=20
>> circumstance. This is not something that can be written in the current=
=20
>> language because it requires interpetation of the strings. How on earth=
=20
>> that is supposed to generalise to choices of fmt, string conversion and=
=20
>> concatenation, stringstreams, and whatever magical solution we're waitin=
g=20
>> on to make string manipulation efficient, I have no idea, especially in =
the=20
>> general situation where the different approaches - e.g. to_string and=20
>> operator<< - are not equivalent.
>>
>
> Maybe this could be based on user-defined literals:
> If for example `operator""_sth` accepts more than two parameters, the=20
> expression "abc{def}ghij"_sth could be rewritten to `operator""_sth("abc"=
,=20
> 3, def, "ghij", 4)`.
> Then the standard library could include a literal suffix based on=20
> iostreams and it should be generic enough to be supported by most librari=
es.
>
> Best regards
> Marcel Kr=C3=BCger
>

Another thought, for prior art we could look on JavaScript:=20
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_=
literals=20
It have very similar approach.
Btw I think this operator arguments should be different:
template<typename... Part>
auto operator ""_sth(Part... part) { return part.str() + ...; };
This will allow some compile magic to creating constexpr regexp that could=
=20
use this interpolation.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/93445aa1-0df1-40dd-bfa3-a79c33f63878%40isocpp.or=
g.

------=_Part_5434_1922072075.1518203063962
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Friday, February 9, 2018 at 3:07:32 PM UTC+1, M=
arcel Kr=C3=BCger wrote:<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div d=
ir=3D"ltr"><div class=3D"gmail_quote"><div dir=3D"ltr">Jake Arkinstall &lt;=
<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"gYIuhJKF=
CQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#39;;ret=
urn true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;">jake.=
ar...@gmail.com</a>&gt; schrieb am Fr., 9. Feb. 2018 um 14:51=C2=A0Uhr:</di=
v><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:=
1px #ccc solid;padding-left:1ex"><div dir=3D"auto"><div dir=3D"auto"><br></=
div></div><div dir=3D"auto"><div dir=3D"auto">That would be nice, but gener=
ic is a royal pain in the backside in this circumstance. This is not someth=
ing that can be written in the current language because it requires interpe=
tation of the strings. How on earth that is supposed to generalise to choic=
es of fmt, string conversion and concatenation, stringstreams, and whatever=
 magical solution we&#39;re waiting on to make string manipulation efficien=
t, I have no idea, especially in the general situation where the different =
approaches - e.g. to_string and operator&lt;&lt; - are not equivalent.</div=
></div></blockquote><div><br></div><div>Maybe this could be based on user-d=
efined literals:</div><div>If for example `operator&quot;&quot;_sth` accept=
s more than two parameters, the expression &quot;abc{def}ghij&quot;_sth cou=
ld be rewritten to `operator&quot;&quot;_sth(&quot;abc&quot;, 3, def, &quot=
;ghij&quot;, 4)`.</div><div>Then the standard library could include a liter=
al suffix based on iostreams and it should be generic enough to be supporte=
d by most libraries.</div><div><br></div><div>Best regards</div><div>Marcel=
 Kr=C3=BCger</div></div></div></blockquote><div><br>Another thought, for pr=
ior art we could look on JavaScript: https://developer.mozilla.org/en-US/do=
cs/Web/JavaScript/Reference/Template_literals It have very similar approach=
..<br>Btw I think this operator arguments should be different:<br><div style=
=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187);=
 border-style: solid; border-width: 1px; overflow-wrap: break-word;" class=
=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subprettyprint">=
<span style=3D"color: #008;" class=3D"styled-by-prettify">template</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">typename</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">...</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606=
;" class=3D"styled-by-prettify">Part</span><span style=3D"color: #660;" cla=
ss=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">auto</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">o=
perator</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;&quot;=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">_sth</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span st=
yle=3D"color: #606;" class=3D"styled-by-prettify">Part</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">...</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> part</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"style=
d-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">ret=
urn</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> part</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">.</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">str</span><span style=
=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: #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-b=
y-prettify">...;</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></span>=
</div></code></div>This will allow some compile magic to creating constexpr=
 regexp that could use this interpolation.<br><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/93445aa1-0df1-40dd-bfa3-a79c33f63878%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/93445aa1-0df1-40dd-bfa3-a79c33f63878=
%40isocpp.org</a>.<br />

------=_Part_5434_1922072075.1518203063962--

------=_Part_5433_1269882007.1518203063962--

.


Author: Jake Arkinstall <jake.arkinstall@gmail.com>
Date: Fri, 9 Feb 2018 19:12:55 +0000
Raw View
--94eb2c1c00dedd2c860564cc50d5
Content-Type: text/plain; charset="UTF-8"

Several people have suggested that it might be difficult and provided their
issues with it, which is constructive. Several people have also given
constructive suggestions about implementations and adding flexibility.

That's the point of discussion. We can think about things in a "here's what
we have, what can we do with it?" vs "here's what we want, how do we do
it?" way (though I believe string literal evaluation at translation time
might be worth a discussion in itself). Both have their place, and denying
one because the "how can we do it" is under constructive discussion is not
constructive. In fact, the "how to do it" can involve a change that opens
up more possibilities, such as the evaluation of constexpr strings. It
might not catch on, but it's an example of how a "how can we do X" leads to
"this allows us to do X,Y, and Z".

To clarify, the "idea" here is "let's make C++ variable-string
concatenation a bit more user friendly". My suggested implementation was
simply based on the method that people already widely use and have the code
already written for, and wasn't intended to be perfect. I stated again and
again that it could do as a solution in the case that the downfalls of the
approach are not an actual problem. If we can come up with an acceptable
solution which does do things in a better way, I'm obviously all for it and
my ears are open.

On 9 Feb 2018 18:11, "Ren Industries" <renindustries@gmail.com> wrote:

On Fri, Feb 9, 2018 at 11:40 AM, Jake Arkinstall <jake.arkinstall@gmail.com>
wrote:

> Okay, so a feature which exists in many languages, with considerably wide
> use, cannot possibly be used in C++ because it isn't good enough for us.
>
> This is why we cannot have nice things.
>

Or because what you are proposing is not a nice thing, as several
knowledgable people have told you.

--
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/is
ocpp.org/d/msgid/std-proposals/CAMD6iD_9wmiL3_kyah7YFVHuXiXw
4oT8jyA8NGWvZjfSPuVJcQ%40mail.gmail.com
<https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAMD6iD_9wmiL3_kyah7YFVHuXiXw4oT8jyA8NGWvZjfSPuVJcQ%40mail.gmail.com?utm_medium=email&utm_source=footer>
..

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCMe5hRo5sQDfkKz2%3D7Os8%3DH_EyWf7csDQJ%3De97_oPSEJw%40mail.gmail.com.

--94eb2c1c00dedd2c860564cc50d5
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"auto">Several people have suggested that it might be difficult =
and provided their issues with it, which is constructive. Several people ha=
ve also given constructive suggestions about implementations and adding fle=
xibility.=C2=A0<div dir=3D"auto"><br></div><div dir=3D"auto">That&#39;s the=
 point of discussion. We can think about things in a &quot;here&#39;s what =
we have, what can we do with it?&quot; vs &quot;here&#39;s what we want, ho=
w do we do it?&quot; way (though I believe string literal evaluation at tra=
nslation time might be worth a discussion in itself). Both have their place=
, and denying one because the &quot;how can we do it&quot; is under constru=
ctive discussion is not constructive. In fact, the &quot;how to do it&quot;=
 can involve a change that opens up more possibilities, such as the evaluat=
ion of constexpr strings. It might not catch on, but it&#39;s an example of=
 how a &quot;how can we do X&quot; leads to &quot;this allows us to do X,Y,=
 and Z&quot;.</div><div dir=3D"auto"><br></div><div dir=3D"auto">To clarify=
, the &quot;idea&quot; here is &quot;let&#39;s make C++ variable-string con=
catenation a bit more user friendly&quot;. My suggested implementation was =
simply based on the method that people already widely use and have the code=
 already written for, and wasn&#39;t intended to be perfect. I stated again=
 and again that it could do as a solution in the case that the downfalls of=
 the approach are not an actual problem. If we can come up with an acceptab=
le solution which does do things in a better way, I&#39;m obviously all for=
 it and my ears are open.</div><div class=3D"gmail_extra" dir=3D"auto"><br>=
<div class=3D"gmail_quote">On 9 Feb 2018 18:11, &quot;Ren Industries&quot; =
&lt;<a href=3D"mailto:renindustries@gmail.com" target=3D"_blank">renindustr=
ies@gmail.com</a>&gt; wrote:<br type=3D"attribution"><blockquote class=3D"m=
_-7135439478321377984quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc=
 solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div c=
lass=3D"gmail_quote"><div class=3D"m_-7135439478321377984quoted-text">On Fr=
i, Feb 9, 2018 at 11:40 AM, Jake Arkinstall <span dir=3D"ltr">&lt;<a href=
=3D"mailto:jake.arkinstall@gmail.com" target=3D"_blank">jake.arkinstall@gma=
il.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"=
margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"=
auto">Okay, so a feature which exists in many languages, with considerably =
wide use, cannot possibly be used in C++ because it isn&#39;t good enough f=
or us.<div dir=3D"auto"><br></div><div dir=3D"auto">This is why we cannot h=
ave nice things.</div></div></blockquote><div><br></div></div><div>Or becau=
se what you are proposing is not a nice thing, as several knowledgable peop=
le have told you.=C2=A0</div></div></div></div><div class=3D"m_-71354394783=
21377984quoted-text">

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isoc<wbr>pp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></div>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAMD6iD_9wmiL3_kyah7YFVHuXiXw4oT8jyA8=
NGWvZjfSPuVJcQ%40mail.gmail.com?utm_medium=3Demail&amp;utm_source=3Dfooter"=
 target=3D"_blank">https://groups.google.com/a/is<wbr>ocpp.org/d/msgid/std-=
proposals<wbr>/CAMD6iD_9wmiL3_kyah7YFVHuXiXw<wbr>4oT8jyA8NGWvZjfSPuVJcQ%40m=
ail.<wbr>gmail.com</a>.<br>
</blockquote></div><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCMe5hRo5sQDfkKz2%3D7Os8%3DH_E=
yWf7csDQJ%3De97_oPSEJw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CC=
Me5hRo5sQDfkKz2%3D7Os8%3DH_EyWf7csDQJ%3De97_oPSEJw%40mail.gmail.com</a>.<br=
 />

--94eb2c1c00dedd2c860564cc50d5--

.


Author: Avi Kivity <avi@scylladb.com>
Date: Fri, 9 Feb 2018 21:31:44 +0200
Raw View
This is a multi-part message in MIME format.
--------------31464E7D3DBE30D97D3F2880
Content-Type: text/plain; charset="UTF-8"; format=flowed
Content-Transfer-Encoding: quoted-printable

On 02/09/2018 06:14 PM, Jake Arkinstall wrote:
> So an approach to eval() in a compiled language?
>

Yes

> There are many dangers here,

Yes

> but also a lot of flexibility.

Yes

> It allows libraries to change the language, opens up the potential for=20
> more advanced preprocessing (especially given that they could have state)=
..
>
> It could very well be worth considering.
>

I feel dirty

> On 9 Feb 2018 15:42, "Avi Kivity" <avi@scylladb.com=20
> <mailto:avi@scylladb.com>> wrote:
>
>     On 02/09/2018 04:07 PM, Marcel F. Kr=C3=BCger wrote:
>>     Jake Arkinstall <jake.arkinstall@gmail.com
>>     <mailto:jake.arkinstall@gmail.com>> schrieb am Fr., 9. Feb. 2018
>>     um 14:51=C2=A0Uhr:
>>
>>
>>         That would be nice, but generic is a royal pain in the
>>         backside in this circumstance. This is not something that can
>>         be written in the current language because it requires
>>         interpetation of the strings. How on earth that is supposed
>>         to generalise to choices of fmt, string conversion and
>>         concatenation, stringstreams, and whatever magical solution
>>         we're waiting on to make string manipulation efficient, I
>>         have no idea, especially in the general situation where the
>>         different approaches - e.g. to_string and operator<< - are
>>         not equivalent.
>>
>>
>>     Maybe this could be based on user-defined literals:
>>     If for example `operator""_sth` accepts more than two parameters,
>>     the expression "abc{def}ghij"_sth could be rewritten to
>>     `operator""_sth("abc", 3, def, "ghij", 4)`.
>>     Then the standard library could include a literal suffix based on
>>     iostreams and it should be generic enough to be supported by most
>>     libraries.
>>
>
>     I hate myself for suggesting it, but what about code injection?
>
>     =C2=A0=C2=A0=C2=A0 constexpr std::injected_code operator""v(const cha=
r* literal)
>     { ... }
>
>     The "std::injected_code" return type is a string that gets
>     injected into the code, replacing the literal.
>
>     This could be abused in so many wonderful ways.
>
>
>     --=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 email to std-proposals+unsubscribe@isocpp.org
>     <mailto:std-proposals+unsubscribe@isocpp.org>.
>     To post to this group, send email to std-proposals@isocpp.org
>     <mailto:std-proposals@isocpp.org>.
>     To view this discussion on the web visit
>     https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/33eb3ce3=
-12a5-800d-9c4d-2a362fb139d6%40scylladb.com
>     <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/33eb3ce=
3-12a5-800d-9c4d-2a362fb139d6%40scylladb.com?utm_medium=3Demail&utm_source=
=3Dfooter>.
>
> --=20
> You received this message because you are subscribed to the Google=20
> Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send=20
> an email to std-proposals+unsubscribe@isocpp.org=20
> <mailto:std-proposals+unsubscribe@isocpp.org>.
> To post to this group, send email to std-proposals@isocpp.org=20
> <mailto:std-proposals@isocpp.org>.
> To view this discussion on the web visit=20
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCPvO=
W5KdxWjbWr3BUPrE9PU9A3nkoZKgE687ySzp%2BJ%2BBw%40mail.gmail.com=20
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCPv=
OW5KdxWjbWr3BUPrE9PU9A3nkoZKgE687ySzp%2BJ%2BBw%40mail.gmail.com?utm_medium=
=3Demail&utm_source=3Dfooter>.


--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/b6409b0a-1ee4-d45c-8370-981764513a5f%40scylladb.=
com.

--------------31464E7D3DBE30D97D3F2880
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<html>
  <head>
    <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-8=
">
  </head>
  <body text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div class=3D"moz-cite-prefix">On 02/09/2018 06:14 PM, Jake Arkinstall
      wrote:<br>
    </div>
    <blockquote type=3D"cite"
cite=3D"mid:CAC+0CCPvOW5KdxWjbWr3BUPrE9PU9A3nkoZKgE687ySzp+J+Bw@mail.gmail.=
com">
      <div dir=3D"auto">So an approach to eval() in a compiled language?
        <div dir=3D"auto"><br>
        </div>
      </div>
    </blockquote>
    <br>
    Yes<br>
    <br>
    <blockquote type=3D"cite"
cite=3D"mid:CAC+0CCPvOW5KdxWjbWr3BUPrE9PU9A3nkoZKgE687ySzp+J+Bw@mail.gmail.=
com">
      <div dir=3D"auto">
        <div dir=3D"auto">There are many dangers here,</div>
      </div>
    </blockquote>
    <br>
    Yes<br>
    <br>
    <blockquote type=3D"cite"
cite=3D"mid:CAC+0CCPvOW5KdxWjbWr3BUPrE9PU9A3nkoZKgE687ySzp+J+Bw@mail.gmail.=
com">
      <div dir=3D"auto">
        <div dir=3D"auto"> but also a lot of flexibility. </div>
      </div>
    </blockquote>
    <br>
    Yes<br>
    <br>
    <blockquote type=3D"cite"
cite=3D"mid:CAC+0CCPvOW5KdxWjbWr3BUPrE9PU9A3nkoZKgE687ySzp+J+Bw@mail.gmail.=
com">
      <div dir=3D"auto">
        <div dir=3D"auto">It allows libraries to change the language,
          opens up the potential for more advanced preprocessing
          (especially given that they could have state).</div>
        <div dir=3D"auto"><br>
        </div>
        <div dir=3D"auto">It could very well be worth considering.</div>
      </div>
      <div class=3D"gmail_extra"><br>
      </div>
    </blockquote>
    <br>
    I feel dirty<br>
    <br>
    <blockquote type=3D"cite"
cite=3D"mid:CAC+0CCPvOW5KdxWjbWr3BUPrE9PU9A3nkoZKgE687ySzp+J+Bw@mail.gmail.=
com">
      <div class=3D"gmail_extra">
        <div class=3D"gmail_quote">On 9 Feb 2018 15:42, "Avi Kivity" &lt;<a
            href=3D"mailto:avi@scylladb.com" moz-do-not-send=3D"true">avi@s=
cylladb.com</a>&gt;
          wrote:<br type=3D"attribution">
          <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0
            .8ex;border-left:1px #ccc solid;padding-left:1ex">
            <div text=3D"#000000" bgcolor=3D"#FFFFFF">
              <div class=3D"m_-3260905452705745034moz-cite-prefix">On
                02/09/2018 04:07 PM, Marcel F. Kr=C3=BCger wrote:<br>
              </div>
              <blockquote type=3D"cite">
                <div dir=3D"ltr">
                  <div class=3D"gmail_quote">
                    <div dir=3D"ltr">Jake Arkinstall &lt;<a
                        href=3D"mailto:jake.arkinstall@gmail.com"
                        target=3D"_blank" moz-do-not-send=3D"true">jake.ark=
install@gmail.com</a>&gt;
                      schrieb am Fr., 9. Feb. 2018 um 14:51=C2=A0Uhr:</div>
                    <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0
                      .8ex;border-left:1px #ccc solid;padding-left:1ex">
                      <div dir=3D"auto">
                        <div dir=3D"auto"><br>
                        </div>
                      </div>
                      <div dir=3D"auto">
                        <div dir=3D"auto">That would be nice, but generic
                          is a royal pain in the backside in this
                          circumstance. This is not something that can
                          be written in the current language because it
                          requires interpetation of the strings. How on
                          earth that is supposed to generalise to
                          choices of fmt, string conversion and
                          concatenation, stringstreams, and whatever
                          magical solution we're waiting on to make
                          string manipulation efficient, I have no idea,
                          especially in the general situation where the
                          different approaches - e.g. to_string and
                          operator&lt;&lt; - are not equivalent.</div>
                      </div>
                    </blockquote>
                    <div><br>
                    </div>
                    <div>Maybe this could be based on user-defined
                      literals:</div>
                    <div>If for example `operator""_sth` accepts more
                      than two parameters, the expression
                      "abc{def}ghij"_sth could be rewritten to
                      `operator""_sth("abc", 3, def, "ghij", 4)`.</div>
                    <div>Then the standard library could include a
                      literal suffix based on iostreams and it should be
                      generic enough to be supported by most libraries.</di=
v>
                    <div><br>
                    </div>
                  </div>
                </div>
              </blockquote>
              <br>
              I hate myself for suggesting it, but what about code
              injection?<br>
              <br>
              =C2=A0=C2=A0=C2=A0 constexpr std::injected_code operator""v(c=
onst char*
              literal) { ... }<br>
              <br>
              The "std::injected_code" return type is a string that gets
              injected into the code, replacing the literal.<br>
              <br>
              This could be abused in so many wonderful ways.<br>
              <br>
              =C2=A0=C2=A0=C2=A0 <br>
            </div>
            -- <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 email to <a
              href=3D"mailto:std-proposals+unsubscribe@isocpp.org"
              target=3D"_blank" moz-do-not-send=3D"true">std-proposals+unsu=
bscribe@<wbr>isocpp.org</a>.<br>
            To post to this group, send email to <a
              href=3D"mailto:std-proposals@isocpp.org" target=3D"_blank"
              moz-do-not-send=3D"true">std-proposals@isocpp.org</a>.<br>
            To view this discussion on the web visit <a
href=3D"https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/33eb3c=
e3-12a5-800d-9c4d-2a362fb139d6%40scylladb.com?utm_medium=3Demail&amp;utm_so=
urce=3Dfooter"
              target=3D"_blank" moz-do-not-send=3D"true">https://groups.goo=
gle.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/33eb3ce3-12a5-800d-<wb=
r>9c4d-2a362fb139d6%40scylladb.<wbr>com</a>.<br>
          </blockquote>
        </div>
      </div>
      -- <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 email to <a
        href=3D"mailto:std-proposals+unsubscribe@isocpp.org"
        moz-do-not-send=3D"true">std-proposals+unsubscribe@isocpp.org</a>.<=
br>
      To post to this group, send email to <a
        href=3D"mailto:std-proposals@isocpp.org" moz-do-not-send=3D"true">s=
td-proposals@isocpp.org</a>.<br>
      To view this discussion on the web visit <a
href=3D"https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B=
0CCPvOW5KdxWjbWr3BUPrE9PU9A3nkoZKgE687ySzp%2BJ%2BBw%40mail.gmail.com?utm_me=
dium=3Demail&amp;utm_source=3Dfooter"
        moz-do-not-send=3D"true">https://groups.google.com/a/isocpp.org/d/m=
sgid/std-proposals/CAC%2B0CCPvOW5KdxWjbWr3BUPrE9PU9A3nkoZKgE687ySzp%2BJ%2BB=
w%40mail.gmail.com</a>.<br>
    </blockquote>
    <p><br>
    </p>
  </body>
</html>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/b6409b0a-1ee4-d45c-8370-981764513a5f%=
40scylladb.com?utm_medium=3Demail&utm_source=3Dfooter">https://groups.googl=
e.com/a/isocpp.org/d/msgid/std-proposals/b6409b0a-1ee4-d45c-8370-981764513a=
5f%40scylladb.com</a>.<br />

--------------31464E7D3DBE30D97D3F2880--

.


Author: Richard Hodges <hodges.r@gmail.com>
Date: Fri, 9 Feb 2018 21:08:26 +0100
Raw View
--001a1144c9e65d7c860564cd17f1
Content-Type: text/plain; charset="UTF-8"

> I'm not saying your idea has no merit. I said that the proposal, as it was
posted, has no future. Improve it

Here's an idea. How about you approach this genuine desire to do a good
thing more positively. I know you can be negative. Anyone can.

I am interested to see how you can positively contribute to an idea that
seeks to help us all.

If you improved your attitude you might see more positive engagement and
enthusiasm from the people you currently insult.

On 9 Feb 2018 6:55 pm, "Thiago Macieira" <thiago@macieira.org> wrote:

> On Friday, 9 February 2018 10:43:41 PST Richard Hodges wrote:
> > With ADL customisation points the default behaviour could be easily
> changed.
> >
> > No-one is advocating cementing in iostreams, merely using it for
> > convenience.
> >
> > Please kindly read my (presumably poorly worded) post again.
>
> Then please reword it and talk about how it would work with the not-yet-
> existent std2::iostreams and QTextStream.
>
> I'm not saying your idea has no merit. I said that the proposal, as it was
> posted, has no future. Improve it.
>
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
>    Software Architect - Intel Open Source Technology Center
>
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit https://groups.google.com/a/
> isocpp.org/d/msgid/std-proposals/4890431.TR9UepuQra%40tjmaciei-mobl1.
>

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3hac77b6Z%3DEOWzKqynALi1-352OvY0dnnOer8rN6tfa01g%40mail.gmail.com.

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

<div dir=3D"auto">&gt;=C2=A0<span style=3D"font-family:sans-serif;font-size=
:12.8px">I&#39;m not saying your idea has no merit. I said that the proposa=
l, as it was</span><br style=3D"font-family:sans-serif;font-size:12.8px"><s=
pan style=3D"font-family:sans-serif;font-size:12.8px">posted, has no future=
.. Improve it</span><div dir=3D"auto"><span style=3D"font-family:sans-serif;=
font-size:12.8px"><br></span></div><div dir=3D"auto"><span style=3D"font-fa=
mily:sans-serif;font-size:12.8px">Here&#39;s an idea. How about you approac=
h this genuine desire to do a good thing more positively. I know you can be=
 negative. Anyone can.=C2=A0</span></div><div dir=3D"auto"><span style=3D"f=
ont-family:sans-serif;font-size:12.8px"><br></span></div><div dir=3D"auto">=
<span style=3D"font-family:sans-serif;font-size:12.8px">I am interested to =
see how you can positively contribute to an idea that seeks to help us all.=
</span></div><div dir=3D"auto"><span style=3D"font-family:sans-serif;font-s=
ize:12.8px"><br></span></div><div dir=3D"auto"><span style=3D"font-family:s=
ans-serif;font-size:12.8px">If you improved your attitude you might see mor=
e positive engagement and enthusiasm from the people you currently insult.=
=C2=A0</span></div></div><div class=3D"gmail_extra"><br><div class=3D"gmail=
_quote">On 9 Feb 2018 6:55 pm, &quot;Thiago Macieira&quot; &lt;<a href=3D"m=
ailto:thiago@macieira.org">thiago@macieira.org</a>&gt; wrote:<br type=3D"at=
tribution"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bor=
der-left:1px #ccc solid;padding-left:1ex">On Friday, 9 February 2018 10:43:=
41 PST Richard Hodges wrote:<br>
&gt; With ADL customisation points the default behaviour could be easily ch=
anged.<br>
&gt;<br>
&gt; No-one is advocating cementing in iostreams, merely using it for<br>
&gt; convenience.<br>
&gt;<br>
&gt; Please kindly read my (presumably poorly worded) post again.<br>
<br>
Then please reword it and talk about how it would work with the not-yet-<br=
>
existent std2::iostreams and QTextStream.<br>
<br>
I&#39;m not saying your idea has no merit. I said that the proposal, as it =
was<br>
posted, has no future. Improve it.<br>
<br>
--<br>
Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" rel=3D"noref=
errer" target=3D"_blank">macieira.info</a> - thiago (AT) <a href=3D"http://=
kde.org" rel=3D"noreferrer" target=3D"_blank">kde.org</a><br>
=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center<br>
<br>
<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%2Bunsubscribe@isocpp.org">std-propo=
sals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/4890431.TR9UepuQra%40tjmaciei-mobl1" =
rel=3D"noreferrer" target=3D"_blank">https://groups.google.com/a/<wbr>isocp=
p.org/d/msgid/std-<wbr>proposals/4890431.TR9UepuQra%<wbr>40tjmaciei-mobl1</=
a>.<br>
</blockquote></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CALvx3hac77b6Z%3DEOWzKqynALi1-352OvY0=
dnnOer8rN6tfa01g%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3hac77b6Z%=
3DEOWzKqynALi1-352OvY0dnnOer8rN6tfa01g%40mail.gmail.com</a>.<br />

--001a1144c9e65d7c860564cd17f1--

.


Author: Barry Revzin <barry.revzin@gmail.com>
Date: Fri, 9 Feb 2018 12:37:10 -0800 (PST)
Raw View
------=_Part_5460_2007340702.1518208630449
Content-Type: multipart/alternative;
 boundary="----=_Part_5461_63284334.1518208630449"

------=_Part_5461_63284334.1518208630449
Content-Type: text/plain; charset="UTF-8"


>
>
> When reflection hit we can have this syntax:
> auto f = "test {0.a} test {0.b} test"_str;
> auto r1 = f(ArgType{ .a = 4, .b = 3 }); //"test 4 test 3 test"
> auto r2 = f(OtherType{ .a = "zzz", .b = 42f, .c = true }); //"test zzz
> test 42.00 test"
> auto r3 = f(5); //compile error! `int` do not have `a`
>
> This is only matter of finding member address using compile time string.
>

This. Plus more doing just general name lookup using a compile-time string
so you can do:

int answer = 42;
auto s = format("The answer is {answer:*^4}."); // The answer is *42*.

Either way, I think this is two orthogonal problems: a good formatting
library and a good reflection system.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b540b67a-3aed-4a70-b264-5e81adccb6a1%40isocpp.org.

------=_Part_5461_63284334.1518208630449
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<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><br>When=
 reflection hit we can have this syntax:<br><div style=3D"background-color:=
rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-wi=
dth:1px"><code><div><span style=3D"color:#008">auto</span><span style=3D"co=
lor:#000"> f </span><span style=3D"color:#660">=3D</span><span style=3D"col=
or:#000"> </span><span style=3D"color:#080">&quot;test {0.a} test {0.b} tes=
t&quot;</span><span style=3D"color:#000">_str</span><span style=3D"color:#6=
60">;</span><span style=3D"color:#000"><br></span><span style=3D"color:#008=
">auto</span><span style=3D"color:#000"> r1 </span><span style=3D"color:#66=
0">=3D</span><span style=3D"color:#000"> f</span><span style=3D"color:#660"=
>(</span><span style=3D"color:#606">ArgType</span><span style=3D"color:#660=
">{</span><span style=3D"color:#000"> </span><span style=3D"color:#660">.</=
span><span style=3D"color:#000">a </span><span style=3D"color:#660">=3D</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#066">4</span><s=
pan style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#660">.</span><span style=3D"color:#000">b </span><span style=
=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D=
"color:#066">3</span><span style=3D"color:#000"> </span><span style=3D"colo=
r:#660">});</span><span style=3D"color:#000"> </span><span style=3D"color:#=
800">//&quot;test 4 test 3 test&quot;</span><span style=3D"color:#000"><br>=
</span><span style=3D"color:#008">auto</span><span style=3D"color:#000"> r2=
 </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> f<=
/span><span style=3D"color:#660">(</span><span style=3D"color:#606">OtherTy=
pe</span><span style=3D"color:#660">{</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#660">.</span><span style=3D"color:#000">a </span>=
<span style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#080">&quot;zzz&quot;</span><span style=3D"color:#660">,<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#660">.</span=
><span style=3D"color:#000">b </span><span style=3D"color:#660">=3D</span><=
span style=3D"color:#000"> </span><span style=3D"color:#066">42f</span><spa=
n style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#660">.</span><span style=3D"color:#000">c </span><span style=
=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D=
"color:#008">true</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#660">});</span><span style=3D"color:#000"> </span><span style=3D"colo=
r:#800">//&quot;test zzz test 42.00 test&quot;</span><span style=3D"color:#=
000"><br></span><span style=3D"color:#008">auto</span><span style=3D"color:=
#000"> r3 </span><span style=3D"color:#660">=3D</span><span style=3D"color:=
#000"> f</span><span style=3D"color:#660">(</span><span style=3D"color:#066=
">5</span><span style=3D"color:#660">);</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#800">//compile error! `int` do not have `a`</sp=
an><span style=3D"color:#000"><br></span></div></code></div><br>This is onl=
y matter of finding member address using compile time string.<br></div></di=
v></blockquote><div><br></div><div>This. Plus more doing just general name =
lookup using a compile-time string so you can do:</div><div><br></div><div>=
<div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); b=
order-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; wo=
rd-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettypr=
int"><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> answer </span><spa=
n 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=
: #066;" class=3D"styled-by-prettify">42</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> s </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> form=
at</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span>=
<span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;The answer =
is {answer:*^4}.&quot;</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">);</span><font color=3D"#880000"><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #800;" class=3D"s=
tyled-by-prettify">// The answer is *42*.</span></font></div></code></div><=
br>Either way, I think this is two orthogonal problems: a good formatting l=
ibrary and a good reflection system.<br></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/b540b67a-3aed-4a70-b264-5e81adccb6a1%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/b540b67a-3aed-4a70-b264-5e81adccb6a1=
%40isocpp.org</a>.<br />

------=_Part_5461_63284334.1518208630449--

------=_Part_5460_2007340702.1518208630449--

.


Author: Ren Industries <renindustries@gmail.com>
Date: Fri, 9 Feb 2018 15:48:38 -0500
Raw View
--94eb2c1953942a08250564cda7e7
Content-Type: text/plain; charset="UTF-8"

>
>
> Here's an idea. How about you approach this genuine desire to do a good
> thing more positively. I know you can be negative. Anyone can.
>
> I am interested to see how you can positively contribute to an idea that
> seeks to help us all.
>
> If you improved your attitude you might see more positive engagement and
> enthusiasm from the people you currently insult.
>

Anyone can be positive too.
Maybe if you improved your proposal you'd see more positive engagement and
enthusiasm from the people you think are insulting you.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAMD6iD9b7J%3DuQXqAj6o1V9sOQof4VkjvFY1Tk4z-J0HL1jiK7w%40mail.gmail.com.

--94eb2c1953942a08250564cda7e7
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #c=
cc solid;padding-left:1ex"><div dir=3D"auto"><span class=3D""><div dir=3D"a=
uto"><span style=3D"font-family:sans-serif;font-size:12.8px"><br></span></d=
iv></span><div dir=3D"auto"><span style=3D"font-family:sans-serif;font-size=
:12.8px">Here&#39;s an idea. How about you approach this genuine desire to =
do a good thing more positively. I know you can be negative. Anyone can.=C2=
=A0</span></div><div dir=3D"auto"><span style=3D"font-family:sans-serif;fon=
t-size:12.8px"><br></span></div><div dir=3D"auto"><span style=3D"font-famil=
y:sans-serif;font-size:12.8px">I am interested to see how you can positivel=
y contribute to an idea that seeks to help us all.</span></div><div dir=3D"=
auto"><span style=3D"font-family:sans-serif;font-size:12.8px"><br></span></=
div><div dir=3D"auto"><span style=3D"font-family:sans-serif;font-size:12.8p=
x">If you improved your attitude you might see more positive engagement and=
 enthusiasm from the people you currently insult.=C2=A0</span></div></div><=
/blockquote><div><br></div><div>Anyone can be positive too.=C2=A0</div><div=
>Maybe if you improved your proposal you&#39;d see more positive engagement=
 and enthusiasm from the people you think are insulting you.</div></div></d=
iv></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAMD6iD9b7J%3DuQXqAj6o1V9sOQof4VkjvFY=
1Tk4z-J0HL1jiK7w%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAMD6iD9b7J%3Du=
QXqAj6o1V9sOQof4VkjvFY1Tk4z-J0HL1jiK7w%40mail.gmail.com</a>.<br />

--94eb2c1953942a08250564cda7e7--

.


Author: inkwizytoryankes@gmail.com
Date: Fri, 9 Feb 2018 12:51:55 -0800 (PST)
Raw View
------=_Part_5425_1042536176.1518209515594
Content-Type: multipart/alternative;
 boundary="----=_Part_5426_372986613.1518209515595"

------=_Part_5426_372986613.1518209515595
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



On Friday, February 9, 2018 at 9:08:29 PM UTC+1, Richard Hodges wrote:
>
> > I'm not saying your idea has no merit. I said that the proposal, as it=
=20
> was
> posted, has no future. Improve it
>
> Here's an idea. How about you approach this genuine desire to do a good=
=20
> thing more positively. I know you can be negative. Anyone can.=20
>
> I am interested to see how you can positively contribute to an idea that=
=20
> seeks to help us all.
>
>
=20
Minimal version than could be added to C++ is new string prefix `F`=20
(because we have `R`, `u`, `u8` and `U` already, and `$` is outside of=20
source characters) that enable mixing code with string literals.
As Marcel Kr=C3=BCger wrote, language could transform this string literal t=
o:
F"testA{a}test{{B}}"_x; =3D> operator""_x("testA"_x, a, "test{B}"_x); //usi=
ng=20
same postfix to parse sub-literals
FR"aa(x{b}y)aa"_x; =3D> operator""_x(R"aa(x)aa"_x, b, R"aa(y)aa"_x); //it=
=20
have precedence over `R` prefix



Rest will be implemented by library, this mean `F"a {5} b"` will not=20
compile because there is no matching operator. stl could add this operator=
=20
for `s` postfix, that will use `std::to_string` for conversing all=20
arguments:
template<typename... Parts>
std::string operator""s(Parts&&... p) { return std::to_string(std::forward<
Parts>(p)) + ...; }

int main()
{
    auto x =3D F"Test {{a}} =3D {10+5}"s; //x =3D=3D "Test {a} =3D 15"s
}
No iosteam, and even more it could if someone relay desire to have=20
localizations:

F"Test {356*10}"_loc("Prod {0} OK!", "fr") =3D=3D "Prod 3.560,00 OK!";

Only drawback is some template bloat but this is probably acceptable cost.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/1cdb6300-7397-46d7-bce9-62e6e8dac40b%40isocpp.or=
g.

------=_Part_5426_372986613.1518209515595
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Friday, February 9, 2018 at 9:08:29 PM UTC+1, R=
ichard Hodges wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"auto">&gt;=C2=A0<span style=3D"font-family:sans-serif;font-size:12.8px"=
>I&#39;m not saying your idea has no merit. I said that the proposal, as it=
 was</span><br style=3D"font-family:sans-serif;font-size:12.8px"><span styl=
e=3D"font-family:sans-serif;font-size:12.8px">posted, has no future. Improv=
e it</span><div dir=3D"auto"><span style=3D"font-family:sans-serif;font-siz=
e:12.8px"><br></span></div><div dir=3D"auto"><span style=3D"font-family:san=
s-serif;font-size:12.8px">Here&#39;s an idea. How about you approach this g=
enuine desire to do a good thing more positively. I know you can be negativ=
e. Anyone can.=C2=A0</span></div><div dir=3D"auto"><span style=3D"font-fami=
ly:sans-serif;font-size:12.8px"><br></span></div><div dir=3D"auto"><span st=
yle=3D"font-family:sans-serif;font-size:12.8px">I am interested to see how =
you can positively contribute to an idea that seeks to help us all.</span><=
/div><br></div></blockquote><div><br>=C2=A0<br>Minimal version than could b=
e added to C++ is new string prefix `F` (because we have `R`, `u`, `u8` and=
 `U` already, and `$` is outside of source characters) that enable mixing c=
ode with string literals.<br>As Marcel Kr=C3=BCger wrote, language could tr=
ansform this string literal to:<br><div style=3D"background-color: rgb(250,=
 250, 250); border-color: rgb(187, 187, 187); border-style: solid; border-w=
idth: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code class=3D=
"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">F</span><span style=3D"color: #080;" class=3D"st=
yled-by-prettify">&quot;testA{a}test{{B}}&quot;</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"> </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">=3D&gt;</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">o=
perator</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&qu=
ot;&quot;</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: #080;" class=3D"styled-by-prettify">&quot;testA&quot;<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify">_x</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> a</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: #080;" class=3D=
"styled-by-prettify">&quot;test{B}&quot;</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"styl=
ed-by-prettify"> </span><span style=3D"color: #800;" class=3D"styled-by-pre=
ttify">//using same postfix to parse sub-literals</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br>FR</span><span style=3D"color: #=
080;" class=3D"styled-by-prettify">&quot;aa(x{b}y)aa&quot;</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">_x</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: #660;" class=
=3D"styled-by-prettify">=3D&gt;</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">operator</span><span style=3D"color: #080;" class=3D"styled-by-=
prettify">&quot;&quot;</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">_x</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">R</sp=
an><span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;aa(x)aa&=
quot;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">_x</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> b</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> R</span><span style=3D"color: #080;"=
 class=3D"styled-by-prettify">&quot;aa(y)aa&quot;</span><span style=3D"colo=
r: #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"> </span><span style=3D"color: #800;" class=3D"style=
d-by-prettify">//it have precedence over `R` prefix</span></div></code></di=
v><br><br><br>Rest will be implemented by library, this mean `F&quot;a {5} =
b&quot;` will not compile because there is no matching operator. stl could =
add this operator for `s` postfix, that will use `std::to_string` for conve=
rsing all arguments:<br><div style=3D"background-color: rgb(250, 250, 250);=
 border-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; =
overflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"prettyprin=
t"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">template</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">typename</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: #606;" class=3D"styled-by-prettify">Parts</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br>std</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">string</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;"=
 class=3D"styled-by-prettify">operator</span><span style=3D"color: #080;" c=
lass=3D"styled-by-prettify">&quot;&quot;</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify">s</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">(</span><span style=3D"color: #606;" class=3D"styled-b=
y-prettify">Parts</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">&amp;&amp;...</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> p</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">{</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">return</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: #000;" class=
=3D"styled-by-prettify">to_string</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">std</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">::</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">Parts</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;(</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">p</span><span style=
=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: #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-b=
y-prettify">...;</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><br></sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> main</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> x </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> F</span><span style=3D"color: #080;" class=3D"styled-by-pret=
tify">&quot;Test {{a}} =3D {10+5}&quot;</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">s</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify=
">//x =3D=3D &quot;Test {a} =3D 15&quot;s</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><code>No iosteam, and even mo=
re it could if someone relay desire to have localizations:<br><br><div styl=
e=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187)=
; border-style: solid; border-width: 1px; overflow-wrap: break-word;" class=
=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subprettyprint">=
<span style=3D"color: #000;" class=3D"styled-by-prettify">F</span><span sty=
le=3D"color: #080;" class=3D"styled-by-prettify">&quot;Test {356*10}&quot;<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify">_loc</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span sty=
le=3D"color: #080;" class=3D"styled-by-prettify">&quot;Prod {0} OK!&quot;</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #080;" class=3D"styled-by-prettify">&quot;fr&quot;</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #080;" class=3D"=
styled-by-prettify">&quot;Prod 3.560,00 OK!&quot;</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br></span></div></code></div><br>Only drawba=
ck is some template bloat but this is probably acceptable cost.<br></code><=
br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/1cdb6300-7397-46d7-bce9-62e6e8dac40b%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/1cdb6300-7397-46d7-bce9-62e6e8dac40b=
%40isocpp.org</a>.<br />

------=_Part_5426_372986613.1518209515595--

------=_Part_5425_1042536176.1518209515594--

.


Author: Jake Arkinstall <jake.arkinstall@gmail.com>
Date: Fri, 9 Feb 2018 21:03:06 +0000
Raw View
--94eb2c1c1adce3bb930564cdda6e
Content-Type: text/plain; charset="UTF-8"

I think you're confusing users here.

On 9 Feb 2018 20:48, "Ren Industries" <renindustries@gmail.com> wrote:


> Here's an idea. How about you approach this genuine desire to do a good
> thing more positively. I know you can be negative. Anyone can.
>
> I am interested to see how you can positively contribute to an idea that
> seeks to help us all.
>
> If you improved your attitude you might see more positive engagement and
> enthusiasm from the people you currently insult.
>

Anyone can be positive too.
Maybe if you improved your proposal you'd see more positive engagement and
enthusiasm from the people you think are insulting you.

--
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/
isocpp.org/d/msgid/std-proposals/CAMD6iD9b7J%3DuQXqAj6o1V9sOQof4VkjvFY1Tk4z
-J0HL1jiK7w%40mail.gmail.com
<https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAMD6iD9b7J%3DuQXqAj6o1V9sOQof4VkjvFY1Tk4z-J0HL1jiK7w%40mail.gmail.com?utm_medium=email&utm_source=footer>
..

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCMpf5EztnX7d0iKicbHCxcm9Jm1rNfby4GvQMcMwPVezA%40mail.gmail.com.

--94eb2c1c1adce3bb930564cdda6e
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"auto"><div>I think you&#39;re confusing users here.<br><div cla=
ss=3D"gmail_extra"><br><div class=3D"gmail_quote">On 9 Feb 2018 20:48, &quo=
t;Ren Industries&quot; &lt;<a href=3D"mailto:renindustries@gmail.com">renin=
dustries@gmail.com</a>&gt; wrote:<br type=3D"attribution"><blockquote class=
=3D"quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quo=
te"><div class=3D"quoted-text"><blockquote class=3D"gmail_quote" style=3D"m=
argin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"a=
uto"><span><div dir=3D"auto"><span style=3D"font-family:sans-serif;font-siz=
e:12.8px"><br></span></div></span><div dir=3D"auto"><span style=3D"font-fam=
ily:sans-serif;font-size:12.8px">Here&#39;s an idea. How about you approach=
 this genuine desire to do a good thing more positively. I know you can be =
negative. Anyone can.=C2=A0</span></div><div dir=3D"auto"><span style=3D"fo=
nt-family:sans-serif;font-size:12.8px"><br></span></div><div dir=3D"auto"><=
span style=3D"font-family:sans-serif;font-size:12.8px">I am interested to s=
ee how you can positively contribute to an idea that seeks to help us all.<=
/span></div><div dir=3D"auto"><span style=3D"font-family:sans-serif;font-si=
ze:12.8px"><br></span></div><div dir=3D"auto"><span style=3D"font-family:sa=
ns-serif;font-size:12.8px">If you improved your attitude you might see more=
 positive engagement and enthusiasm from the people you currently insult.=
=C2=A0</span></div></div></blockquote><div><br></div></div><div>Anyone can =
be positive too.=C2=A0</div><div>Maybe if you improved your proposal you&#3=
9;d see more positive engagement and enthusiasm from the people you think a=
re insulting you.</div></div></div></div><div class=3D"quoted-text">

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></div>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAMD6iD9b7J%3DuQXqAj6o1V9sOQof4VkjvFY=
1Tk4z-J0HL1jiK7w%40mail.gmail.com?utm_medium=3Demail&amp;utm_source=3Dfoote=
r" target=3D"_blank">https://groups.google.com/a/<wbr>isocpp.org/d/msgid/st=
d-<wbr>proposals/CAMD6iD9b7J%<wbr>3DuQXqAj6o1V9sOQof4VkjvFY1Tk4z<wbr>-J0HL1=
jiK7w%40mail.gmail.com</a>.<br>
</blockquote></div><br></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCMpf5EztnX7d0iKicbHCxcm9Jm1rN=
fby4GvQMcMwPVezA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCMpf5Ez=
tnX7d0iKicbHCxcm9Jm1rNfby4GvQMcMwPVezA%40mail.gmail.com</a>.<br />

--94eb2c1c1adce3bb930564cdda6e--

.


Author: Jake Arkinstall <jake.arkinstall@gmail.com>
Date: Fri, 9 Feb 2018 21:13:07 +0000
Raw View
--001a11c0327aba08bb0564cdfe15
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On 9 Feb 2018 20:51, <inkwizytoryankes@gmail.com> wrote:


Minimal version than could be added to C++ is new string prefix `F`
(because we have `R`, `u`, `u8` and `U` already, and `$` is outside of
source characters) that enable mixing code with string literals.
As Marcel Kr=C3=BCger wrote, language could transform this string literal t=
o:
F"testA{a}test{{B}}"_x; =3D> operator""_x("testA"_x, a, "test{B}"_x); //usi=
ng
same postfix to parse sub-literals
FR"aa(x{b}y)aa"_x; =3D> operator""_x(R"aa(x)aa"_x, b, R"aa(y)aa"_x); //it
have precedence over `R` prefix



Rest will be implemented by library, this mean `F"a {5} b"` will not
compile because there is no matching operator. stl could add this operator
for `s` postfix, that will use `std::to_string` for conversing all
arguments:
template<typename... Parts>
std::string operator""s(Parts&&... p) { return std::to_string(std::forward<
Parts>(p)) + ...; }

int main()
{
    auto x =3D F"Test {{a}} =3D {10+5}"s; //x =3D=3D "Test {a} =3D 15"s
}
No iosteam, and even more it could if someone relay desire to have
localizations:

F"Test {356*10}"_loc("Prod {0} OK!", "fr") =3D=3D "Prod 3.560,00 OK!";

Only drawback is some template bloat but this is probably acceptable cost.


This is exactly the kind of thing I'm aiming for, although I dont believe
string conversion and concatenation to be the final solution - unless my
recall of benchmarks is out of date, streams are faster than string
concatenation.

This being said, similar ideas can be applied to utilise the fmt library,
for example.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CAC%2B0CCOSZHaTA%3DYPSDU8Add7mE_BYcYPRCmGW8TRPtZ=
hdqL8Hw%40mail.gmail.com.

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

<div dir=3D"auto"><div><br><div class=3D"gmail_extra"><br><div class=3D"gma=
il_quote">On 9 Feb 2018 20:51,  &lt;<a href=3D"mailto:inkwizytoryankes@gmai=
l.com">inkwizytoryankes@gmail.com</a>&gt; wrote:<br type=3D"attribution"><b=
lockquote class=3D"quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"quoted-text"><br></di=
v><div>Minimal version than could be added to C++ is new string prefix `F` =
(because we have `R`, `u`, `u8` and `U` already, and `$` is outside of sour=
ce characters) that enable mixing code with string literals.<br>As Marcel K=
r=C3=BCger wrote, language could transform this string literal to:<br><div =
style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);bo=
rder-style:solid;border-width:1px" class=3D"m_9005655817011445617prettyprin=
t"><code class=3D"m_9005655817011445617prettyprint"><div class=3D"m_9005655=
817011445617subprettyprint"><span style=3D"color:#000" class=3D"m_900565581=
7011445617styled-by-prettify">F</span><span style=3D"color:#080" class=3D"m=
_9005655817011445617styled-by-prettify">&quot;testA{a}test{{B}}&quot;</span=
><span style=3D"color:#000" class=3D"m_9005655817011445617styled-by-prettif=
y">_x</span><span style=3D"color:#660" class=3D"m_9005655817011445617styled=
-by-prettify">;</span><span style=3D"color:#000" class=3D"m_900565581701144=
5617styled-by-prettify"> </span><span style=3D"color:#660" class=3D"m_90056=
55817011445617styled-by-prettify">=3D&gt;</span><span style=3D"color:#000" =
class=3D"m_9005655817011445617styled-by-prettify"> </span><span style=3D"co=
lor:#008" class=3D"m_9005655817011445617styled-by-prettify">operator</span>=
<span style=3D"color:#080" class=3D"m_9005655817011445617styled-by-prettify=
">&quot;&quot;</span><span style=3D"color:#000" class=3D"m_9005655817011445=
617styled-by-prettify">_x</span><span style=3D"color:#660" class=3D"m_90056=
55817011445617styled-by-prettify">(</span><span style=3D"color:#080" class=
=3D"m_9005655817011445617styled-by-prettify">&quot;testA&quot;</span><span =
style=3D"color:#000" class=3D"m_9005655817011445617styled-by-prettify">_x</=
span><span style=3D"color:#660" class=3D"m_9005655817011445617styled-by-pre=
ttify">,</span><span style=3D"color:#000" class=3D"m_9005655817011445617sty=
led-by-prettify"> a</span><span style=3D"color:#660" class=3D"m_90056558170=
11445617styled-by-prettify">,</span><span style=3D"color:#000" class=3D"m_9=
005655817011445617styled-by-prettify"> </span><span style=3D"color:#080" cl=
ass=3D"m_9005655817011445617styled-by-prettify">&quot;test{B}&quot;</span><=
span style=3D"color:#000" class=3D"m_9005655817011445617styled-by-prettify"=
>_x</span><span style=3D"color:#660" class=3D"m_9005655817011445617styled-b=
y-prettify">);</span><span style=3D"color:#000" class=3D"m_9005655817011445=
617styled-by-prettify"> </span><span style=3D"color:#800" class=3D"m_900565=
5817011445617styled-by-prettify">//using same postfix to parse sub-literals=
</span><span style=3D"color:#000" class=3D"m_9005655817011445617styled-by-p=
rettify"><br>FR</span><span style=3D"color:#080" class=3D"m_900565581701144=
5617styled-by-prettify">&quot;aa(x{b}y)aa&quot;</span><span style=3D"color:=
#000" class=3D"m_9005655817011445617styled-by-prettify">_x</span><span styl=
e=3D"color:#660" class=3D"m_9005655817011445617styled-by-prettify">;</span>=
<span style=3D"color:#000" class=3D"m_9005655817011445617styled-by-prettify=
"> </span><span style=3D"color:#660" class=3D"m_9005655817011445617styled-b=
y-prettify">=3D&gt;</span><span style=3D"color:#000" class=3D"m_90056558170=
11445617styled-by-prettify"> </span><span style=3D"color:#008" class=3D"m_9=
005655817011445617styled-by-prettify">operator</span><span style=3D"color:#=
080" class=3D"m_9005655817011445617styled-by-prettify">&quot;&quot;</span><=
span style=3D"color:#000" class=3D"m_9005655817011445617styled-by-prettify"=
>_x</span><span style=3D"color:#660" class=3D"m_9005655817011445617styled-b=
y-prettify">(</span><span style=3D"color:#000" class=3D"m_90056558170114456=
17styled-by-prettify">R</span><span style=3D"color:#080" class=3D"m_9005655=
817011445617styled-by-prettify">&quot;aa(x)aa&quot;</span><span style=3D"co=
lor:#000" class=3D"m_9005655817011445617styled-by-prettify">_x</span><span =
style=3D"color:#660" class=3D"m_9005655817011445617styled-by-prettify">,</s=
pan><span style=3D"color:#000" class=3D"m_9005655817011445617styled-by-pret=
tify"> b</span><span style=3D"color:#660" class=3D"m_9005655817011445617sty=
led-by-prettify">,</span><span style=3D"color:#000" class=3D"m_900565581701=
1445617styled-by-prettify"> R</span><span style=3D"color:#080" class=3D"m_9=
005655817011445617styled-by-prettify">&quot;aa(y)aa&quot;</span><span style=
=3D"color:#000" class=3D"m_9005655817011445617styled-by-prettify">_x</span>=
<span style=3D"color:#660" class=3D"m_9005655817011445617styled-by-prettify=
">);</span><span style=3D"color:#000" class=3D"m_9005655817011445617styled-=
by-prettify"> </span><span style=3D"color:#800" class=3D"m_9005655817011445=
617styled-by-prettify">//it have precedence over `R` prefix</span></div></c=
ode></div><br><br><br>Rest will be implemented by library, this mean `F&quo=
t;a {5} b&quot;` will not compile because there is no matching operator. st=
l could add this operator for `s` postfix, that will use `std::to_string` f=
or conversing all arguments:<br><div style=3D"background-color:rgb(250,250,=
250);border-color:rgb(187,187,187);border-style:solid;border-width:1px" cla=
ss=3D"m_9005655817011445617prettyprint"><code class=3D"m_900565581701144561=
7prettyprint"><div class=3D"m_9005655817011445617subprettyprint"><span styl=
e=3D"color:#008" class=3D"m_9005655817011445617styled-by-prettify">template=
</span><span style=3D"color:#660" class=3D"m_9005655817011445617styled-by-p=
rettify">&lt;</span><span style=3D"color:#008" class=3D"m_90056558170114456=
17styled-by-prettify">typename</span><span style=3D"color:#660" class=3D"m_=
9005655817011445617styled-by-prettify">...</span><span style=3D"color:#000"=
 class=3D"m_9005655817011445617styled-by-prettify"> </span><span style=3D"c=
olor:#606" class=3D"m_9005655817011445617styled-by-prettify">Parts</span><s=
pan style=3D"color:#660" class=3D"m_9005655817011445617styled-by-prettify">=
&gt;</span><span style=3D"color:#000" class=3D"m_9005655817011445617styled-=
by-prettify"><br>std</span><span style=3D"color:#660" class=3D"m_9005655817=
011445617styled-by-prettify">::</span><span style=3D"color:#008" class=3D"m=
_9005655817011445617styled-by-prettify">string</span><span style=3D"color:#=
000" class=3D"m_9005655817011445617styled-by-prettify"> </span><span style=
=3D"color:#008" class=3D"m_9005655817011445617styled-by-prettify">operator<=
/span><span style=3D"color:#080" class=3D"m_9005655817011445617styled-by-pr=
ettify">&quot;&quot;</span><span style=3D"color:#000" class=3D"m_9005655817=
011445617styled-by-prettify">s</span><span style=3D"color:#660" class=3D"m_=
9005655817011445617styled-by-prettify">(</span><span style=3D"color:#606" c=
lass=3D"m_9005655817011445617styled-by-prettify">Parts</span><span style=3D=
"color:#660" class=3D"m_9005655817011445617styled-by-prettify">&amp;&amp;..=
..</span><span style=3D"color:#000" class=3D"m_9005655817011445617styled-by-=
prettify"> p</span><span style=3D"color:#660" class=3D"m_900565581701144561=
7styled-by-prettify">)</span><span style=3D"color:#000" class=3D"m_90056558=
17011445617styled-by-prettify"> </span><span style=3D"color:#660" class=3D"=
m_9005655817011445617styled-by-prettify">{</span><span style=3D"color:#000"=
 class=3D"m_9005655817011445617styled-by-prettify"> </span><span style=3D"c=
olor:#008" class=3D"m_9005655817011445617styled-by-prettify">return</span><=
span style=3D"color:#000" class=3D"m_9005655817011445617styled-by-prettify"=
> std</span><span style=3D"color:#660" class=3D"m_9005655817011445617styled=
-by-prettify">::</span><span style=3D"color:#000" class=3D"m_90056558170114=
45617styled-by-prettify">to_string</span><span style=3D"color:#660" class=
=3D"m_9005655817011445617styled-by-prettify">(</span><span style=3D"color:#=
000" class=3D"m_9005655817011445617styled-by-prettify">std</span><span styl=
e=3D"color:#660" class=3D"m_9005655817011445617styled-by-prettify">::</span=
><span style=3D"color:#000" class=3D"m_9005655817011445617styled-by-prettif=
y">forward</span><span style=3D"color:#660" class=3D"m_9005655817011445617s=
tyled-by-prettify">&lt;</span><span style=3D"color:#606" class=3D"m_9005655=
817011445617styled-by-prettify">Pa<wbr>rts</span><span style=3D"color:#660"=
 class=3D"m_9005655817011445617styled-by-prettify">&gt;(</span><span style=
=3D"color:#000" class=3D"m_9005655817011445617styled-by-prettify">p</span><=
span style=3D"color:#660" class=3D"m_9005655817011445617styled-by-prettify"=
>))</span><span style=3D"color:#000" class=3D"m_9005655817011445617styled-b=
y-prettify"> </span><span style=3D"color:#660" class=3D"m_90056558170114456=
17styled-by-prettify">+</span><span style=3D"color:#000" class=3D"m_9005655=
817011445617styled-by-prettify"> </span><span style=3D"color:#660" class=3D=
"m_9005655817011445617styled-by-prettify">...;</span><span style=3D"color:#=
000" class=3D"m_9005655817011445617styled-by-prettify"> </span><span style=
=3D"color:#660" class=3D"m_9005655817011445617styled-by-prettify">}</span><=
span style=3D"color:#000" class=3D"m_9005655817011445617styled-by-prettify"=
><br><br></span><span style=3D"color:#008" class=3D"m_9005655817011445617st=
yled-by-prettify">int</span><span style=3D"color:#000" class=3D"m_900565581=
7011445617styled-by-prettify"> main</span><span style=3D"color:#660" class=
=3D"m_9005655817011445617styled-by-prettify">()</span><span style=3D"color:=
#000" class=3D"m_9005655817011445617styled-by-prettify"><br></span><span st=
yle=3D"color:#660" class=3D"m_9005655817011445617styled-by-prettify">{</spa=
n><span style=3D"color:#000" class=3D"m_9005655817011445617styled-by-pretti=
fy"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008" class=3D"m_90056558=
17011445617styled-by-prettify">auto</span><span style=3D"color:#000" class=
=3D"m_9005655817011445617styled-by-prettify"> x </span><span style=3D"color=
:#660" class=3D"m_9005655817011445617styled-by-prettify">=3D</span><span st=
yle=3D"color:#000" class=3D"m_9005655817011445617styled-by-prettify"> F</sp=
an><span style=3D"color:#080" class=3D"m_9005655817011445617styled-by-prett=
ify">&quot;Test {{a}} =3D {10+5}&quot;</span><span style=3D"color:#000" cla=
ss=3D"m_9005655817011445617styled-by-prettify">s</span><span style=3D"color=
:#660" class=3D"m_9005655817011445617styled-by-prettify">;</span><span styl=
e=3D"color:#000" class=3D"m_9005655817011445617styled-by-prettify"> </span>=
<span style=3D"color:#800" class=3D"m_9005655817011445617styled-by-prettify=
">//x =3D=3D &quot;Test {a} =3D 15&quot;s</span><span style=3D"color:#000" =
class=3D"m_9005655817011445617styled-by-prettify"><br></span><span style=3D=
"color:#660" class=3D"m_9005655817011445617styled-by-prettify">}</span><spa=
n style=3D"color:#000" class=3D"m_9005655817011445617styled-by-prettify"><b=
r></span></div></code></div><code>No iosteam, and even more it could if som=
eone relay desire to have localizations:<br><br><div style=3D"background-co=
lor:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;borde=
r-width:1px" class=3D"m_9005655817011445617prettyprint"><code class=3D"m_90=
05655817011445617prettyprint"><div class=3D"m_9005655817011445617subprettyp=
rint"><span style=3D"color:#000" class=3D"m_9005655817011445617styled-by-pr=
ettify">F</span><span style=3D"color:#080" class=3D"m_9005655817011445617st=
yled-by-prettify">&quot;Test {356*10}&quot;</span><span style=3D"color:#000=
" class=3D"m_9005655817011445617styled-by-prettify">_loc</span><span style=
=3D"color:#660" class=3D"m_9005655817011445617styled-by-prettify">(</span><=
span style=3D"color:#080" class=3D"m_9005655817011445617styled-by-prettify"=
>&quot;Prod {0} OK!&quot;</span><span style=3D"color:#660" class=3D"m_90056=
55817011445617styled-by-prettify">,</span><span style=3D"color:#000" class=
=3D"m_9005655817011445617styled-by-prettify"> </span><span style=3D"color:#=
080" class=3D"m_9005655817011445617styled-by-prettify">&quot;fr&quot;</span=
><span style=3D"color:#660" class=3D"m_9005655817011445617styled-by-prettif=
y">)</span><span style=3D"color:#000" class=3D"m_9005655817011445617styled-=
by-prettify"> </span><span style=3D"color:#660" class=3D"m_9005655817011445=
617styled-by-prettify">=3D=3D</span><span style=3D"color:#000" class=3D"m_9=
005655817011445617styled-by-prettify"> </span><span style=3D"color:#080" cl=
ass=3D"m_9005655817011445617styled-by-prettify">&quot;Prod 3.560,00 OK!&quo=
t;</span><span style=3D"color:#660" class=3D"m_9005655817011445617styled-by=
-prettify">;</span><span style=3D"color:#000" class=3D"m_900565581701144561=
7styled-by-prettify"><br></span></div></code></div><br>Only drawback is som=
e template bloat but this is probably acceptable cost.</code></div></div></=
blockquote></div></div></div><div dir=3D"auto"><br></div><div dir=3D"auto">=
This is exactly the kind of thing I&#39;m aiming for, although I dont belie=
ve string conversion and concatenation to be the final solution - unless my=
 recall of benchmarks is out of date, streams are faster than string concat=
enation.</div><div dir=3D"auto"><br></div><div dir=3D"auto">This being said=
, similar ideas can be applied to utilise the fmt library, for example.</di=
v><div dir=3D"auto"></div><div dir=3D"auto"><div class=3D"gmail_extra"><div=
 class=3D"gmail_quote"><blockquote class=3D"quote" style=3D"margin:0 0 0 .8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><code=
></code></div></div></blockquote></div></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCOSZHaTA%3DYPSDU8Add7mE_BYcYP=
RCmGW8TRPtZhdqL8Hw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCOSZH=
aTA%3DYPSDU8Add7mE_BYcYPRCmGW8TRPtZhdqL8Hw%40mail.gmail.com</a>.<br />

--001a11c0327aba08bb0564cdfe15--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 9 Feb 2018 13:37:27 -0800 (PST)
Raw View
------=_Part_3215_1142360921.1518212247677
Content-Type: multipart/alternative;
 boundary="----=_Part_3216_740970474.1518212247678"

------=_Part_3216_740970474.1518212247678
Content-Type: text/plain; charset="UTF-8"

On Friday, February 9, 2018 at 1:55:48 PM UTC-5, Hyman Rosen wrote:
>
> On Fri, Feb 9, 2018 at 1:38 PM, Ren Industries <renind...@gmail.com
> <javascript:>> wrote:
>>
>> It's a pretty big mystery to me why anyone would want something built on
>> iostreams in 2018.
>> Honestly, since when is making one of the worst parts of the language
>> MORE vital a nice thing?
>>
>
> What's wrong with iostreams?  Is it that virtual functions aren't good
> enough for optimizationists?
>
> From more recent C++  standardization, we have
>     { std::vector<int>         v{3}; } // v.size() == 1
>     { std::vector<std::string> v{3}; } // v.size() == 3
>     { std::vector<int>         v{0}; } // v.size() == 1
>     { std::vector<std::string> v{0}; } // undefined behavior
>
> That does not inspire the greatest confidence that new designs emerging
> from the
> standardization process are going to be any better than what we already
> have.
>

I'm not going to defend some of the uniform initialization decisions. But
unless you can come up with a better process, the one we have is *the one
we have*. iostream's deficiencies are well-known, and suggesting that we
can't do better by bringing up one instance of the committee's failure is a
terrible reason not to try to do better.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/aba6679c-4e85-4ae0-b03b-e3f4031e352d%40isocpp.org.

------=_Part_3216_740970474.1518212247678
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Friday, February 9, 2018 at 1:55:48 PM UTC-5, Hyman Ros=
en 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"><div=
><div class=3D"gmail_quote">On Fri, Feb 9, 2018 at 1:38 PM, Ren Industries =
<span dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfusca=
ted-mailto=3D"M75mgE2VCQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#3=
9;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#3=
9;;return true;">renind...@gmail.com</a>&gt;</span> wrote:<blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div>It&#39;=
s a pretty big mystery to me why anyone would want something built on iostr=
eams in 2018.=C2=A0</div><div>Honestly, since when is making one of the wor=
st parts of the language MORE vital a nice thing?</div></div></div></div></=
blockquote><div><br>What&#39;s wrong with iostreams?=C2=A0 Is it that virtu=
al functions aren&#39;t good enough for optimizationists?<br><br>From more =
recent C++=C2=A0 standardization, we have<br><font face=3D"monospace, monos=
pace">=C2=A0 =C2=A0 { std::vector&lt;int&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0v{3}; } // v.size() =3D=3D 1<br>=C2=A0 =C2=A0 { std::vector&lt;std::stri=
ng&gt; v{3}; } // v.size() =3D=3D 3

<br style=3D"color:rgb(34,34,34);font-size:small;font-style:normal;font-wei=
ght:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transfo=
rm:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,25=
5)"><span style=3D"color:rgb(34,34,34);font-size:small;font-style:normal;fo=
nt-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-t=
ransform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,=
255,255);float:none;display:inline">=C2=A0 =C2=A0 { std::vector&lt;int&gt;=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0v{0}; } // v.size() =3D=3D 1</span><br st=
yle=3D"color:rgb(34,34,34);font-size:small;font-style:normal;font-weight:40=
0;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:non=
e;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255)"></=
font><span style=3D"color:rgb(34,34,34);font-size:small;font-style:normal;f=
ont-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-=
transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255=
,255,255);float:none;display:inline"><font face=3D"monospace, monospace">=
=C2=A0 =C2=A0 { std::vector&lt;std::string&gt; v{0}; } // undefined behavio=
r</font><br><br>That does not inspire the greatest confidence that new desi=
gns emerging from the<br>standardization process are going to be any better=
 than what we already have.</span></div></div></div></div></blockquote><div=
><br>I&#39;m not going to defend some of the uniform initialization decisio=
ns. But unless you can come up with a better process, the one we have is <i=
>the one we have</i>. iostream&#39;s deficiencies are well-known, and sugge=
sting that we can&#39;t do better by bringing up one instance of the commit=
tee&#39;s failure is a terrible reason not to try to do better.<br></div></=
div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/aba6679c-4e85-4ae0-b03b-e3f4031e352d%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/aba6679c-4e85-4ae0-b03b-e3f4031e352d=
%40isocpp.org</a>.<br />

------=_Part_3216_740970474.1518212247678--

------=_Part_3215_1142360921.1518212247677--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 9 Feb 2018 14:00:16 -0800 (PST)
Raw View
------=_Part_5504_678290328.1518213616784
Content-Type: multipart/alternative;
 boundary="----=_Part_5505_1961679114.1518213616785"

------=_Part_5505_1961679114.1518213616785
Content-Type: text/plain; charset="UTF-8"

On Friday, February 9, 2018 at 8:51:31 AM UTC-5, Jake Arkinstall wrote:
>
> On 9 Feb 2018 08:24, "Thiago Macieira" <thi...@macieira.org <javascript:>>
> wrote:
>
> On Friday, 9 February 2018 00:05:44 PST Richard Hodges wrote:
> > It's a great idea. Naysayers talk of performance concerns as a result of
> > virtual functions. These are irrelevant.
> >
> > Firstly, the cost of turning numeric values into strings far outweighs
> the
> > cost of a virtual call
>
> That depends on a lot. The cost of a virtual call could easily get to 5%
> total
> time of a conversion, which is non-negligible, if there's no memory
> allocation
> involved.
>
>
> 5% during a debug stage is no big deal. I set the scene for a good reason:
> not all code is production code.
>

So... you want to add a language feature that you know up-front ought not
be used in production code? No, the committee should not spend time on
things like that. Not when there are genuine deficiencies in the language
that matter for actual production code.

We shouldn't be making language features that "production code" should
avoid. We should be making "production code" *easier to write*.

My focus here is making C++ friendlier until performance is a goal.
>

Again, you start from the presumption that "performance" and "friendliness"
are diametrically opposed. I see nothing about writing conversion functions
that require "unfriendliness". Just because it isn't the iostreams garbage
doesn't make it unfriendly; just *new*.

There is absolutely no reason, that I can see, to treat early development
> with the same fine-tooth comb as the final product.
>

Early development code often *becomes* code in the final product. I've seen
it happen in many projects. You write something quick and dirty, with the
expectation that you'll refactor it later or something. But you never get
the chance to actually do so; there are too many actually important things
to be getting on with. So the bad code sits there.

> Second, fixing iostream to make it more efficient is a separate concern.
>
> More than likely, doing that means replacing it entirely, which in turn
> means
> this feature cannot depend on iostreams. It must be generic, if it exists
> at
> all.
>
>
> That would be nice, but generic is a royal pain in the backside in this
> circumstance.
>

Then make it *not* be "a royal pain in the backside." Put forth a design
that doesn't have these pain points.

Simply declaring that it won't work without investigating the possibilities
is defeatist. *Especially* since we're now on the cusp of having
compile-time string manipulation in the language. I know that's not enough
to do what you're talking about, but the existence of such a thing means
that the idea is not beyond the realm of possibility.


> This is not something that can be written in the current language because
> it requires interpetation of the strings.
>

There are three aspects to this proposal: 1) the parsing of a string
literal into sections of the literal and object names, 2) the conversion of
each object name into a string, and 3) the concatenation of those bits of
strings into the final string. Obviously, steps 2 and 3 can be rather
interrelated.


> How on earth that is supposed to generalise to choices of fmt, string
> conversion and concatenation, stringstreams, and whatever magical solution
> we're waiting on to make string manipulation efficient, I have no idea,
> especially in the general situation where the different approaches - e.g.
> to_string and operator<< - are not equivalent.
>

That's the thing with proposals. If you're serious about it, you *find*
ways to solve the problems.

Your proposal's biggest problem is that it binds a rightfully-maligned
library construct to a language construct, thereby *permanently* affixing
it into people's code, to the point where said language construct will be
avoided by people who actually care about performance. You even acknowledge
that this is a problem by saying that it's not for "production code". Why
should we add language features that production code should avoid?

The other thing is that you don't have to generalize the solution to be
able to work with any conversion system. The problem is not that you've
picked a *particular* library solution. It's that you've picked a *bad*
particular library solution.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/32bedcad-92df-4d63-98ed-8f05c558cab7%40isocpp.org.

------=_Part_5505_1961679114.1518213616785
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Friday, February 9, 2018 at 8:51:31 AM UTC-5, Jake Arki=
nstall wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"auto"=
><div><div><div class=3D"gmail_quote">On 9 Feb 2018 08:24, &quot;Thiago Mac=
ieira&quot; &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-ma=
ilto=3D"IzdCzbKECQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;java=
script:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;ret=
urn true;">thi...@macieira.org</a>&gt; wrote:<br type=3D"attribution"><bloc=
kquote style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div>On Friday, 9 February 2018 00:05:44 PST Richard Hodges wrote:<br>
&gt; It&#39;s a great idea. Naysayers talk of performance concerns as a res=
ult of<br>
&gt; virtual functions. These are irrelevant.<br>
&gt;<br>
&gt; Firstly, the cost of turning numeric values into strings far outweighs=
 the<br>
&gt; cost of a virtual call<br>
<br>
</div>That depends on a lot. The cost of a virtual call could easily get to=
 5% total<br>
time of a conversion, which is non-negligible, if there&#39;s no memory all=
ocation<br>
involved.<br></blockquote></div></div></div><div dir=3D"auto"><br></div><di=
v dir=3D"auto">5% during a debug stage is no big deal. I set the scene for =
a good reason: not all code is production code.</div></div></blockquote><di=
v><br>So... you want to add a language feature that you know up-front ought=
 not be used in production code? No, the committee should not spend time on=
 things like that. Not when there are genuine deficiencies in the language =
that matter for actual production code.<br><br>We shouldn&#39;t be making l=
anguage features that &quot;production code&quot; should avoid. We should b=
e making &quot;production code&quot; <i>easier to write</i>.<br><br></div><=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"auto"><div dir=3D"a=
uto">My focus here is making C++ friendlier until performance is a goal.</d=
iv></div></blockquote><div><br>Again, you start from the presumption that &=
quot;performance&quot; and &quot;friendliness&quot; are diametrically oppos=
ed. I see nothing about writing conversion functions that require &quot;unf=
riendliness&quot;. Just because it isn&#39;t the iostreams garbage doesn&#3=
9;t make it unfriendly; just <i>new</i>.<br><br></div><blockquote class=3D"=
gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc so=
lid;padding-left: 1ex;"><div dir=3D"auto"><div dir=3D"auto">There is absolu=
tely no reason, that I can see, to treat early development with the same fi=
ne-tooth comb as the final product.</div></div></blockquote><div><br>Early =
development code often <i>becomes</i> code in the final product. I&#39;ve s=
een it happen in many projects. You write something quick and dirty, with t=
he expectation that you&#39;ll refactor it later or something. But you neve=
r get the chance to actually do so; there are too many actually important t=
hings to be getting on with. So the bad code sits there.<br><br></div><bloc=
kquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-l=
eft: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"auto"><div dir=3D"auto"=
></div><div dir=3D"auto"><div><div class=3D"gmail_quote"><blockquote style=
=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div>
&gt; Second, fixing iostream to make it more efficient is a separate concer=
n.<br>
<br>
</div>More than likely, doing that means replacing it entirely, which in tu=
rn means<br>
this feature cannot depend on iostreams. It must be generic, if it exists a=
t<br>
all.</blockquote></div></div></div><div dir=3D"auto"><br></div><div dir=3D"=
auto">That would be nice, but generic is a royal pain in the backside in th=
is circumstance.</div></div></blockquote><div><br>Then make it <i>not</i> b=
e &quot;a royal pain in the backside.&quot; Put forth a design that doesn&#=
39;t have these pain points.<br><br>Simply declaring that it won&#39;t work=
 without investigating the possibilities is defeatist. <i>Especially</i> si=
nce we&#39;re now on the cusp of having compile-time string manipulation in=
 the language. I know that&#39;s not enough to do what you&#39;re talking a=
bout, but the existence of such a thing means that the idea is not beyond t=
he realm of possibility.<br>=C2=A0</div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-le=
ft: 1ex;"><div dir=3D"auto"><div dir=3D"auto">This is not something that ca=
n be written in the current language because it requires interpetation of t=
he strings.</div></div></blockquote><div><br>There are three aspects to thi=
s proposal: 1) the parsing of a string literal into sections of the literal=
 and object names, 2) the conversion of each object name into a string, and=
 3) the concatenation of those bits of strings into the final string. Obvio=
usly, steps 2 and 3 can be rather interrelated.<br>=C2=A0</div><blockquote =
class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1p=
x #ccc solid;padding-left: 1ex;"><div dir=3D"auto"><div dir=3D"auto">How on=
 earth that is supposed to generalise to choices of fmt, string conversion =
and concatenation, stringstreams, and whatever magical solution we&#39;re w=
aiting on to make string manipulation efficient, I have no idea, especially=
 in the general situation where the different approaches - e.g. to_string a=
nd operator&lt;&lt; - are not equivalent.</div></div></blockquote><div><br>=
That&#39;s the thing with proposals. If you&#39;re serious about it, you <i=
>find</i> ways to solve the problems.<br><br>Your proposal&#39;s biggest pr=
oblem is that it binds a rightfully-maligned library construct to a languag=
e construct, thereby <i>permanently</i> affixing it into people&#39;s code,=
 to the point where said language construct will be avoided by people who a=
ctually care about performance. You even acknowledge that this is a problem=
 by saying that it&#39;s not for &quot;production code&quot;. Why should we=
 add language features that production code should avoid?<br><br>The other =
thing is that you don&#39;t have to generalize the solution to be able to w=
ork with any conversion system. The problem is not that you&#39;ve picked a=
 <i>particular</i> library solution. It&#39;s that you&#39;ve picked a <i>b=
ad</i> particular library solution.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/32bedcad-92df-4d63-98ed-8f05c558cab7%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/32bedcad-92df-4d63-98ed-8f05c558cab7=
%40isocpp.org</a>.<br />

------=_Part_5505_1961679114.1518213616785--

------=_Part_5504_678290328.1518213616784--

.


Author: inkwizytoryankes@gmail.com
Date: Fri, 9 Feb 2018 14:12:26 -0800 (PST)
Raw View
------=_Part_2334_264573856.1518214346871
Content-Type: multipart/alternative;
 boundary="----=_Part_2335_1613922253.1518214346872"

------=_Part_2335_1613922253.1518214346872
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



On Friday, February 9, 2018 at 10:13:10 PM UTC+1, Jake Arkinstall wrote:
>
>
>
> On 9 Feb 2018 20:51, <inkwizyt...@gmail.com <javascript:>> wrote:
>
>
> Minimal version than could be added to C++ is new string prefix `F`=20
> (because we have `R`, `u`, `u8` and `U` already, and `$` is outside of=20
> source characters) that enable mixing code with string literals.
> As Marcel Kr=C3=BCger wrote, language could transform this string literal=
 to:
> F"testA{a}test{{B}}"_x; =3D> operator""_x("testA"_x, a, "test{B}"_x); //u=
sing=20
> same postfix to parse sub-literals
> FR"aa(x{b}y)aa"_x; =3D> operator""_x(R"aa(x)aa"_x, b, R"aa(y)aa"_x); //it=
=20
> have precedence over `R` prefix
>
>
>
> Rest will be implemented by library, this mean `F"a {5} b"` will not=20
> compile because there is no matching operator. stl could add this operato=
r=20
> for `s` postfix, that will use `std::to_string` for conversing all=20
> arguments:
> template<typename... Parts>
> std::string operator""s(Parts&&... p) { return std::to_string(std::forwar=
d
> <Parts>(p)) + ...; }
>
> int main()
> {
>     auto x =3D F"Test {{a}} =3D {10+5}"s; //x =3D=3D "Test {a} =3D 15"s
> }
> No iosteam, and even more it could if someone relay desire to have=20
> localizations:
>
> F"Test {356*10}"_loc("Prod {0} OK!", "fr") =3D=3D "Prod 3.560,00 OK!";
>
> Only drawback is some template bloat but this is probably acceptable cost=
..
>
>
> This is exactly the kind of thing I'm aiming for, although I dont believe=
=20
> string conversion and concatenation to be the final solution - unless my=
=20
> recall of benchmarks is out of date, streams are faster than string=20
> concatenation.
>
> This being said, similar ideas can be applied to utilise the fmt library,=
=20
> for example.
>
=20
This is irrelevant, how it will be implemented is QoI, It could be done=20
using `snprintf`, or even not implemented at all, only prefix `F`and its=20
transformation is important.

More I think about this more it look as great addition to language:
std::string a;
int b =3D 0;
int c =3D 42;
db.run(F"select name as {a}, age as {b} from table where id =3D {c}"_sql);

auto i =3D 1;
auto j =3D 3;
FR"(
set x =3D {i};
set b =3D {j};
set {i} =3D 3 * x + b + b;
)"_script;
assert(i =3D=3D 9);

F"Log %f{3.5f} %3f{100f} %d{5}"_printf; // equal to printf("Log %f %3f %d",=
=20
3.5f, 100f, 5)





--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/4bce681e-e729-4124-9322-69291fdb6678%40isocpp.or=
g.

------=_Part_2335_1613922253.1518214346872
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Friday, February 9, 2018 at 10:13:10 PM UTC+1, =
Jake Arkinstall 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"auto"><div><br><div><br><div class=3D"gmail_quote">On 9 Feb 2018 20:51,=
  &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"gF=
2xaMycCQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#3=
9;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;"=
>inkwizyt...@gmail.com</a>&gt; wrote:<br type=3D"attribution"><blockquote s=
tyle=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div=
 dir=3D"ltr"><div><br></div><div>Minimal version than could be added to C++=
 is new string prefix `F` (because we have `R`, `u`, `u8` and `U` already, =
and `$` is outside of source characters) that enable mixing code with strin=
g literals.<br>As Marcel Kr=C3=BCger wrote, language could transform this s=
tring literal to:<br><div style=3D"background-color:rgb(250,250,250);border=
-color:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><sp=
an style=3D"color:#000">F</span><span style=3D"color:#080">&quot;testA{a}te=
st{{B}}&quot;</span><span style=3D"color:#000">_x</span><span style=3D"colo=
r:#660">;</span><span style=3D"color:#000"> </span><span style=3D"color:#66=
0">=3D&gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#0=
08">operator</span><span style=3D"color:#080">&quot;&quot;</span><span styl=
e=3D"color:#000">_x</span><span style=3D"color:#660">(</span><span style=3D=
"color:#080">&quot;testA&quot;</span><span style=3D"color:#000">_x</span><s=
pan style=3D"color:#660">,</span><span style=3D"color:#000"> a</span><span =
style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=
=3D"color:#080">&quot;test{B}&quot;</span><span style=3D"color:#000">_x</sp=
an><span style=3D"color:#660">);</span><span style=3D"color:#000"> </span><=
span style=3D"color:#800">//using same postfix to parse sub-literals</span>=
<span style=3D"color:#000"><br>FR</span><span style=3D"color:#080">&quot;aa=
(x{b}y)aa&quot;</span><span style=3D"color:#000">_x</span><span style=3D"co=
lor:#660">;</span><span style=3D"color:#000"> </span><span style=3D"color:#=
660">=3D&gt;</span><span style=3D"color:#000"> </span><span style=3D"color:=
#008">operator</span><span style=3D"color:#080">&quot;&quot;</span><span st=
yle=3D"color:#000">_x</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">R</span><span style=3D"color:#080">&quot;aa(x)aa&quot;</spa=
n><span style=3D"color:#000">_x</span><span style=3D"color:#660">,</span><s=
pan style=3D"color:#000"> b</span><span style=3D"color:#660">,</span><span =
style=3D"color:#000"> R</span><span style=3D"color:#080">&quot;aa(y)aa&quot=
;</span><span style=3D"color:#000">_x</span><span style=3D"color:#660">);</=
span><span style=3D"color:#000"> </span><span style=3D"color:#800">//it hav=
e precedence over `R` prefix</span></div></code></div><br><br><br>Rest will=
 be implemented by library, this mean `F&quot;a {5} b&quot;` will not compi=
le because there is no matching operator. stl could add this operator for `=
s` postfix, that will use `std::to_string` for conversing all arguments:<br=
><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,1=
87);border-style:solid;border-width:1px"><code><div><span style=3D"color:#0=
08">template</span><span style=3D"color:#660">&lt;</span><span style=3D"col=
or:#008">typename</span><span style=3D"color:#660">...</span><span style=3D=
"color:#000"> </span><span style=3D"color:#606">Parts</span><span style=3D"=
color:#660">&gt;</span><span style=3D"color:#000"><br>std</span><span style=
=3D"color:#660">::</span><span style=3D"color:#008">string</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#008">operator</span><span st=
yle=3D"color:#080">&quot;&quot;</span><span style=3D"color:#000">s</span><s=
pan style=3D"color:#660">(</span><span style=3D"color:#606">Parts</span><sp=
an style=3D"color:#660">&amp;&amp;...</span><span style=3D"color:#000"> p</=
span><span style=3D"color:#660">)</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#660">{</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#008">return</span><span style=3D"color:#000"> std</span><s=
pan style=3D"color:#660">::</span><span style=3D"color:#000">to_string</spa=
n><span style=3D"color:#660">(</span><span style=3D"color:#000">std</span><=
span style=3D"color:#660">::</span><span style=3D"color:#000">forward</span=
><span style=3D"color:#660">&lt;</span><span style=3D"color:#606">Pa<wbr>rt=
s</span><span style=3D"color:#660">&gt;(</span><span style=3D"color:#000">p=
</span><span style=3D"color:#660">))</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#660">+</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#660">...;</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#660">}</span><span style=3D"color:#000"><br><br></span><s=
pan style=3D"color:#008">int</span><span style=3D"color:#000"> main</span><=
span style=3D"color:#660">()</span><span style=3D"color:#000"><br></span><s=
pan style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color:#008">auto</span><span style=3D"color:#000"=
> x </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000">=
 F</span><span style=3D"color:#080">&quot;Test {{a}} =3D {10+5}&quot;</span=
><span style=3D"color:#000">s</span><span style=3D"color:#660">;</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#800">//x =3D=3D &quot;=
Test {a} =3D 15&quot;s</span><span style=3D"color:#000"><br></span><span st=
yle=3D"color:#660">}</span><span style=3D"color:#000"><br></span></div></co=
de></div><code>No iosteam, and even more it could if someone relay desire t=
o have localizations:<br><br><div style=3D"background-color:rgb(250,250,250=
);border-color:rgb(187,187,187);border-style:solid;border-width:1px"><code>=
<div><span style=3D"color:#000">F</span><span style=3D"color:#080">&quot;Te=
st {356*10}&quot;</span><span style=3D"color:#000">_loc</span><span style=
=3D"color:#660">(</span><span style=3D"color:#080">&quot;Prod {0} OK!&quot;=
</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#080">&quot;fr&quot;</span><span style=3D"color:#660=
">)</span><span style=3D"color:#000"> </span><span style=3D"color:#660">=3D=
=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#080">&qu=
ot;Prod 3.560,00 OK!&quot;</span><span style=3D"color:#660">;</span><span s=
tyle=3D"color:#000"><br></span></div></code></div><br>Only drawback is some=
 template bloat but this is probably acceptable cost.</code></div></div></b=
lockquote></div></div></div><div dir=3D"auto"><br></div><div dir=3D"auto">T=
his is exactly the kind of thing I&#39;m aiming for, although I dont believ=
e string conversion and concatenation to be the final solution - unless my =
recall of benchmarks is out of date, streams are faster than string concate=
nation.</div><div dir=3D"auto"><br></div><div dir=3D"auto">This being said,=
 similar ideas can be applied to utilise the fmt library, for example.</div=
></div></blockquote><div>=C2=A0<br>This is irrelevant, how it will be imple=
mented is QoI, It could be done using `snprintf`, or even not implemented a=
t all, only prefix `F`and its transformation is important.<br><br>More I th=
ink about this more it look as great addition to language:<br><div style=3D=
"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); bo=
rder-style: solid; border-width: 1px; overflow-wrap: break-word;" class=3D"=
prettyprint"><code class=3D"prettyprint"><div class=3D"subprettyprint"><spa=
n 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"colo=
r: #008;" class=3D"styled-by-prettify">string</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> a</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">int</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> b </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: #066;" class=3D"styled-by-prettify">0</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> c </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: #066;" class=3D"styled-by-prett=
ify">42</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>db</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">run</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">F</span><span style=3D"color: #080;" clas=
s=3D"styled-by-prettify">&quot;select name as {a}, age as {b} from table wh=
ere id =3D {c}&quot;</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">_sql</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
<br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> i </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: #066;" class=3D"styled-by-prettify">1</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> j </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #066;" class=3D"styled-by-prettify">3</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>FR</span><span style=3D"=
color: #080;" class=3D"styled-by-prettify">&quot;(<br>set x =3D {i};<br>set=
 b =3D {j};<br>set {i} =3D 3 * x + b + b;<br>)&quot;</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">_script</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">assert</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">i </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">=3D=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #066;" class=3D"styled-by-prettify">9</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br><br>F</span><span style=
=3D"color: #080;" class=3D"styled-by-prettify">&quot;Log %f{3.5f} %3f{100f}=
 %d{5}&quot;</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
">_printf</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">// equal to printf(=
&quot;Log %f %3f %d&quot;, 3.5f, 100f, 5)</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br><br><br></span></div></code></div><br><b=
r><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/4bce681e-e729-4124-9322-69291fdb6678%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/4bce681e-e729-4124-9322-69291fdb6678=
%40isocpp.org</a>.<br />

------=_Part_2335_1613922253.1518214346872--

------=_Part_2334_264573856.1518214346871--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Fri, 09 Feb 2018 14:16:27 -0800
Raw View
On Friday, 9 February 2018 10:55:24 PST Hyman Rosen wrote:
> From more recent C++  standardization, we have
>     { std::vector<int>         v{3}; } // v.size() == 1
>     { std::vector<std::string> v{3}; } // v.size() == 3
>     { std::vector<int>         v{0}; } // v.size() == 1
>     { std::vector<std::string> v{0}; } // undefined behavior
>
> That does not inspire the greatest confidence that new designs emerging
> from the
> standardization process are going to be any better than what we already
> have.

So the committee is fallible.

Should we stop trying and improving?

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center



--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/5762965.mfLdIVPXM0%40tjmaciei-mobl1.

.


Author: Jake Arkinstall <jake.arkinstall@gmail.com>
Date: Fri, 9 Feb 2018 22:37:19 +0000
Raw View
--f4f5e808d750db41bb0564cf2b96
Content-Type: text/plain; charset="UTF-8"

Yep, understood. My aim was to get a discussion rolling, and my idea was to
communicate my idea through a way that is clear as day. Now the idea is
communicated, and the retaliation being that streams are viewed as the
Satan's rectum of C++, the constructive part can start. And it has. I
appreciate your advice about the seriousness in which one should approach a
proposal.

Let's do ourselves a favour and move on from the original implementation
idea and on to the possibilities that have opened up from other users. The
last thing we need is such ideas being swallowed up in discussion of an
expired implementation idea.

On 9 Feb 2018 22:00, "Nicol Bolas" <jmckesson@gmail.com> wrote:

> On Friday, February 9, 2018 at 8:51:31 AM UTC-5, Jake Arkinstall wrote:
>>
>> On 9 Feb 2018 08:24, "Thiago Macieira" <thi...@macieira.org> wrote:
>>
>> On Friday, 9 February 2018 00:05:44 PST Richard Hodges wrote:
>> > It's a great idea. Naysayers talk of performance concerns as a result of
>> > virtual functions. These are irrelevant.
>> >
>> > Firstly, the cost of turning numeric values into strings far outweighs
>> the
>> > cost of a virtual call
>>
>> That depends on a lot. The cost of a virtual call could easily get to 5%
>> total
>> time of a conversion, which is non-negligible, if there's no memory
>> allocation
>> involved.
>>
>>
>> 5% during a debug stage is no big deal. I set the scene for a good
>> reason: not all code is production code.
>>
>
> So... you want to add a language feature that you know up-front ought not
> be used in production code? No, the committee should not spend time on
> things like that. Not when there are genuine deficiencies in the language
> that matter for actual production code.
>
> We shouldn't be making language features that "production code" should
> avoid. We should be making "production code" *easier to write*.
>
> My focus here is making C++ friendlier until performance is a goal.
>>
>
> Again, you start from the presumption that "performance" and
> "friendliness" are diametrically opposed. I see nothing about writing
> conversion functions that require "unfriendliness". Just because it isn't
> the iostreams garbage doesn't make it unfriendly; just *new*.
>
> There is absolutely no reason, that I can see, to treat early development
>> with the same fine-tooth comb as the final product.
>>
>
> Early development code often *becomes* code in the final product. I've
> seen it happen in many projects. You write something quick and dirty, with
> the expectation that you'll refactor it later or something. But you never
> get the chance to actually do so; there are too many actually important
> things to be getting on with. So the bad code sits there.
>
> > Second, fixing iostream to make it more efficient is a separate concern.
>>
>> More than likely, doing that means replacing it entirely, which in turn
>> means
>> this feature cannot depend on iostreams. It must be generic, if it exists
>> at
>> all.
>>
>>
>> That would be nice, but generic is a royal pain in the backside in this
>> circumstance.
>>
>
> Then make it *not* be "a royal pain in the backside." Put forth a design
> that doesn't have these pain points.
>
> Simply declaring that it won't work without investigating the
> possibilities is defeatist. *Especially* since we're now on the cusp of
> having compile-time string manipulation in the language. I know that's not
> enough to do what you're talking about, but the existence of such a thing
> means that the idea is not beyond the realm of possibility.
>
>
>> This is not something that can be written in the current language because
>> it requires interpetation of the strings.
>>
>
> There are three aspects to this proposal: 1) the parsing of a string
> literal into sections of the literal and object names, 2) the conversion of
> each object name into a string, and 3) the concatenation of those bits of
> strings into the final string. Obviously, steps 2 and 3 can be rather
> interrelated.
>
>
>> How on earth that is supposed to generalise to choices of fmt, string
>> conversion and concatenation, stringstreams, and whatever magical solution
>> we're waiting on to make string manipulation efficient, I have no idea,
>> especially in the general situation where the different approaches - e.g.
>> to_string and operator<< - are not equivalent.
>>
>
> That's the thing with proposals. If you're serious about it, you *find*
> ways to solve the problems.
>
> Your proposal's biggest problem is that it binds a rightfully-maligned
> library construct to a language construct, thereby *permanently* affixing
> it into people's code, to the point where said language construct will be
> avoided by people who actually care about performance. You even acknowledge
> that this is a problem by saying that it's not for "production code". Why
> should we add language features that production code should avoid?
>
> The other thing is that you don't have to generalize the solution to be
> able to work with any conversion system. The problem is not that you've
> picked a *particular* library solution. It's that you've picked a *bad*
> particular library solution.
>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit https://groups.google.com/a/
> isocpp.org/d/msgid/std-proposals/32bedcad-92df-4d63-
> 98ed-8f05c558cab7%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/32bedcad-92df-4d63-98ed-8f05c558cab7%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCOEw3aZAH1tB4hKeZyVWKG%2BHiGybyvGk5X1PehdY0aBHg%40mail.gmail.com.

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

<div dir=3D"auto">Yep, understood. My aim was to get a discussion rolling, =
and my idea was to communicate my idea through a way that is clear as day. =
Now the idea is communicated, and the retaliation being that streams are vi=
ewed as the Satan&#39;s rectum of C++, the constructive part can start. And=
 it has. I appreciate your advice about the seriousness in which one should=
 approach a proposal.<div dir=3D"auto"><br></div><div dir=3D"auto">Let&#39;=
s do ourselves a favour and move on from the original implementation idea a=
nd on to the possibilities that have opened up from other users. The last t=
hing we need is such ideas being swallowed up in discussion of an expired i=
mplementation idea.</div></div><div class=3D"gmail_extra"><br><div class=3D=
"gmail_quote">On 9 Feb 2018 22:00, &quot;Nicol Bolas&quot; &lt;<a href=3D"m=
ailto:jmckesson@gmail.com">jmckesson@gmail.com</a>&gt; wrote:<br type=3D"at=
tribution"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Friday, Febru=
ary 9, 2018 at 8:51:31 AM UTC-5, Jake Arkinstall wrote:<blockquote class=3D=
"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"auto"><div><div><div class=3D"gmail_quote">=
On 9 Feb 2018 08:24, &quot;Thiago Macieira&quot; &lt;<a rel=3D"nofollow">th=
i...@macieira.org</a>&gt; wrote:<br type=3D"attribution"><blockquote style=
=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>On =
Friday, 9 February 2018 00:05:44 PST Richard Hodges wrote:<br>
&gt; It&#39;s a great idea. Naysayers talk of performance concerns as a res=
ult of<br>
&gt; virtual functions. These are irrelevant.<br>
&gt;<br>
&gt; Firstly, the cost of turning numeric values into strings far outweighs=
 the<br>
&gt; cost of a virtual call<br>
<br>
</div>That depends on a lot. The cost of a virtual call could easily get to=
 5% total<br>
time of a conversion, which is non-negligible, if there&#39;s no memory all=
ocation<br>
involved.<br></blockquote></div></div></div><div dir=3D"auto"><br></div><di=
v dir=3D"auto">5% during a debug stage is no big deal. I set the scene for =
a good reason: not all code is production code.</div></div></blockquote><di=
v><br>So... you want to add a language feature that you know up-front ought=
 not be used in production code? No, the committee should not spend time on=
 things like that. Not when there are genuine deficiencies in the language =
that matter for actual production code.<br><br>We shouldn&#39;t be making l=
anguage features that &quot;production code&quot; should avoid. We should b=
e making &quot;production code&quot; <i>easier to write</i>.<br><br></div><=
blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border=
-left:1px #ccc solid;padding-left:1ex"><div dir=3D"auto"><div dir=3D"auto">=
My focus here is making C++ friendlier until performance is a goal.</div></=
div></blockquote><div><br>Again, you start from the presumption that &quot;=
performance&quot; and &quot;friendliness&quot; are diametrically opposed. I=
 see nothing about writing conversion functions that require &quot;unfriend=
liness&quot;. Just because it isn&#39;t the iostreams garbage doesn&#39;t m=
ake it unfriendly; just <i>new</i>.<br><br></div><blockquote class=3D"gmail=
_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"auto"><div dir=3D"auto">There is absolutely no re=
ason, that I can see, to treat early development with the same fine-tooth c=
omb as the final product.</div></div></blockquote><div><br>Early developmen=
t code often <i>becomes</i> code in the final product. I&#39;ve seen it hap=
pen in many projects. You write something quick and dirty, with the expecta=
tion that you&#39;ll refactor it later or something. But you never get the =
chance to actually do so; there are too many actually important things to b=
e getting on with. So the bad code sits there.<br><br></div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc=
 solid;padding-left:1ex"><div dir=3D"auto"><div dir=3D"auto"></div><div dir=
=3D"auto"><div><div class=3D"gmail_quote"><blockquote style=3D"margin:0 0 0=
 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div>
&gt; Second, fixing iostream to make it more efficient is a separate concer=
n.<br>
<br>
</div>More than likely, doing that means replacing it entirely, which in tu=
rn means<br>
this feature cannot depend on iostreams. It must be generic, if it exists a=
t<br>
all.</blockquote></div></div></div><div dir=3D"auto"><br></div><div dir=3D"=
auto">That would be nice, but generic is a royal pain in the backside in th=
is circumstance.</div></div></blockquote><div><br>Then make it <i>not</i> b=
e &quot;a royal pain in the backside.&quot; Put forth a design that doesn&#=
39;t have these pain points.<br><br>Simply declaring that it won&#39;t work=
 without investigating the possibilities is defeatist. <i>Especially</i> si=
nce we&#39;re now on the cusp of having compile-time string manipulation in=
 the language. I know that&#39;s not enough to do what you&#39;re talking a=
bout, but the existence of such a thing means that the idea is not beyond t=
he realm of possibility.<br>=C2=A0</div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:=
1ex"><div dir=3D"auto"><div dir=3D"auto">This is not something that can be =
written in the current language because it requires interpetation of the st=
rings.</div></div></blockquote><div><br>There are three aspects to this pro=
posal: 1) the parsing of a string literal into sections of the literal and =
object names, 2) the conversion of each object name into a string, and 3) t=
he concatenation of those bits of strings into the final string. Obviously,=
 steps 2 and 3 can be rather interrelated.<br>=C2=A0</div><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"auto"><div dir=3D"auto">How on earth tha=
t is supposed to generalise to choices of fmt, string conversion and concat=
enation, stringstreams, and whatever magical solution we&#39;re waiting on =
to make string manipulation efficient, I have no idea, especially in the ge=
neral situation where the different approaches - e.g. to_string and operato=
r&lt;&lt; - are not equivalent.</div></div></blockquote><div><br>That&#39;s=
 the thing with proposals. If you&#39;re serious about it, you <i>find</i> =
ways to solve the problems.<br><br>Your proposal&#39;s biggest problem is t=
hat it binds a rightfully-maligned library construct to a language construc=
t, thereby <i>permanently</i> affixing it into people&#39;s code, to the po=
int where said language construct will be avoided by people who actually ca=
re about performance. You even acknowledge that this is a problem by saying=
 that it&#39;s not for &quot;production code&quot;. Why should we add langu=
age features that production code should avoid?<br><br>The other thing is t=
hat you don&#39;t have to generalize the solution to be able to work with a=
ny conversion system. The problem is not that you&#39;ve picked a <i>partic=
ular</i> library solution. It&#39;s that you&#39;ve picked a <i>bad</i> par=
ticular library solution.<br></div></div>

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/32bedcad-92df-4d63-98ed-8f05c558cab7%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/32be=
dcad-92df-4d63-<wbr>98ed-8f05c558cab7%40isocpp.org</a><wbr>.<br>
</blockquote></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCOEw3aZAH1tB4hKeZyVWKG%2BHiGy=
byvGk5X1PehdY0aBHg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCOEw3=
aZAH1tB4hKeZyVWKG%2BHiGybyvGk5X1PehdY0aBHg%40mail.gmail.com</a>.<br />

--f4f5e808d750db41bb0564cf2b96--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 9 Feb 2018 21:30:15 -0800 (PST)
Raw View
------=_Part_5909_1899918254.1518240615486
Content-Type: multipart/alternative;
 boundary="----=_Part_5910_1603451035.1518240615486"

------=_Part_5910_1603451035.1518240615486
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



On Friday, February 9, 2018 at 5:12:26 PM UTC-5, Marcin Jaczewski wrote:
>
>
>
> On Friday, February 9, 2018 at 10:13:10 PM UTC+1, Jake Arkinstall wrote:
>>
>>
>>
>> On 9 Feb 2018 20:51, <inkwizyt...@gmail.com> wrote:
>>
>>
>> Minimal version than could be added to C++ is new string prefix `F`=20
>> (because we have `R`, `u`, `u8` and `U` already, and `$` is outside of=
=20
>> source characters) that enable mixing code with string literals.
>> As Marcel Kr=C3=BCger wrote, language could transform this string litera=
l to:
>> F"testA{a}test{{B}}"_x; =3D> operator""_x("testA"_x, a, "test{B}"_x); //=
using=20
>> same postfix to parse sub-literals
>> FR"aa(x{b}y)aa"_x; =3D> operator""_x(R"aa(x)aa"_x, b, R"aa(y)aa"_x); //i=
t=20
>> have precedence over `R` prefix
>>
>>
>>
>> Rest will be implemented by library, this mean `F"a {5} b"` will not=20
>> compile because there is no matching operator. stl could add this operat=
or=20
>> for `s` postfix, that will use `std::to_string` for conversing all=20
>> arguments:
>> template<typename... Parts>
>> std::string operator""s(Parts&&... p) { return std::to_string(std::
>> forward<Parts>(p)) + ...; }
>>
>> int main()
>> {
>>     auto x =3D F"Test {{a}} =3D {10+5}"s; //x =3D=3D "Test {a} =3D 15"s
>> }
>> No iosteam, and even more it could if someone relay desire to have=20
>> localizations:
>>
>> F"Test {356*10}"_loc("Prod {0} OK!", "fr") =3D=3D "Prod 3.560,00 OK!";
>>
>> Only drawback is some template bloat but this is probably acceptable cos=
t.
>>
>>
>> This is exactly the kind of thing I'm aiming for, although I dont believ=
e=20
>> string conversion and concatenation to be the final solution - unless my=
=20
>> recall of benchmarks is out of date, streams are faster than string=20
>> concatenation.
>>
>> This being said, similar ideas can be applied to utilise the fmt library=
,=20
>> for example.
>>
> =20
> This is irrelevant, how it will be implemented is QoI, It could be done=
=20
> using `snprintf`, or even not implemented at all, only prefix `F`and its=
=20
> transformation is important.
>
> More I think about this more it look as great addition to language:
> std::string a;
> int b =3D 0;
> int c =3D 42;
> db.run(F"select name as {a}, age as {b} from table where id =3D {c}"_sql)=
;
>
>
If how this is implemented is a mere implementation detail, how would you=
=20
make it use bound parameters or otherwise sanitize string inputs? Have we=
=20
learned nothing from Little Bobby Tables <https://xkcd.com/327/>?

Indeed, this seems like a justification to *not* provide this feature.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/f5feb9a0-99d3-433a-ae46-af34c8d00a61%40isocpp.or=
g.

------=_Part_5910_1603451035.1518240615486
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Friday, February 9, 2018 at 5:12:26 PM UTC-5, M=
arcin Jaczewski 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"><br><br>On Friday, February 9, 2018 at 10:13:10 PM UTC+1, Jake Ark=
install wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-le=
ft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"auto"><di=
v><br><div><br><div class=3D"gmail_quote">On 9 Feb 2018 20:51,  &lt;<a rel=
=3D"nofollow">inkwizyt...@gmail.com</a>&gt; wrote:<br type=3D"attribution">=
<blockquote style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"ltr"><div><br></div><div>Minimal version than could be=
 added to C++ is new string prefix `F` (because we have `R`, `u`, `u8` and =
`U` already, and `$` is outside of source characters) that enable mixing co=
de with string literals.<br>As Marcel Kr=C3=BCger wrote, language could tra=
nsform this string literal to:<br><div style=3D"background-color:rgb(250,25=
0,250);border-color:rgb(187,187,187);border-style:solid;border-width:1px"><=
code><div><span style=3D"color:#000">F</span><span style=3D"color:#080">&qu=
ot;testA{a}test{{B}}&quot;</span><span style=3D"color:#000">_x</span><span =
style=3D"color:#660">;</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">=3D&gt;</span><span style=3D"color:#000"> </span><span styl=
e=3D"color:#008">operator</span><span style=3D"color:#080">&quot;&quot;</sp=
an><span style=3D"color:#000">_x</span><span style=3D"color:#660">(</span><=
span style=3D"color:#080">&quot;testA&quot;</span><span style=3D"color:#000=
">_x</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> a=
</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#080">&quot;test{B}&quot;</span><span style=3D"color=
:#000">_x</span><span style=3D"color:#660">);</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#800">//using same postfix to parse sub-li=
terals</span><span style=3D"color:#000"><br>FR</span><span style=3D"color:#=
080">&quot;aa(x{b}y)aa&quot;</span><span style=3D"color:#000">_x</span><spa=
n style=3D"color:#660">;</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#660">=3D&gt;</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#008">operator</span><span style=3D"color:#080">&quot;&quot;</=
span><span style=3D"color:#000">_x</span><span style=3D"color:#660">(</span=
><span style=3D"color:#000">R</span><span style=3D"color:#080">&quot;aa(x)a=
a&quot;</span><span style=3D"color:#000">_x</span><span style=3D"color:#660=
">,</span><span style=3D"color:#000"> b</span><span style=3D"color:#660">,<=
/span><span style=3D"color:#000"> R</span><span style=3D"color:#080">&quot;=
aa(y)aa&quot;</span><span style=3D"color:#000">_x</span><span style=3D"colo=
r:#660">);</span><span style=3D"color:#000"> </span><span style=3D"color:#8=
00">//it have precedence over `R` prefix</span></div></code></div><br><br><=
br>Rest will be implemented by library, this mean `F&quot;a {5} b&quot;` wi=
ll not compile because there is no matching operator. stl could add this op=
erator for `s` postfix, that will use `std::to_string` for conversing all a=
rguments:<br><div style=3D"background-color:rgb(250,250,250);border-color:r=
gb(187,187,187);border-style:solid;border-width:1px"><code><div><span style=
=3D"color:#008">template</span><span style=3D"color:#660">&lt;</span><span =
style=3D"color:#008">typename</span><span style=3D"color:#660">...</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#606">Parts</span><sp=
an style=3D"color:#660">&gt;</span><span style=3D"color:#000"><br>std</span=
><span style=3D"color:#660">::</span><span style=3D"color:#008">string</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#008">operator</s=
pan><span style=3D"color:#080">&quot;&quot;</span><span style=3D"color:#000=
">s</span><span style=3D"color:#660">(</span><span style=3D"color:#606">Par=
ts</span><span style=3D"color:#660">&amp;&amp;...</span><span style=3D"colo=
r:#000"> p</span><span style=3D"color:#660">)</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"> =
</span><span style=3D"color:#008">return</span><span style=3D"color:#000"> =
std</span><span style=3D"color:#660">::</span><span style=3D"color:#000">to=
_string</span><span style=3D"color:#660">(</span><span style=3D"color:#000"=
>std</span><span style=3D"color:#660">::</span><span style=3D"color:#000">f=
orward</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#60=
6">Pa<wbr>rts</span><span style=3D"color:#660">&gt;(</span><span style=3D"c=
olor:#000">p</span><span style=3D"color:#660">))</span><span style=3D"color=
:#000"> </span><span style=3D"color:#660">+</span><span style=3D"color:#000=
"> </span><span style=3D"color:#660">...;</span><span style=3D"color:#000">=
 </span><span style=3D"color:#660">}</span><span style=3D"color:#000"><br><=
br></span><span style=3D"color:#008">int</span><span style=3D"color:#000"> =
main</span><span style=3D"color:#660">()</span><span style=3D"color:#000"><=
br></span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br=
>=C2=A0 =C2=A0 </span><span style=3D"color:#008">auto</span><span style=3D"=
color:#000"> x </span><span style=3D"color:#660">=3D</span><span style=3D"c=
olor:#000"> F</span><span style=3D"color:#080">&quot;Test {{a}} =3D {10+5}&=
quot;</span><span style=3D"color:#000">s</span><span style=3D"color:#660">;=
</span><span style=3D"color:#000"> </span><span style=3D"color:#800">//x =
=3D=3D &quot;Test {a} =3D 15&quot;s</span><span style=3D"color:#000"><br></=
span><span style=3D"color:#660">}</span><span style=3D"color:#000"><br></sp=
an></div></code></div><code>No iosteam, and even more it could if someone r=
elay desire to have localizations:<br><br><div style=3D"background-color:rg=
b(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-widt=
h:1px"><code><div><span style=3D"color:#000">F</span><span style=3D"color:#=
080">&quot;Test {356*10}&quot;</span><span style=3D"color:#000">_loc</span>=
<span style=3D"color:#660">(</span><span style=3D"color:#080">&quot;Prod {0=
} OK!&quot;</span><span style=3D"color:#660">,</span><span style=3D"color:#=
000"> </span><span style=3D"color:#080">&quot;fr&quot;</span><span style=3D=
"color:#660">)</span><span style=3D"color:#000"> </span><span style=3D"colo=
r:#660">=3D=3D</span><span style=3D"color:#000"> </span><span style=3D"colo=
r:#080">&quot;Prod 3.560,00 OK!&quot;</span><span style=3D"color:#660">;</s=
pan><span style=3D"color:#000"><br></span></div></code></div><br>Only drawb=
ack is some template bloat but this is probably acceptable cost.</code></di=
v></div></blockquote></div></div></div><div dir=3D"auto"><br></div><div dir=
=3D"auto">This is exactly the kind of thing I&#39;m aiming for, although I =
dont believe string conversion and concatenation to be the final solution -=
 unless my recall of benchmarks is out of date, streams are faster than str=
ing concatenation.</div><div dir=3D"auto"><br></div><div dir=3D"auto">This =
being said, similar ideas can be applied to utilise the fmt library, for ex=
ample.</div></div></blockquote><div>=C2=A0<br>This is irrelevant, how it wi=
ll be implemented is QoI, It could be done using `snprintf`, or even not im=
plemented at all, only prefix `F`and its transformation is important.<br><b=
r>More I think about this more it look as great addition to language:<br><d=
iv style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187)=
;border-style:solid;border-width:1px"><code><div><span style=3D"color:#000"=
>std</span><span style=3D"color:#660">::</span><span style=3D"color:#008">s=
tring</span><span style=3D"color:#000"> a</span><span style=3D"color:#660">=
;</span><span style=3D"color:#000"><br></span><span style=3D"color:#008">in=
t</span><span style=3D"color:#000"> b </span><span style=3D"color:#660">=3D=
</span><span style=3D"color:#000"> </span><span style=3D"color:#066">0</spa=
n><span style=3D"color:#660">;</span><span style=3D"color:#000"><br></span>=
<span style=3D"color:#008">int</span><span style=3D"color:#000"> c </span><=
span style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#066">42</span><span style=3D"color:#660">;</span><span st=
yle=3D"color:#000"><br>db</span><span style=3D"color:#660">.</span><span st=
yle=3D"color:#000">run</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">F</span><span style=3D"color:#080">&quot;select name as {a}=
, age as {b} from table where id =3D {c}&quot;</span><span style=3D"color:#=
000">_sql</span><span style=3D"color:#660">);</span><span style=3D"color:#0=
00"><br><br></span></div></code></div></div></div></blockquote><div><br>If =
how this is implemented is a mere implementation detail, how would you make=
 it use bound parameters or otherwise sanitize string inputs? Have we learn=
ed nothing from <a href=3D"https://xkcd.com/327/">Little Bobby Tables</a>?<=
br><br>Indeed, this seems like a justification to <i>not</i> provide this f=
eature.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/f5feb9a0-99d3-433a-ae46-af34c8d00a61%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/f5feb9a0-99d3-433a-ae46-af34c8d00a61=
%40isocpp.org</a>.<br />

------=_Part_5910_1603451035.1518240615486--

------=_Part_5909_1899918254.1518240615486--

.


Author: Jake Arkinstall <jake.arkinstall@gmail.com>
Date: Sat, 10 Feb 2018 13:31:46 +0000
Raw View
--001a113ceaeea848c80564dbaa41
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Im a bit confused about the suggestion but it appears that the input is an
int, where the name and age are outputs. In this scenario, the _sql parser
(provided by some library) could convert that to

db.run("select name, age from table where id =3D " + db::int_input(id),
db::string_output(name), db::int_output(age));

which sets the name and age variables to the name and age columns. Adding
sql sanitisers is then done via the db::*_input methods. It just might be
possible. It would require a lot of compile-time parsing, and so a proposal
to allow this would probably need to include a bunch of mechanisms to
process string literals at compile time, but it's interesting.

I'm not sure about that exact idea, but the point is the creativity - a way
of a library being able to parse a string literal, putting code in its
place which in turn gets compiled, would give a lot more flexibility to
libraries, and let them get very creative. It could open the door to
libraries providing syntactic sugar that still provides efficient code. A
language within a language.


On 10 Feb 2018 05:30, "Nicol Bolas" <jmckesson@gmail.com> wrote:



On Friday, February 9, 2018 at 5:12:26 PM UTC-5, Marcin Jaczewski wrote:
>
>
>
> On Friday, February 9, 2018 at 10:13:10 PM UTC+1, Jake Arkinstall wrote:
>>
>>
>>
>> On 9 Feb 2018 20:51, <inkwizyt...@gmail.com> wrote:
>>
>>
>> Minimal version than could be added to C++ is new string prefix `F`
>> (because we have `R`, `u`, `u8` and `U` already, and `$` is outside of
>> source characters) that enable mixing code with string literals.
>> As Marcel Kr=C3=BCger wrote, language could transform this string litera=
l to:
>> F"testA{a}test{{B}}"_x; =3D> operator""_x("testA"_x, a, "test{B}"_x); //=
using
>> same postfix to parse sub-literals
>> FR"aa(x{b}y)aa"_x; =3D> operator""_x(R"aa(x)aa"_x, b, R"aa(y)aa"_x); //i=
t
>> have precedence over `R` prefix
>>
>>
>>
>> Rest will be implemented by library, this mean `F"a {5} b"` will not
>> compile because there is no matching operator. stl could add this operat=
or
>> for `s` postfix, that will use `std::to_string` for conversing all
>> arguments:
>> template<typename... Parts>
>> std::string operator""s(Parts&&... p) { return std::to_string(std::
>> forward<Parts>(p)) + ...; }
>>
>> int main()
>> {
>>     auto x =3D F"Test {{a}} =3D {10+5}"s; //x =3D=3D "Test {a} =3D 15"s
>> }
>> No iosteam, and even more it could if someone relay desire to have
>> localizations:
>>
>> F"Test {356*10}"_loc("Prod {0} OK!", "fr") =3D=3D "Prod 3.560,00 OK!";
>>
>> Only drawback is some template bloat but this is probably acceptable cos=
t.
>>
>>
>> This is exactly the kind of thing I'm aiming for, although I dont believ=
e
>> string conversion and concatenation to be the final solution - unless my
>> recall of benchmarks is out of date, streams are faster than string
>> concatenation.
>>
>> This being said, similar ideas can be applied to utilise the fmt library=
,
>> for example.
>>
>
> This is irrelevant, how it will be implemented is QoI, It could be done
> using `snprintf`, or even not implemented at all, only prefix `F`and its
> transformation is important.
>
> More I think about this more it look as great addition to language:
> std::string a;
> int b =3D 0;
> int c =3D 42;
> db.run(F"select name as {a}, age as {b} from table where id =3D {c}"_sql)=
;
>
>
If how this is implemented is a mere implementation detail, how would you
make it use bound parameters or otherwise sanitize string inputs? Have we
learned nothing from Little Bobby Tables <https://xkcd.com/327/>?

Indeed, this seems like a justification to *not* provide this feature.

--=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
email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/
isocpp.org/d/msgid/std-proposals/f5feb9a0-99d3-433a-
ae46-af34c8d00a61%40isocpp.org
<https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/f5feb9a0-99d3=
-433a-ae46-af34c8d00a61%40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter=
>
..

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CAC%2B0CCM-e6Ghg_KOGP9Cpm5NKvgkLSpcyV05%2BksP2Pm=
VBzXoQw%40mail.gmail.com.

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

<div dir=3D"auto"><div>Im a bit confused about the suggestion but it appear=
s that the input is an int, where the name and age are outputs. In this sce=
nario, the _sql parser (provided by some library) could convert that to</di=
v><div dir=3D"auto"><br></div><div dir=3D"auto">db.run(&quot;select name, a=
ge from table where id =3D &quot; + db::int_input(id), db::string_output(na=
me), db::int_output(age));</div><div dir=3D"auto"><br></div><div dir=3D"aut=
o">which sets the name and age variables to the name and age columns. Addin=
g sql sanitisers is then done via the db::*_input methods. It just might be=
 possible. It would require a lot of compile-time parsing, and so a proposa=
l to allow this would probably need to include a bunch of mechanisms to pro=
cess string literals at compile time, but it&#39;s interesting.</div><div d=
ir=3D"auto"><br></div><div dir=3D"auto">I&#39;m not sure about that exact i=
dea, but the point is the creativity - a way of a library being able to par=
se a string literal, putting code in its place which in turn gets compiled,=
 would give a lot more flexibility to libraries, and let them get very crea=
tive. It could open the door to libraries providing syntactic sugar that st=
ill provides efficient code. A language within a language.</div><div dir=3D=
"auto"><br><div class=3D"gmail_extra" dir=3D"auto"><br><div class=3D"gmail_=
quote">On 10 Feb 2018 05:30, &quot;Nicol Bolas&quot; &lt;<a href=3D"mailto:=
jmckesson@gmail.com">jmckesson@gmail.com</a>&gt; wrote:<br type=3D"attribut=
ion"><blockquote class=3D"quote" style=3D"margin:0 0 0 .8ex;border-left:1px=
 #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"quoted-text"><=
br><br>On Friday, February 9, 2018 at 5:12:26 PM UTC-5, Marcin Jaczewski wr=
ote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;b=
order-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><br>On Fri=
day, February 9, 2018 at 10:13:10 PM UTC+1, Jake Arkinstall wrote:<blockquo=
te class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"auto"><div><br><div><br><div cla=
ss=3D"gmail_quote">On 9 Feb 2018 20:51,  &lt;<a rel=3D"nofollow">inkwizyt..=
..@gmail.com</a>&gt; wrote:<br type=3D"attribution"><blockquote style=3D"mar=
gin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr=
"><div><br></div><div>Minimal version than could be added to C++ is new str=
ing prefix `F` (because we have `R`, `u`, `u8` and `U` already, and `$` is =
outside of source characters) that enable mixing code with string literals.=
<br>As Marcel Kr=C3=BCger wrote, language could transform this string liter=
al to:<br><div style=3D"background-color:rgb(250,250,250);border-color:rgb(=
187,187,187);border-style:solid;border-width:1px"><code><div><span style=3D=
"color:#000">F</span><span style=3D"color:#080">&quot;testA{a}test{{B}}&quo=
t;</span><span style=3D"color:#000">_x</span><span style=3D"color:#660">;</=
span><span style=3D"color:#000"> </span><span style=3D"color:#660">=3D&gt;<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#008">operato=
r</span><span style=3D"color:#080">&quot;&quot;</span><span style=3D"color:=
#000">_x</span><span style=3D"color:#660">(</span><span style=3D"color:#080=
">&quot;testA&quot;</span><span style=3D"color:#000">_x</span><span style=
=3D"color:#660">,</span><span style=3D"color:#000"> a</span><span style=3D"=
color:#660">,</span><span style=3D"color:#000"> </span><span style=3D"color=
:#080">&quot;test{B}&quot;</span><span style=3D"color:#000">_x</span><span =
style=3D"color:#660">);</span><span style=3D"color:#000"> </span><span styl=
e=3D"color:#800">//using same postfix to parse sub-literals</span><span sty=
le=3D"color:#000"><br>FR</span><span style=3D"color:#080">&quot;aa(x{b}y)aa=
&quot;</span><span style=3D"color:#000">_x</span><span style=3D"color:#660"=
>;</span><span style=3D"color:#000"> </span><span style=3D"color:#660">=3D&=
gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#008">ope=
rator</span><span style=3D"color:#080">&quot;&quot;</span><span style=3D"co=
lor:#000">_x</span><span style=3D"color:#660">(</span><span style=3D"color:=
#000">R</span><span style=3D"color:#080">&quot;aa(x)aa&quot;</span><span st=
yle=3D"color:#000">_x</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> b</span><span style=3D"color:#660">,</span><span style=3D"=
color:#000"> R</span><span style=3D"color:#080">&quot;aa(y)aa&quot;</span><=
span style=3D"color:#000">_x</span><span style=3D"color:#660">);</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#800">//it have precede=
nce over `R` prefix</span></div></code></div><br><br><br>Rest will be imple=
mented by library, this mean `F&quot;a {5} b&quot;` will not compile becaus=
e there is no matching operator. stl could add this operator for `s` postfi=
x, that will use `std::to_string` for conversing all arguments:<br><div sty=
le=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);borde=
r-style:solid;border-width:1px"><code><div><span style=3D"color:#008">templ=
ate</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">=
typename</span><span style=3D"color:#660">...</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#606">Parts</span><span style=3D"color:#66=
0">&gt;</span><span style=3D"color:#000"><br>std</span><span style=3D"color=
:#660">::</span><span style=3D"color:#008">string</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#008">operator</span><span style=3D"co=
lor:#080">&quot;&quot;</span><span style=3D"color:#000">s</span><span style=
=3D"color:#660">(</span><span style=3D"color:#606">Parts</span><span style=
=3D"color:#660">&amp;&amp;...</span><span style=3D"color:#000"> p</span><sp=
an style=3D"color:#660">)</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#660">{</span><span style=3D"color:#000"> </span><span style=
=3D"color:#008">return</span><span style=3D"color:#000"> std</span><span st=
yle=3D"color:#660">::</span><span style=3D"color:#000">to_string</span><spa=
n style=3D"color:#660">(</span><span style=3D"color:#000">std</span><span s=
tyle=3D"color:#660">::</span><span style=3D"color:#000">forward</span><span=
 style=3D"color:#660">&lt;</span><span style=3D"color:#606">Pa<wbr>rts</spa=
n><span style=3D"color:#660">&gt;(</span><span style=3D"color:#000">p</span=
><span style=3D"color:#660">))</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#660">+</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#660">...;</span><span style=3D"color:#000"> </span><span styl=
e=3D"color:#660">}</span><span style=3D"color:#000"><br><br></span><span st=
yle=3D"color:#008">int</span><span style=3D"color:#000"> main</span><span s=
tyle=3D"color:#660">()</span><span style=3D"color:#000"><br></span><span st=
yle=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </s=
pan><span style=3D"color:#008">auto</span><span style=3D"color:#000"> x </s=
pan><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> F</spa=
n><span style=3D"color:#080">&quot;Test {{a}} =3D {10+5}&quot;</span><span =
style=3D"color:#000">s</span><span style=3D"color:#660">;</span><span style=
=3D"color:#000"> </span><span style=3D"color:#800">//x =3D=3D &quot;Test {a=
} =3D 15&quot;s</span><span style=3D"color:#000"><br></span><span style=3D"=
color:#660">}</span><span style=3D"color:#000"><br></span></div></code></di=
v><code>No iosteam, and even more it could if someone relay desire to have =
localizations:<br><br><div style=3D"background-color:rgb(250,250,250);borde=
r-color:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><s=
pan style=3D"color:#000">F</span><span style=3D"color:#080">&quot;Test {356=
*10}&quot;</span><span style=3D"color:#000">_loc</span><span style=3D"color=
:#660">(</span><span style=3D"color:#080">&quot;Prod {0} OK!&quot;</span><s=
pan style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#080">&quot;fr&quot;</span><span style=3D"color:#660">)</span=
><span style=3D"color:#000"> </span><span style=3D"color:#660">=3D=3D</span=
><span style=3D"color:#000"> </span><span style=3D"color:#080">&quot;Prod 3=
..560,00 OK!&quot;</span><span style=3D"color:#660">;</span><span style=3D"c=
olor:#000"><br></span></div></code></div><br>Only drawback is some template=
 bloat but this is probably acceptable cost.</code></div></div></blockquote=
></div></div></div><div dir=3D"auto"><br></div><div dir=3D"auto">This is ex=
actly the kind of thing I&#39;m aiming for, although I dont believe string =
conversion and concatenation to be the final solution - unless my recall of=
 benchmarks is out of date, streams are faster than string concatenation.</=
div><div dir=3D"auto"><br></div><div dir=3D"auto">This being said, similar =
ideas can be applied to utilise the fmt library, for example.</div></div></=
blockquote><div>=C2=A0<br>This is irrelevant, how it will be implemented is=
 QoI, It could be done using `snprintf`, or even not implemented at all, on=
ly prefix `F`and its transformation is important.<br><br>More I think about=
 this more it look as great addition to language:<br><div style=3D"backgrou=
nd-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;=
border-width:1px"><code><div><span style=3D"color:#000">std</span><span sty=
le=3D"color:#660">::</span><span style=3D"color:#008">string</span><span st=
yle=3D"color:#000"> a</span><span style=3D"color:#660">;</span><span style=
=3D"color:#000"><br></span><span style=3D"color:#008">int</span><span style=
=3D"color:#000"> b </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> </span><span style=3D"color:#066">0</span><span style=3D"c=
olor:#660">;</span><span style=3D"color:#000"><br></span><span style=3D"col=
or:#008">int</span><span style=3D"color:#000"> c </span><span style=3D"colo=
r:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#=
066">42</span><span style=3D"color:#660">;</span><span style=3D"color:#000"=
><br>db</span><span style=3D"color:#660">.</span><span style=3D"color:#000"=
>run</span><span style=3D"color:#660">(</span><span style=3D"color:#000">F<=
/span><span style=3D"color:#080">&quot;select name as {a}, age as {b} from =
table where id =3D {c}&quot;</span><span style=3D"color:#000">_sql</span><s=
pan style=3D"color:#660">);</span><span style=3D"color:#000"><br><br></span=
></div></code></div></div></div></blockquote></div><div><br>If how this is =
implemented is a mere implementation detail, how would you make it use boun=
d parameters or otherwise sanitize string inputs? Have we learned nothing f=
rom <a href=3D"https://xkcd.com/327/" target=3D"_blank">Little Bobby Tables=
</a>?<br><br>Indeed, this seems like a justification to <i>not</i> provide =
this feature.<br></div></div><div class=3D"quoted-text">

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></div>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/f5feb9a0-99d3-433a-ae46-af34c8d00a61%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/f5fe=
b9a0-99d3-433a-<wbr>ae46-af34c8d00a61%40isocpp.org</a><wbr>.<br>
</blockquote></div><br></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCM-e6Ghg_KOGP9Cpm5NKvgkLSpcyV=
05%2BksP2PmVBzXoQw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCM-e6=
Ghg_KOGP9Cpm5NKvgkLSpcyV05%2BksP2PmVBzXoQw%40mail.gmail.com</a>.<br />

--001a113ceaeea848c80564dbaa41--

.


Author: inkwizytoryankes@gmail.com
Date: Sat, 10 Feb 2018 10:39:45 -0800 (PST)
Raw View
------=_Part_6744_1031796837.1518287985319
Content-Type: multipart/alternative;
 boundary="----=_Part_6745_2004159494.1518287985320"

------=_Part_6745_2004159494.1518287985320
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



On Saturday, February 10, 2018 at 6:30:15 AM UTC+1, Nicol Bolas wrote:
>
>
>
> On Friday, February 9, 2018 at 5:12:26 PM UTC-5, Marcin Jaczewski wrote:
>>
>>
>>
>> On Friday, February 9, 2018 at 10:13:10 PM UTC+1, Jake Arkinstall wrote:
>>>
>>>
>>>
>>> On 9 Feb 2018 20:51, <inkwizyt...@gmail.com> wrote:
>>>
>>>
>>> Minimal version than could be added to C++ is new string prefix `F`=20
>>> (because we have `R`, `u`, `u8` and `U` already, and `$` is outside of=
=20
>>> source characters) that enable mixing code with string literals.
>>> As Marcel Kr=C3=BCger wrote, language could transform this string liter=
al to:
>>> F"testA{a}test{{B}}"_x; =3D> operator""_x("testA"_x, a, "test{B}"_x); /=
/using=20
>>> same postfix to parse sub-literals
>>> FR"aa(x{b}y)aa"_x; =3D> operator""_x(R"aa(x)aa"_x, b, R"aa(y)aa"_x); //=
it=20
>>> have precedence over `R` prefix
>>>
>>>
>>>
>>> Rest will be implemented by library, this mean `F"a {5} b"` will not=20
>>> compile because there is no matching operator. stl could add this opera=
tor=20
>>> for `s` postfix, that will use `std::to_string` for conversing all=20
>>> arguments:
>>> template<typename... Parts>
>>> std::string operator""s(Parts&&... p) { return std::to_string(std::
>>> forward<Parts>(p)) + ...; }
>>>
>>> int main()
>>> {
>>>     auto x =3D F"Test {{a}} =3D {10+5}"s; //x =3D=3D "Test {a} =3D 15"s
>>> }
>>> No iosteam, and even more it could if someone relay desire to have=20
>>> localizations:
>>>
>>> F"Test {356*10}"_loc("Prod {0} OK!", "fr") =3D=3D "Prod 3.560,00 OK!";
>>>
>>> Only drawback is some template bloat but this is probably acceptable=20
>>> cost.
>>>
>>>
>>> This is exactly the kind of thing I'm aiming for, although I dont=20
>>> believe string conversion and concatenation to be the final solution -=
=20
>>> unless my recall of benchmarks is out of date, streams are faster than=
=20
>>> string concatenation.
>>>
>>> This being said, similar ideas can be applied to utilise the fmt=20
>>> library, for example.
>>>
>> =20
>> This is irrelevant, how it will be implemented is QoI, It could be done=
=20
>> using `snprintf`, or even not implemented at all, only prefix `F`and its=
=20
>> transformation is important.
>>
>> More I think about this more it look as great addition to language:
>> std::string a;
>> int b =3D 0;
>> int c =3D 42;
>> db.run(F"select name as {a}, age as {b} from table where id =3D {c}"_sql=
);
>>
>>
> If how this is implemented is a mere implementation detail, how would you=
=20
> make it use bound parameters or otherwise sanitize string inputs? Have we=
=20
> learned nothing from Little Bobby Tables <https://xkcd.com/327/>?
>
> Indeed, this seems like a justification to *not* provide this feature.
>
=20

But it can easy check it, `_sql` is not string, if you pass string then it=
=20
will be escaped before it is appended to finals string that is send to=20
database.
And how it will be exactly implemented? Like this:
db.run(operator""_sql("select name as "_sql, a, ", age as "_sql, b, "from=
=20
table where id =3D "_sql, c, ""_sql));

This will call:
sql_command operator""_sql(sql_command, std::string& a, sql_command, int& b=
,=20
sql_command, int& c, sql_command);

We have all needed information how to handle each parameter.
We can take address of `a`, `b`, and `c`. We can merge parts of sql and=20
merge in one querry.
From that we can deduce usage and if type is string we add quotes and=20
escapes value (if we need pass some sql part then we use `" and state =3D 1=
=20
"_sql` that return `sql_command` not `std::string`).
It could too simply forward to some current implementation like:
auto sql =3D sql_command("select name as PARAM_0, age as PARAM_1 from table=
=20
where id =3D $0").bind(0, c).execute(db);
a =3D sql.get<std::string>("PARAM_0");
b =3D sql.get<int>("PARAM_1");

Some of this transformation can be done at compile time (like constexpr=20
regexp).

Because we can take reference to object then we can do two-way=20
communication.



--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/8e456af5-09c3-461d-8562-30df127e93af%40isocpp.or=
g.

------=_Part_6745_2004159494.1518287985320
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Saturday, February 10, 2018 at 6:30:15 AM UTC+1=
, Nicol Bolas wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><br><br>On Friday, February 9, 2018 at 5:12:26 PM UTC-5, Marcin Ja=
czewski wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-le=
ft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br>=
<br>On Friday, February 9, 2018 at 10:13:10 PM UTC+1, Jake Arkinstall wrote=
:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div dir=3D"auto"><div><br><div><b=
r><div class=3D"gmail_quote">On 9 Feb 2018 20:51,  &lt;<a rel=3D"nofollow">=
inkwizyt...@gmail.com</a>&gt; wrote:<br type=3D"attribution"><blockquote st=
yle=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr"><div><br></div><div>Minimal version than could be added to C++ =
is new string prefix `F` (because we have `R`, `u`, `u8` and `U` already, a=
nd `$` is outside of source characters) that enable mixing code with string=
 literals.<br>As Marcel Kr=C3=BCger wrote, language could transform this st=
ring literal to:<br><div style=3D"background-color:rgb(250,250,250);border-=
color:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><spa=
n style=3D"color:#000">F</span><span style=3D"color:#080">&quot;testA{a}tes=
t{{B}}&quot;</span><span style=3D"color:#000">_x</span><span style=3D"color=
:#660">;</span><span style=3D"color:#000"> </span><span style=3D"color:#660=
">=3D&gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#00=
8">operator</span><span style=3D"color:#080">&quot;&quot;</span><span style=
=3D"color:#000">_x</span><span style=3D"color:#660">(</span><span style=3D"=
color:#080">&quot;testA&quot;</span><span style=3D"color:#000">_x</span><sp=
an style=3D"color:#660">,</span><span style=3D"color:#000"> a</span><span s=
tyle=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=
=3D"color:#080">&quot;test{B}&quot;</span><span style=3D"color:#000">_x</sp=
an><span style=3D"color:#660">);</span><span style=3D"color:#000"> </span><=
span style=3D"color:#800">//using same postfix to parse sub-literals</span>=
<span style=3D"color:#000"><br>FR</span><span style=3D"color:#080">&quot;aa=
(x{b}y)aa&quot;</span><span style=3D"color:#000">_x</span><span style=3D"co=
lor:#660">;</span><span style=3D"color:#000"> </span><span style=3D"color:#=
660">=3D&gt;</span><span style=3D"color:#000"> </span><span style=3D"color:=
#008">operator</span><span style=3D"color:#080">&quot;&quot;</span><span st=
yle=3D"color:#000">_x</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">R</span><span style=3D"color:#080">&quot;aa(x)aa&quot;</spa=
n><span style=3D"color:#000">_x</span><span style=3D"color:#660">,</span><s=
pan style=3D"color:#000"> b</span><span style=3D"color:#660">,</span><span =
style=3D"color:#000"> R</span><span style=3D"color:#080">&quot;aa(y)aa&quot=
;</span><span style=3D"color:#000">_x</span><span style=3D"color:#660">);</=
span><span style=3D"color:#000"> </span><span style=3D"color:#800">//it hav=
e precedence over `R` prefix</span></div></code></div><br><br><br>Rest will=
 be implemented by library, this mean `F&quot;a {5} b&quot;` will not compi=
le because there is no matching operator. stl could add this operator for `=
s` postfix, that will use `std::to_string` for conversing all arguments:<br=
><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,1=
87);border-style:solid;border-width:1px"><code><div><span style=3D"color:#0=
08">template</span><span style=3D"color:#660">&lt;</span><span style=3D"col=
or:#008">typename</span><span style=3D"color:#660">...</span><span style=3D=
"color:#000"> </span><span style=3D"color:#606">Parts</span><span style=3D"=
color:#660">&gt;</span><span style=3D"color:#000"><br>std</span><span style=
=3D"color:#660">::</span><span style=3D"color:#008">string</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#008">operator</span><span st=
yle=3D"color:#080">&quot;&quot;</span><span style=3D"color:#000">s</span><s=
pan style=3D"color:#660">(</span><span style=3D"color:#606">Parts</span><sp=
an style=3D"color:#660">&amp;&amp;...</span><span style=3D"color:#000"> p</=
span><span style=3D"color:#660">)</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#660">{</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#008">return</span><span style=3D"color:#000"> std</span><s=
pan style=3D"color:#660">::</span><span style=3D"color:#000">to_string</spa=
n><span style=3D"color:#660">(</span><span style=3D"color:#000">std</span><=
span style=3D"color:#660">::</span><span style=3D"color:#000">forward</span=
><span style=3D"color:#660">&lt;</span><span style=3D"color:#606">Pa<wbr>rt=
s</span><span style=3D"color:#660">&gt;(</span><span style=3D"color:#000">p=
</span><span style=3D"color:#660">))</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#660">+</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#660">...;</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#660">}</span><span style=3D"color:#000"><br><br></span><s=
pan style=3D"color:#008">int</span><span style=3D"color:#000"> main</span><=
span style=3D"color:#660">()</span><span style=3D"color:#000"><br></span><s=
pan style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color:#008">auto</span><span style=3D"color:#000"=
> x </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000">=
 F</span><span style=3D"color:#080">&quot;Test {{a}} =3D {10+5}&quot;</span=
><span style=3D"color:#000">s</span><span style=3D"color:#660">;</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#800">//x =3D=3D &quot;=
Test {a} =3D 15&quot;s</span><span style=3D"color:#000"><br></span><span st=
yle=3D"color:#660">}</span><span style=3D"color:#000"><br></span></div></co=
de></div><code>No iosteam, and even more it could if someone relay desire t=
o have localizations:<br><br><div style=3D"background-color:rgb(250,250,250=
);border-color:rgb(187,187,187);border-style:solid;border-width:1px"><code>=
<div><span style=3D"color:#000">F</span><span style=3D"color:#080">&quot;Te=
st {356*10}&quot;</span><span style=3D"color:#000">_loc</span><span style=
=3D"color:#660">(</span><span style=3D"color:#080">&quot;Prod {0} OK!&quot;=
</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#080">&quot;fr&quot;</span><span style=3D"color:#660=
">)</span><span style=3D"color:#000"> </span><span style=3D"color:#660">=3D=
=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#080">&qu=
ot;Prod 3.560,00 OK!&quot;</span><span style=3D"color:#660">;</span><span s=
tyle=3D"color:#000"><br></span></div></code></div><br>Only drawback is some=
 template bloat but this is probably acceptable cost.</code></div></div></b=
lockquote></div></div></div><div dir=3D"auto"><br></div><div dir=3D"auto">T=
his is exactly the kind of thing I&#39;m aiming for, although I dont believ=
e string conversion and concatenation to be the final solution - unless my =
recall of benchmarks is out of date, streams are faster than string concate=
nation.</div><div dir=3D"auto"><br></div><div dir=3D"auto">This being said,=
 similar ideas can be applied to utilise the fmt library, for example.</div=
></div></blockquote><div>=C2=A0<br>This is irrelevant, how it will be imple=
mented is QoI, It could be done using `snprintf`, or even not implemented a=
t all, only prefix `F`and its transformation is important.<br><br>More I th=
ink about this more it look as great addition to language:<br><div style=3D=
"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-sty=
le:solid;border-width:1px"><code><div><span style=3D"color:#000">std</span>=
<span style=3D"color:#660">::</span><span style=3D"color:#008">string</span=
><span style=3D"color:#000"> a</span><span style=3D"color:#660">;</span><sp=
an style=3D"color:#000"><br></span><span style=3D"color:#008">int</span><sp=
an style=3D"color:#000"> b </span><span style=3D"color:#660">=3D</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#066">0</span><span sty=
le=3D"color:#660">;</span><span style=3D"color:#000"><br></span><span style=
=3D"color:#008">int</span><span style=3D"color:#000"> c </span><span style=
=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D=
"color:#066">42</span><span style=3D"color:#660">;</span><span style=3D"col=
or:#000"><br>db</span><span style=3D"color:#660">.</span><span style=3D"col=
or:#000">run</span><span style=3D"color:#660">(</span><span style=3D"color:=
#000">F</span><span style=3D"color:#080">&quot;select name as {a}, age as {=
b} from table where id =3D {c}&quot;</span><span style=3D"color:#000">_sql<=
/span><span style=3D"color:#660">);</span><span style=3D"color:#000"><br><b=
r></span></div></code></div></div></div></blockquote><div><br>If how this i=
s implemented is a mere implementation detail, how would you make it use bo=
und parameters or otherwise sanitize string inputs? Have we learned nothing=
 from <a href=3D"https://xkcd.com/327/" target=3D"_blank" rel=3D"nofollow" =
onmousedown=3D"this.href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F=
%2Fxkcd.com%2F327%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFtYwt6Qicp6LHU=
xtH-OvBP7DZQjw&#39;;return true;" onclick=3D"this.href=3D&#39;https://www.g=
oogle.com/url?q\x3dhttps%3A%2F%2Fxkcd.com%2F327%2F\x26sa\x3dD\x26sntz\x3d1\=
x26usg\x3dAFQjCNFtYwt6Qicp6LHUxtH-OvBP7DZQjw&#39;;return true;">Little Bobb=
y Tables</a>?<br><br>Indeed, this seems like a justification to <i>not</i> =
provide this feature.<br></div></div></blockquote><div>=C2=A0<br><br>But it=
 can easy check it, `_sql` is not string, if you pass string then it will b=
e escaped before it is appended to finals string that is send to database.<=
br>And how it will be exactly implemented? Like this:<br><div style=3D"back=
ground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-=
style: solid; border-width: 1px; overflow-wrap: break-word;" class=3D"prett=
yprint"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify">db</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">.</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">run</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">operator</span><span style=3D"color: #080;" class=3D"styled=
-by-prettify">&quot;&quot;</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">_sql</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">(</span><span style=3D"color: #080;" class=3D"styled-by-prettify"=
>&quot;select name as &quot;</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">_sql</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> a</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: #080;" class=3D"styled-by-prettify">&quot;, age as &quot;</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">_sql</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> b</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: #080;" class=
=3D"styled-by-prettify">&quot;from table where id =3D &quot;</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">_sql</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> c</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #080;" class=3D"styled-by-p=
rettify">&quot;&quot;</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">_sql</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">));</span></div></code></div><br>This will call:<br><div style=3D"back=
ground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-=
style: solid; border-width: 1px; overflow-wrap: break-word;" class=3D"prett=
yprint"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify">sql_command </span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">operator</span><span sty=
le=3D"color: #080;" class=3D"styled-by-prettify">&quot;&quot;</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">_sql</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">sql_command</span><span style=3D"colo=
r: #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"styl=
ed-by-prettify">string</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">&amp;</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> a</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> sql_comma=
nd</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">&amp;</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> b</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> sql_command</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">int</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&=
amp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> c</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> sql_command</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">);</span></div></code=
></div><br>We have all needed information how to handle each parameter.<br>=
We can take address of `a`, `b`, and `c`. We can merge parts of sql and mer=
ge in one querry.<br>From that we can deduce usage and if type is string we=
 add quotes and escapes value (if we need pass some sql part then we use `&=
quot; and state =3D 1 &quot;_sql` that return `sql_command` not `std::strin=
g`).<br>It could too simply forward to some current implementation like:<br=
><div style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187,=
 187, 187); border-style: solid; border-width: 1px; overflow-wrap: break-wo=
rd;" class=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subpre=
ttyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> sql </span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> sql_command</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"=
color: #080;" class=3D"styled-by-prettify">&quot;select name as PARAM_0, ag=
e as PARAM_1 from table where id =3D $0&quot;</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">).</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">bind</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">(</span><span style=3D"color: #066;" class=3D"styled-b=
y-prettify">0</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> c</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">).</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify">execute</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">db</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br>a </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> sql</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">.</span><span style=3D"color: #008;" class=3D"styled-by-prettify">g=
et</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">std</span><spa=
n 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;" class=3D"styled-by-prettify">&gt;(</span><span style=3D"color=
: #080;" class=3D"styled-by-prettify">&quot;PARAM_0&quot;</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br>b </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> sql</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">.</span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">get</span><span style=3D"color: #080;" class=3D"styled-by-pr=
ettify">&lt;int&gt;</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">(</span><span style=3D"color: #080;" class=3D"styled-by-prettify">=
&quot;PARAM_1&quot;</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">);</span></div></code></div><br>Some of this transformation can be=
 done at compile time (like constexpr regexp).<br><br>Because we can take r=
eference to object then we can do two-way communication.<br><br><br><br></d=
iv></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/8e456af5-09c3-461d-8562-30df127e93af%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/8e456af5-09c3-461d-8562-30df127e93af=
%40isocpp.org</a>.<br />

------=_Part_6745_2004159494.1518287985320--

------=_Part_6744_1031796837.1518287985319--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 10 Feb 2018 11:37:45 -0800 (PST)
Raw View
------=_Part_6877_222613273.1518291465356
Content-Type: multipart/alternative;
 boundary="----=_Part_6878_1862741571.1518291465357"

------=_Part_6878_1862741571.1518291465357
Content-Type: text/plain; charset="UTF-8"

On Saturday, February 10, 2018 at 1:39:45 PM UTC-5, Marcin Jaczewski wrote:
>
> But it can easy check it, `_sql` is not string, if you pass string then it
> will be escaped before it is appended to finals string that is send to
> database.
> And how it will be exactly implemented? Like this:
> db.run(operator""_sql("select name as "_sql, a, ", age as "_sql, b, "from
> table where id = "_sql, c, ""_sql));
>
> This will call:
> sql_command operator""_sql(sql_command, std::string& a, sql_command, int&
> b, sql_command, int& c, sql_command);
>
>
I see some value in the general approach, but allow me to redefine it in a
more coherent way.

The token `F""` is treated a lot like we treat `...` pack expansions. The
`F` prefix performs a "string literal expansion" operation, transforming
the literal into a sequence of literals and identifiers extracted from the
literal.

What I find wrongheaded and/or confusing about your approach here is that
you apply the UDL *twice*, with two different meanings. The outer UDL is
about string concatenation. The inner UDL is about regular UDL stuff.

I would much rather have the outer UDL simply not exist. That is, if you do
this:

F"select name as {a}, age as {b} from table where id = {c}"_sql

Then that expands to this:

"select name as "_sql, a, ", age as "_sql, b, " from table where id = "_sql,
c

So the `_sql` simply does regular UDL stuff. How do you put all of these
together? That's the job of `db:run`. It gets a sequence of parameters;
some of those parameters are the results of the `_sql` UDL; others are just
generic values it will do with as it pleases.

So doing standard "string interpolation" operations through iostreams would
look like this:

std::stream_fmt(F"Hello, {recipient}!");

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/bd24b702-025a-4b06-976b-559c779851e1%40isocpp.org.

------=_Part_6878_1862741571.1518291465357
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Saturday, February 10, 2018 at 1:39:45 PM UTC-5, Marcin=
 Jaczewski wrote:<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>But it can easy check it, `_sql` is not string, if you pass string=
 then it will be escaped before it is appended to finals string that is sen=
d to database.<br>And how it will be exactly implemented? Like this:<br><di=
v style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);=
border-style:solid;border-width:1px"><code><div><span style=3D"color:#000">=
db</span><span style=3D"color:#660">.</span><span style=3D"color:#000">run<=
/span><span style=3D"color:#660">(</span><span style=3D"color:#008">operato=
r</span><span style=3D"color:#080">&quot;&quot;</span><span style=3D"color:=
#000">_sql</span><span style=3D"color:#660">(</span><span style=3D"color:#0=
80">&quot;select name as &quot;</span><span style=3D"color:#000">_sql</span=
><span style=3D"color:#660">,</span><span style=3D"color:#000"> a</span><sp=
an style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#080">&quot;, age as &quot;</span><span style=3D"color:#000">_=
sql</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> b<=
/span><span style=3D"color:#660">,</span><span style=3D"color:#000"> </span=
><span style=3D"color:#080">&quot;from table where id =3D &quot;</span><spa=
n style=3D"color:#000">_sql</span><span style=3D"color:#660">,</span><span =
style=3D"color:#000"> c</span><span style=3D"color:#660">,</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#080">&quot;&quot;</span><spa=
n style=3D"color:#000">_sql</span><span style=3D"color:#660">));</span></di=
v></code></div><br>This will call:<br><div style=3D"background-color:rgb(25=
0,250,250);border-color:rgb(187,187,187);border-style:solid;border-width:1p=
x"><code><div><span style=3D"color:#000">sql_command </span><span style=3D"=
color:#008">operator</span><span style=3D"color:#080">&quot;&quot;</span><s=
pan style=3D"color:#000">_sql</span><span style=3D"color:#660">(</span><spa=
n style=3D"color:#000">sql_command</span><span style=3D"color:#660">,</span=
><span style=3D"color:#000"> std</span><span style=3D"color:#660">::</span>=
<span style=3D"color:#008">string</span><span style=3D"color:#660">&amp;</s=
pan><span style=3D"color:#000"> a</span><span style=3D"color:#660">,</span>=
<span style=3D"color:#000"> sql_command</span><span style=3D"color:#660">,<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#008">int</sp=
an><span style=3D"color:#660">&amp;</span><span style=3D"color:#000"> b</sp=
an><span style=3D"color:#660">,</span><span style=3D"color:#000"> sql_comma=
nd</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#008">int</span><span style=3D"color:#660">&amp;</=
span><span style=3D"color:#000"> c</span><span style=3D"color:#660">,</span=
><span style=3D"color:#000"> sql_command</span><span style=3D"color:#660">)=
;</span></div></code></div><br></div></div></blockquote><div><br>I see some=
 value in the general approach, but allow me to redefine it in a more coher=
ent way.<br><br>The token `F&quot;&quot;` is treated a lot like we treat `.=
...` pack expansions. The `F` prefix performs a &quot;string literal expansi=
on&quot; operation, transforming the literal into a sequence of literals an=
d identifiers extracted from the literal.<br><br>What I find wrongheaded an=
d/or confusing about your approach here is that you apply the UDL <i>twice<=
/i>, with two different meanings. The outer UDL is about string concatenati=
on. The inner UDL is about regular UDL stuff.<br><br>I would much rather ha=
ve the outer UDL simply not exist. That is, if you do this:<br><br><div sty=
le=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187=
); border-style: solid; border-width: 1px; overflow-wrap: break-word;" clas=
s=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subprettyprint"=
><span style=3D"color: #000;" class=3D"styled-by-prettify">F</span><span st=
yle=3D"color: #080;" class=3D"styled-by-prettify">&quot;select name as {a},=
 age as {b} from table where id =3D {c}&quot;</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">_sql</span></div></code></div><br>Then t=
hat expands to this:<br><br><div style=3D"background-color: rgb(250, 250, 2=
50); border-color: rgb(187, 187, 187); border-style: solid; border-width: 1=
px; overflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"pretty=
print"><div class=3D"subprettyprint"><span style=3D"color: #080;" class=3D"=
styled-by-prettify">&quot;select name as &quot;</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify">_sql</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> a</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #080;" class=3D"styled-by-prettify">&q=
uot;, age as &quot;</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">_sql</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> b</sp=
an><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: #080;" class=3D"styled-by-prettify">&quot; from table where id =3D &=
quot;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">_sql<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> c</span></div></cod=
e></div><br>So the `_sql` simply does regular UDL stuff. How do you put all=
 of these together? That&#39;s the job of `db:run`. It gets a sequence of p=
arameters; some of those parameters are the results of the `_sql` UDL; othe=
rs are just generic values it will do with as it pleases.<br><br>So doing s=
tandard &quot;string interpolation&quot; operations through iostreams would=
 look like this:<br><br><div style=3D"background-color: rgb(250, 250, 250);=
 border-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; =
overflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"prettyprin=
t"><div class=3D"subprettyprint"><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">std</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>stream_fmt</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">F</span>=
<span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;Hello, {rec=
ipient}!&quot;</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">);</span></div></code></div></div><br></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/bd24b702-025a-4b06-976b-559c779851e1%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/bd24b702-025a-4b06-976b-559c779851e1=
%40isocpp.org</a>.<br />

------=_Part_6878_1862741571.1518291465357--

------=_Part_6877_222613273.1518291465356--

.


Author: inkwizytoryankes@gmail.com
Date: Sat, 10 Feb 2018 18:38:20 -0800 (PST)
Raw View
------=_Part_7159_1679314213.1518316700294
Content-Type: multipart/alternative;
 boundary="----=_Part_7160_1150572824.1518316700295"

------=_Part_7160_1150572824.1518316700295
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



On Saturday, February 10, 2018 at 8:37:45 PM UTC+1, Nicol Bolas wrote:
>
> On Saturday, February 10, 2018 at 1:39:45 PM UTC-5, Marcin Jaczewski wrot=
e:
>>
>> But it can easy check it, `_sql` is not string, if you pass string then=
=20
>> it will be escaped before it is appended to finals string that is send t=
o=20
>> database.
>> And how it will be exactly implemented? Like this:
>> db.run(operator""_sql("select name as "_sql, a, ", age as "_sql, b, "fro=
m=20
>> table where id =3D "_sql, c, ""_sql));
>>
>> This will call:
>> sql_command operator""_sql(sql_command, std::string& a, sql_command, int=
&=20
>> b, sql_command, int& c, sql_command);
>>
>>
> I see some value in the general approach, but allow me to redefine it in =
a=20
> more coherent way.
>
> The token `F""` is treated a lot like we treat `...` pack expansions. The=
=20
> `F` prefix performs a "string literal expansion" operation, transforming=
=20
> the literal into a sequence of literals and identifiers extracted from th=
e=20
> literal.
>
>
And then wat result will be of:
auto x =3D F"A {42} B"_z;

If it work as pack expansion then it do not have meaning on its own.
I would like if it work similar to:
auto x =3D "A B"_z;

It create new object with some type controlled by `_z` UDL.
=20

> What I find wrongheaded and/or confusing about your approach here is that=
=20
> you apply the UDL *twice*, with two different meanings. The outer UDL is=
=20
> about string concatenation. The inner UDL is about regular UDL stuff.
>
>
As I based this on Marcel Kr=C3=BCger sugestion, he used normal string lite=
rals=20
as parameters but this prevent any meta programing with it. This mean each=
=20
parameter need be separate type.Question is what type? Some=20
`std::string_literal<char, 'a', 'b', 'c'>`? But this will need adding=20
header like for `std::initializer_list`. But I thought that better is apply=
=20
again same postfix for inner parts because you should already have control=
=20
of this.

=20

> I would much rather have the outer UDL simply not exist. That is, if you=
=20
> do this:
>
> F"select name as {a}, age as {b} from table where id =3D {c}"_sql
>
> Then that expands to this:
>
> "select name as "_sql, a, ", age as "_sql, b, " from table where id =3D "
> _sql, c
>
>
One detail, after `c` will be `""_sql`, in this case it would be not very=
=20
important but if we have:
F"{a}{b}{c}"_x =3D> ""_x, a, ""_x, b, ""_x, c, ""_x

With this you can relay that odd parameters are code arguments and even=20
parameters are part of literal. Even if all have same type:
F"{""_s}"_s =3D> ""_s, ""_s, ""_s

Second is from code and we could parse it differently (like escaping=20
special symbols)

=20

> So the `_sql` simply does regular UDL stuff. How do you put all of these=
=20
> together? That's the job of `db:run`. It gets a sequence of parameters;=
=20
> some of those parameters are the results of the `_sql` UDL; others are ju=
st=20
> generic values it will do with as it pleases.
>
> So doing standard "string interpolation" operations through iostreams=20
> would look like this:
>
> std::stream_fmt(F"Hello, {recipient}!");
>
> =20

This could work too, but it this better would be if `F` return normal=20
object:
genericFunc(fmt(F"Hello {name}"), fmt(F"Sth {x}")); //yours version
genericFunc(F"Hello {name}"_fmt, F"Sth {x}"_fmt); //my version

Overall I think this should be done this way because you will have better=
=20
control over what semantic this string literal will have. In your case it=
=20
all will depend on context.
One drawback of my version is that without UDL `F"{a}"` have no meaning.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/f63ed807-c5f6-4997-b03f-b4bc16a70982%40isocpp.or=
g.

------=_Part_7160_1150572824.1518316700295
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Saturday, February 10, 2018 at 8:37:45 PM UTC+1=
, Nicol Bolas wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr">On Saturday, February 10, 2018 at 1:39:45 PM UTC-5, Marcin Jaczews=
ki 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"><div>But =
it can easy check it, `_sql` is not string, if you pass string then it will=
 be escaped before it is appended to finals string that is send to database=
..<br>And how it will be exactly implemented? Like this:<br><div style=3D"ba=
ckground-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:=
solid;border-width:1px"><code><div><span style=3D"color:#000">db</span><spa=
n style=3D"color:#660">.</span><span style=3D"color:#000">run</span><span s=
tyle=3D"color:#660">(</span><span style=3D"color:#008">operator</span><span=
 style=3D"color:#080">&quot;&quot;</span><span style=3D"color:#000">_sql</s=
pan><span style=3D"color:#660">(</span><span style=3D"color:#080">&quot;sel=
ect name as &quot;</span><span style=3D"color:#000">_sql</span><span style=
=3D"color:#660">,</span><span style=3D"color:#000"> a</span><span style=3D"=
color:#660">,</span><span style=3D"color:#000"> </span><span style=3D"color=
:#080">&quot;, age as &quot;</span><span style=3D"color:#000">_sql</span><s=
pan style=3D"color:#660">,</span><span style=3D"color:#000"> b</span><span =
style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=
=3D"color:#080">&quot;from table where id =3D &quot;</span><span style=3D"c=
olor:#000">_sql</span><span style=3D"color:#660">,</span><span style=3D"col=
or:#000"> c</span><span style=3D"color:#660">,</span><span style=3D"color:#=
000"> </span><span style=3D"color:#080">&quot;&quot;</span><span style=3D"c=
olor:#000">_sql</span><span style=3D"color:#660">));</span></div></code></d=
iv><br>This will call:<br><div style=3D"background-color:rgb(250,250,250);b=
order-color:rgb(187,187,187);border-style:solid;border-width:1px"><code><di=
v><span style=3D"color:#000">sql_command </span><span style=3D"color:#008">=
operator</span><span style=3D"color:#080">&quot;&quot;</span><span style=3D=
"color:#000">_sql</span><span style=3D"color:#660">(</span><span style=3D"c=
olor:#000">sql_command</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span style=
=3D"color:#008">string</span><span style=3D"color:#660">&amp;</span><span s=
tyle=3D"color:#000"> a</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> sql_command</span><span style=3D"color:#660">,</span><span=
 style=3D"color:#000"> </span><span style=3D"color:#008">int</span><span st=
yle=3D"color:#660">&amp;</span><span style=3D"color:#000"> b</span><span st=
yle=3D"color:#660">,</span><span style=3D"color:#000"> sql_command</span><s=
pan style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#008">int</span><span style=3D"color:#660">&amp;</span><span =
style=3D"color:#000"> c</span><span style=3D"color:#660">,</span><span styl=
e=3D"color:#000"> sql_command</span><span style=3D"color:#660">);</span></d=
iv></code></div><br></div></div></blockquote><div><br>I see some value in t=
he general approach, but allow me to redefine it in a more coherent way.<br=
><br>The token `F&quot;&quot;` is treated a lot like we treat `...` pack ex=
pansions. The `F` prefix performs a &quot;string literal expansion&quot; op=
eration, transforming the literal into a sequence of literals and identifie=
rs extracted from the literal.<br><br></div></div></blockquote><div><br>And=
 then wat result will be of:<br><div style=3D"background-color: rgb(250, 25=
0, 250); border-color: rgb(187, 187, 187); border-style: solid; border-widt=
h: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"pr=
ettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=
=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> x </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> F</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&quo=
t;A {42} B&quot;</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">_z</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;<=
/span></div></code></div><br>If it work as pack expansion then it do not ha=
ve meaning on its own.<br>I would like if it work similar to:<br><div style=
=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187);=
 border-style: solid; border-width: 1px; overflow-wrap: break-word;" class=
=3D"prettyprint"><code class=3D"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"> x </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #080;=
" class=3D"styled-by-prettify">&quot;A B&quot;</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify">_z</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">;</span></div></code></div><br>It create new ob=
ject with some type controlled by `_z` UDL.<br>=C2=A0</div><blockquote clas=
s=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #c=
cc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>What I find wrongheaded =
and/or confusing about your approach here is that you apply the UDL <i>twic=
e</i>, with two different meanings. The outer UDL is about string concatena=
tion. The inner UDL is about regular UDL stuff.<br><br></div></div></blockq=
uote><div><br>As I based this on Marcel Kr=C3=BCger sugestion, he used norm=
al string literals as parameters but this prevent any meta programing with =
it. This mean each parameter need be separate type.Question is what type? S=
ome `std::string_literal&lt;char, &#39;a&#39;, &#39;b&#39;, &#39;c&#39;&gt;=
`? But this will need adding header like for `std::initializer_list`. But I=
 thought that better is apply again same postfix for inner parts because yo=
u should already have control of this.<br><br>=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;"><div dir=3D"ltr"><div>I would much rather have =
the outer UDL simply not exist. That is, if you do this:<br><br><div style=
=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-=
style:solid;border-width:1px"><code><div><span style=3D"color:#000">F</span=
><span style=3D"color:#080">&quot;select name as {a}, age as {b} from table=
 where id =3D {c}&quot;</span><span style=3D"color:#000">_sql</span></div><=
/code></div><br>Then that expands to this:<br><br><div style=3D"background-=
color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;bor=
der-width:1px"><code><div><span style=3D"color:#080">&quot;select name as &=
quot;</span><span style=3D"color:#000">_sql</span><span style=3D"color:#660=
">,</span><span style=3D"color:#000"> a</span><span style=3D"color:#660">,<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#080">&quot;,=
 age as &quot;</span><span style=3D"color:#000">_sql</span><span style=3D"c=
olor:#660">,</span><span style=3D"color:#000"> b</span><span style=3D"color=
:#660">,</span><span style=3D"color:#000"> </span><span style=3D"color:#080=
">&quot; from table where id =3D &quot;</span><span style=3D"color:#000">_s=
ql</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> c</=
span></div></code></div><br></div></div></blockquote><div><br>One detail, a=
fter `c` will be `&quot;&quot;_sql`, in this case it would be not very impo=
rtant but if we have:<br><div style=3D"background-color: rgb(250, 250, 250)=
; border-color: rgb(187, 187, 187); border-style: solid; border-width: 1px;=
 overflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"prettypri=
nt"><div class=3D"subprettyprint"><span style=3D"color: #000;" class=3D"sty=
led-by-prettify">F</span><span style=3D"color: #080;" class=3D"styled-by-pr=
ettify">&quot;{a}{b}{c}&quot;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">_x </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">=3D&gt;</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #080;" class=3D"styled-by-prettify">=
&quot;&quot;</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
">_x</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> a</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #0=
80;" class=3D"styled-by-prettify">&quot;&quot;</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify">_x</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> b</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: #080;" class=3D"styled-by-prettify">&quot;&=
quot;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">_x</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> c</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: #080;" =
class=3D"styled-by-prettify">&quot;&quot;</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">_x</span></div></code></div><br>With this yo=
u can relay that odd parameters are code arguments and even parameters are =
part of literal. Even if all have same type:<br><div style=3D"background-co=
lor: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: so=
lid; border-width: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><=
code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">F</span><span style=3D"color: #080;=
" class=3D"styled-by-prettify">&quot;{&quot;&quot;_s}&quot;</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify">_s </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">=3D&gt;</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #080;"=
 class=3D"styled-by-prettify">&quot;&quot;</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">_s</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: #080;" class=3D"styled-by-pret=
tify">&quot;&quot;</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">_s</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: #080;" class=3D"styled-by-prettify">&quot;&quot;</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">_s</span></div><=
/code></div><br>Second is from code and we could parse it differently (like=
 escaping special symbols)<br><br>=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;"><div dir=3D"ltr"><div>So the `_sql` simply does regular UDL=
 stuff. How do you put all of these together? That&#39;s the job of `db:run=
`. It gets a sequence of parameters; some of those parameters are the resul=
ts of the `_sql` UDL; others are just generic values it will do with as it =
pleases.<br><br>So doing standard &quot;string interpolation&quot; operatio=
ns through iostreams would look like this:<br><br><div style=3D"background-=
color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;bor=
der-width:1px"><code><div><span style=3D"color:#000">std</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">stream_fmt</span><span =
style=3D"color:#660">(</span><span style=3D"color:#000">F</span><span style=
=3D"color:#080">&quot;Hello, {recipient}!&quot;</span><span style=3D"color:=
#660">);</span></div></code></div></div><br></div></blockquote><div>=C2=A0<=
br><br>This could work too, but it this better would be if `F` return norma=
l object:<br><div style=3D"background-color: rgb(250, 250, 250); border-col=
or: rgb(187, 187, 187); border-style: solid; border-width: 1px; overflow-wr=
ap: break-word;" class=3D"prettyprint"><code class=3D"prettyprint"><div cla=
ss=3D"subprettyprint"><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">genericFunc</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">fmt=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">F</span><span style=
=3D"color: #080;" class=3D"styled-by-prettify">&quot;Hello {name}&quot;</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">),</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> fmt</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">F</span><span style=3D"color: #080;" =
class=3D"styled-by-prettify">&quot;Sth {x}&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: #800;" class=
=3D"styled-by-prettify">//yours version</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br>genericFunc</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">F</span><span style=3D"color: #080;" class=3D"styl=
ed-by-prettify">&quot;Hello {name}&quot;</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify">_fmt</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> F</span><span style=3D"color: #080;" class=3D"styled-by-pre=
ttify">&quot;Sth {x}&quot;</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">_fmt</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">//my ve=
rsion</span></div></code></div><br>Overall I think this should be done this=
 way because you will have better control over what semantic this string li=
teral will have. In your case it all will depend on context.<br>One drawbac=
k of my version is that without UDL `F&quot;{a}&quot;` have no meaning.<br>=
<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/f63ed807-c5f6-4997-b03f-b4bc16a70982%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/f63ed807-c5f6-4997-b03f-b4bc16a70982=
%40isocpp.org</a>.<br />

------=_Part_7160_1150572824.1518316700295--

------=_Part_7159_1679314213.1518316700294--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 11 Feb 2018 00:35:50 -0800 (PST)
Raw View
------=_Part_4946_247154927.1518338150569
Content-Type: multipart/alternative;
 boundary="----=_Part_4947_144716130.1518338150570"

------=_Part_4947_144716130.1518338150570
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



On Saturday, February 10, 2018 at 9:38:20 PM UTC-5, Marcin Jaczewski wrote:
>
>
>
> On Saturday, February 10, 2018 at 8:37:45 PM UTC+1, Nicol Bolas wrote:
>>
>> On Saturday, February 10, 2018 at 1:39:45 PM UTC-5, Marcin Jaczewski=20
>> wrote:
>>>
>>> But it can easy check it, `_sql` is not string, if you pass string then=
=20
>>> it will be escaped before it is appended to finals string that is send =
to=20
>>> database.
>>> And how it will be exactly implemented? Like this:
>>> db.run(operator""_sql("select name as "_sql, a, ", age as "_sql, b, "fr=
om=20
>>> table where id =3D "_sql, c, ""_sql));
>>>
>>> This will call:
>>> sql_command operator""_sql(sql_command, std::string& a, sql_command, in=
t
>>> & b, sql_command, int& c, sql_command);
>>>
>>>
>> I see some value in the general approach, but allow me to redefine it in=
=20
>> a more coherent way.
>>
>> The token `F""` is treated a lot like we treat `...` pack expansions. Th=
e=20
>> `F` prefix performs a "string literal expansion" operation, transforming=
=20
>> the literal into a sequence of literals and identifiers extracted from t=
he=20
>> literal.
>>
>>
> And then wat result will be of:
> auto x =3D F"A {42} B"_z;
>
> If it work as pack expansion then it do not have meaning on its own.
>

You say that like it's a bad thing. Does `pack...` have meaning on its own?

The point of my idea is that it provides a sharp separation between the two=
=20
fundamental operations of "string interpolation". There's the "convert a=20
string literal into a bunch of smaller literals and variables" part. And=20
there's the "do something with that bunch of smaller literals and=20
variables."

By making part 1 into a pack expansion-like construct, it forces you to=20
make the way you want to process that expansion *explicit*. It also makes a=
=20
clear distinction between a UDL used for normal purposes and the system=20
used to process code.

For example, let's say I want to use interpolation to process a literal and=
=20
store all of the elements in a tuple. We can store each of the non-literal=
=20
parts easily enough. But what about the literal parts? You might say that a=
=20
`const char*` is good enough, but maybe I want it to be a `string_view`. To=
=20
do that with my system, it's as simple as:

tuple(F"some string {variable} other string"sv);

I have to write precisely *zero code* to make that work.

With your system, I have to write a function. Scratch that; I have to=20
create *two* functions. One function is the string fragment UDL, which does=
=20
exactly what `operator""sv` does. And the other is literally just `return=
=20
tuple(std::forward<Args>(args)...);`.

So I have to write two functions, and both of them are one-liners.

And if I want to do the exact same tuple building, only with `std::string`=
=20
instead of `string_view`, I have to write two functions. Again. One of them=
=20
will be *exactly identical* to the one paired with `string_view`.

Or I could just do:

tuple(F"some string {variable} other string"s);

No additional code needs to be written here. It Just Works(tm).

And look back at your `_sql` example. To me, a string with the `_sql`=20
literal suffix ought to be a compiled SQL statement, ready to be executed.=
=20
The syntax of the this statement shoudl be verified as valid.

But that's not the case with the `_sql` suffixes used on the string=20
fragments. While the total result of the interpolation is an SQL statement,=
=20
"select name as" is not valid SQL *by itself*. So what exactly is the=20
`_sql` suffix doing to these fragments? Some basic token recognition? Why=
=20
bother; the final concatenation process is what has to do all of the=20
serious validation work.

This separation between how a string fragment is processed and how the=20
aggregation is built is important. And the best way to achieve that=20
separation is to actually separate them.

I also find that my idea is more forward-looking. If we do get full=20
`constexpr` string support, then there's no reason why we shouldn't be able=
=20
to invoke the compiler's support for "string interpolation" on such a=20
string. Your idea is so heavily based on UDLs that it becomes difficult to=
=20
make it work on `constexpr` non-UDL strings. Why? Because your design=20
requires two parts: grammar to say "interpolate string" and a secondary=20
parameter that says "with this".

My design has grammar that says "interpolation string". The "with this"=20
part comes out through the regular rules of C++: explicit function calls.=
=20
That means we already have grammar to say "with this". All my design would=
=20
need to service `constexpr` strings is for the "interpolate string" grammar=
=20
to be something that can be applied to variables as well as literals.

Your design would require being able to apply UDLs to a `constexpr` string.

I would like if it work similar to:
> auto x =3D "A B"_z;
>
> It create new object with some type controlled by `_z` UDL.
>

I don't understand why you have such a need to have UDLs control this=20
process. We already have ways to take a sequence of values and aggregate=20
them into an object. It's called "calling a function with them".

What I find wrongheaded and/or confusing about your approach here is that=
=20
>> you apply the UDL *twice*, with two different meanings. The outer UDL is=
=20
>> about string concatenation. The inner UDL is about regular UDL stuff.
>>
>>
> As I based this on Marcel Kr=C3=BCger sugestion, he used normal string li=
terals=20
> as parameters but this prevent any meta programing with it.
>

It doesn't interfere with constexpr programming, though. Let's stop trying=
=20
to apply C++03 solutions to C++20.

This mean each parameter need be separate type. Question is what type? Some=
=20
> `std::string_literal<char, 'a', 'b', 'c'>`? But this will need adding=20
> header like for `std::initializer_list`. But I thought that better is app=
ly=20
> again same postfix for inner parts because you should already have contro=
l=20
> of this.
>

And if you want to apply a suffix that returns such a thing with my design,=
=20
you can. But there need not be a *direct* connection between how you=20
process the string fragments and how you apply the aggregation.

So the `_sql` simply does regular UDL stuff. How do you put all of these=20
>> together? That's the job of `db:run`. It gets a sequence of parameters;=
=20
>> some of those parameters are the results of the `_sql` UDL; others are j=
ust=20
>> generic values it will do with as it pleases.
>>
>> So doing standard "string interpolation" operations through iostreams=20
>> would look like this:
>>
>> std::stream_fmt(F"Hello, {recipient}!");
>>
>> =20
>
> This could work too, but it this better would be if `F` return normal=20
> object:
> genericFunc(fmt(F"Hello {name}"), fmt(F"Sth {x}")); //yours version
> genericFunc(F"Hello {name}"_fmt, F"Sth {x}"_fmt); //my version
>
> Overall I think this should be done this way because you will have better=
=20
> control over what semantic this string literal will have. In your case it=
=20
> all will depend on context.
> One drawback of my version is that without UDL `F"{a}"` have no meaning.
>

But you have less control over it, because you have this UDL issue. Your=20
method requires two different kinds of UDLs: a UDL for the purpose of=20
interpreting a literal (aka: what UDLs are for), and a "UDL" that acts as a=
=20
processing framework for an string interpolation sequence. Why do these two=
=20
things need to be spelled the same way?

Consider an `fmt` that uses iostreams. So you do this:

F"some string {variable} other {variable}"fmt;

And that's supposed to be converted into:

operator ""fmt(operator ""fmt("some string "), variable, operator ""fmt("=
=20
other "), variable);

But all of those inner "fmt" literals? They *don't do anything*. All they=
=20
do is return the string. It's the outer "fmt" call that creates the=20
`ostringstream` and outputs each object to it.

Any serious work spent processing the string fragments will be done by the=
=20
outer UDL, which is not really a UDL at all. You have two *fundamentally*=
=20
different things going on, but you're trying to pretend that they're the=20
same. They aren't.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/28e80709-5ebb-44d2-b26d-22cafd681330%40isocpp.or=
g.

------=_Part_4947_144716130.1518338150570
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Saturday, February 10, 2018 at 9:38:20 PM UTC-5=
, Marcin Jaczewski 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"><br><br>On Saturday, February 10, 2018 at 8:37:45 PM UTC+1, Nic=
ol Bolas wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-l=
eft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On =
Saturday, February 10, 2018 at 1:39:45 PM UTC-5, Marcin Jaczewski wrote:<bl=
ockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>But it can easy =
check it, `_sql` is not string, if you pass string then it will be escaped =
before it is appended to finals string that is send to database.<br>And how=
 it will be exactly implemented? Like this:<br><div style=3D"background-col=
or:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border=
-width:1px"><code><div><span style=3D"color:#000">db</span><span style=3D"c=
olor:#660">.</span><span style=3D"color:#000">run</span><span style=3D"colo=
r:#660">(</span><span style=3D"color:#008">operator</span><span style=3D"co=
lor:#080">&quot;&quot;</span><span style=3D"color:#000">_sql</span><span st=
yle=3D"color:#660">(</span><span style=3D"color:#080">&quot;select name as =
&quot;</span><span style=3D"color:#000">_sql</span><span style=3D"color:#66=
0">,</span><span style=3D"color:#000"> a</span><span style=3D"color:#660">,=
</span><span style=3D"color:#000"> </span><span style=3D"color:#080">&quot;=
, age as &quot;</span><span style=3D"color:#000">_sql</span><span style=3D"=
color:#660">,</span><span style=3D"color:#000"> b</span><span style=3D"colo=
r:#660">,</span><span style=3D"color:#000"> </span><span style=3D"color:#08=
0">&quot;from table where id =3D &quot;</span><span style=3D"color:#000">_s=
ql</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> c</=
span><span style=3D"color:#660">,</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#080">&quot;&quot;</span><span style=3D"color:#000">_s=
ql</span><span style=3D"color:#660">));</span></div></code></div><br>This w=
ill call:<br><div style=3D"background-color:rgb(250,250,250);border-color:r=
gb(187,187,187);border-style:solid;border-width:1px"><code><div><span style=
=3D"color:#000">sql_command </span><span style=3D"color:#008">operator</spa=
n><span style=3D"color:#080">&quot;&quot;</span><span style=3D"color:#000">=
_sql</span><span style=3D"color:#660">(</span><span style=3D"color:#000">sq=
l_command</span><span style=3D"color:#660">,</span><span style=3D"color:#00=
0"> std</span><span style=3D"color:#660">::</span><span style=3D"color:#008=
">string</span><span style=3D"color:#660">&amp;</span><span style=3D"color:=
#000"> a</span><span style=3D"color:#660">,</span><span style=3D"color:#000=
"> sql_command</span><span style=3D"color:#660">,</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#008">int</span><span style=3D"color:#=
660">&amp;</span><span style=3D"color:#000"> b</span><span style=3D"color:#=
660">,</span><span style=3D"color:#000"> sql_command</span><span style=3D"c=
olor:#660">,</span><span style=3D"color:#000"> </span><span style=3D"color:=
#008">int</span><span style=3D"color:#660">&amp;</span><span style=3D"color=
:#000"> c</span><span style=3D"color:#660">,</span><span style=3D"color:#00=
0"> sql_command</span><span style=3D"color:#660">);</span></div></code></di=
v><br></div></div></blockquote><div><br>I see some value in the general app=
roach, but allow me to redefine it in a more coherent way.<br><br>The token=
 `F&quot;&quot;` is treated a lot like we treat `...` pack expansions. The =
`F` prefix performs a &quot;string literal expansion&quot; operation, trans=
forming the literal into a sequence of literals and identifiers extracted f=
rom the literal.<br><br></div></div></blockquote><div><br>And then wat resu=
lt will be of:<br><div style=3D"background-color:rgb(250,250,250);border-co=
lor:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><span =
style=3D"color:#008">auto</span><span style=3D"color:#000"> x </span><span =
style=3D"color:#660">=3D</span><span style=3D"color:#000"> F</span><span st=
yle=3D"color:#080">&quot;A {42} B&quot;</span><span style=3D"color:#000">_z=
</span><span style=3D"color:#660">;</span></div></code></div><br>If it work=
 as pack expansion then it do not have meaning on its own.<br></div></div><=
/blockquote><div><br>You say that like it&#39;s a bad thing. Does `pack...`=
 have meaning on its own?<br><br>The point of my idea is that it provides a=
 sharp separation between the two fundamental operations of &quot;string in=
terpolation&quot;. There&#39;s the &quot;convert a string literal into a bu=
nch of smaller literals and variables&quot; part. And there&#39;s the &quot=
;do something with that bunch of smaller literals and variables.&quot;<br><=
br>By making part 1 into a pack expansion-like construct, it forces you to =
make the way you want to process that expansion <i>explicit</i>. It also ma=
kes a clear distinction between a UDL used for normal purposes and the syst=
em used to process code.<br><br>For example, let&#39;s say I want to use in=
terpolation to process a literal and store all of the elements in a tuple. =
We can store each of the non-literal parts easily enough. But what about th=
e literal parts? You might say that a `const char*` is good enough, but may=
be I want it to be a `string_view`. To do that with my system, it&#39;s as =
simple as:<br><br><div style=3D"background-color: rgb(250, 250, 250); borde=
r-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; overfl=
ow-wrap: break-word;" class=3D"prettyprint"><code class=3D"prettyprint"><di=
v class=3D"subprettyprint"><span style=3D"color: #000;" class=3D"styled-by-=
prettify">tuple</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">F</s=
pan><span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;some st=
ring {variable} other string&quot;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">sv</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">);</span></div></code></div><br>I have to write precisely <=
i>zero code</i> to make that work.<br><br>With your system, I have to write=
 a function. Scratch that; I have to create <i>two</i> functions. One funct=
ion is the string fragment UDL, which does exactly what `operator&quot;&quo=
t;sv` does. And the other is literally just `return tuple(std::forward&lt;A=
rgs&gt;(args)...);`.<br><br>So I have to write two functions, and both of t=
hem are one-liners.<br><br>And if I want to do the exact same tuple buildin=
g, only with `std::string` instead of `string_view`, I have to write two fu=
nctions. Again. One of them will be <i>exactly identical</i> to the one pai=
red with `string_view`.<br><br>Or I could just do:<br><br><div style=3D"bac=
kground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border=
-style: solid; border-width: 1px; overflow-wrap: break-word;" class=3D"pret=
typrint"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">tuple</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">F</span><span style=3D"color: #080;" =
class=3D"styled-by-prettify">&quot;some string {variable} other string&quot=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">s</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">);</span></div></c=
ode></div><br>No additional code needs to be written here. It Just Works(tm=
).<br><br>And look back at your `_sql` example. To me, a string with the `_=
sql` literal suffix ought to be a compiled SQL statement, ready to be execu=
ted. The syntax of the this statement shoudl be verified as valid.<br><br>B=
ut that&#39;s not the case with the `_sql` suffixes used on the string frag=
ments. While the total result of the interpolation is an SQL statement, &qu=
ot;select name as&quot; is not valid SQL <i>by itself</i>. So what exactly =
is the `_sql` suffix doing to these fragments? Some basic token recognition=
? Why bother; the final concatenation process is what has to do all of the =
serious validation work.<br><br>This separation between how a string fragme=
nt is processed and how the aggregation is built is important. And the best=
 way to achieve that separation is to actually separate them.<br><br>I also=
 find that my idea is more forward-looking. If we do get full `constexpr` s=
tring support, then there&#39;s no reason why we shouldn&#39;t be able to i=
nvoke the compiler&#39;s support for &quot;string interpolation&quot; on su=
ch a string. Your idea is so heavily based on UDLs that it becomes difficul=
t to make it work on `constexpr` non-UDL strings. Why? Because your design =
requires two parts: grammar to say &quot;interpolate string&quot; and a sec=
ondary parameter that says &quot;with this&quot;.<br><br>My design has gram=
mar that says &quot;interpolation string&quot;. The &quot;with this&quot; p=
art comes out through the regular rules of C++: explicit function calls. Th=
at means we already have grammar to say &quot;with this&quot;. All my desig=
n would need to service `constexpr` strings is for the &quot;interpolate st=
ring&quot; grammar to be something that can be applied to variables as well=
 as literals.<br><br>Your design would require being able to apply UDLs to =
a `constexpr` string.<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>I would like if it work similar to:<br><div sty=
le=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);borde=
r-style:solid;border-width:1px"><code><div><span style=3D"color:#008">auto<=
/span><span style=3D"color:#000"> x </span><span style=3D"color:#660">=3D</=
span><span style=3D"color:#000"> </span><span style=3D"color:#080">&quot;A =
B&quot;</span><span style=3D"color:#000">_z</span><span style=3D"color:#660=
">;</span></div></code></div><br>It create new object with some type contro=
lled by `_z` UDL.<br></div></div></blockquote><div><br>I don&#39;t understa=
nd why you have such a need to have UDLs control this process. We already h=
ave ways to take a sequence of values and aggregate them into an object. It=
&#39;s called &quot;calling a function with them&quot;.<br><br></div><block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1=
px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>What I find wronghead=
ed and/or confusing about your approach here is that you apply the UDL <i>t=
wice</i>, with two different meanings. The outer UDL is about string concat=
enation. The inner UDL is about regular UDL stuff.<br><br></div></div></blo=
ckquote><div><br>As I based this on Marcel Kr=C3=BCger sugestion, he used n=
ormal string literals as parameters but this prevent any meta programing wi=
th it.</div></div></blockquote><div><br>It doesn&#39;t interfere with const=
expr programming, though. Let&#39;s stop trying to apply C++03 solutions to=
 C++20.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><div>This mean each parameter need be separate type. Question is w=
hat type? Some `std::string_literal&lt;char, &#39;a&#39;, &#39;b&#39;, &#39=
;c&#39;&gt;`? But this will need adding header like for `std::initializer_l=
ist`. But I thought that better is apply again same postfix for inner parts=
 because you should already have control of this.<br></div></div></blockquo=
te><div><br>And if you want to apply a suffix that returns such a thing wit=
h my design, you can. But there need not be a <i>direct</i> connection betw=
een how you process the string fragments and how you apply the aggregation.=
<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"=
><div></div></div></blockquote><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"><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"ltr">=
<div>So the `_sql` simply does regular UDL stuff. How do you put all of the=
se together? That&#39;s the job of `db:run`. It gets a sequence of paramete=
rs; some of those parameters are the results of the `_sql` UDL; others are =
just generic values it will do with as it pleases.<br><br>So doing standard=
 &quot;string interpolation&quot; operations through iostreams would look l=
ike this:<br><br><div style=3D"background-color:rgb(250,250,250);border-col=
or:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><span s=
tyle=3D"color:#000">std</span><span style=3D"color:#660">::</span><span sty=
le=3D"color:#000">stream_fmt</span><span style=3D"color:#660">(</span><span=
 style=3D"color:#000">F</span><span style=3D"color:#080">&quot;Hello, {reci=
pient}!&quot;</span><span style=3D"color:#660">);</span></div></code></div>=
</div><br></div></blockquote><div>=C2=A0<br><br>This could work too, but it=
 this better would be if `F` return normal object:<br><div style=3D"backgro=
und-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid=
;border-width:1px"><code><div><span style=3D"color:#000">genericFunc</span>=
<span style=3D"color:#660">(</span><span style=3D"color:#000">fmt</span><sp=
an style=3D"color:#660">(</span><span style=3D"color:#000">F</span><span st=
yle=3D"color:#080">&quot;Hello {name}&quot;</span><span style=3D"color:#660=
">),</span><span style=3D"color:#000"> fmt</span><span style=3D"color:#660"=
>(</span><span style=3D"color:#000">F</span><span style=3D"color:#080">&quo=
t;Sth {x}&quot;</span><span style=3D"color:#660">));</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#800">//yours version</span><span s=
tyle=3D"color:#000"><br>genericFunc</span><span style=3D"color:#660">(</spa=
n><span style=3D"color:#000">F</span><span style=3D"color:#080">&quot;Hello=
 {name}&quot;</span><span style=3D"color:#000">_fmt</span><span style=3D"co=
lor:#660">,</span><span style=3D"color:#000"> F</span><span style=3D"color:=
#080">&quot;Sth {x}&quot;</span><span style=3D"color:#000">_fmt</span><span=
 style=3D"color:#660">);</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#800">//my version</span></div></code></div><br>Overall I think=
 this should be done this way because you will have better control over wha=
t semantic this string literal will have. In your case it all will depend o=
n context.<br>One drawback of my version is that without UDL `F&quot;{a}&qu=
ot;` have no meaning.<br></div></div></blockquote><div><br>But you have les=
s control over it, because you have this UDL issue. Your method requires tw=
o different kinds of UDLs: a UDL for the purpose of interpreting a literal =
(aka: what UDLs are for), and a &quot;UDL&quot; that acts as a processing f=
ramework for an string interpolation sequence. Why do these two things need=
 to be spelled the same way?<br><br>Consider an `fmt` that uses iostreams. =
So you do this:<br><br><div style=3D"background-color: rgb(250, 250, 250); =
border-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; o=
verflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"prettyprint=
"><div class=3D"subprettyprint"><span style=3D"color: #000;" class=3D"style=
d-by-prettify">F</span><span style=3D"color: #080;" class=3D"styled-by-pret=
tify">&quot;some string {variable} other {variable}&quot;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">fmt</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">;</span></div></code></div><br>And =
that&#39;s supposed to be converted into:<br><br><div style=3D"background-c=
olor: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: s=
olid; border-width: 1px; overflow-wrap: break-word;" class=3D"prettyprint">=
<code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">operator</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #080;"=
 class=3D"styled-by-prettify">&quot;&quot;</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">fmt</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">operator</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #080;" class=3D"styled-by-prett=
ify">&quot;&quot;</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">fmt</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
(</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;som=
e string &quot;</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">),</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> va=
riable</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #008;" class=3D"styled-by-prettify">operator</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #080;" class=3D"styled-by-prettify">&quot;&quot;</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">fmt</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #080;" c=
lass=3D"styled-by-prettify">&quot; other &quot;</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">),</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> variable</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">);</span></div></code></div><br>But all of thos=
e inner &quot;fmt&quot; literals? They <i>don&#39;t do anything</i>. All th=
ey do is return the string. It&#39;s the outer &quot;fmt&quot; call that cr=
eates the `ostringstream` and outputs each object to it.<br><br>Any serious=
 work spent processing the string fragments will be done by the outer UDL, =
which is not really a UDL at all. You have two <i>fundamentally</i> differe=
nt things going on, but you&#39;re trying to pretend that they&#39;re the s=
ame. They aren&#39;t.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/28e80709-5ebb-44d2-b26d-22cafd681330%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/28e80709-5ebb-44d2-b26d-22cafd681330=
%40isocpp.org</a>.<br />

------=_Part_4947_144716130.1518338150570--

------=_Part_4946_247154927.1518338150569--

.


Author: Avi Kivity <avi@scylladb.com>
Date: Sun, 11 Feb 2018 15:06:42 +0200
Raw View
This is a multi-part message in MIME format.
--------------D4C9F3A332FB9B8A35F1ACB7
Content-Type: text/plain; charset="UTF-8"; format=flowed
Content-Transfer-Encoding: quoted-printable

On 02/10/2018 07:30 AM, Nicol Bolas wrote:
>
>
> On Friday, February 9, 2018 at 5:12:26 PM UTC-5, Marcin Jaczewski wrote:
>
>
>
>     On Friday, February 9, 2018 at 10:13:10 PM UTC+1, Jake Arkinstall
>     wrote:
>
>
>
>         On 9 Feb 2018 20:51, <inkwizyt...@gmail.com> wrote:
>
>
>             Minimal version than could be added to C++ is new string
>             prefix `F` (because we have `R`, `u`, `u8` and `U`
>             already, and `$` is outside of source characters) that
>             enable mixing code with string literals.
>             As Marcel Kr=C3=BCger wrote, language could transform this
>             string literal to:
>             |
>             F"testA{a}test{{B}}"_x;=3D>operator""_x("testA"_x,a,"test{B}"=
_x);//using
>             same postfix to parse sub-literals
>             FR"aa(x{b}y)aa"_x;=3D>operator""_x(R"aa(x)aa"_x,b,R"aa(y)aa"_=
x);//it
>             have precedence over `R` prefix
>             |
>
>
>
>             Rest will be implemented by library, this mean `F"a {5}
>             b"` will not compile because there is no matching
>             operator. stl could add this operator for `s` postfix,
>             that will use `std::to_string` for conversing all arguments:
>             |
>             template<typename...Parts>
>             std::stringoperator""s(Parts&&...p){returnstd::to_string(std:=
:forward<Parts>(p))+...;}
>
>             intmain()
>             {
>             autox =3DF"Test {{a}} =3D {10+5}"s;//x =3D=3D "Test {a} =3D 1=
5"s
>             }
>             |
>             |No iosteam, and even more it could if someone relay
>             desire to have localizations:
>
>             |
>             F"Test {356*10}"_loc("Prod {0} OK!","fr")=3D=3D"Prod 3.560,00
>             OK!";
>             |
>
>             Only drawback is some template bloat but this is probably
>             acceptable cost.|
>
>
>         This is exactly the kind of thing I'm aiming for, although I
>         dont believe string conversion and concatenation to be the
>         final solution - unless my recall of benchmarks is out of
>         date, streams are faster than string concatenation.
>
>         This being said, similar ideas can be applied to utilise the
>         fmt library, for example.
>
>
>     This is irrelevant, how it will be implemented is QoI, It could be
>     done using `snprintf`, or even not implemented at all, only prefix
>     `F`and its transformation is important.
>
>     More I think about this more it look as great addition to language:
>     |
>     std::stringa;
>     intb =3D0;
>     intc =3D42;
>     db.run(F"select name as {a}, age as {b} from table where id =3D
>     {c}"_sql);
>
>     |
>
>
> If how this is implemented is a mere implementation detail, how would=20
> you make it use bound parameters or otherwise sanitize string inputs?=20
> Have we learned nothing from Little Bobby Tables <https://xkcd.com/327/>?
>


My horrible code injection proposal would make it work. It would=20
transform the thingie above into "prepare_and_execute("select name as ?,=20
age as ? from table where id =3D ?", a, b, c)" (ignoring the bad SQL for a=
=20
minute).





> Indeed, this seems like a justification to /not/ provide this feature.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/ff46a2e5-cf65-7612-a284-6163e53b9bc3%40scylladb.=
com.

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

<html>
  <head>
    <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-8=
">
  </head>
  <body text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div class=3D"moz-cite-prefix">On 02/10/2018 07:30 AM, Nicol Bolas
      wrote:<br>
    </div>
    <blockquote type=3D"cite"
      cite=3D"mid:f5feb9a0-99d3-433a-ae46-af34c8d00a61@isocpp.org">
      <div dir=3D"ltr"><br>
        <br>
        On Friday, February 9, 2018 at 5:12:26 PM UTC-5, Marcin
        Jaczewski 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"><br>
            <br>
            On Friday, February 9, 2018 at 10:13:10 PM UTC+1, Jake
            Arkinstall 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"auto">
                <div><br>
                  <div><br>
                    <div class=3D"gmail_quote">On 9 Feb 2018 20:51, &lt;<a
                        rel=3D"nofollow" moz-do-not-send=3D"true">inkwizyt.=
...@gmail.com</a>&gt;
                      wrote:<br type=3D"attribution">
                      <blockquote style=3D"margin:0 0 0
                        .8ex;border-left:1px #ccc
                        solid;padding-left:1ex">
                        <div dir=3D"ltr">
                          <div><br>
                          </div>
                          <div>Minimal version than could be added to
                            C++ is new string prefix `F` (because we
                            have `R`, `u`, `u8` and `U` already, and `$`
                            is outside of source characters) that enable
                            mixing code with string literals.<br>
                            As Marcel Kr=C3=BCger wrote, language could
                            transform this string literal to:<br>
                            <div
style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);bo=
rder-style:solid;border-width:1px"><code>
                                <div><span style=3D"color:#000">F</span><sp=
an
                                    style=3D"color:#080">"testA{a}test{{B}}=
"</span><span
                                    style=3D"color:#000">_x</span><span
                                    style=3D"color:#660">;</span><span
                                    style=3D"color:#000"> </span><span
                                    style=3D"color:#660">=3D&gt;</span><spa=
n
                                    style=3D"color:#000"> </span><span
                                    style=3D"color:#008">operator</span><sp=
an
                                    style=3D"color:#080">""</span><span
                                    style=3D"color:#000">_x</span><span
                                    style=3D"color:#660">(</span><span
                                    style=3D"color:#080">"testA"</span><spa=
n
                                    style=3D"color:#000">_x</span><span
                                    style=3D"color:#660">,</span><span
                                    style=3D"color:#000"> a</span><span
                                    style=3D"color:#660">,</span><span
                                    style=3D"color:#000"> </span><span
                                    style=3D"color:#080">"test{B}"</span><s=
pan
                                    style=3D"color:#000">_x</span><span
                                    style=3D"color:#660">);</span><span
                                    style=3D"color:#000"> </span><span
                                    style=3D"color:#800">//using same
                                    postfix to parse sub-literals</span><sp=
an
                                    style=3D"color:#000"><br>
                                    FR</span><span style=3D"color:#080">"aa=
(x{b}y)aa"</span><span
                                    style=3D"color:#000">_x</span><span
                                    style=3D"color:#660">;</span><span
                                    style=3D"color:#000"> </span><span
                                    style=3D"color:#660">=3D&gt;</span><spa=
n
                                    style=3D"color:#000"> </span><span
                                    style=3D"color:#008">operator</span><sp=
an
                                    style=3D"color:#080">""</span><span
                                    style=3D"color:#000">_x</span><span
                                    style=3D"color:#660">(</span><span
                                    style=3D"color:#000">R</span><span
                                    style=3D"color:#080">"aa(x)aa"</span><s=
pan
                                    style=3D"color:#000">_x</span><span
                                    style=3D"color:#660">,</span><span
                                    style=3D"color:#000"> b</span><span
                                    style=3D"color:#660">,</span><span
                                    style=3D"color:#000"> R</span><span
                                    style=3D"color:#080">"aa(y)aa"</span><s=
pan
                                    style=3D"color:#000">_x</span><span
                                    style=3D"color:#660">);</span><span
                                    style=3D"color:#000"> </span><span
                                    style=3D"color:#800">//it have
                                    precedence over `R` prefix</span></div>
                              </code></div>
                            <br>
                            <br>
                            <br>
                            Rest will be implemented by library, this
                            mean `F"a {5} b"` will not compile because
                            there is no matching operator. stl could add
                            this operator for `s` postfix, that will use
                            `std::to_string` for conversing all
                            arguments:<br>
                            <div
style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);bo=
rder-style:solid;border-width:1px"><code>
                                <div><span style=3D"color:#008">template</s=
pan><span
                                    style=3D"color:#660">&lt;</span><span
                                    style=3D"color:#008">typename</span><sp=
an
                                    style=3D"color:#660">...</span><span
                                    style=3D"color:#000"> </span><span
                                    style=3D"color:#606">Parts</span><span
                                    style=3D"color:#660">&gt;</span><span
                                    style=3D"color:#000"><br>
                                    std</span><span style=3D"color:#660">::=
</span><span
                                    style=3D"color:#008">string</span><span
                                    style=3D"color:#000"> </span><span
                                    style=3D"color:#008">operator</span><sp=
an
                                    style=3D"color:#080">""</span><span
                                    style=3D"color:#000">s</span><span
                                    style=3D"color:#660">(</span><span
                                    style=3D"color:#606">Parts</span><span
                                    style=3D"color:#660">&amp;&amp;...</spa=
n><span
                                    style=3D"color:#000"> p</span><span
                                    style=3D"color:#660">)</span><span
                                    style=3D"color:#000"> </span><span
                                    style=3D"color:#660">{</span><span
                                    style=3D"color:#000"> </span><span
                                    style=3D"color:#008">return</span><span
                                    style=3D"color:#000"> std</span><span
                                    style=3D"color:#660">::</span><span
                                    style=3D"color:#000">to_string</span><s=
pan
                                    style=3D"color:#660">(</span><span
                                    style=3D"color:#000">std</span><span
                                    style=3D"color:#660">::</span><span
                                    style=3D"color:#000">forward</span><spa=
n
                                    style=3D"color:#660">&lt;</span><span
                                    style=3D"color:#606">Pa<wbr>rts</span><=
span
                                    style=3D"color:#660">&gt;(</span><span
                                    style=3D"color:#000">p</span><span
                                    style=3D"color:#660">))</span><span
                                    style=3D"color:#000"> </span><span
                                    style=3D"color:#660">+</span><span
                                    style=3D"color:#000"> </span><span
                                    style=3D"color:#660">...;</span><span
                                    style=3D"color:#000"> </span><span
                                    style=3D"color:#660">}</span><span
                                    style=3D"color:#000"><br>
                                    <br>
                                  </span><span style=3D"color:#008">int</sp=
an><span
                                    style=3D"color:#000"> main</span><span
                                    style=3D"color:#660">()</span><span
                                    style=3D"color:#000"><br>
                                  </span><span style=3D"color:#660">{</span=
><span
                                    style=3D"color:#000"><br>
                                    =C2=A0 =C2=A0 </span><span style=3D"col=
or:#008">auto</span><span
                                    style=3D"color:#000"> x </span><span
                                    style=3D"color:#660">=3D</span><span
                                    style=3D"color:#000"> F</span><span
                                    style=3D"color:#080">"Test {{a}} =3D
                                    {10+5}"</span><span
                                    style=3D"color:#000">s</span><span
                                    style=3D"color:#660">;</span><span
                                    style=3D"color:#000"> </span><span
                                    style=3D"color:#800">//x =3D=3D "Test {=
a}
                                    =3D 15"s</span><span
                                    style=3D"color:#000"><br>
                                  </span><span style=3D"color:#660">}</span=
><span
                                    style=3D"color:#000"><br>
                                  </span></div>
                              </code></div>
                            <code>No iosteam, and even more it could if
                              someone relay desire to have
                              localizations:<br>
                              <br>
                              <div
style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);bo=
rder-style:solid;border-width:1px"><code>
                                  <div><span style=3D"color:#000">F</span><=
span
                                      style=3D"color:#080">"Test {356*10}"<=
/span><span
                                      style=3D"color:#000">_loc</span><span
                                      style=3D"color:#660">(</span><span
                                      style=3D"color:#080">"Prod {0} OK!"</=
span><span
                                      style=3D"color:#660">,</span><span
                                      style=3D"color:#000"> </span><span
                                      style=3D"color:#080">"fr"</span><span
                                      style=3D"color:#660">)</span><span
                                      style=3D"color:#000"> </span><span
                                      style=3D"color:#660">=3D=3D</span><sp=
an
                                      style=3D"color:#000"> </span><span
                                      style=3D"color:#080">"Prod 3.560,00
                                      OK!"</span><span
                                      style=3D"color:#660">;</span><span
                                      style=3D"color:#000"><br>
                                    </span></div>
                                </code></div>
                              <br>
                              Only drawback is some template bloat but
                              this is probably acceptable cost.</code></div=
>
                        </div>
                      </blockquote>
                    </div>
                  </div>
                </div>
                <div dir=3D"auto"><br>
                </div>
                <div dir=3D"auto">This is exactly the kind of thing I'm
                  aiming for, although I dont believe string conversion
                  and concatenation to be the final solution - unless my
                  recall of benchmarks is out of date, streams are
                  faster than string concatenation.</div>
                <div dir=3D"auto"><br>
                </div>
                <div dir=3D"auto">This being said, similar ideas can be
                  applied to utilise the fmt library, for example.</div>
              </div>
            </blockquote>
            <div>=C2=A0<br>
              This is irrelevant, how it will be implemented is QoI, It
              could be done using `snprintf`, or even not implemented at
              all, only prefix `F`and its transformation is important.<br>
              <br>
              More I think about this more it look as great addition to
              language:<br>
              <div
style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);bo=
rder-style:solid;border-width:1px"><code>
                  <div><span style=3D"color:#000">std</span><span
                      style=3D"color:#660">::</span><span
                      style=3D"color:#008">string</span><span
                      style=3D"color:#000"> a</span><span
                      style=3D"color:#660">;</span><span
                      style=3D"color:#000"><br>
                    </span><span style=3D"color:#008">int</span><span
                      style=3D"color:#000"> b </span><span
                      style=3D"color:#660">=3D</span><span
                      style=3D"color:#000"> </span><span
                      style=3D"color:#066">0</span><span
                      style=3D"color:#660">;</span><span
                      style=3D"color:#000"><br>
                    </span><span style=3D"color:#008">int</span><span
                      style=3D"color:#000"> c </span><span
                      style=3D"color:#660">=3D</span><span
                      style=3D"color:#000"> </span><span
                      style=3D"color:#066">42</span><span
                      style=3D"color:#660">;</span><span
                      style=3D"color:#000"><br>
                      db</span><span style=3D"color:#660">.</span><span
                      style=3D"color:#000">run</span><span
                      style=3D"color:#660">(</span><span
                      style=3D"color:#000">F</span><span
                      style=3D"color:#080">"select name as {a}, age as {b}
                      from table where id =3D {c}"</span><span
                      style=3D"color:#000">_sql</span><span
                      style=3D"color:#660">);</span><span
                      style=3D"color:#000"><br>
                      <br>
                    </span></div>
                </code></div>
            </div>
          </div>
        </blockquote>
        <div><br>
          If how this is implemented is a mere implementation detail,
          how would you make it use bound parameters or otherwise
          sanitize string inputs? Have we learned nothing from <a
            href=3D"https://xkcd.com/327/" moz-do-not-send=3D"true">Little
            Bobby Tables</a>?<br>
          <br>
        </div>
      </div>
    </blockquote>
    <br>
    <br>
    My horrible code injection proposal would make it work. It would
    transform the thingie above into "prepare_and_execute("select name
    as ?, age as ? from table where id =3D ?", a, b, c)" (ignoring the bad
    SQL for a minute).<br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <blockquote type=3D"cite"
      cite=3D"mid:f5feb9a0-99d3-433a-ae46-af34c8d00a61@isocpp.org">
      <div dir=3D"ltr">
        <div>Indeed, this seems like a justification to <i>not</i>
          provide this feature.<br>
        </div>
      </div>
    </blockquote>
    <br>
  </body>
</html>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/ff46a2e5-cf65-7612-a284-6163e53b9bc3%=
40scylladb.com?utm_medium=3Demail&utm_source=3Dfooter">https://groups.googl=
e.com/a/isocpp.org/d/msgid/std-proposals/ff46a2e5-cf65-7612-a284-6163e53b9b=
c3%40scylladb.com</a>.<br />

--------------D4C9F3A332FB9B8A35F1ACB7--

.


Author: Jake Arkinstall <jake.arkinstall@gmail.com>
Date: Sun, 11 Feb 2018 13:13:07 +0000
Raw View
--001a1135615cc9d9c10564ef8543
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Horrible is... subjective. Such ideas are dangerous in weak hands, but are
nonetheless available in most interpreted languages.

I like other approach just because it's more in tune with the direction the
language is already going in, but the power of compile-time code injection
is intriguing. In order to make it see it's potential we'd have to add a
bunch of constexpr string functions.

On 11 Feb 2018 13:06, "Avi Kivity" <avi@scylladb.com> wrote:

> On 02/10/2018 07:30 AM, Nicol Bolas wrote:
>
>
>
> On Friday, February 9, 2018 at 5:12:26 PM UTC-5, Marcin Jaczewski wrote:
>>
>>
>>
>> On Friday, February 9, 2018 at 10:13:10 PM UTC+1, Jake Arkinstall wrote:
>>>
>>>
>>>
>>> On 9 Feb 2018 20:51, <inkwizyt...@gmail.com> wrote:
>>>
>>>
>>> Minimal version than could be added to C++ is new string prefix `F`
>>> (because we have `R`, `u`, `u8` and `U` already, and `$` is outside of
>>> source characters) that enable mixing code with string literals.
>>> As Marcel Kr=C3=BCger wrote, language could transform this string liter=
al to:
>>> F"testA{a}test{{B}}"_x; =3D> operator""_x("testA"_x, a, "test{B}"_x); /=
/using
>>> same postfix to parse sub-literals
>>> FR"aa(x{b}y)aa"_x; =3D> operator""_x(R"aa(x)aa"_x, b, R"aa(y)aa"_x); //=
it
>>> have precedence over `R` prefix
>>>
>>>
>>>
>>> Rest will be implemented by library, this mean `F"a {5} b"` will not
>>> compile because there is no matching operator. stl could add this opera=
tor
>>> for `s` postfix, that will use `std::to_string` for conversing all
>>> arguments:
>>> template<typename... Parts>
>>> std::string operator""s(Parts&&... p) { return std::to_string(std::
>>> forward<Parts>(p)) + ...; }
>>>
>>> int main()
>>> {
>>>     auto x =3D F"Test {{a}} =3D {10+5}"s; //x =3D=3D "Test {a} =3D 15"s
>>> }
>>> No iosteam, and even more it could if someone relay desire to have
>>> localizations:
>>>
>>> F"Test {356*10}"_loc("Prod {0} OK!", "fr") =3D=3D "Prod 3.560,00 OK!";
>>>
>>> Only drawback is some template bloat but this is probably acceptable
>>> cost.
>>>
>>>
>>> This is exactly the kind of thing I'm aiming for, although I dont
>>> believe string conversion and concatenation to be the final solution -
>>> unless my recall of benchmarks is out of date, streams are faster than
>>> string concatenation.
>>>
>>> This being said, similar ideas can be applied to utilise the fmt
>>> library, for example.
>>>
>>
>> This is irrelevant, how it will be implemented is QoI, It could be done
>> using `snprintf`, or even not implemented at all, only prefix `F`and its
>> transformation is important.
>>
>> More I think about this more it look as great addition to language:
>> std::string a;
>> int b =3D 0;
>> int c =3D 42;
>> db.run(F"select name as {a}, age as {b} from table where id =3D {c}"_sql=
);
>>
>>
> If how this is implemented is a mere implementation detail, how would you
> make it use bound parameters or otherwise sanitize string inputs? Have we
> learned nothing from Little Bobby Tables <https://xkcd.com/327/>?
>
>
>
> My horrible code injection proposal would make it work. It would transfor=
m
> the thingie above into "prepare_and_execute("select name as ?, age as ?
> from table where id =3D ?", a, b, c)" (ignoring the bad SQL for a minute)=
..
>
>
>
>
>
> Indeed, this seems like a justification to *not* provide this feature.
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit https://groups.google.com/a/
> isocpp.org/d/msgid/std-proposals/ff46a2e5-cf65-7612-
> a284-6163e53b9bc3%40scylladb.com
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/ff46a2e5-cf=
65-7612-a284-6163e53b9bc3%40scylladb.com?utm_medium=3Demail&utm_source=3Dfo=
oter>
> .
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CAC%2B0CCNZXxi9DsmADBbC9Ov6JQrcJHzPdDLtCe7_4-6yO=
i%3DGxA%40mail.gmail.com.

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

<div dir=3D"auto">Horrible is... subjective. Such ideas are dangerous in we=
ak hands, but are nonetheless available in most interpreted languages.<div =
dir=3D"auto"><br></div><div dir=3D"auto">I like other approach just because=
 it&#39;s more in tune with the direction the language is already going in,=
 but the power of compile-time code injection is intriguing. In order to ma=
ke it see it&#39;s potential we&#39;d have to add a bunch of constexpr stri=
ng functions.</div></div><div class=3D"gmail_extra"><br><div class=3D"gmail=
_quote">On 11 Feb 2018 13:06, &quot;Avi Kivity&quot; &lt;<a href=3D"mailto:=
avi@scylladb.com">avi@scylladb.com</a>&gt; wrote:<br type=3D"attribution"><=
blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px=
 #ccc solid;padding-left:1ex">
 =20
   =20
 =20
  <div text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div class=3D"m_837665124437514935moz-cite-prefix">On 02/10/2018 07:30 =
AM, Nicol Bolas
      wrote:<br>
    </div>
    <blockquote type=3D"cite">
      <div dir=3D"ltr"><br>
        <br>
        On Friday, February 9, 2018 at 5:12:26 PM UTC-5, Marcin
        Jaczewski wrote:
        <blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex">
          <div dir=3D"ltr"><br>
            <br>
            On Friday, February 9, 2018 at 10:13:10 PM UTC+1, Jake
            Arkinstall 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"auto">
                <div><br>
                  <div><br>
                    <div class=3D"gmail_quote">On 9 Feb 2018 20:51, &lt;<a =
rel=3D"nofollow">inkwizyt...@gmail.com</a>&gt;
                      wrote:<br type=3D"attribution">
                      <blockquote style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">
                        <div dir=3D"ltr">
                          <div><br>
                          </div>
                          <div>Minimal version than could be added to
                            C++ is new string prefix `F` (because we
                            have `R`, `u`, `u8` and `U` already, and `$`
                            is outside of source characters) that enable
                            mixing code with string literals.<br>
                            As Marcel Kr=C3=BCger wrote, language could
                            transform this string literal to:<br>
                            <div style=3D"background-color:rgb(250,250,250)=
;border-color:rgb(187,187,187);border-style:solid;border-width:1px"><code>
                                <div><span style=3D"color:#000">F</span><sp=
an style=3D"color:#080">&quot;testA{a}test{{B}}&quot;</span><span style=3D"=
color:#000">_x</span><span style=3D"color:#660">;</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#660">=3D&gt;</span><span style=3D"col=
or:#000"> </span><span style=3D"color:#008">operator</span><span style=3D"c=
olor:#080">&quot;&quot;</span><span style=3D"color:#000">_x</span><span sty=
le=3D"color:#660">(</span><span style=3D"color:#080">&quot;testA&quot;</spa=
n><span style=3D"color:#000">_x</span><span style=3D"color:#660">,</span><s=
pan style=3D"color:#000"> a</span><span style=3D"color:#660">,</span><span =
style=3D"color:#000"> </span><span style=3D"color:#080">&quot;test{B}&quot;=
</span><span style=3D"color:#000">_x</span><span style=3D"color:#660">);</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#800">//using s=
ame
                                    postfix to parse sub-literals</span><sp=
an style=3D"color:#000"><br>
                                    FR</span><span style=3D"color:#080">&qu=
ot;aa(x{b}y)aa&quot;</span><span style=3D"color:#000">_x</span><span style=
=3D"color:#660">;</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#660">=3D&gt;</span><span style=3D"color:#000"> </span><span style=3D"=
color:#008">operator</span><span style=3D"color:#080">&quot;&quot;</span><s=
pan style=3D"color:#000">_x</span><span style=3D"color:#660">(</span><span =
style=3D"color:#000">R</span><span style=3D"color:#080">&quot;aa(x)aa&quot;=
</span><span style=3D"color:#000">_x</span><span style=3D"color:#660">,</sp=
an><span style=3D"color:#000"> b</span><span style=3D"color:#660">,</span><=
span style=3D"color:#000"> R</span><span style=3D"color:#080">&quot;aa(y)aa=
&quot;</span><span style=3D"color:#000">_x</span><span style=3D"color:#660"=
>);</span><span style=3D"color:#000"> </span><span style=3D"color:#800">//i=
t have
                                    precedence over `R` prefix</span></div>
                              </code></div>
                            <br>
                            <br>
                            <br>
                            Rest will be implemented by library, this
                            mean `F&quot;a {5} b&quot;` will not compile be=
cause
                            there is no matching operator. stl could add
                            this operator for `s` postfix, that will use
                            `std::to_string` for conversing all
                            arguments:<br>
                            <div style=3D"background-color:rgb(250,250,250)=
;border-color:rgb(187,187,187);border-style:solid;border-width:1px"><code>
                                <div><span style=3D"color:#008">template</s=
pan><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">typena=
me</span><span style=3D"color:#660">...</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#606">Parts</span><span style=3D"color:#660">&gt=
;</span><span style=3D"color:#000"><br>
                                    std</span><span style=3D"color:#660">::=
</span><span style=3D"color:#008">string</span><span style=3D"color:#000"> =
</span><span style=3D"color:#008">operator</span><span style=3D"color:#080"=
>&quot;&quot;</span><span style=3D"color:#000">s</span><span style=3D"color=
:#660">(</span><span style=3D"color:#606">Parts</span><span style=3D"color:=
#660">&amp;&amp;...</span><span style=3D"color:#000"> p</span><span style=
=3D"color:#660">)</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#660">{</span><span style=3D"color:#000"> </span><span style=3D"color:=
#008">return</span><span style=3D"color:#000"> std</span><span style=3D"col=
or:#660">::</span><span style=3D"color:#000">to_string</span><span style=3D=
"color:#660">(</span><span style=3D"color:#000">std</span><span style=3D"co=
lor:#660">::</span><span style=3D"color:#000">forward</span><span style=3D"=
color:#660">&lt;</span><span style=3D"color:#606">Pa<wbr>rts</span><span st=
yle=3D"color:#660">&gt;(</span><span style=3D"color:#000">p</span><span sty=
le=3D"color:#660">))</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">+</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#660">...;</span><span style=3D"color:#000"> </span><span style=3D"col=
or:#660">}</span><span style=3D"color:#000"><br>
                                    <br>
                                  </span><span style=3D"color:#008">int</sp=
an><span style=3D"color:#000"> main</span><span style=3D"color:#660">()</sp=
an><span style=3D"color:#000"><br>
                                  </span><span style=3D"color:#660">{</span=
><span style=3D"color:#000"><br>
                                    =C2=A0 =C2=A0 </span><span style=3D"col=
or:#008">auto</span><span style=3D"color:#000"> x </span><span style=3D"col=
or:#660">=3D</span><span style=3D"color:#000"> F</span><span style=3D"color=
:#080">&quot;Test {{a}} =3D
                                    {10+5}&quot;</span><span style=3D"color=
:#000">s</span><span style=3D"color:#660">;</span><span style=3D"color:#000=
"> </span><span style=3D"color:#800">//x =3D=3D &quot;Test {a}
                                    =3D 15&quot;s</span><span style=3D"colo=
r:#000"><br>
                                  </span><span style=3D"color:#660">}</span=
><span style=3D"color:#000"><br>
                                  </span></div>
                              </code></div>
                            <code>No iosteam, and even more it could if
                              someone relay desire to have
                              localizations:<br>
                              <br>
                              <div style=3D"background-color:rgb(250,250,25=
0);border-color:rgb(187,187,187);border-style:solid;border-width:1px"><code=
>
                                  <div><span style=3D"color:#000">F</span><=
span style=3D"color:#080">&quot;Test {356*10}&quot;</span><span style=3D"co=
lor:#000">_loc</span><span style=3D"color:#660">(</span><span style=3D"colo=
r:#080">&quot;Prod {0} OK!&quot;</span><span style=3D"color:#660">,</span><=
span style=3D"color:#000"> </span><span style=3D"color:#080">&quot;fr&quot;=
</span><span style=3D"color:#660">)</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#660">=3D=3D</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#080">&quot;Prod 3.560,00
                                      OK!&quot;</span><span style=3D"color:=
#660">;</span><span style=3D"color:#000"><br>
                                    </span></div>
                                </code></div>
                              <br>
                              Only drawback is some template bloat but
                              this is probably acceptable cost.</code></div=
>
                        </div>
                      </blockquote>
                    </div>
                  </div>
                </div>
                <div dir=3D"auto"><br>
                </div>
                <div dir=3D"auto">This is exactly the kind of thing I&#39;m
                  aiming for, although I dont believe string conversion
                  and concatenation to be the final solution - unless my
                  recall of benchmarks is out of date, streams are
                  faster than string concatenation.</div>
                <div dir=3D"auto"><br>
                </div>
                <div dir=3D"auto">This being said, similar ideas can be
                  applied to utilise the fmt library, for example.</div>
              </div>
            </blockquote>
            <div>=C2=A0<br>
              This is irrelevant, how it will be implemented is QoI, It
              could be done using `snprintf`, or even not implemented at
              all, only prefix `F`and its transformation is important.<br>
              <br>
              More I think about this more it look as great addition to
              language:<br>
              <div style=3D"background-color:rgb(250,250,250);border-color:=
rgb(187,187,187);border-style:solid;border-width:1px"><code>
                  <div><span style=3D"color:#000">std</span><span style=3D"=
color:#660">::</span><span style=3D"color:#008">string</span><span style=3D=
"color:#000"> a</span><span style=3D"color:#660">;</span><span style=3D"col=
or:#000"><br>
                    </span><span style=3D"color:#008">int</span><span style=
=3D"color:#000"> b </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> </span><span style=3D"color:#066">0</span><span style=3D"c=
olor:#660">;</span><span style=3D"color:#000"><br>
                    </span><span style=3D"color:#008">int</span><span style=
=3D"color:#000"> c </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> </span><span style=3D"color:#066">42</span><span style=3D"=
color:#660">;</span><span style=3D"color:#000"><br>
                      db</span><span style=3D"color:#660">.</span><span sty=
le=3D"color:#000">run</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">F</span><span style=3D"color:#080">&quot;select name as {a}=
, age as {b}
                      from table where id =3D {c}&quot;</span><span style=
=3D"color:#000">_sql</span><span style=3D"color:#660">);</span><span style=
=3D"color:#000"><br>
                      <br>
                    </span></div>
                </code></div>
            </div>
          </div>
        </blockquote>
        <div><br>
          If how this is implemented is a mere implementation detail,
          how would you make it use bound parameters or otherwise
          sanitize string inputs? Have we learned nothing from <a href=3D"h=
ttps://xkcd.com/327/" target=3D"_blank">Little
            Bobby Tables</a>?<br>
          <br>
        </div>
      </div>
    </blockquote>
    <br>
    <br>
    My horrible code injection proposal would make it work. It would
    transform the thingie above into &quot;prepare_and_execute(&quot;select=
 name
    as ?, age as ? from table where id =3D ?&quot;, a, b, c)&quot; (ignorin=
g the bad
    SQL for a minute).<br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>Indeed, this seems like a justification to <i>not</i>
          provide this feature.<br>
        </div>
      </div>
    </blockquote>
    <br>
  </div>


<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/ff46a2e5-cf65-7612-a284-6163e53b9bc3%=
40scylladb.com?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank=
">https://groups.google.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/ff=
46a2e5-cf65-7612-<wbr>a284-6163e53b9bc3%40scylladb.<wbr>com</a>.<br>
</blockquote></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCNZXxi9DsmADBbC9Ov6JQrcJHzPdD=
LtCe7_4-6yOi%3DGxA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCNZXx=
i9DsmADBbC9Ov6JQrcJHzPdDLtCe7_4-6yOi%3DGxA%40mail.gmail.com</a>.<br />

--001a1135615cc9d9c10564ef8543--

.


Author: inkwizytoryankes@gmail.com
Date: Sun, 11 Feb 2018 06:20:27 -0800 (PST)
Raw View
------=_Part_7962_1595625738.1518358827912
Content-Type: multipart/alternative;
 boundary="----=_Part_7963_1164743747.1518358827913"

------=_Part_7963_1164743747.1518358827913
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



On Sunday, February 11, 2018 at 9:35:50 AM UTC+1, Nicol Bolas wrote:
>
>
>
> On Saturday, February 10, 2018 at 9:38:20 PM UTC-5, Marcin Jaczewski wrot=
e:
>>
>>
>>
>> On Saturday, February 10, 2018 at 8:37:45 PM UTC+1, Nicol Bolas wrote:
>>>
>>> On Saturday, February 10, 2018 at 1:39:45 PM UTC-5, Marcin Jaczewski=20
>>> wrote:
>>>>
>>>> But it can easy check it, `_sql` is not string, if you pass string the=
n=20
>>>> it will be escaped before it is appended to finals string that is send=
 to=20
>>>> database.
>>>> And how it will be exactly implemented? Like this:
>>>> db.run(operator""_sql("select name as "_sql, a, ", age as "_sql, b, "f=
rom=20
>>>> table where id =3D "_sql, c, ""_sql));
>>>>
>>>> This will call:
>>>> sql_command operator""_sql(sql_command, std::string& a, sql_command,=
=20
>>>> int& b, sql_command, int& c, sql_command);
>>>>
>>>>
>>> I see some value in the general approach, but allow me to redefine it i=
n=20
>>> a more coherent way.
>>>
>>> The token `F""` is treated a lot like we treat `...` pack expansions.=
=20
>>> The `F` prefix performs a "string literal expansion" operation,=20
>>> transforming the literal into a sequence of literals and identifiers=20
>>> extracted from the literal.
>>>
>>>
>> And then wat result will be of:
>> auto x =3D F"A {42} B"_z;
>>
>> If it work as pack expansion then it do not have meaning on its own.
>>
>
> You say that like it's a bad thing. Does `pack...` have meaning on its ow=
n?
>
>
You can use pack expansion only in specific places:
template<typename... A>
void f(A... a)
{
    a...; //error: expected ';' before '...' token
    F"{42}"; //then it should too generate same error
    f(F"{42}"); //now is fine
}

Probably statement "have meaning on its own" is not most accuracy way to=20
describe this, I probably should use "independent" or "standalone", because=
=20
only in specific places you can use it.

=20

> The point of my idea is that it provides a sharp separation between the=
=20
> two fundamental operations of "string interpolation". There's the "conver=
t=20
> a string literal into a bunch of smaller literals and variables" part. An=
d=20
> there's the "do something with that bunch of smaller literals and=20
> variables."
>
> By making part 1 into a pack expansion-like construct, it forces you to=
=20
> make the way you want to process that expansion *explicit*. It also makes=
=20
> a clear distinction between a UDL used for normal purposes and the system=
=20
> used to process code.
>
> =20
But this work in this way in C# and JavaScript (and probably other=20
languages too), C# return final string (or interface that you can tweak=20
result a bit) and JS return fully processed object from tag function.
My approach mimic it.
=20

For example, let's say I want to use interpolation to process a literal and=
=20
> store all of the elements in a tuple. We can store each of the non-litera=
l=20
> parts easily enough. But what about the literal parts? You might say that=
 a=20
> `const char*` is good enough, but maybe I want it to be a `string_view`. =
To=20
> do that with my system, it's as simple as:
>
> tuple(F"some string {variable} other string"sv);
>
> I have to write precisely *zero code* to make that work.
>
> With your system, I have to write a function. Scratch that; I have to=20
> create *two* functions. One function is the string fragment UDL, which=20
> does exactly what `operator""sv` does. And the other is literally just=20
> `return tuple(std::forward<Args>(args)...);`.
>
> So I have to write two functions, and both of them are one-liners.
>
> And if I want to do the exact same tuple building, only with `std::string=
`=20
> instead of `string_view`, I have to write two functions. Again. One of th=
em=20
> will be *exactly identical* to the one paired with `string_view`.
>
> Or I could just do:
>
> tuple(F"some string {variable} other string"s);
>
> No additional code needs to be written here. It Just Works(tm).
>
>
Every solution have strong parts and weak parts, if you want only "pack=20
expansion" then my will be inferior but if you what final product then my=
=20
will be superior:
void f(std::string s);

f(std::concat(F"My name is {name}")); //your version
f(F"My name is {name}"s); //my version

This is simply trade off where we move boilerplate.

I do not except that every project will have multiple different string=20
literals, in my version even `F"Answer: {42}"sv` should not exist because=
=20
it would need allocate memory.
Again this is trade off, I sacrifice on thing to grain other, right now I=
=20
use C# literals, work flow look like this:
foo("My name is X"); //original version with hardcoded value
foo($"My name is {name}");

Now I would like have same thing in C++:
foo("My name is X"s);
foo(F"My name is {name}"s);

I except more use cases like this, small tweaks to add different data.
=20
=20

> And look back at your `_sql` example. To me, a string with the `_sql`=20
> literal suffix ought to be a compiled SQL statement, ready to be executed=
..=20
> The syntax of the this statement shoudl be verified as valid.
>
> But that's not the case with the `_sql` suffixes used on the string=20
> fragments. While the total result of the interpolation is an SQL statemen=
t,=20
> "select name as" is not valid SQL *by itself*. So what exactly is the=20
> `_sql` suffix doing to these fragments? Some basic token recognition? Why=
=20
> bother; the final concatenation process is what has to do all of the=20
> serious validation work.
>
> This separation between how a string fragment is processed and how the=20
> aggregation is built is important. And the best way to achieve that=20
> separation is to actually separate them.
>
>
You are right, reusing postfix for literals parts could be more troublesome=
=20
than its worth, then I probably should stick to `std::string_literal` that=
=20
will do same work and will not mix both concepts.
F"Test{a}"s =3D> operator""s("Test"type, a, ""type)

BTW in your case you can't use `_sql` with `F` because you will get same=20
problem that I had. It will apply in on string that aren't proper sql.
=20

> I also find that my idea is more forward-looking. If we do get full=20
> `constexpr` string support, then there's no reason why we shouldn't be ab=
le=20
> to invoke the compiler's support for "string interpolation" on such a=20
> string. Your idea is so heavily based on UDLs that it becomes difficult t=
o=20
> make it work on `constexpr` non-UDL strings. Why? Because your design=20
> requires two parts: grammar to say "interpolate string" and a secondary=
=20
> parameter that says "with this".
>
> My design has grammar that says "interpolation string". The "with this"=
=20
> part comes out through the regular rules of C++: explicit function calls.=
=20
> That means we already have grammar to say "with this". All my design woul=
d=20
> need to service `constexpr` strings is for the "interpolate string" gramm=
ar=20
> to be something that can be applied to variables as well as literals.
>
> Your design would require being able to apply UDLs to a `constexpr` strin=
g.
>
> I would like if it work similar to:
>> auto x =3D "A B"_z;
>>
>> It create new object with some type controlled by `_z` UDL.
>>
>
> I don't understand why you have such a need to have UDLs control this=20
> process. We already have ways to take a sequence of values and aggregate=
=20
> them into an object. It's called "calling a function with them".
>
> What I find wrongheaded and/or confusing about your approach here is that=
=20
>>> you apply the UDL *twice*, with two different meanings. The outer UDL=
=20
>>> is about string concatenation. The inner UDL is about regular UDL stuff=
..
>>>
>>>
>> As I based this on Marcel Kr=C3=BCger sugestion, he used normal string=
=20
>> literals as parameters but this prevent any meta programing with it.
>>
>
> It doesn't interfere with constexpr programming, though. Let's stop tryin=
g=20
> to apply C++03 solutions to C++20.
>
>
You can't change return type based on `char*` value (this was what Marcel=
=20
used in his version), this would require `constexpr` arguments that=20
probably will be never added to language.
=20
=20

> [..]
>
=20
After your suggestion my solution should look like:

We have new UDL signature that is available for string literals that start=
=20
with `F` prefix:
template<typename... Parts>
auto operator""_x(Parts&&... p) { ... }

Each usage of
std::string name =3D "X";
int i =3D 5;
F"Test {name}{i}"_x;

Will be changed to:
operator""_x("Test "type, name, ""type, i); //"Test "type =3D=3D=3D=20
std::string_literal<char, 'T', 'e', 's', 't', ' '>


Now biggest difference between our version is where processing will be=20
done, in my case it will be done by `operator""_x`, in your in your case=20
will be function that get this parameter packs.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/52b86f0a-b3b9-455f-9d4d-0f6b15192c90%40isocpp.or=
g.

------=_Part_7963_1164743747.1518358827913
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Sunday, February 11, 2018 at 9:35:50 AM UTC+1, =
Nicol Bolas wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"=
ltr"><br><br>On Saturday, February 10, 2018 at 9:38:20 PM UTC-5, Marcin Jac=
zewski wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-lef=
t:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><=
br>On Saturday, February 10, 2018 at 8:37:45 PM UTC+1, Nicol Bolas wrote:<b=
lockquote 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 Saturday, Februar=
y 10, 2018 at 1:39:45 PM UTC-5, Marcin Jaczewski wrote:<blockquote class=3D=
"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"ltr"><div>But it can easy check it, `_sql` =
is not string, if you pass string then it will be escaped before it is appe=
nded to finals string that is send to database.<br>And how it will be exact=
ly implemented? Like this:<br><div style=3D"background-color:rgb(250,250,25=
0);border-color:rgb(187,187,187);border-style:solid;border-width:1px"><code=
><div><span style=3D"color:#000">db</span><span style=3D"color:#660">.</spa=
n><span style=3D"color:#000">run</span><span style=3D"color:#660">(</span><=
span style=3D"color:#008">operator</span><span style=3D"color:#080">&quot;&=
quot;</span><span style=3D"color:#000">_sql</span><span style=3D"color:#660=
">(</span><span style=3D"color:#080">&quot;select name as &quot;</span><spa=
n style=3D"color:#000">_sql</span><span style=3D"color:#660">,</span><span =
style=3D"color:#000"> a</span><span style=3D"color:#660">,</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#080">&quot;, age as &quot;</=
span><span style=3D"color:#000">_sql</span><span style=3D"color:#660">,</sp=
an><span style=3D"color:#000"> b</span><span style=3D"color:#660">,</span><=
span style=3D"color:#000"> </span><span style=3D"color:#080">&quot;from tab=
le where id =3D &quot;</span><span style=3D"color:#000">_sql</span><span st=
yle=3D"color:#660">,</span><span style=3D"color:#000"> c</span><span style=
=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#080">&quot;&quot;</span><span style=3D"color:#000">_sql</span><span s=
tyle=3D"color:#660">));</span></div></code></div><br>This will call:<br><di=
v style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);=
border-style:solid;border-width:1px"><code><div><span style=3D"color:#000">=
sql_command </span><span style=3D"color:#008">operator</span><span style=3D=
"color:#080">&quot;&quot;</span><span style=3D"color:#000">_sql</span><span=
 style=3D"color:#660">(</span><span style=3D"color:#000">sql_command</span>=
<span style=3D"color:#660">,</span><span style=3D"color:#000"> std</span><s=
pan style=3D"color:#660">::</span><span style=3D"color:#008">string</span><=
span style=3D"color:#660">&amp;</span><span style=3D"color:#000"> a</span><=
span style=3D"color:#660">,</span><span style=3D"color:#000"> sql_command</=
span><span style=3D"color:#660">,</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#008">int</span><span style=3D"color:#660">&amp;</span=
><span style=3D"color:#000"> b</span><span style=3D"color:#660">,</span><sp=
an style=3D"color:#000"> sql_command</span><span style=3D"color:#660">,</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#008">int</span>=
<span style=3D"color:#660">&amp;</span><span style=3D"color:#000"> c</span>=
<span style=3D"color:#660">,</span><span style=3D"color:#000"> sql_command<=
/span><span style=3D"color:#660">);</span></div></code></div><br></div></di=
v></blockquote><div><br>I see some value in the general approach, but allow=
 me to redefine it in a more coherent way.<br><br>The token `F&quot;&quot;`=
 is treated a lot like we treat `...` pack expansions. The `F` prefix perfo=
rms a &quot;string literal expansion&quot; operation, transforming the lite=
ral into a sequence of literals and identifiers extracted from the literal.=
<br><br></div></div></blockquote><div><br>And then wat result will be of:<b=
r><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,=
187);border-style:solid;border-width:1px"><code><div><span style=3D"color:#=
008">auto</span><span style=3D"color:#000"> x </span><span style=3D"color:#=
660">=3D</span><span style=3D"color:#000"> F</span><span style=3D"color:#08=
0">&quot;A {42} B&quot;</span><span style=3D"color:#000">_z</span><span sty=
le=3D"color:#660">;</span></div></code></div><br>If it work as pack expansi=
on then it do not have meaning on its own.<br></div></div></blockquote><div=
><br>You say that like it&#39;s a bad thing. Does `pack...` have meaning on=
 its own?<br><br></div></div></blockquote><div><br>You can use pack expansi=
on only in specific places:<br><div style=3D"background-color: rgb(250, 250=
, 250); border-color: rgb(187, 187, 187); border-style: solid; border-width=
: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"pre=
ttyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=
=3D"styled-by-prettify">template</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">typename</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">...</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> A</span><span style=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"> f</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">A</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">...</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> a</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 =C2=A0 a</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">...;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #800;" class=3D"styled-by-prettify">//error: expe=
cted &#39;;&#39; before &#39;...&#39; token</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 F</span><span style=3D"c=
olor: #080;" class=3D"styled-by-prettify">&quot;{42}&quot;</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">//then it should too generate same error</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 f</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">F</span><span =
style=3D"color: #080;" class=3D"styled-by-prettify">&quot;{42}&quot;</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #800;" class=3D"styled-by-prettify">//now is fine</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br></span></div></code></div><br>Probably sta=
tement &quot;have meaning on its own&quot; is not most accuracy way to desc=
ribe this, I probably should use &quot;independent&quot; or &quot;standalon=
e&quot;, because only in specific places you can use it.<br><br>=C2=A0</div=
><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bo=
rder-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>The poi=
nt of my idea is that it provides a sharp separation between the two fundam=
ental operations of &quot;string interpolation&quot;. There&#39;s the &quot=
;convert a string literal into a bunch of smaller literals and variables&qu=
ot; part. And there&#39;s the &quot;do something with that bunch of smaller=
 literals and variables.&quot;<br><br>By making part 1 into a pack expansio=
n-like construct, it forces you to make the way you want to process that ex=
pansion <i>explicit</i>. It also makes a clear distinction between a UDL us=
ed for normal purposes and the system used to process code.<br><br></div></=
div></blockquote><div>=C2=A0<br>But this work in this way in C# and JavaScr=
ipt (and probably other languages too), C# return final string (or interfac=
e that you can tweak result a bit) and JS return fully processed object fro=
m tag function.<br>My approach mimic it.<br>=C2=A0<br><br></div><blockquote=
 class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1=
px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>For example, let&#3=
9;s say I want to use interpolation to process a literal and store all of t=
he elements in a tuple. We can store each of the non-literal parts easily e=
nough. But what about the literal parts? You might say that a `const char*`=
 is good enough, but maybe I want it to be a `string_view`. To do that with=
 my system, it&#39;s as simple as:<br><br><div style=3D"background-color:rg=
b(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-widt=
h:1px"><code><div><span style=3D"color:#000">tuple</span><span style=3D"col=
or:#660">(</span><span style=3D"color:#000">F</span><span style=3D"color:#0=
80">&quot;some string {variable} other string&quot;</span><span style=3D"co=
lor:#000">sv</span><span style=3D"color:#660">);</span></div></code></div><=
br>I have to write precisely <i>zero code</i> to make that work.<br><br>Wit=
h your system, I have to write a function. Scratch that; I have to create <=
i>two</i> functions. One function is the string fragment UDL, which does ex=
actly what `operator&quot;&quot;sv` does. And the other is literally just `=
return tuple(std::forward&lt;Args&gt;(args)<wbr>...);`.<br><br>So I have to=
 write two functions, and both of them are one-liners.<br><br>And if I want=
 to do the exact same tuple building, only with `std::string` instead of `s=
tring_view`, I have to write two functions. Again. One of them will be <i>e=
xactly identical</i> to the one paired with `string_view`.<br><br>Or I coul=
d just do:<br><br><div style=3D"background-color:rgb(250,250,250);border-co=
lor:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><span =
style=3D"color:#000">tuple</span><span style=3D"color:#660">(</span><span s=
tyle=3D"color:#000">F</span><span style=3D"color:#080">&quot;some string {v=
ariable} other string&quot;</span><span style=3D"color:#000">s</span><span =
style=3D"color:#660">);</span></div></code></div><br>No additional code nee=
ds to be written here. It Just Works(tm).<br><br></div></div></blockquote><=
div><br>Every solution have strong parts and weak parts, if you want only &=
quot;pack expansion&quot; then my will be inferior but if you what final pr=
oduct then my will be superior:<br><div style=3D"background-color: rgb(250,=
 250, 250); border-color: rgb(187, 187, 187); border-style: solid; border-w=
idth: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code class=3D=
"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">void</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> f</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::<=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">string</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> s</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br><br>f</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">std</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">concat</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">F</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&qu=
ot;My name is {name}&quot;</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">));</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">=
//your version</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br>f</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: #080;" class=3D"styled-by-prettify">&quot;My name is {n=
ame}&quot;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
s</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #800;" class=3D"styled-by-prettify">//my version</span></div><=
/code></div><br>This is simply trade off where we move boilerplate.<br><br>=
I do not except that every project will have multiple different string lite=
rals, in my version even `F&quot;Answer: {42}&quot;sv` should not exist bec=
ause it would need allocate memory.<br>Again this is trade off, I sacrifice=
 on thing to grain other, right now I use C# literals, work flow look like =
this:<br><div style=3D"background-color: rgb(250, 250, 250); border-color: =
rgb(187, 187, 187); border-style: solid; border-width: 1px; overflow-wrap: =
break-word;" class=3D"prettyprint"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">foo</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</s=
pan><span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;My name=
 is X&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: #800;" class=3D"styled-by-prettify">//original versi=
on with hardcoded value</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br>foo</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: #080;" class=3D"styled-by-prettify">&quot;My=
 name is {name}&quot;</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br></span></div></code></div><br>Now I would like have same thing in C+=
+:<br><div style=3D"background-color: rgb(250, 250, 250); border-color: rgb=
(187, 187, 187); border-style: solid; border-width: 1px; overflow-wrap: bre=
ak-word;" class=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"s=
ubprettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettify">fo=
o</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><=
span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;My name is X=
&quot;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">s</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br>foo</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: #08=
0;" class=3D"styled-by-prettify">&quot;My name is {name}&quot;</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify">s</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">);</span></div></code></div><br>=
I except more use cases like this, small tweaks to add different data.<br>=
=C2=A0<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>And look back at your `_sql` example. To me, a string with th=
e `_sql` literal suffix ought to be a compiled SQL statement, ready to be e=
xecuted. The syntax of the this statement shoudl be verified as valid.<br><=
br>But that&#39;s not the case with the `_sql` suffixes used on the string =
fragments. While the total result of the interpolation is an SQL statement,=
 &quot;select name as&quot; is not valid SQL <i>by itself</i>. So what exac=
tly is the `_sql` suffix doing to these fragments? Some basic token recogni=
tion? Why bother; the final concatenation process is what has to do all of =
the serious validation work.<br><br>This separation between how a string fr=
agment is processed and how the aggregation is built is important. And the =
best way to achieve that separation is to actually separate them.<br><br></=
div></div></blockquote><div><br>You are right, reusing postfix for literals=
 parts could be more troublesome than its worth, then I probably should sti=
ck to `std::string_literal` that will do same work and will not mix both co=
ncepts.<br><div style=3D"background-color: rgb(250, 250, 250); border-color=
: rgb(187, 187, 187); border-style: solid; border-width: 1px; overflow-wrap=
: break-word;" class=3D"prettyprint"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">F</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;=
Test{a}&quot;</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">s </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D&g=
t;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">operator</span><s=
pan style=3D"color: #080;" class=3D"styled-by-prettify">&quot;&quot;</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">s</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"col=
or: #080;" class=3D"styled-by-prettify">&quot;Test&quot;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">type</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> a</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #080;" class=3D"styled-by-pret=
tify">&quot;&quot;</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">type</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">)</span></div></code></div><br>BTW in your case you can&#39;t use `_sql` =
with `F` because you will get same problem that I had. It will apply in on =
string that aren&#39;t proper sql.<br>=C2=A0</div><blockquote class=3D"gmai=
l_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;=
padding-left: 1ex;"><div dir=3D"ltr"><div>I also find that my idea is more =
forward-looking. If we do get full `constexpr` string support, then there&#=
39;s no reason why we shouldn&#39;t be able to invoke the compiler&#39;s su=
pport for &quot;string interpolation&quot; on such a string. Your idea is s=
o heavily based on UDLs that it becomes difficult to make it work on `const=
expr` non-UDL strings. Why? Because your design requires two parts: grammar=
 to say &quot;interpolate string&quot; and a secondary parameter that says =
&quot;with this&quot;.<br><br>My design has grammar that says &quot;interpo=
lation string&quot;. The &quot;with this&quot; part comes out through the r=
egular rules of C++: explicit function calls. That means we already have gr=
ammar to say &quot;with this&quot;. All my design would need to service `co=
nstexpr` strings is for the &quot;interpolate string&quot; grammar to be so=
mething that can be applied to variables as well as literals.<br><br>Your d=
esign would require being able to apply UDLs to a `constexpr` string.<br><b=
r></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>I wou=
ld like if it work similar to:<br><div style=3D"background-color:rgb(250,25=
0,250);border-color:rgb(187,187,187);border-style:solid;border-width:1px"><=
code><div><span style=3D"color:#008">auto</span><span style=3D"color:#000">=
 x </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> =
</span><span style=3D"color:#080">&quot;A B&quot;</span><span style=3D"colo=
r:#000">_z</span><span style=3D"color:#660">;</span></div></code></div><br>=
It create new object with some type controlled by `_z` UDL.<br></div></div>=
</blockquote><div><br>I don&#39;t understand why you have such a need to ha=
ve UDLs control this process. We already have ways to take a sequence of va=
lues and aggregate them into an object. It&#39;s called &quot;calling a fun=
ction with them&quot;.<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><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div d=
ir=3D"ltr"><div>What I find wrongheaded and/or confusing about your approac=
h here is that you apply the UDL <i>twice</i>, with two different meanings.=
 The outer UDL is about string concatenation. The inner UDL is about regula=
r UDL stuff.<br><br></div></div></blockquote><div><br>As I based this on Ma=
rcel Kr=C3=BCger sugestion, he used normal string literals as parameters bu=
t this prevent any meta programing with it.</div></div></blockquote><div><b=
r>It doesn&#39;t interfere with constexpr programming, though. Let&#39;s st=
op trying to apply C++03 solutions to C++20.<br><br></div></div></blockquot=
e><div><br>You can&#39;t change return type based on `char*` value (this wa=
s what Marcel used in his version), this would require `constexpr` argument=
s that probably will be never added to language.<br>=C2=A0<br>=C2=A0</div><=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div>[..=
]</div></blockquote><div>=C2=A0<br>After your suggestion my solution should=
 look like:<br><br>We have new UDL signature that is available for string l=
iterals that start with `F` prefix:<br><div style=3D"background-color: rgb(=
250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; bord=
er-width: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code clas=
s=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;=
" class=3D"styled-by-prettify">template</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">typename</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">...</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-pr=
ettify">Parts</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
></span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">operator</span><span sty=
le=3D"color: #080;" class=3D"styled-by-prettify">&quot;&quot;</span><span s=
tyle=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: #6=
06;" class=3D"styled-by-prettify">Parts</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">&amp;&amp;...</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> p</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">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">...</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"color=
: #000;" class=3D"styled-by-prettify"><br></span></div></code></div><br>Eac=
h usage of<br><div style=3D"background-color: rgb(250, 250, 250); border-co=
lor: rgb(187, 187, 187); border-style: solid; border-width: 1px; overflow-w=
rap: break-word;" class=3D"prettyprint"><code class=3D"prettyprint"><div cl=
ass=3D"subprettyprint"><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: #008;" class=3D"styled-by-prettify">string</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> name </span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #080;" class=3D"styled-by-prettify">&quot;X&quot;</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">int</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> i </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify=
">5</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>F</span><spa=
n style=3D"color: #080;" class=3D"styled-by-prettify">&quot;Test {name}{i}&=
quot;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">_x</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span></div=
></code></div><br>Will be changed to:<br><div style=3D"background-color: rg=
b(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; bo=
rder-width: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code cl=
ass=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">operator</span><span style=3D"color: #080;=
" class=3D"styled-by-prettify">&quot;&quot;</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">_x</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">(</span><span style=3D"color: #080;" class=3D"styl=
ed-by-prettify">&quot;Test &quot;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">type</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> name</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: #080;" class=3D"styled-by-prettify">&quot;&quot;</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">type</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> i</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">//&quot;Test &quot;type =3D=3D=3D std::string_liter=
al&lt;char, &#39;T&#39;, &#39;e&#39;, &#39;s&#39;, &#39;t&#39;, &#39; &#39;=
&gt;</span></div></code></div><br><br>Now biggest difference between our ve=
rsion is where processing will be done, in my case it will be done by `oper=
ator&quot;&quot;_x`, in your in your case will be function that get this pa=
rameter packs.<br><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/52b86f0a-b3b9-455f-9d4d-0f6b15192c90%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/52b86f0a-b3b9-455f-9d4d-0f6b15192c90=
%40isocpp.org</a>.<br />

------=_Part_7963_1164743747.1518358827913--

------=_Part_7962_1595625738.1518358827912--

.


Author: Todd Fleming <tbfleming@gmail.com>
Date: Sun, 11 Feb 2018 07:45:18 -0800 (PST)
Raw View
------=_Part_3856_886590181.1518363918199
Content-Type: multipart/alternative;
 boundary="----=_Part_3857_1412491744.1518363918200"

------=_Part_3857_1412491744.1518363918200
Content-Type: text/plain; charset="UTF-8"

On Sunday, February 11, 2018 at 3:35:50 AM UTC-5, Nicol Bolas wrote:
>
> For example, let's say I want to use interpolation to process a literal
> and store all of the elements in a tuple. We can store each of the
> non-literal parts easily enough. But what about the literal parts? You
> might say that a `const char*` is good enough, but maybe I want it to be a
> `string_view`. To do that with my system, it's as simple as:
>
> tuple(F"some string {variable} other string"sv);
>
> I have to write precisely *zero code* to make that work.
>

I'm starting to really love this idea. I've been racking my head on how to
get lit-html <https://github.com/Polymer/lit-html>'s simplicity and
expressiveness to C++ code compiled to wasm. The way this proposal is going
I'd end up with something like this:

auto h = html(F"<div><h1>{title}</h1><p>{text}</p></div>"sv);

Todd

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/58edbd0a-fb4c-48dd-8819-6fea7e9c8e39%40isocpp.org.

------=_Part_3857_1412491744.1518363918200
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Sunday, February 11, 2018 at 3:35:50 AM UTC-5, Nicol Bo=
las 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"><di=
v>For example, let&#39;s say I want to use interpolation to process a liter=
al and store all of the elements in a tuple. We can store each of the non-l=
iteral parts easily enough. But what about the literal parts? You might say=
 that a `const char*` is good enough, but maybe I want it to be a `string_v=
iew`. To do that with my system, it&#39;s as simple as:<br><br><div style=
=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-=
style:solid;border-width:1px"><code><div><span style=3D"color:#000">tuple</=
span><span style=3D"color:#660">(</span><span style=3D"color:#000">F</span>=
<span style=3D"color:#080">&quot;some string {variable} other string&quot;<=
/span><span style=3D"color:#000">sv</span><span style=3D"color:#660">);</sp=
an></div></code></div><br>I have to write precisely <i>zero code</i> to mak=
e that work.<br></div></div></blockquote><div><br></div><div>I&#39;m starti=
ng to really love this idea. I&#39;ve been racking my head on how to get=C2=
=A0<a href=3D"https://github.com/Polymer/lit-html">lit-html</a>&#39;s simpl=
icity and expressiveness to C++ code compiled to wasm. The way this proposa=
l is going I&#39;d end up with something like this:</div><div><br></div><di=
v><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"subpretty=
print"><font color=3D"#660066"><span style=3D"color: #008;" class=3D"styled=
-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> h </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> html<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">F</span><span style=
=3D"color: #080;" class=3D"styled-by-prettify">&quot;&lt;div&gt;&lt;h1&gt;{=
title}&lt;/h1&gt;&lt;p&gt;{text}&lt;/p&gt;&lt;/div&gt;&quot;</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">sv</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">);</span></font></div></code></di=
v><br>Todd</div><div><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/58edbd0a-fb4c-48dd-8819-6fea7e9c8e39%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/58edbd0a-fb4c-48dd-8819-6fea7e9c8e39=
%40isocpp.org</a>.<br />

------=_Part_3857_1412491744.1518363918200--

------=_Part_3856_886590181.1518363918199--

.


Author: Todd Fleming <tbfleming@gmail.com>
Date: Sun, 11 Feb 2018 09:02:26 -0800 (PST)
Raw View
------=_Part_647_1727766916.1518368546672
Content-Type: multipart/alternative;
 boundary="----=_Part_648_1218297557.1518368546672"

------=_Part_648_1218297557.1518368546672
Content-Type: text/plain; charset="UTF-8"

On Sunday, February 11, 2018 at 10:45:18 AM UTC-5, Todd Fleming wrote:
>
> On Sunday, February 11, 2018 at 3:35:50 AM UTC-5, Nicol Bolas wrote:
>>
>> For example, let's say I want to use interpolation to process a literal
>> and store all of the elements in a tuple. We can store each of the
>> non-literal parts easily enough. But what about the literal parts? You
>> might say that a `const char*` is good enough, but maybe I want it to be a
>> `string_view`. To do that with my system, it's as simple as:
>>
>> tuple(F"some string {variable} other string"sv);
>>
>> I have to write precisely *zero code* to make that work.
>>
>
> I'm starting to really love this idea. I've been racking my head on how to
> get lit-html <https://github.com/Polymer/lit-html>'s simplicity and
> expressiveness to C++ code compiled to wasm. The way this proposal is going
> I'd end up with something like this:
>
> auto h = html(F"<div><h1>{title}</h1><p>{text}</p></div>"sv);
>
> Todd
>
>
Expanding on this a bit since Marcin mentioned JS template literals. The
html function would internally call another function, int
template_literal(string_view...). template_literal would return a constant
which is a handle to a JS template literal. Constant because emscripten
runs wasm through a post processor (binaryen) which can do transforms like
this prior to running wasm-specific reoptimization.

I believe Nicol's approach gives me the final piece of the puzzle I need to
pull this off with a convenient syntax. Now if only I had this approach
today...

Todd

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/2a820658-2c83-4614-b871-b19a760faafd%40isocpp.org.

------=_Part_648_1218297557.1518368546672
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Sunday, February 11, 2018 at 10:45:18 AM UTC-5, Todd Fl=
eming wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">O=
n Sunday, February 11, 2018 at 3:35:50 AM UTC-5, Nicol Bolas wrote:<blockqu=
ote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1=
px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>For example, let&#39;=
s say I want to use interpolation to process a literal and store all of the=
 elements in a tuple. We can store each of the non-literal parts easily eno=
ugh. But what about the literal parts? You might say that a `const char*` i=
s good enough, but maybe I want it to be a `string_view`. To do that with m=
y system, it&#39;s as simple as:<br><br><div style=3D"background-color:rgb(=
250,250,250);border-color:rgb(187,187,187);border-style:solid;border-width:=
1px"><code><div><span style=3D"color:#000">tuple</span><span style=3D"color=
:#660">(</span><span style=3D"color:#000">F</span><span style=3D"color:#080=
">&quot;some string {variable} other string&quot;</span><span style=3D"colo=
r:#000">sv</span><span style=3D"color:#660">);</span></div></code></div><br=
>I have to write precisely <i>zero code</i> to make that work.<br></div></d=
iv></blockquote><div><br></div><div>I&#39;m starting to really love this id=
ea. I&#39;ve been racking my head on how to get=C2=A0<a href=3D"https://git=
hub.com/Polymer/lit-html" target=3D"_blank" rel=3D"nofollow" onmousedown=3D=
"this.href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%=
2FPolymer%2Flit-html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHLwwkL7NWqLnso=
njlzdoVv_ie3Ig&#39;;return true;" onclick=3D"this.href=3D&#39;https://www.g=
oogle.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2FPolymer%2Flit-html\x26sa\x3dD=
\x26sntz\x3d1\x26usg\x3dAFQjCNHLwwkL7NWqLnsonjlzdoVv_ie3Ig&#39;;return true=
;">lit-html</a>&#39;s simplicity and expressiveness to C++ code compiled to=
 wasm. The way this proposal is going I&#39;d end up with something like th=
is:</div><div><br></div><div><div style=3D"background-color:rgb(250,250,250=
);border-color:rgb(187,187,187);border-style:solid;border-width:1px;word-wr=
ap:break-word"><code><div><font color=3D"#660066"><span style=3D"color:#008=
">auto</span><span style=3D"color:#000"> h </span><span style=3D"color:#660=
">=3D</span><span style=3D"color:#000"> html</span><span style=3D"color:#66=
0">(</span><span style=3D"color:#000">F</span><span style=3D"color:#080">&q=
uot;&lt;div&gt;&lt;h1&gt;{title}&lt;/h1&gt;&lt;<wbr>p&gt;{text}&lt;/p&gt;&l=
t;/div&gt;&quot;</span><span style=3D"color:#000">sv</span><span style=3D"c=
olor:#660">);</span></font></div></code></div><br>Todd</div><div><br></div>=
</div></blockquote><div><br></div><div>Expanding on this a bit since Marcin=
 mentioned JS template literals. The html function would internally call an=
other function, int template_literal(string_view...). template_literal woul=
d return a constant which is a handle to a JS template literal. Constant be=
cause emscripten runs wasm through a post processor (binaryen) which can do=
 transforms like this prior to running wasm-specific reoptimization.</div><=
div><br></div><div>I believe Nicol&#39;s approach gives me the final piece =
of the puzzle I need to pull this off with a convenient syntax. Now if only=
 I had this approach today...</div><div><br></div><div>Todd</div><div><br><=
/div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/2a820658-2c83-4614-b871-b19a760faafd%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/2a820658-2c83-4614-b871-b19a760faafd=
%40isocpp.org</a>.<br />

------=_Part_648_1218297557.1518368546672--

------=_Part_647_1727766916.1518368546672--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 11 Feb 2018 10:08:44 -0800 (PST)
Raw View
------=_Part_2489_1164935945.1518372525022
Content-Type: multipart/alternative;
 boundary="----=_Part_2490_1052652035.1518372525022"

------=_Part_2490_1052652035.1518372525022
Content-Type: text/plain; charset="UTF-8"

Your new idea is really no better than the old one. The problem comes back
to the same point: you are conflating two fundamentally distinct
operations: the operation to be applied to each string fragment, and the
operation to be applied to aggregate the fragments into a whole.

Your first idea involved the use of two UDL overloads, thereby tightly
coupling the two operations. Your second idea only uses one UDL overload,
but it still tightly couples the two operations by forcing all string
fragments to use the "same type". Or more specifically, to use the same
string fragment processed template: `std::string_literal`.

In 99% of cases, you don't need to do character-by-character analysis of
such literals. A simple array of characters will do. This is why the UDL
definition syntax doesn't *force* you to process all literals by characters
of a template parameter. It certainly gives you that option, but it is not
forced on you.

There is no reason why string interpolation should force this upon you.
With my way, you can *choose* to process the fragments this way:

template <char... chars>
auto operator ""literal() {return std::string_literal<chars...>{};}

std::do_something(F"some string {variable}"literal);

But you aren't *required* to. You can choose how you want to process those
fragments. The 99% of cases that work just fine with `const char*`s or
whatever don't have to deal with this `std::string_literal` type. The 1% of
template metaprogramming heavy cases have this available as an option.

Exceptional circumstances should be optional, not the default.

I do not understand your fervent insistence on using UDLs to provide the
aggregation function to be called, rather than explicitly calling an actual
function. It doesn't even make sense conceptually.

On a conceptual level, a UDL operation produces an object. But not all
aggregation operations on an interpolated string will produce an "object";
I see no reason why I can't do this:

std::output(std::cout, F"some string {variable}");

This just writes the individual members of the interpolated string to the
given output stream. No object is being generated; I'm simply invoking a
process.

Something similar goes for your SQL database operation:

db.exec(F"some sql stuff {var1} more sql {var2};");

No object needs to be created; you're just running a command.

Using UDLs to invoke the aggregation operation is just the wrong concept.

On Sunday, February 11, 2018 at 9:20:28 AM UTC-5, Marcin Jaczewski wrote:
>
> On Sunday, February 11, 2018 at 9:35:50 AM UTC+1, Nicol Bolas wrote:
>>
>> On Saturday, February 10, 2018 at 9:38:20 PM UTC-5, Marcin Jaczewski
>> wrote:
>>>
>>> And then wat result will be of:
>>> auto x = F"A {42} B"_z;
>>>
>>> If it work as pack expansion then it do not have meaning on its own.
>>>
>>
>> You say that like it's a bad thing. Does `pack...` have meaning on its
>> own?
>>
>>
> You can use pack expansion only in specific places:
>

I know that. My point was that we already have grammatical constructs like
that which only work in a limited number of places. What is wrong with
making string interpolation work that way?

The point of my idea is that it provides a sharp separation between the two
>> fundamental operations of "string interpolation". There's the "convert a
>> string literal into a bunch of smaller literals and variables" part. And
>> there's the "do something with that bunch of smaller literals and
>> variables."
>>
>> By making part 1 into a pack expansion-like construct, it forces you to
>> make the way you want to process that expansion *explicit*. It also
>> makes a clear distinction between a UDL used for normal purposes and the
>> system used to process code.
>>
>>
> But this work in this way in C# and JavaScript (and probably other
> languages too), C# return final string (or interface that you can tweak
> result a bit) and JS return fully processed object from tag function.
> My approach mimic it.
>

C++ has many language features that do similar things from other languages
but in different ways. Lambdas are pretty unique in C++, as are the way we
handle variadic parameters and expansion (most languages make you index the
variadic list; we allow you to write patterns and expand them in-situ).
Indeed, every language has its own specific quirks and distinctions. I see
no reason to exactly mimic other languages when we can make the mechanism
so much more flexible than what you're proposing.

Not unless it actually gains us something.

You can't change return type based on `char*` value (this was what Marcel
> used in his version), this would require `constexpr` arguments that
> probably will be never added to language.
>

`constexpr` programming is not based on a 1:1 mapping between "type" and
"value"; it's based on regular C++ programming principles. On using
different *values* for those types; we're just doing it at compile time
instead of runtime. That's why its much better than trying to use template
metaprogramming.

In short, you don't *need* it to work this way. Once we can actually create
and manipulate strings at compile time, there's little point to using
metaprogramming to process them.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1e9a5468-6efa-48a2-87ce-6bdb6d5c4e83%40isocpp.org.

------=_Part_2490_1052652035.1518372525022
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Your new idea is really no better than the old one. The pr=
oblem comes back to the same point: you are conflating two fundamentally di=
stinct operations: the operation to be applied to each string fragment, and=
 the operation to be applied to aggregate the fragments into a whole.<br><b=
r>Your first idea involved the use of two UDL overloads, thereby tightly co=
upling the two operations. Your second idea only uses one UDL overload, but=
 it still tightly couples the two operations by forcing all string fragment=
s to use the &quot;same type&quot;. Or more specifically, to use the same s=
tring fragment processed template: `std::string_literal`.<br><br>In 99% of =
cases, you don&#39;t need to do character-by-character analysis of such lit=
erals. A simple array of characters will do. This is why the UDL definition=
 syntax doesn&#39;t <i>force</i> you to process all literals by characters =
of a template parameter. It certainly gives you that option, but it is not =
forced on you.<br><br>There is no reason why string interpolation should fo=
rce this upon you. With my way, you can <i>choose</i> to process the fragme=
nts this way:<br><br><div style=3D"background-color: rgb(250, 250, 250); bo=
rder-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; ove=
rflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"prettyprint">=
<div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-=
by-prettify">template</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">char=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">...</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> chars</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">operator</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #080;" class=3D"styl=
ed-by-prettify">&quot;&quot;</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">literal</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">()</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: #008;" class=3D"styled-by-prettify">return</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">string_literal</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">chars</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">...&gt;{};}</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br><br>std</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify">do_something</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">F</span><span style=3D"color: #080;" class=3D"=
styled-by-prettify">&quot;some string {variable}&quot;</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">literal</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">);</span></div></code></div><br>Bu=
t you aren&#39;t <i>required</i> to. You can choose how you want to process=
 those fragments. The 99% of cases that work just fine with `const char*`s =
or whatever=20
don&#39;t have to deal with this `std::string_literal` type. The 1% of temp=
late=20
metaprogramming heavy cases have this available as an option.<br><br>Except=
ional circumstances should be optional, not the default.<br><br>I do not un=
derstand your fervent insistence on using UDLs to provide the aggregation f=
unction to be called, rather than explicitly calling an actual function. It=
 doesn&#39;t even make sense conceptually.<br><br>On a conceptual level, a =
UDL operation produces an object. But not all aggregation operations on an =
interpolated string will produce an &quot;object&quot;; I see no reason why=
 I can&#39;t do this:<br><br><div style=3D"background-color: rgb(250, 250, =
250); border-color: rgb(187, 187, 187); border-style: solid; border-width: =
1px; overflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"prett=
yprint"><div class=3D"subprettyprint"><span style=3D"color: #000;" class=3D=
"styled-by-prettify">std</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">output</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">std</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify">cout</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> F</span><span style=3D"color: #080;"=
 class=3D"styled-by-prettify">&quot;some string {variable}&quot;</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">);</span></div></code=
></div><br>This just writes the individual members of the interpolated stri=
ng to the given output stream. No object is being generated; I&#39;m simply=
 invoking a process.<br><br>Something similar goes for your SQL database op=
eration:<br><br><div style=3D"background-color: rgb(250, 250, 250); border-=
color: rgb(187, 187, 187); border-style: solid; border-width: 1px; overflow=
-wrap: break-word;" class=3D"prettyprint"><code class=3D"prettyprint"><div =
class=3D"subprettyprint"><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">db</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
..</span><span style=3D"color: #008;" class=3D"styled-by-prettify">exec</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">F</span><span style=3D"c=
olor: #080;" class=3D"styled-by-prettify">&quot;some sql stuff {var1} more =
sql {var2};&quot;</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">);</span></div></code></div><br>No object needs to be created; you&#=
39;re just running a command.<br><br>Using UDLs to invoke the aggregation o=
peration is just the wrong concept.<br><br>On Sunday, February 11, 2018 at =
9:20:28 AM UTC-5, Marcin Jaczewski wrote:<blockquote class=3D"gmail_quote" =
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-l=
eft: 1ex;"><div dir=3D"ltr">On Sunday, February 11, 2018 at 9:35:50 AM UTC+=
1, Nicol Bolas wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;ma=
rgin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"lt=
r">On Saturday, February 10, 2018 at 9:38:20 PM UTC-5, Marcin Jaczewski wro=
te:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bo=
rder-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>And then w=
at result will be of:<br><div style=3D"background-color:rgb(250,250,250);bo=
rder-color:rgb(187,187,187);border-style:solid;border-width:1px"><code><div=
><span style=3D"color:#008">auto</span><span style=3D"color:#000"> x </span=
><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> F</span><=
span style=3D"color:#080">&quot;A {42} B&quot;</span><span style=3D"color:#=
000">_z</span><span style=3D"color:#660">;</span></div></code></div><br>If =
it work as pack expansion then it do not have meaning on its own.<br></div>=
</div></blockquote><div><br>You say that like it&#39;s a bad thing. Does `p=
ack...` have meaning on its own?<br><br></div></div></blockquote><div><br>Y=
ou can use pack expansion only in specific places:<br></div></div></blockqu=
ote><div><br>I know that. My point was that we already have grammatical con=
structs like that which only work in a limited number of places. What is wr=
ong with making string interpolation work that way?<br><br></div><blockquot=
e class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: =
1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><blockquote =
class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #=
ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>The point of my idea is t=
hat it provides a sharp separation between the two fundamental operations o=
f &quot;string interpolation&quot;. There&#39;s the &quot;convert a string =
literal into a bunch of smaller literals and variables&quot; part. And ther=
e&#39;s the &quot;do something with that bunch of smaller literals and vari=
ables.&quot;<br><br>By making part 1 into a pack expansion-like construct, =
it forces you to make the way you want to process that expansion <i>explici=
t</i>. It also makes a clear distinction between a UDL used for normal purp=
oses and the system used to process code.<br><br></div></div></blockquote><=
div>=C2=A0<br>But this work in this way in C# and JavaScript (and probably =
other languages too), C# return final string (or interface that you can twe=
ak result a bit) and JS return fully processed object from tag function.<br=
>My approach mimic it.<br></div></div></blockquote><div dir=3D"ltr"><br>C++=
 has many language features that do similar things from other languages but=
 in different ways. Lambdas are pretty unique in C++, as are the way we han=
dle variadic parameters and expansion (most languages make you index the va=
riadic list; we allow you to write patterns and expand them in-situ). Indee=
d, every language has its own specific quirks and distinctions. I see no re=
ason to exactly mimic other languages when we can make the mechanism so muc=
h more flexible than what you&#39;re proposing.<br><br>Not unless it actual=
ly gains us something. <br><br></div><blockquote class=3D"gmail_quote" styl=
e=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left:=
 1ex;"><div dir=3D"ltr"><div>You can&#39;t change return type based on `cha=
r*` value (this was what Marcel used in his version), this would require `c=
onstexpr` arguments that probably will be never added to language.<br></div=
></div></blockquote><div><br>`constexpr` programming is not based on a 1:1 =
mapping between &quot;type&quot; and &quot;value&quot;; it&#39;s based on r=
egular C++ programming principles. On using different <i>values</i> for tho=
se types; we&#39;re just doing it at compile time instead of runtime. That&=
#39;s why its much better than trying to use template metaprogramming.<br><=
br>In short, you don&#39;t <i>need</i> it to work this way. Once we can act=
ually create and manipulate strings at compile time, there&#39;s little poi=
nt to using metaprogramming to process them.</div><br></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/1e9a5468-6efa-48a2-87ce-6bdb6d5c4e83%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/1e9a5468-6efa-48a2-87ce-6bdb6d5c4e83=
%40isocpp.org</a>.<br />

------=_Part_2490_1052652035.1518372525022--

------=_Part_2489_1164935945.1518372525022--

.


Author: florian.csdt@gmail.com
Date: Mon, 12 Feb 2018 02:17:45 -0800 (PST)
Raw View
------=_Part_6458_588853956.1518430665592
Content-Type: multipart/alternative;
 boundary="----=_Part_6459_1552059679.1518430665596"

------=_Part_6459_1552059679.1518430665596
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Let me suggest something close to Nicol's solution, but not quite.

The F"" operator returns a special type that could be like a simple tuple=
=20
(let's name it std::string_processing for now).

Then the user can use it directly into its own functions.


auto column =3D "col"s;
auto table =3D "tab"sv;
auto req =3D sql(F"select {column} from {table};");

// would be equivalent to:
auto req =3D sql(std::string_processing<const char[8]&, std::string&, const=
=20
char[7]&, std::string_view&, const char[2]&>("select ", column, " from ",=
=20
table, ";"));

Now, if we want, we could also support UDL (but not mandatory) by allowing=
=20
to call UDL on the std::string_processing:

auto column =3D "col"s;
auto table =3D "tab"sv;
auto req =3D F"select {column} from {table};"_sql;

// would be equivalent to:
auto req =3D operator ""_sql (std::string_processing<const char[8]&, std::
string&, const char[7]&, std::string_view&, const char[2]&>("select ",=20
column, " from ", table, ";"));

Now let's have some examples of it could be:

Simple string concatenation would be simple
auto concatenated =3D F"{str1}{str2}{str3}"s;
// converted into an efficient concatenation of the 3 strings

We could print it into an iostream if we want (but would be here only for=
=20
convenience on legacy code)
std::cout << F"{str1}{str2}\n";
// equivalent to:
std::cout << str1 << str2 << "\n";

It could be implicitly convertible to a std::string (only if variables are=
=20
implicitly convertible to std::string)
std::string concatenated =3D F"{str1}{str2}";

(No example with FMT as I don't know how it works, but I don't see any=20
reason for it not to be compatible with FMT.)

And this would be constexpr-able.

Now, formatting would require a bit more elaborated type that could store=
=20
formatting information.
But in the end, only the user will know what to do with it.
However, I would prefer *not* to embed formatting in such a type, just to=
=20
keep it simple. And use a library based solution when I really need=20
formatting.

It has all the advantages of Nicol's solution, while being more versatile.

Florian

Le dimanche 11 f=C3=A9vrier 2018 19:08:45 UTC+1, Nicol Bolas a =C3=A9crit :
>
> Your new idea is really no better than the old one. The problem comes bac=
k=20
> to the same point: you are conflating two fundamentally distinct=20
> operations: the operation to be applied to each string fragment, and the=
=20
> operation to be applied to aggregate the fragments into a whole.
>
> Your first idea involved the use of two UDL overloads, thereby tightly=20
> coupling the two operations. Your second idea only uses one UDL overload,=
=20
> but it still tightly couples the two operations by forcing all string=20
> fragments to use the "same type". Or more specifically, to use the same=
=20
> string fragment processed template: `std::string_literal`.
>
> In 99% of cases, you don't need to do character-by-character analysis of=
=20
> such literals. A simple array of characters will do. This is why the UDL=
=20
> definition syntax doesn't *force* you to process all literals by=20
> characters of a template parameter. It certainly gives you that option, b=
ut=20
> it is not forced on you.
>
> There is no reason why string interpolation should force this upon you.=
=20
> With my way, you can *choose* to process the fragments this way:
>
> template <char... chars>
> auto operator ""literal() {return std::string_literal<chars...>{};}
>
> std::do_something(F"some string {variable}"literal);
>
> But you aren't *required* to. You can choose how you want to process=20
> those fragments. The 99% of cases that work just fine with `const char*`s=
=20
> or whatever don't have to deal with this `std::string_literal` type. The =
1%=20
> of template metaprogramming heavy cases have this available as an option.
>
> Exceptional circumstances should be optional, not the default.
>
> I do not understand your fervent insistence on using UDLs to provide the=
=20
> aggregation function to be called, rather than explicitly calling an actu=
al=20
> function. It doesn't even make sense conceptually.
>
> On a conceptual level, a UDL operation produces an object. But not all=20
> aggregation operations on an interpolated string will produce an "object"=
;=20
> I see no reason why I can't do this:
>
> std::output(std::cout, F"some string {variable}");
>
> This just writes the individual members of the interpolated string to the=
=20
> given output stream. No object is being generated; I'm simply invoking a=
=20
> process.
>
> Something similar goes for your SQL database operation:
>
> db.exec(F"some sql stuff {var1} more sql {var2};");
>
> No object needs to be created; you're just running a command.
>
> Using UDLs to invoke the aggregation operation is just the wrong concept.
>
> On Sunday, February 11, 2018 at 9:20:28 AM UTC-5, Marcin Jaczewski wrote:
>>
>> On Sunday, February 11, 2018 at 9:35:50 AM UTC+1, Nicol Bolas wrote:
>>>
>>> On Saturday, February 10, 2018 at 9:38:20 PM UTC-5, Marcin Jaczewski=20
>>> wrote:
>>>>
>>>> And then wat result will be of:
>>>> auto x =3D F"A {42} B"_z;
>>>>
>>>> If it work as pack expansion then it do not have meaning on its own.
>>>>
>>>
>>> You say that like it's a bad thing. Does `pack...` have meaning on its=
=20
>>> own?
>>>
>>>
>> You can use pack expansion only in specific places:
>>
>
> I know that. My point was that we already have grammatical constructs lik=
e=20
> that which only work in a limited number of places. What is wrong with=20
> making string interpolation work that way?
>
> The point of my idea is that it provides a sharp separation between the=
=20
>>> two fundamental operations of "string interpolation". There's the "conv=
ert=20
>>> a string literal into a bunch of smaller literals and variables" part. =
And=20
>>> there's the "do something with that bunch of smaller literals and=20
>>> variables."
>>>
>>> By making part 1 into a pack expansion-like construct, it forces you to=
=20
>>> make the way you want to process that expansion *explicit*. It also=20
>>> makes a clear distinction between a UDL used for normal purposes and th=
e=20
>>> system used to process code.
>>>
>>> =20
>> But this work in this way in C# and JavaScript (and probably other=20
>> languages too), C# return final string (or interface that you can tweak=
=20
>> result a bit) and JS return fully processed object from tag function.
>> My approach mimic it.
>>
>
> C++ has many language features that do similar things from other language=
s=20
> but in different ways. Lambdas are pretty unique in C++, as are the way w=
e=20
> handle variadic parameters and expansion (most languages make you index t=
he=20
> variadic list; we allow you to write patterns and expand them in-situ).=
=20
> Indeed, every language has its own specific quirks and distinctions. I se=
e=20
> no reason to exactly mimic other languages when we can make the mechanism=
=20
> so much more flexible than what you're proposing.
>
> Not unless it actually gains us something.=20
>
> You can't change return type based on `char*` value (this was what Marcel=
=20
>> used in his version), this would require `constexpr` arguments that=20
>> probably will be never added to language.
>>
>
> `constexpr` programming is not based on a 1:1 mapping between "type" and=
=20
> "value"; it's based on regular C++ programming principles. On using=20
> different *values* for those types; we're just doing it at compile time=
=20
> instead of runtime. That's why its much better than trying to use templat=
e=20
> metaprogramming.
>
> In short, you don't *need* it to work this way. Once we can actually=20
> create and manipulate strings at compile time, there's little point to=20
> using metaprogramming to process them.
>
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/750ecf62-9637-40f4-8585-e3be2780fb46%40isocpp.or=
g.

------=_Part_6459_1552059679.1518430665596
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Let me suggest something close to Nicol&#39;s solution, bu=
t not quite.<br><br>The F&quot;&quot; operator returns a special type that =
could be like a simple tuple (let&#39;s name it std::string_processing for =
now).<br><br>Then the user can use it directly into its own functions.<br><=
br><br><div style=3D"background-color: rgb(250, 250, 250); border-color: rg=
b(187, 187, 187); border-style: solid; border-width: 1px; overflow-wrap: br=
eak-word;" class=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"=
subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">a=
uto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> column=
 </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 st=
yle=3D"color: #080;" class=3D"styled-by-prettify">&quot;col&quot;</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">s</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> table </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #080;" class=3D"styled-by-pr=
ettify">&quot;tab&quot;</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify">sv</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> req </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> sql</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">F</span><span style=3D"color: #080;" class=
=3D"styled-by-prettify">&quot;select {column} from {table};&quot;</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">// would be equivalent to:</=
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 s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> req </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> sql</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">std</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">string_processing</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">const</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">cha=
r</span><span style=3D"color: #660;" class=3D"styled-by-prettify">[</span><=
span style=3D"color: #066;" class=3D"styled-by-prettify">8</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">]&amp;,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">string</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">&amp;,</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">const</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">char</span><span style=3D"color: #660;" class=3D"styled-by-prettify">[</s=
pan><span style=3D"color: #066;" class=3D"styled-by-prettify">7</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">]&amp;,</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify">string_view</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">&amp;,</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">const</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">char</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">[</span><span style=3D"color: #066;" class=3D"styled-by-prettify">2</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">]&amp;&gt;(</s=
pan><span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;select =
&quot;</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> column</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #080;" class=3D"styled-by-prettify">&quot; from &quot;</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> table</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #080;" class=3D"st=
yled-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"><br></span></div></code></div><br>Now, if we want, we could a=
lso support UDL (but not mandatory) by allowing to call UDL on the std::str=
ing_processing:<br><br><div style=3D"background-color: rgb(250, 250, 250); =
border-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; o=
verflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"prettyprint=
"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"style=
d-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> column </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 </span><span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;col=
&quot;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">s</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> table </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: #080;" class=
=3D"styled-by-prettify">&quot;tab&quot;</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">sv</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 req </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> F</span><sp=
an style=3D"color: #080;" class=3D"styled-by-prettify">&quot;select {column=
} from {table};&quot;</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">_sql</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
<br></span><span style=3D"color: #800;" class=3D"styled-by-prettify">// wou=
ld be equivalent to:</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> r=
eq </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #008;" class=3D"styled-by-prettify">operator</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #080;" class=3D"styled-by-prettify">&quot;&quot;</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">_sql </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: #000;" class=3D"styl=
ed-by-prettify">string_processing</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">const</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">char</span><span style=3D"color: #660;" class=3D"styled-by-prettify">[<=
/span><span style=3D"color: #066;" class=3D"styled-by-prettify">8</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">]&amp;,</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"colo=
r: #008;" class=3D"styled-by-prettify">string</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">&amp;,</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">const</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">char</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">[</span><span style=3D"color: #066;" class=3D"styled-by-prettify">7</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">]&amp;,</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: #000;" class=3D"styled-by-prettify">string_view</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&amp;,</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">const</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">char</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">[</span><span style=3D"color: #066;" class=3D"styled-by-prett=
ify">2</span><span style=3D"color: #660;" class=3D"styled-by-prettify">]&am=
p;&gt;(</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&qu=
ot;select &quot;</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> co=
lumn</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #080;" class=3D"styled-by-prettify">&quot; from &quot;</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> table</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: #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;" clas=
s=3D"styled-by-prettify"><br></span></div></code></div><br>Now let&#39;s ha=
ve some examples of it could be:<br><br>Simple string concatenation would b=
e simple<br><div style=3D"background-color: rgb(250, 250, 250); border-colo=
r: rgb(187, 187, 187); border-style: solid; border-width: 1px; overflow-wra=
p: break-word;" class=3D"prettyprint"><code class=3D"prettyprint"><div clas=
s=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> c=
oncatenated </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> F</s=
pan><span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;{str1}{=
str2}{str3}&quot;</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">s</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: #800;" class=3D"styled-by-prettify">// converted into=
 an efficient concatenation of the 3 strings</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br></span></div></code></div><br>We coul=
d print it into an iostream if we want (but would be here only for convenie=
nce on legacy code)<br><div style=3D"background-color: rgb(250, 250, 250); =
border-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; o=
verflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"prettyprint=
"><div class=3D"subprettyprint"><span style=3D"color: #000;" class=3D"style=
d-by-prettify">std</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
cout </span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;&=
lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> F</spa=
n><span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;{str1}{st=
r2}\n&quot;</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></sp=
an><span style=3D"color: #800;" class=3D"styled-by-prettify">// equivalent =
to:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>std=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify">cout </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">&lt;&lt;</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> str1 </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&lt;&lt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> str2 </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">&lt;&lt;</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #080=
;" class=3D"styled-by-prettify">&quot;\n&quot;</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br></span></div></code></div><br>It could be im=
plicitly convertible to a std::string (only if variables are implicitly con=
vertible to std::string)<br><div style=3D"background-color: rgb(250, 250, 2=
50); border-color: rgb(187, 187, 187); border-style: solid; border-width: 1=
px; overflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"pretty=
print"><div class=3D"subprettyprint"><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-prett=
ify">string</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> concatenated </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> F=
</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;{str=
1}{str2}&quot;</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><=
/span></div></code></div><br>(No example with FMT as I don&#39;t know how i=
t works, but I don&#39;t see any reason for it not to be compatible with FM=
T.)<br><br>And this would be constexpr-able.<br><br>Now, formatting would r=
equire a bit more elaborated type that could store formatting information.<=
br>But in the end, only the user will know what to do with it.<br>However, =
I would prefer <b>not</b> to embed formatting in such a type, just to keep =
it simple. And use a library based solution when I really need formatting.<=
br><br>It has all the advantages of Nicol&#39;s solution, while being more =
versatile.<br><br>Florian<br><br>Le dimanche 11 f=C3=A9vrier 2018 19:08:45 =
UTC+1, Nicol Bolas a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" sty=
le=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left=
: 1ex;"><div dir=3D"ltr">Your new idea is really no better than the old one=
.. The problem comes back to the same point: you are conflating two fundamen=
tally distinct operations: the operation to be applied to each string fragm=
ent, and the operation to be applied to aggregate the fragments into a whol=
e.<br><br>Your first idea involved the use of two UDL overloads, thereby ti=
ghtly coupling the two operations. Your second idea only uses one UDL overl=
oad, but it still tightly couples the two operations by forcing all string =
fragments to use the &quot;same type&quot;. Or more specifically, to use th=
e same string fragment processed template: `std::string_literal`.<br><br>In=
 99% of cases, you don&#39;t need to do character-by-character analysis of =
such literals. A simple array of characters will do. This is why the UDL de=
finition syntax doesn&#39;t <i>force</i> you to process all literals by cha=
racters of a template parameter. It certainly gives you that option, but it=
 is not forced on you.<br><br>There is no reason why string interpolation s=
hould force this upon you. With my way, you can <i>choose</i> to process th=
e fragments this way:<br><br><div style=3D"background-color:rgb(250,250,250=
);border-color:rgb(187,187,187);border-style:solid;border-width:1px"><code>=
<div><span style=3D"color:#008">template</span><span style=3D"color:#000"> =
</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">cha=
r</span><span style=3D"color:#660">...</span><span style=3D"color:#000"> ch=
ars</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000">=
<br></span><span style=3D"color:#008">auto</span><span style=3D"color:#000"=
> </span><span style=3D"color:#008">operator</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#080">&quot;&quot;</span><span style=3D"col=
or:#000">literal</span><span style=3D"color:#660">()</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#660">{</span><span style=3D"color:=
#008">return</span><span style=3D"color:#000"> std</span><span style=3D"col=
or:#660">::</span><span style=3D"color:#000">string_literal</span><span sty=
le=3D"color:#660">&lt;</span><span style=3D"color:#000">chars</span><span s=
tyle=3D"color:#660">...&gt;{<wbr>};}</span><span style=3D"color:#000"><br><=
br>std</span><span style=3D"color:#660">::</span><span style=3D"color:#000"=
>do_something</span><span style=3D"color:#660">(</span><span style=3D"color=
:#000">F</span><span style=3D"color:#080">&quot;some string {variable}&quot=
;</span><span style=3D"color:#000">literal</span><span style=3D"color:#660"=
>);</span></div></code></div><br>But you aren&#39;t <i>required</i> to. You=
 can choose how you want to process those fragments. The 99% of cases that =
work just fine with `const char*`s or whatever=20
don&#39;t have to deal with this `std::string_literal` type. The 1% of temp=
late=20
metaprogramming heavy cases have this available as an option.<br><br>Except=
ional circumstances should be optional, not the default.<br><br>I do not un=
derstand your fervent insistence on using UDLs to provide the aggregation f=
unction to be called, rather than explicitly calling an actual function. It=
 doesn&#39;t even make sense conceptually.<br><br>On a conceptual level, a =
UDL operation produces an object. But not all aggregation operations on an =
interpolated string will produce an &quot;object&quot;; I see no reason why=
 I can&#39;t do this:<br><br><div style=3D"background-color:rgb(250,250,250=
);border-color:rgb(187,187,187);border-style:solid;border-width:1px"><code>=
<div><span style=3D"color:#000">std</span><span style=3D"color:#660">::</sp=
an><span style=3D"color:#000">output</span><span style=3D"color:#660">(</sp=
an><span style=3D"color:#000">std</span><span style=3D"color:#660">::</span=
><span style=3D"color:#000">cout</span><span style=3D"color:#660">,</span><=
span style=3D"color:#000"> F</span><span style=3D"color:#080">&quot;some st=
ring {variable}&quot;</span><span style=3D"color:#660">);</span></div></cod=
e></div><br>This just writes the individual members of the interpolated str=
ing to the given output stream. No object is being generated; I&#39;m simpl=
y invoking a process.<br><br>Something similar goes for your SQL database o=
peration:<br><br><div style=3D"background-color:rgb(250,250,250);border-col=
or:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><span s=
tyle=3D"color:#000">db</span><span style=3D"color:#660">.</span><span style=
=3D"color:#008">exec</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">F</span><span style=3D"color:#080">&quot;some sql stuff {va=
r1} more sql {var2};&quot;</span><span style=3D"color:#660">);</span></div>=
</code></div><br>No object needs to be created; you&#39;re just running a c=
ommand.<br><br>Using UDLs to invoke the aggregation operation is just the w=
rong concept.<br><br>On Sunday, February 11, 2018 at 9:20:28 AM UTC-5, Marc=
in Jaczewski wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;marg=
in-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"=
>On Sunday, February 11, 2018 at 9:35:50 AM UTC+1, Nicol Bolas wrote:<block=
quote 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 Saturday, February 10=
, 2018 at 9:38:20 PM UTC-5, Marcin Jaczewski wrote:<blockquote class=3D"gma=
il_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pa=
dding-left:1ex"><div dir=3D"ltr"><div>And then wat result will be of:<br><d=
iv style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187)=
;border-style:solid;border-width:1px"><code><div><span style=3D"color:#008"=
>auto</span><span style=3D"color:#000"> x </span><span style=3D"color:#660"=
>=3D</span><span style=3D"color:#000"> F</span><span style=3D"color:#080">&=
quot;A {42} B&quot;</span><span style=3D"color:#000">_z</span><span style=
=3D"color:#660">;</span></div></code></div><br>If it work as pack expansion=
 then it do not have meaning on its own.<br></div></div></blockquote><div><=
br>You say that like it&#39;s a bad thing. Does `pack...` have meaning on i=
ts own?<br><br></div></div></blockquote><div><br>You can use pack expansion=
 only in specific places:<br></div></div></blockquote><div><br>I know that.=
 My point was that we already have grammatical constructs like that which o=
nly work in a limited number of places. What is wrong with making string in=
terpolation work that way?<br><br></div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:=
1ex"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" style=3D=
"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><div>The point of my idea is that it provides a sharp separa=
tion between the two fundamental operations of &quot;string interpolation&q=
uot;. There&#39;s the &quot;convert a string literal into a bunch of smalle=
r literals and variables&quot; part. And there&#39;s the &quot;do something=
 with that bunch of smaller literals and variables.&quot;<br><br>By making =
part 1 into a pack expansion-like construct, it forces you to make the way =
you want to process that expansion <i>explicit</i>. It also makes a clear d=
istinction between a UDL used for normal purposes and the system used to pr=
ocess code.<br><br></div></div></blockquote><div>=C2=A0<br>But this work in=
 this way in C# and JavaScript (and probably other languages too), C# retur=
n final string (or interface that you can tweak result a bit) and JS return=
 fully processed object from tag function.<br>My approach mimic it.<br></di=
v></div></blockquote><div dir=3D"ltr"><br>C++ has many language features th=
at do similar things from other languages but in different ways. Lambdas ar=
e pretty unique in C++, as are the way we handle variadic parameters and ex=
pansion (most languages make you index the variadic list; we allow you to w=
rite patterns and expand them in-situ). Indeed, every language has its own =
specific quirks and distinctions. I see no reason to exactly mimic other la=
nguages when we can make the mechanism so much more flexible than what you&=
#39;re proposing.<br><br>Not unless it actually gains us something. <br><br=
></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>You ca=
n&#39;t change return type based on `char*` value (this was what Marcel use=
d in his version), this would require `constexpr` arguments that probably w=
ill be never added to language.<br></div></div></blockquote><div><br>`const=
expr` programming is not based on a 1:1 mapping between &quot;type&quot; an=
d &quot;value&quot;; it&#39;s based on regular C++ programming principles. =
On using different <i>values</i> for those types; we&#39;re just doing it a=
t compile time instead of runtime. That&#39;s why its much better than tryi=
ng to use template metaprogramming.<br><br>In short, you don&#39;t <i>need<=
/i> it to work this way. Once we can actually create and manipulate strings=
 at compile time, there&#39;s little point to using metaprogramming to proc=
ess them.</div><br></div></blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/750ecf62-9637-40f4-8585-e3be2780fb46%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/750ecf62-9637-40f4-8585-e3be2780fb46=
%40isocpp.org</a>.<br />

------=_Part_6459_1552059679.1518430665596--

------=_Part_6458_588853956.1518430665592--

.


Author: Jake Arkinstall <jake.arkinstall@gmail.com>
Date: Mon, 12 Feb 2018 14:38:47 +0000
Raw View
--001a11c022f001c410056504d601
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Is recursion a reasonable request in the proposal too? I actually can't
think of WHY one would want it, but it might be worth a discussion for
completeness.

Nicol, what are your thoughts on Florian's suggestion?

In the interest of grounding ourselves (although I'm getting quite excited
here), does anybody from the compiler community have any input as to any
stumbling blocks in the implementation of this?


On 12 Feb 2018 10:17, <florian.csdt@gmail.com> wrote:

Let me suggest something close to Nicol's solution, but not quite.

The F"" operator returns a special type that could be like a simple tuple
(let's name it std::string_processing for now).

Then the user can use it directly into its own functions.


auto column =3D "col"s;
auto table =3D "tab"sv;
auto req =3D sql(F"select {column} from {table};");

// would be equivalent to:
auto req =3D sql(std::string_processing<const char[8]&, std::string&, const
char[7]&, std::string_view&, const char[2]&>("select ", column, " from ",
table, ";"));

Now, if we want, we could also support UDL (but not mandatory) by allowing
to call UDL on the std::string_processing:

auto column =3D "col"s;
auto table =3D "tab"sv;
auto req =3D F"select {column} from {table};"_sql;

// would be equivalent to:
auto req =3D operator ""_sql (std::string_processing<const char[8]&, std::
string&, const char[7]&, std::string_view&, const char[2]&>("select ",
column, " from ", table, ";"));

Now let's have some examples of it could be:

Simple string concatenation would be simple
auto concatenated =3D F"{str1}{str2}{str3}"s;
// converted into an efficient concatenation of the 3 strings

We could print it into an iostream if we want (but would be here only for
convenience on legacy code)
std::cout << F"{str1}{str2}\n";
// equivalent to:
std::cout << str1 << str2 << "\n";

It could be implicitly convertible to a std::string (only if variables are
implicitly convertible to std::string)
std::string concatenated =3D F"{str1}{str2}";

(No example with FMT as I don't know how it works, but I don't see any
reason for it not to be compatible with FMT.)

And this would be constexpr-able.

Now, formatting would require a bit more elaborated type that could store
formatting information.
But in the end, only the user will know what to do with it.
However, I would prefer *not* to embed formatting in such a type, just to
keep it simple. And use a library based solution when I really need
formatting.

It has all the advantages of Nicol's solution, while being more versatile.

Florian


Le dimanche 11 f=C3=A9vrier 2018 19:08:45 UTC+1, Nicol Bolas a =C3=A9crit :
>
> Your new idea is really no better than the old one. The problem comes bac=
k
> to the same point: you are conflating two fundamentally distinct
> operations: the operation to be applied to each string fragment, and the
> operation to be applied to aggregate the fragments into a whole.
>
> Your first idea involved the use of two UDL overloads, thereby tightly
> coupling the two operations. Your second idea only uses one UDL overload,
> but it still tightly couples the two operations by forcing all string
> fragments to use the "same type". Or more specifically, to use the same
> string fragment processed template: `std::string_literal`.
>
> In 99% of cases, you don't need to do character-by-character analysis of
> such literals. A simple array of characters will do. This is why the UDL
> definition syntax doesn't *force* you to process all literals by
> characters of a template parameter. It certainly gives you that option, b=
ut
> it is not forced on you.
>
> There is no reason why string interpolation should force this upon you.
> With my way, you can *choose* to process the fragments this way:
>
> template <char... chars>
> auto operator ""literal() {return std::string_literal<chars...>{};}
>
> std::do_something(F"some string {variable}"literal);
>
> But you aren't *required* to. You can choose how you want to process
> those fragments. The 99% of cases that work just fine with `const char*`s
> or whatever don't have to deal with this `std::string_literal` type. The =
1%
> of template metaprogramming heavy cases have this available as an option.
>
> Exceptional circumstances should be optional, not the default.
>
> I do not understand your fervent insistence on using UDLs to provide the
> aggregation function to be called, rather than explicitly calling an actu=
al
> function. It doesn't even make sense conceptually.
>
> On a conceptual level, a UDL operation produces an object. But not all
> aggregation operations on an interpolated string will produce an "object"=
;
> I see no reason why I can't do this:
>
> std::output(std::cout, F"some string {variable}");
>
> This just writes the individual members of the interpolated string to the
> given output stream. No object is being generated; I'm simply invoking a
> process.
>
> Something similar goes for your SQL database operation:
>
> db.exec(F"some sql stuff {var1} more sql {var2};");
>
> No object needs to be created; you're just running a command.
>
> Using UDLs to invoke the aggregation operation is just the wrong concept.
>
> On Sunday, February 11, 2018 at 9:20:28 AM UTC-5, Marcin Jaczewski wrote:
>>
>> On Sunday, February 11, 2018 at 9:35:50 AM UTC+1, Nicol Bolas wrote:
>>>
>>> On Saturday, February 10, 2018 at 9:38:20 PM UTC-5, Marcin Jaczewski
>>> wrote:
>>>>
>>>> And then wat result will be of:
>>>> auto x =3D F"A {42} B"_z;
>>>>
>>>> If it work as pack expansion then it do not have meaning on its own.
>>>>
>>>
>>> You say that like it's a bad thing. Does `pack...` have meaning on its
>>> own?
>>>
>>>
>> You can use pack expansion only in specific places:
>>
>
> I know that. My point was that we already have grammatical constructs lik=
e
> that which only work in a limited number of places. What is wrong with
> making string interpolation work that way?
>
> The point of my idea is that it provides a sharp separation between the
>>> two fundamental operations of "string interpolation". There's the "conv=
ert
>>> a string literal into a bunch of smaller literals and variables" part. =
And
>>> there's the "do something with that bunch of smaller literals and
>>> variables."
>>>
>>> By making part 1 into a pack expansion-like construct, it forces you to
>>> make the way you want to process that expansion *explicit*. It also
>>> makes a clear distinction between a UDL used for normal purposes and th=
e
>>> system used to process code.
>>>
>>>
>> But this work in this way in C# and JavaScript (and probably other
>> languages too), C# return final string (or interface that you can tweak
>> result a bit) and JS return fully processed object from tag function.
>> My approach mimic it.
>>
>
> C++ has many language features that do similar things from other language=
s
> but in different ways. Lambdas are pretty unique in C++, as are the way w=
e
> handle variadic parameters and expansion (most languages make you index t=
he
> variadic list; we allow you to write patterns and expand them in-situ).
> Indeed, every language has its own specific quirks and distinctions. I se=
e
> no reason to exactly mimic other languages when we can make the mechanism
> so much more flexible than what you're proposing.
>
> Not unless it actually gains us something.
>
> You can't change return type based on `char*` value (this was what Marcel
>> used in his version), this would require `constexpr` arguments that
>> probably will be never added to language.
>>
>
> `constexpr` programming is not based on a 1:1 mapping between "type" and
> "value"; it's based on regular C++ programming principles. On using
> different *values* for those types; we're just doing it at compile time
> instead of runtime. That's why its much better than trying to use templat=
e
> metaprogramming.
>
> In short, you don't *need* it to work this way. Once we can actually
> create and manipulate strings at compile time, there's little point to
> using metaprogramming to process them.
>
> --
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/
isocpp.org/d/msgid/std-proposals/750ecf62-9637-40f4-
8585-e3be2780fb46%40isocpp.org
<https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/750ecf62-9637=
-40f4-8585-e3be2780fb46%40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter=
>
..

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CAC%2B0CCOV7Qf21J-MBpdggkkrNt8Hs2dN03o52F0s-QXY6=
f%3Dcbw%40mail.gmail.com.

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

<div dir=3D"auto"><div dir=3D"auto">Is recursion a reasonable request in th=
e proposal too? I actually can&#39;t think of WHY one would want it, but it=
 might be worth a discussion for completeness.</div><div dir=3D"auto"><br><=
/div>Nicol, what are your thoughts on Florian&#39;s suggestion?<div dir=3D"=
auto"><br></div><div dir=3D"auto">In the interest of grounding ourselves (a=
lthough I&#39;m getting quite excited here), does anybody from the compiler=
 community have any input as to any stumbling blocks in the implementation =
of this?</div><br><div class=3D"gmail_extra" dir=3D"auto"><br><div class=3D=
"gmail_quote">On 12 Feb 2018 10:17,  &lt;<a href=3D"mailto:florian.csdt@gma=
il.com">florian.csdt@gmail.com</a>&gt; wrote:<br type=3D"attribution"><bloc=
kquote class=3D"quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"ltr">Let me suggest something close to Nico=
l&#39;s solution, but not quite.<br><br>The F&quot;&quot; operator returns =
a special type that could be like a simple tuple (let&#39;s name it std::st=
ring_processing for now).<br><br>Then the user can use it directly into its=
 own functions.<br><br><br><div style=3D"background-color:rgb(250,250,250);=
border-color:rgb(187,187,187);border-style:solid;border-width:1px" class=3D=
"m_5802088551998586929prettyprint"><code class=3D"m_5802088551998586929pret=
typrint"><div class=3D"m_5802088551998586929subprettyprint"><span style=3D"=
color:#008" class=3D"m_5802088551998586929styled-by-prettify">auto</span><s=
pan style=3D"color:#000" class=3D"m_5802088551998586929styled-by-prettify">=
 column </span><span style=3D"color:#660" class=3D"m_5802088551998586929sty=
led-by-prettify">=3D</span><span style=3D"color:#000" class=3D"m_5802088551=
998586929styled-by-prettify"> </span><span style=3D"color:#080" class=3D"m_=
5802088551998586929styled-by-prettify">&quot;col&quot;</span><span style=3D=
"color:#000" class=3D"m_5802088551998586929styled-by-prettify">s</span><spa=
n style=3D"color:#660" class=3D"m_5802088551998586929styled-by-prettify">;<=
/span><span style=3D"color:#000" class=3D"m_5802088551998586929styled-by-pr=
ettify"><br></span><span style=3D"color:#008" class=3D"m_580208855199858692=
9styled-by-prettify">auto</span><span style=3D"color:#000" class=3D"m_58020=
88551998586929styled-by-prettify"> table </span><span style=3D"color:#660" =
class=3D"m_5802088551998586929styled-by-prettify">=3D</span><span style=3D"=
color:#000" class=3D"m_5802088551998586929styled-by-prettify"> </span><span=
 style=3D"color:#080" class=3D"m_5802088551998586929styled-by-prettify">&qu=
ot;tab&quot;</span><span style=3D"color:#000" class=3D"m_580208855199858692=
9styled-by-prettify">sv</span><span style=3D"color:#660" class=3D"m_5802088=
551998586929styled-by-prettify">;</span><span style=3D"color:#000" class=3D=
"m_5802088551998586929styled-by-prettify"><br></span><span style=3D"color:#=
008" class=3D"m_5802088551998586929styled-by-prettify">auto</span><span sty=
le=3D"color:#000" class=3D"m_5802088551998586929styled-by-prettify"> req </=
span><span style=3D"color:#660" class=3D"m_5802088551998586929styled-by-pre=
ttify">=3D</span><span style=3D"color:#000" class=3D"m_5802088551998586929s=
tyled-by-prettify"> sql</span><span style=3D"color:#660" class=3D"m_5802088=
551998586929styled-by-prettify">(</span><span style=3D"color:#000" class=3D=
"m_5802088551998586929styled-by-prettify">F</span><span style=3D"color:#080=
" class=3D"m_5802088551998586929styled-by-prettify">&quot;select {column} f=
rom {table};&quot;</span><span style=3D"color:#660" class=3D"m_580208855199=
8586929styled-by-prettify">);</span><span style=3D"color:#000" class=3D"m_5=
802088551998586929styled-by-prettify"><br><br></span><span style=3D"color:#=
800" class=3D"m_5802088551998586929styled-by-prettify">// would be equivale=
nt to:</span><span style=3D"color:#000" class=3D"m_5802088551998586929style=
d-by-prettify"><br></span><span style=3D"color:#008" class=3D"m_58020885519=
98586929styled-by-prettify">auto</span><span style=3D"color:#000" class=3D"=
m_5802088551998586929styled-by-prettify"> req </span><span style=3D"color:#=
660" class=3D"m_5802088551998586929styled-by-prettify">=3D</span><span styl=
e=3D"color:#000" class=3D"m_5802088551998586929styled-by-prettify"> sql</sp=
an><span style=3D"color:#660" class=3D"m_5802088551998586929styled-by-prett=
ify">(</span><span style=3D"color:#000" class=3D"m_5802088551998586929style=
d-by-prettify">std</span><span style=3D"color:#660" class=3D"m_580208855199=
8586929styled-by-prettify">::</span><span style=3D"color:#000" class=3D"m_5=
802088551998586929styled-by-prettify">string_processing</span><span style=
=3D"color:#660" class=3D"m_5802088551998586929styled-by-prettify">&lt;</spa=
n><span style=3D"color:#008" class=3D"m_5802088551998586929styled-by-pretti=
fy">con<wbr>st</span><span style=3D"color:#000" class=3D"m_5802088551998586=
929styled-by-prettify"> </span><span style=3D"color:#008" class=3D"m_580208=
8551998586929styled-by-prettify">char</span><span style=3D"color:#660" clas=
s=3D"m_5802088551998586929styled-by-prettify">[</span><span style=3D"color:=
#066" class=3D"m_5802088551998586929styled-by-prettify">8</span><span style=
=3D"color:#660" class=3D"m_5802088551998586929styled-by-prettify">]&amp;,</=
span><span style=3D"color:#000" class=3D"m_5802088551998586929styled-by-pre=
ttify"> std</span><span style=3D"color:#660" class=3D"m_5802088551998586929=
styled-by-prettify">::</span><span style=3D"color:#008" class=3D"m_58020885=
51998586929styled-by-prettify">string</span><span style=3D"color:#660" clas=
s=3D"m_5802088551998586929styled-by-prettify">&amp;,</span><span style=3D"c=
olor:#000" class=3D"m_5802088551998586929styled-by-prettify"> </span><span =
style=3D"color:#008" class=3D"m_5802088551998586929styled-by-prettify">cons=
t</span><span style=3D"color:#000" class=3D"m_5802088551998586929styled-by-=
prettify"> </span><span style=3D"color:#008" class=3D"m_5802088551998586929=
styled-by-prettify">char</span><span style=3D"color:#660" class=3D"m_580208=
8551998586929styled-by-prettify">[</span><span style=3D"color:#066" class=
=3D"m_5802088551998586929styled-by-prettify">7</span><span style=3D"color:#=
660" class=3D"m_5802088551998586929styled-by-prettify">]&amp;,</span><span =
style=3D"color:#000" class=3D"m_5802088551998586929styled-by-prettify"> std=
</span><span style=3D"color:#660" class=3D"m_5802088551998586929styled-by-p=
rettify">::</span><span style=3D"color:#000" class=3D"m_5802088551998586929=
styled-by-prettify">string_view</span><span style=3D"color:#660" class=3D"m=
_5802088551998586929styled-by-prettify">&amp;,</span><span style=3D"color:#=
000" class=3D"m_5802088551998586929styled-by-prettify"> </span><span style=
=3D"color:#008" class=3D"m_5802088551998586929styled-by-prettify">const</sp=
an><span style=3D"color:#000" class=3D"m_5802088551998586929styled-by-prett=
ify"> </span><span style=3D"color:#008" class=3D"m_5802088551998586929style=
d-by-prettify">char</span><span style=3D"color:#660" class=3D"m_58020885519=
98586929styled-by-prettify">[</span><span style=3D"color:#066" class=3D"m_5=
802088551998586929styled-by-prettify">2</span><span style=3D"color:#660" cl=
ass=3D"m_5802088551998586929styled-by-prettify">]&amp;&gt;(</span><span sty=
le=3D"color:#080" class=3D"m_5802088551998586929styled-by-prettify">&quot;s=
elect &quot;</span><span style=3D"color:#660" class=3D"m_580208855199858692=
9styled-by-prettify">,</span><span style=3D"color:#000" class=3D"m_58020885=
51998586929styled-by-prettify"> column</span><span style=3D"color:#660" cla=
ss=3D"m_5802088551998586929styled-by-prettify">,</span><span style=3D"color=
:#000" class=3D"m_5802088551998586929styled-by-prettify"> </span><span styl=
e=3D"color:#080" class=3D"m_5802088551998586929styled-by-prettify">&quot; f=
rom &quot;</span><span style=3D"color:#660" class=3D"m_5802088551998586929s=
tyled-by-prettify">,</span><span style=3D"color:#000" class=3D"m_5802088551=
998586929styled-by-prettify"> table</span><span style=3D"color:#660" class=
=3D"m_5802088551998586929styled-by-prettify">,</span><span style=3D"color:#=
000" class=3D"m_5802088551998586929styled-by-prettify"> </span><span style=
=3D"color:#080" class=3D"m_5802088551998586929styled-by-prettify">&quot;;&q=
uot;</span><span style=3D"color:#660" class=3D"m_5802088551998586929styled-=
by-prettify">));</span><span style=3D"color:#000" class=3D"m_58020885519985=
86929styled-by-prettify"><br></span></div></code></div><br>Now, if we want,=
 we could also support UDL (but not mandatory) by allowing to call UDL on t=
he std::string_processing:<br><br><div style=3D"background-color:rgb(250,25=
0,250);border-color:rgb(187,187,187);border-style:solid;border-width:1px" c=
lass=3D"m_5802088551998586929prettyprint"><code class=3D"m_5802088551998586=
929prettyprint"><div class=3D"m_5802088551998586929subprettyprint"><span st=
yle=3D"color:#008" class=3D"m_5802088551998586929styled-by-prettify">auto</=
span><span style=3D"color:#000" class=3D"m_5802088551998586929styled-by-pre=
ttify"> column </span><span style=3D"color:#660" class=3D"m_580208855199858=
6929styled-by-prettify">=3D</span><span style=3D"color:#000" class=3D"m_580=
2088551998586929styled-by-prettify"> </span><span style=3D"color:#080" clas=
s=3D"m_5802088551998586929styled-by-prettify">&quot;col&quot;</span><span s=
tyle=3D"color:#000" class=3D"m_5802088551998586929styled-by-prettify">s</sp=
an><span style=3D"color:#660" class=3D"m_5802088551998586929styled-by-prett=
ify">;</span><span style=3D"color:#000" class=3D"m_5802088551998586929style=
d-by-prettify"><br></span><span style=3D"color:#008" class=3D"m_58020885519=
98586929styled-by-prettify">auto</span><span style=3D"color:#000" class=3D"=
m_5802088551998586929styled-by-prettify"> table </span><span style=3D"color=
:#660" class=3D"m_5802088551998586929styled-by-prettify">=3D</span><span st=
yle=3D"color:#000" class=3D"m_5802088551998586929styled-by-prettify"> </spa=
n><span style=3D"color:#080" class=3D"m_5802088551998586929styled-by-pretti=
fy">&quot;tab&quot;</span><span style=3D"color:#000" class=3D"m_58020885519=
98586929styled-by-prettify">sv</span><span style=3D"color:#660" class=3D"m_=
5802088551998586929styled-by-prettify">;</span><span style=3D"color:#000" c=
lass=3D"m_5802088551998586929styled-by-prettify"><br></span><span style=3D"=
color:#008" class=3D"m_5802088551998586929styled-by-prettify">auto</span><s=
pan style=3D"color:#000" class=3D"m_5802088551998586929styled-by-prettify">=
 req </span><span style=3D"color:#660" class=3D"m_5802088551998586929styled=
-by-prettify">=3D</span><span style=3D"color:#000" class=3D"m_5802088551998=
586929styled-by-prettify"> F</span><span style=3D"color:#080" class=3D"m_58=
02088551998586929styled-by-prettify">&quot;select {column} from {table};&qu=
ot;</span><span style=3D"color:#000" class=3D"m_5802088551998586929styled-b=
y-prettify">_sql</span><span style=3D"color:#660" class=3D"m_58020885519985=
86929styled-by-prettify">;</span><span style=3D"color:#000" class=3D"m_5802=
088551998586929styled-by-prettify"><br><br></span><span style=3D"color:#800=
" class=3D"m_5802088551998586929styled-by-prettify">// would be equivalent =
to:</span><span style=3D"color:#000" class=3D"m_5802088551998586929styled-b=
y-prettify"><br></span><span style=3D"color:#008" class=3D"m_58020885519985=
86929styled-by-prettify">auto</span><span style=3D"color:#000" class=3D"m_5=
802088551998586929styled-by-prettify"> req </span><span style=3D"color:#660=
" class=3D"m_5802088551998586929styled-by-prettify">=3D</span><span style=
=3D"color:#000" class=3D"m_5802088551998586929styled-by-prettify"> </span><=
span style=3D"color:#008" class=3D"m_5802088551998586929styled-by-prettify"=
>operator</span><span style=3D"color:#000" class=3D"m_5802088551998586929st=
yled-by-prettify"> </span><span style=3D"color:#080" class=3D"m_58020885519=
98586929styled-by-prettify">&quot;&quot;</span><span style=3D"color:#000" c=
lass=3D"m_5802088551998586929styled-by-prettify">_sql </span><span style=3D=
"color:#660" class=3D"m_5802088551998586929styled-by-prettify">(</span><spa=
n style=3D"color:#000" class=3D"m_5802088551998586929styled-by-prettify">st=
d</span><span style=3D"color:#660" class=3D"m_5802088551998586929styled-by-=
prettify">::</span><span style=3D"color:#000" class=3D"m_580208855199858692=
9styled-by-prettify">string_processing</span><span style=3D"color:#660" cla=
ss=3D"m_5802088551998586929styled-by-prettify">&lt;</span><span style=3D"co=
lor:#008" class=3D"m_5802088551998586929styled-by-prettify">const</span><sp=
an style=3D"color:#000" class=3D"m_5802088551998586929styled-by-prettify"> =
</span><span style=3D"color:#008" class=3D"m_5802088551998586929styled-by-p=
rettify">char</span><span style=3D"color:#660" class=3D"m_58020885519985869=
29styled-by-prettify">[</span><span style=3D"color:#066" class=3D"m_5802088=
551998586929styled-by-prettify">8</span><span style=3D"color:#660" class=3D=
"m_5802088551998586929styled-by-prettify">]&amp;,</span><span style=3D"colo=
r:#000" class=3D"m_5802088551998586929styled-by-prettify"> std</span><span =
style=3D"color:#660" class=3D"m_5802088551998586929styled-by-prettify">::</=
span><span style=3D"color:#008" class=3D"m_5802088551998586929styled-by-pre=
ttify">string</span><span style=3D"color:#660" class=3D"m_58020885519985869=
29styled-by-prettify">&amp;,</span><span style=3D"color:#000" class=3D"m_58=
02088551998586929styled-by-prettify"> </span><span style=3D"color:#008" cla=
ss=3D"m_5802088551998586929styled-by-prettify">const</span><span style=3D"c=
olor:#000" class=3D"m_5802088551998586929styled-by-prettify"> </span><span =
style=3D"color:#008" class=3D"m_5802088551998586929styled-by-prettify">char=
</span><span style=3D"color:#660" class=3D"m_5802088551998586929styled-by-p=
rettify">[</span><span style=3D"color:#066" class=3D"m_5802088551998586929s=
tyled-by-prettify">7</span><span style=3D"color:#660" class=3D"m_5802088551=
998586929styled-by-prettify">]&amp;,</span><span style=3D"color:#000" class=
=3D"m_5802088551998586929styled-by-prettify"> std</span><span style=3D"colo=
r:#660" class=3D"m_5802088551998586929styled-by-prettify">::</span><span st=
yle=3D"color:#000" class=3D"m_5802088551998586929styled-by-prettify">string=
_view</span><span style=3D"color:#660" class=3D"m_5802088551998586929styled=
-by-prettify">&amp;,</span><span style=3D"color:#000" class=3D"m_5802088551=
998586929styled-by-prettify"> </span><span style=3D"color:#008" class=3D"m_=
5802088551998586929styled-by-prettify">const</span><span style=3D"color:#00=
0" class=3D"m_5802088551998586929styled-by-prettify"> </span><span style=3D=
"color:#008" class=3D"m_5802088551998586929styled-by-prettify">char</span><=
span style=3D"color:#660" class=3D"m_5802088551998586929styled-by-prettify"=
>[</span><span style=3D"color:#066" class=3D"m_5802088551998586929styled-by=
-prettify">2</span><span style=3D"color:#660" class=3D"m_580208855199858692=
9styled-by-prettify">]&amp;&gt;(</span><span style=3D"color:#080" class=3D"=
m_5802088551998586929styled-by-prettify">&quot;select &quot;</span><span st=
yle=3D"color:#660" class=3D"m_5802088551998586929styled-by-prettify">,</spa=
n><span style=3D"color:#000" class=3D"m_5802088551998586929styled-by-pretti=
fy"> column</span><span style=3D"color:#660" class=3D"m_5802088551998586929=
styled-by-prettify">,</span><span style=3D"color:#000" class=3D"m_580208855=
1998586929styled-by-prettify"> </span><span style=3D"color:#080" class=3D"m=
_5802088551998586929styled-by-prettify">&quot; from &quot;</span><span styl=
e=3D"color:#660" class=3D"m_5802088551998586929styled-by-prettify">,</span>=
<span style=3D"color:#000" class=3D"m_5802088551998586929styled-by-prettify=
"> table</span><span style=3D"color:#660" class=3D"m_5802088551998586929sty=
led-by-prettify">,</span><span style=3D"color:#000" class=3D"m_580208855199=
8586929styled-by-prettify"> </span><span style=3D"color:#080" class=3D"m_58=
02088551998586929styled-by-prettify">&quot;;&quot;</span><span style=3D"col=
or:#660" class=3D"m_5802088551998586929styled-by-prettify">));</span><span =
style=3D"color:#000" class=3D"m_5802088551998586929styled-by-prettify"><br>=
</span></div></code></div><br>Now let&#39;s have some examples of it could =
be:<br><br>Simple string concatenation would be simple<br><div style=3D"bac=
kground-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:s=
olid;border-width:1px" class=3D"m_5802088551998586929prettyprint"><code cla=
ss=3D"m_5802088551998586929prettyprint"><div class=3D"m_5802088551998586929=
subprettyprint"><span style=3D"color:#008" class=3D"m_5802088551998586929st=
yled-by-prettify">auto</span><span style=3D"color:#000" class=3D"m_58020885=
51998586929styled-by-prettify"> concatenated </span><span style=3D"color:#6=
60" class=3D"m_5802088551998586929styled-by-prettify">=3D</span><span style=
=3D"color:#000" class=3D"m_5802088551998586929styled-by-prettify"> F</span>=
<span style=3D"color:#080" class=3D"m_5802088551998586929styled-by-prettify=
">&quot;{str1}{str2}{str3}&quot;</span><span style=3D"color:#000" class=3D"=
m_5802088551998586929styled-by-prettify">s</span><span style=3D"color:#660"=
 class=3D"m_5802088551998586929styled-by-prettify">;</span><span style=3D"c=
olor:#000" class=3D"m_5802088551998586929styled-by-prettify"><br></span><sp=
an style=3D"color:#800" class=3D"m_5802088551998586929styled-by-prettify">/=
/ converted into an efficient concatenation of the 3 strings</span><span st=
yle=3D"color:#000" class=3D"m_5802088551998586929styled-by-prettify"><br></=
span></div></code></div><br>We could print it into an iostream if we want (=
but would be here only for convenience on legacy code)<br><div style=3D"bac=
kground-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:s=
olid;border-width:1px" class=3D"m_5802088551998586929prettyprint"><code cla=
ss=3D"m_5802088551998586929prettyprint"><div class=3D"m_5802088551998586929=
subprettyprint"><span style=3D"color:#000" class=3D"m_5802088551998586929st=
yled-by-prettify">std</span><span style=3D"color:#660" class=3D"m_580208855=
1998586929styled-by-prettify">::</span><span style=3D"color:#000" class=3D"=
m_5802088551998586929styled-by-prettify">cout </span><span style=3D"color:#=
660" class=3D"m_5802088551998586929styled-by-prettify">&lt;&lt;</span><span=
 style=3D"color:#000" class=3D"m_5802088551998586929styled-by-prettify"> F<=
/span><span style=3D"color:#080" class=3D"m_5802088551998586929styled-by-pr=
ettify">&quot;{str1}{str2}\n&quot;</span><span style=3D"color:#660" class=
=3D"m_5802088551998586929styled-by-prettify">;</span><span style=3D"color:#=
000" class=3D"m_5802088551998586929styled-by-prettify"><br></span><span sty=
le=3D"color:#800" class=3D"m_5802088551998586929styled-by-prettify">// equi=
valent to:</span><span style=3D"color:#000" class=3D"m_5802088551998586929s=
tyled-by-prettify"><br>std</span><span style=3D"color:#660" class=3D"m_5802=
088551998586929styled-by-prettify">::</span><span style=3D"color:#000" clas=
s=3D"m_5802088551998586929styled-by-prettify">cout </span><span style=3D"co=
lor:#660" class=3D"m_5802088551998586929styled-by-prettify">&lt;&lt;</span>=
<span style=3D"color:#000" class=3D"m_5802088551998586929styled-by-prettify=
"> str1 </span><span style=3D"color:#660" class=3D"m_5802088551998586929sty=
led-by-prettify">&lt;&lt;</span><span style=3D"color:#000" class=3D"m_58020=
88551998586929styled-by-prettify"> str2 </span><span style=3D"color:#660" c=
lass=3D"m_5802088551998586929styled-by-prettify">&lt;&lt;</span><span style=
=3D"color:#000" class=3D"m_5802088551998586929styled-by-prettify"> </span><=
span style=3D"color:#080" class=3D"m_5802088551998586929styled-by-prettify"=
>&quot;\n&quot;</span><span style=3D"color:#660" class=3D"m_580208855199858=
6929styled-by-prettify">;</span><span style=3D"color:#000" class=3D"m_58020=
88551998586929styled-by-prettify"><br></span></div></code></div><br>It coul=
d be implicitly convertible to a std::string (only if variables are implici=
tly convertible to std::string)<br><div style=3D"background-color:rgb(250,2=
50,250);border-color:rgb(187,187,187);border-style:solid;border-width:1px" =
class=3D"m_5802088551998586929prettyprint"><code class=3D"m_580208855199858=
6929prettyprint"><div class=3D"m_5802088551998586929subprettyprint"><span s=
tyle=3D"color:#000" class=3D"m_5802088551998586929styled-by-prettify">std</=
span><span style=3D"color:#660" class=3D"m_5802088551998586929styled-by-pre=
ttify">::</span><span style=3D"color:#008" class=3D"m_5802088551998586929st=
yled-by-prettify">string</span><span style=3D"color:#000" class=3D"m_580208=
8551998586929styled-by-prettify"> concatenated </span><span style=3D"color:=
#660" class=3D"m_5802088551998586929styled-by-prettify">=3D</span><span sty=
le=3D"color:#000" class=3D"m_5802088551998586929styled-by-prettify"> F</spa=
n><span style=3D"color:#080" class=3D"m_5802088551998586929styled-by-pretti=
fy">&quot;{str1}{str2}&quot;</span><span style=3D"color:#660" class=3D"m_58=
02088551998586929styled-by-prettify">;</span><span style=3D"color:#000" cla=
ss=3D"m_5802088551998586929styled-by-prettify"><br></span></div></code></di=
v><br>(No example with FMT as I don&#39;t know how it works, but I don&#39;=
t see any reason for it not to be compatible with FMT.)<br><br>And this wou=
ld be constexpr-able.<br><br>Now, formatting would require a bit more elabo=
rated type that could store formatting information.<br>But in the end, only=
 the user will know what to do with it.<br>However, I would prefer <b>not</=
b> to embed formatting in such a type, just to keep it simple. And use a li=
brary based solution when I really need formatting.<br><br>It has all the a=
dvantages of Nicol&#39;s solution, while being more versatile.<br><br>Flori=
an<div class=3D"elided-text"><br><br>Le dimanche 11 f=C3=A9vrier 2018 19:08=
:45 UTC+1, Nicol Bolas a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote"=
 style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-lef=
t:1ex"><div dir=3D"ltr">Your new idea is really no better than the old one.=
 The problem comes back to the same point: you are conflating two fundament=
ally distinct operations: the operation to be applied to each string fragme=
nt, and the operation to be applied to aggregate the fragments into a whole=
..<br><br>Your first idea involved the use of two UDL overloads, thereby tig=
htly coupling the two operations. Your second idea only uses one UDL overlo=
ad, but it still tightly couples the two operations by forcing all string f=
ragments to use the &quot;same type&quot;. Or more specifically, to use the=
 same string fragment processed template: `std::string_literal`.<br><br>In =
99% of cases, you don&#39;t need to do character-by-character analysis of s=
uch literals. A simple array of characters will do. This is why the UDL def=
inition syntax doesn&#39;t <i>force</i> you to process all literals by char=
acters of a template parameter. It certainly gives you that option, but it =
is not forced on you.<br><br>There is no reason why string interpolation sh=
ould force this upon you. With my way, you can <i>choose</i> to process the=
 fragments this way:<br><br><div style=3D"background-color:rgb(250,250,250)=
;border-color:rgb(187,187,187);border-style:solid;border-width:1px"><code><=
div><span style=3D"color:#008">template</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">char=
</span><span style=3D"color:#660">...</span><span style=3D"color:#000"> cha=
rs</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"><=
br></span><span style=3D"color:#008">auto</span><span style=3D"color:#000">=
 </span><span style=3D"color:#008">operator</span><span style=3D"color:#000=
"> </span><span style=3D"color:#080">&quot;&quot;</span><span style=3D"colo=
r:#000">literal</span><span style=3D"color:#660">()</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#660">{</span><span style=3D"color:#=
008">return</span><span style=3D"color:#000"> std</span><span style=3D"colo=
r:#660">::</span><span style=3D"color:#000">string_literal</span><span styl=
e=3D"color:#660">&lt;</span><span style=3D"color:#000">chars</span><span st=
yle=3D"color:#660">...&gt;{<wbr>};}</span><span style=3D"color:#000"><br><b=
r>std</span><span style=3D"color:#660">::</span><span style=3D"color:#000">=
do_something</span><span style=3D"color:#660">(</span><span style=3D"color:=
#000">F</span><span style=3D"color:#080">&quot;some string {variable}&quot;=
</span><span style=3D"color:#000">literal</span><span style=3D"color:#660">=
);</span></div></code></div><br>But you aren&#39;t <i>required</i> to. You =
can choose how you want to process those fragments. The 99% of cases that w=
ork just fine with `const char*`s or whatever=20
don&#39;t have to deal with this `std::string_literal` type. The 1% of temp=
late=20
metaprogramming heavy cases have this available as an option.<br><br>Except=
ional circumstances should be optional, not the default.<br><br>I do not un=
derstand your fervent insistence on using UDLs to provide the aggregation f=
unction to be called, rather than explicitly calling an actual function. It=
 doesn&#39;t even make sense conceptually.<br><br>On a conceptual level, a =
UDL operation produces an object. But not all aggregation operations on an =
interpolated string will produce an &quot;object&quot;; I see no reason why=
 I can&#39;t do this:<br><br><div style=3D"background-color:rgb(250,250,250=
);border-color:rgb(187,187,187);border-style:solid;border-width:1px"><code>=
<div><span style=3D"color:#000">std</span><span style=3D"color:#660">::</sp=
an><span style=3D"color:#000">output</span><span style=3D"color:#660">(</sp=
an><span style=3D"color:#000">std</span><span style=3D"color:#660">::</span=
><span style=3D"color:#000">cout</span><span style=3D"color:#660">,</span><=
span style=3D"color:#000"> F</span><span style=3D"color:#080">&quot;some st=
ring {variable}&quot;</span><span style=3D"color:#660">);</span></div></cod=
e></div><br>This just writes the individual members of the interpolated str=
ing to the given output stream. No object is being generated; I&#39;m simpl=
y invoking a process.<br><br>Something similar goes for your SQL database o=
peration:<br><br><div style=3D"background-color:rgb(250,250,250);border-col=
or:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><span s=
tyle=3D"color:#000">db</span><span style=3D"color:#660">.</span><span style=
=3D"color:#008">exec</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">F</span><span style=3D"color:#080">&quot;some sql stuff {va=
r1} more sql {var2};&quot;</span><span style=3D"color:#660">);</span></div>=
</code></div><br>No object needs to be created; you&#39;re just running a c=
ommand.<br><br>Using UDLs to invoke the aggregation operation is just the w=
rong concept.<br><br>On Sunday, February 11, 2018 at 9:20:28 AM UTC-5, Marc=
in Jaczewski wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;marg=
in-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"=
>On Sunday, February 11, 2018 at 9:35:50 AM UTC+1, Nicol Bolas wrote:<block=
quote 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 Saturday, February 10=
, 2018 at 9:38:20 PM UTC-5, Marcin Jaczewski wrote:<blockquote class=3D"gma=
il_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pa=
dding-left:1ex"><div dir=3D"ltr"><div>And then wat result will be of:<br><d=
iv style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187)=
;border-style:solid;border-width:1px"><code><div><span style=3D"color:#008"=
>auto</span><span style=3D"color:#000"> x </span><span style=3D"color:#660"=
>=3D</span><span style=3D"color:#000"> F</span><span style=3D"color:#080">&=
quot;A {42} B&quot;</span><span style=3D"color:#000">_z</span><span style=
=3D"color:#660">;</span></div></code></div><br>If it work as pack expansion=
 then it do not have meaning on its own.<br></div></div></blockquote><div><=
br>You say that like it&#39;s a bad thing. Does `pack...` have meaning on i=
ts own?<br><br></div></div></blockquote><div><br>You can use pack expansion=
 only in specific places:<br></div></div></blockquote><div><br>I know that.=
 My point was that we already have grammatical constructs like that which o=
nly work in a limited number of places. What is wrong with making string in=
terpolation work that way?<br><br></div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:=
1ex"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" style=3D=
"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><div>The point of my idea is that it provides a sharp separa=
tion between the two fundamental operations of &quot;string interpolation&q=
uot;. There&#39;s the &quot;convert a string literal into a bunch of smalle=
r literals and variables&quot; part. And there&#39;s the &quot;do something=
 with that bunch of smaller literals and variables.&quot;<br><br>By making =
part 1 into a pack expansion-like construct, it forces you to make the way =
you want to process that expansion <i>explicit</i>. It also makes a clear d=
istinction between a UDL used for normal purposes and the system used to pr=
ocess code.<br><br></div></div></blockquote><div>=C2=A0<br>But this work in=
 this way in C# and JavaScript (and probably other languages too), C# retur=
n final string (or interface that you can tweak result a bit) and JS return=
 fully processed object from tag function.<br>My approach mimic it.<br></di=
v></div></blockquote><div dir=3D"ltr"><br>C++ has many language features th=
at do similar things from other languages but in different ways. Lambdas ar=
e pretty unique in C++, as are the way we handle variadic parameters and ex=
pansion (most languages make you index the variadic list; we allow you to w=
rite patterns and expand them in-situ). Indeed, every language has its own =
specific quirks and distinctions. I see no reason to exactly mimic other la=
nguages when we can make the mechanism so much more flexible than what you&=
#39;re proposing.<br><br>Not unless it actually gains us something. <br><br=
></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>You ca=
n&#39;t change return type based on `char*` value (this was what Marcel use=
d in his version), this would require `constexpr` arguments that probably w=
ill be never added to language.<br></div></div></blockquote><div><br>`const=
expr` programming is not based on a 1:1 mapping between &quot;type&quot; an=
d &quot;value&quot;; it&#39;s based on regular C++ programming principles. =
On using different <i>values</i> for those types; we&#39;re just doing it a=
t compile time instead of runtime. That&#39;s why its much better than tryi=
ng to use template metaprogramming.<br><br>In short, you don&#39;t <i>need<=
/i> it to work this way. Once we can actually create and manipulate strings=
 at compile time, there&#39;s little point to using metaprogramming to proc=
ess them.</div><br></div></blockquote></div></div><div class=3D"elided-text=
">

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></div>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/750ecf62-9637-40f4-8585-e3be2780fb46%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/750e=
cf62-9637-40f4-<wbr>8585-e3be2780fb46%40isocpp.org</a><wbr>.<br>
</blockquote></div><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCOV7Qf21J-MBpdggkkrNt8Hs2dN03=
o52F0s-QXY6f%3Dcbw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCOV7Q=
f21J-MBpdggkkrNt8Hs2dN03o52F0s-QXY6f%3Dcbw%40mail.gmail.com</a>.<br />

--001a11c022f001c410056504d601--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 12 Feb 2018 06:56:12 -0800 (PST)
Raw View
------=_Part_9306_726954476.1518447372737
Content-Type: multipart/alternative;
 boundary="----=_Part_9307_1016462171.1518447372739"

------=_Part_9307_1016462171.1518447372739
Content-Type: text/plain; charset="UTF-8"

On Monday, February 12, 2018 at 5:17:45 AM UTC-5, floria...@gmail.com wrote:
>
> Let me suggest something close to Nicol's solution, but not quite.
>
> The F"" operator returns a special type that could be like a simple tuple
> (let's name it std::string_processing for now).
>
> Then the user can use it directly into its own functions.
>
>
> auto column = "col"s;
> auto table = "tab"sv;
> auto req = sql(F"select {column} from {table};");
>
> // would be equivalent to:
> auto req = sql(std::string_processing<const char[8]&, std::string&, const
> char[7]&, std::string_view&, const char[2]&>("select ", column, " from ",
> table, ";"));
>
> Now, if we want, we could also support UDL (but not mandatory) by allowing
> to call UDL on the std::string_processing:
>
> auto column = "col"s;
> auto table = "tab"sv;
> auto req = F"select {column} from {table};"_sql;
>
> // would be equivalent to:
> auto req = operator ""_sql (std::string_processing<const char[8]&, std::
> string&, const char[7]&, std::string_view&, const char[2]&>("select ",
> column, " from ", table, ";"));
>
> Now let's have some examples of it could be:
>
> Simple string concatenation would be simple
> auto concatenated = F"{str1}{str2}{str3}"s;
> // converted into an efficient concatenation of the 3 strings
>
> We could print it into an iostream if we want (but would be here only for
> convenience on legacy code)
> std::cout << F"{str1}{str2}\n";
> // equivalent to:
> std::cout << str1 << str2 << "\n";
>
> It could be implicitly convertible to a std::string (only if variables are
> implicitly convertible to std::string)
> std::string concatenated = F"{str1}{str2}";
>
> (No example with FMT as I don't know how it works, but I don't see any
> reason for it not to be compatible with FMT.)
>
> And this would be constexpr-able.
>
> Now, formatting would require a bit more elaborated type that could store
> formatting information.
> But in the end, only the user will know what to do with it.
> However, I would prefer *not* to embed formatting in such a type, just to
> keep it simple. And use a library based solution when I really need
> formatting.
>
> It has all the advantages of Nicol's solution, while being more versatile.
>

I fail to see the versatility here, and it does not have all of the
advantages of my method.

Remember, in my version, UDLs only apply to the string fragments. In your
version, you *cannot* apply UDLs to string fragments; the string fragments
will be packed into your `string_processing` type as views or some such.

Then there's ease of use. Let's see how to implement stream-based string
concatenation with my method:

template<typename ...Args>
auto concat(Args ...&&args)
{
  std::ostringstream stream;
  stream << ... << std::forward<Args>(args);
  return std::move(stream).get();
}

Simple and obvious, a standard bit of C++17 variadic template programming.

Now, how would you go about doing that with `string_processing`? That would
require template metaprogramming:

template<typename ...Args, size_t ...Ints>
void concat_items(std::ostringstream &stream, std::string_processing<Args
....> &&proc, std::index_sequence<Ints...>)
{
  stream << ... << get<Ints>(proc));
}

template<typename ...Args>
auto concat(std::string_processing<Args...> &&proc)
{
  std::ostringstream stream;
  concat_items(stream, std::move(proc), std::make_index_sequence<size...(
Args)>{});
  return std::move(stream).get();
}

This isn't the hardest code to write in the world, but it is much more
complex than the previous one. Also, perfect forwarding doesn't really work
here.

Also, the variadic version of `concat` can be used with stuff that isn't
the result of string interpolation. Or with multiple interpolated strings.
And so forth. Whereas your `string_processing` type is a magic type that
only the compiler can create. And we already have a type that does what
`string_processing` does; it's called `tuple`.

The *only advantage* your method has over mine is that it allows UDLs to
define the aggregation operation. Why is this so important to so many
people?

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/f8f4407b-ecf6-4a4a-b3f6-c65813e3f843%40isocpp.org.

------=_Part_9307_1016462171.1518447372739
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Monday, February 12, 2018 at 5:17:45 AM UTC-5, floria..=
..@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"=
ltr">Let me suggest something close to Nicol&#39;s solution, but not quite.=
<br><br>The F&quot;&quot; operator returns a special type that could be lik=
e a simple tuple (let&#39;s name it std::string_processing for now).<br><br=
>Then the user can use it directly into its own functions.<br><br><br><div =
style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);bo=
rder-style:solid;border-width:1px"><code><div><span style=3D"color:#008">au=
to</span><span style=3D"color:#000"> column </span><span style=3D"color:#66=
0">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#080">=
&quot;col&quot;</span><span style=3D"color:#000">s</span><span style=3D"col=
or:#660">;</span><span style=3D"color:#000"><br></span><span style=3D"color=
:#008">auto</span><span style=3D"color:#000"> table </span><span style=3D"c=
olor:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D"colo=
r:#080">&quot;tab&quot;</span><span style=3D"color:#000">sv</span><span sty=
le=3D"color:#660">;</span><span style=3D"color:#000"><br></span><span style=
=3D"color:#008">auto</span><span style=3D"color:#000"> req </span><span sty=
le=3D"color:#660">=3D</span><span style=3D"color:#000"> sql</span><span sty=
le=3D"color:#660">(</span><span style=3D"color:#000">F</span><span style=3D=
"color:#080">&quot;select {column} from {table};&quot;</span><span style=3D=
"color:#660">);</span><span style=3D"color:#000"><br><br></span><span style=
=3D"color:#800">// would be equivalent to:</span><span style=3D"color:#000"=
><br></span><span style=3D"color:#008">auto</span><span style=3D"color:#000=
"> req </span><span style=3D"color:#660">=3D</span><span style=3D"color:#00=
0"> sql</span><span style=3D"color:#660">(</span><span style=3D"color:#000"=
>std</span><span style=3D"color:#660">::</span><span style=3D"color:#000">s=
tring_processing</span><span style=3D"color:#660">&lt;</span><span style=3D=
"color:#008">con<wbr>st</span><span style=3D"color:#000"> </span><span styl=
e=3D"color:#008">char</span><span style=3D"color:#660">[</span><span style=
=3D"color:#066">8</span><span style=3D"color:#660">]&amp;,</span><span styl=
e=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span style=
=3D"color:#008">string</span><span style=3D"color:#660">&amp;,</span><span =
style=3D"color:#000"> </span><span style=3D"color:#008">const</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#008">char</span><span sty=
le=3D"color:#660">[</span><span style=3D"color:#066">7</span><span style=3D=
"color:#660">]&amp;,</span><span style=3D"color:#000"> std</span><span styl=
e=3D"color:#660">::</span><span style=3D"color:#000">string_view</span><spa=
n style=3D"color:#660">&amp;,</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#008">const</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#008">char</span><span style=3D"color:#660">[</span><span s=
tyle=3D"color:#066">2</span><span style=3D"color:#660">]&amp;&gt;(</span><s=
pan style=3D"color:#080">&quot;select &quot;</span><span style=3D"color:#66=
0">,</span><span style=3D"color:#000"> column</span><span style=3D"color:#6=
60">,</span><span style=3D"color:#000"> </span><span style=3D"color:#080">&=
quot; from &quot;</span><span style=3D"color:#660">,</span><span style=3D"c=
olor:#000"> table</span><span style=3D"color:#660">,</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#080">&quot;;&quot;</span><span sty=
le=3D"color:#660">));</span><span style=3D"color:#000"><br></span></div></c=
ode></div><br>Now, if we want, we could also support UDL (but not mandatory=
) by allowing to call UDL on the std::string_processing:<br><br><div style=
=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-=
style:solid;border-width:1px"><code><div><span style=3D"color:#008">auto</s=
pan><span style=3D"color:#000"> column </span><span style=3D"color:#660">=
=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#080">&qu=
ot;col&quot;</span><span style=3D"color:#000">s</span><span style=3D"color:=
#660">;</span><span style=3D"color:#000"><br></span><span style=3D"color:#0=
08">auto</span><span style=3D"color:#000"> table </span><span style=3D"colo=
r:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#=
080">&quot;tab&quot;</span><span style=3D"color:#000">sv</span><span style=
=3D"color:#660">;</span><span style=3D"color:#000"><br></span><span style=
=3D"color:#008">auto</span><span style=3D"color:#000"> req </span><span sty=
le=3D"color:#660">=3D</span><span style=3D"color:#000"> F</span><span style=
=3D"color:#080">&quot;select {column} from {table};&quot;</span><span style=
=3D"color:#000">_sql</span><span style=3D"color:#660">;</span><span style=
=3D"color:#000"><br><br></span><span style=3D"color:#800">// would be equiv=
alent to:</span><span style=3D"color:#000"><br></span><span style=3D"color:=
#008">auto</span><span style=3D"color:#000"> req </span><span style=3D"colo=
r:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#=
008">operator</span><span style=3D"color:#000"> </span><span style=3D"color=
:#080">&quot;&quot;</span><span style=3D"color:#000">_sql </span><span styl=
e=3D"color:#660">(</span><span style=3D"color:#000">std</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">string_processing</span=
><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">const</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#008">char</span=
><span style=3D"color:#660">[</span><span style=3D"color:#066">8</span><spa=
n style=3D"color:#660">]&amp;,</span><span style=3D"color:#000"> std</span>=
<span style=3D"color:#660">::</span><span style=3D"color:#008">string</span=
><span style=3D"color:#660">&amp;,</span><span style=3D"color:#000"> </span=
><span style=3D"color:#008">const</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#008">char</span><span style=3D"color:#660">[</span><s=
pan style=3D"color:#066">7</span><span style=3D"color:#660">]&amp;,</span><=
span style=3D"color:#000"> std</span><span style=3D"color:#660">::</span><s=
pan style=3D"color:#000">string_view</span><span style=3D"color:#660">&amp;=
,</span><span style=3D"color:#000"> </span><span style=3D"color:#008">const=
</span><span style=3D"color:#000"> </span><span style=3D"color:#008">char</=
span><span style=3D"color:#660">[</span><span style=3D"color:#066">2</span>=
<span style=3D"color:#660">]&amp;&gt;(</span><span style=3D"color:#080">&qu=
ot;select &quot;</span><span style=3D"color:#660">,</span><span style=3D"co=
lor:#000"> column</span><span style=3D"color:#660">,</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#080">&quot; from &quot;</span><spa=
n style=3D"color:#660">,</span><span style=3D"color:#000"> table</span><spa=
n style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#080">&quot;;&quot;</span><span style=3D"color:#660">));</span>=
<span style=3D"color:#000"><br></span></div></code></div><br>Now let&#39;s =
have some examples of it could be:<br><br>Simple string concatenation would=
 be simple<br><div style=3D"background-color:rgb(250,250,250);border-color:=
rgb(187,187,187);border-style:solid;border-width:1px"><code><div><span styl=
e=3D"color:#008">auto</span><span style=3D"color:#000"> concatenated </span=
><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> F</span><=
span style=3D"color:#080">&quot;{str1}{str2}{str3}&quot;</span><span style=
=3D"color:#000">s</span><span style=3D"color:#660">;</span><span style=3D"c=
olor:#000"><br></span><span style=3D"color:#800">// converted into an effic=
ient concatenation of the 3 strings</span><span style=3D"color:#000"><br></=
span></div></code></div><br>We could print it into an iostream if we want (=
but would be here only for convenience on legacy code)<br><div style=3D"bac=
kground-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:s=
olid;border-width:1px"><code><div><span style=3D"color:#000">std</span><spa=
n style=3D"color:#660">::</span><span style=3D"color:#000">cout </span><spa=
n style=3D"color:#660">&lt;&lt;</span><span style=3D"color:#000"> F</span><=
span style=3D"color:#080">&quot;{str1}{str2}\n&quot;</span><span style=3D"c=
olor:#660">;</span><span style=3D"color:#000"><br></span><span style=3D"col=
or:#800">// equivalent to:</span><span style=3D"color:#000"><br>std</span><=
span style=3D"color:#660">::</span><span style=3D"color:#000">cout </span><=
span style=3D"color:#660">&lt;&lt;</span><span style=3D"color:#000"> str1 <=
/span><span style=3D"color:#660">&lt;&lt;</span><span style=3D"color:#000">=
 str2 </span><span style=3D"color:#660">&lt;&lt;</span><span style=3D"color=
:#000"> </span><span style=3D"color:#080">&quot;\n&quot;</span><span style=
=3D"color:#660">;</span><span style=3D"color:#000"><br></span></div></code>=
</div><br>It could be implicitly convertible to a std::string (only if vari=
ables are implicitly convertible to std::string)<br><div style=3D"backgroun=
d-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;b=
order-width:1px"><code><div><span style=3D"color:#000">std</span><span styl=
e=3D"color:#660">::</span><span style=3D"color:#008">string</span><span sty=
le=3D"color:#000"> concatenated </span><span style=3D"color:#660">=3D</span=
><span style=3D"color:#000"> F</span><span style=3D"color:#080">&quot;{str1=
}{str2}&quot;</span><span style=3D"color:#660">;</span><span style=3D"color=
:#000"><br></span></div></code></div><br>(No example with FMT as I don&#39;=
t know how it works, but I don&#39;t see any reason for it not to be compat=
ible with FMT.)<br><br>And this would be constexpr-able.<br><br>Now, format=
ting would require a bit more elaborated type that could store formatting i=
nformation.<br>But in the end, only the user will know what to do with it.<=
br>However, I would prefer <b>not</b> to embed formatting in such a type, j=
ust to keep it simple. And use a library based solution when I really need =
formatting.<br><br>It has all the advantages of Nicol&#39;s solution, while=
 being more versatile.<br></div></blockquote><div><br>I fail to see the ver=
satility here, and it does not have all of the advantages of my method.<br>=
<br>Remember, in my version, UDLs only apply to the string fragments. In yo=
ur version, you <i>cannot</i> apply UDLs to string fragments; the string fr=
agments will be packed into your `string_processing` type as views or some =
such.<br><br>Then there&#39;s ease of use. Let&#39;s see how to implement s=
tream-based string concatenation with my method:<br><br><div style=3D"backg=
round-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-s=
tyle: solid; border-width: 1px; overflow-wrap: break-word;" class=3D"pretty=
print"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">template</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">typename</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: #606;" class=
=3D"styled-by-prettify">Args</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 concat</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: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">...&amp;&amp;</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">args</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 std</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">ostringstream stream</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 stream </span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">&lt;&lt;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">...</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">&lt;&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</sp=
an><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">Args</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&gt;(</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">args</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" c=
lass=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;" clas=
s=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">move</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">stre=
am</span><span style=3D"color: #660;" class=3D"styled-by-prettify">).</span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">get</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">();</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">}</span></div></code></div><br>Sim=
ple and obvious, a standard bit of C++17 variadic template programming.<br>=
<br>Now, how would you go about doing that with `string_processing`? That w=
ould require template metaprogramming:<br><br><div style=3D"background-colo=
r: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: soli=
d; border-width: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><co=
de class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color=
: #008;" class=3D"styled-by-prettify">template</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">&lt;</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">Args</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> si=
ze_t </span><span style=3D"color: #660;" class=3D"styled-by-prettify">...</=
span><span style=3D"color: #606;" class=3D"styled-by-prettify">Ints</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span s=
tyle=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"co=
lor: #000;" class=3D"styled-by-prettify"> concat_items</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;" c=
lass=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">ostringstream </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&amp;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">stream</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">,</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">string_p=
rocessing</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&=
lt;</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Args</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">...&gt;</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">&amp;&amp;</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">proc</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: #000;" class=3D=
"styled-by-prettify">index_sequence</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">&lt;</span><span style=3D"color: #606;" class=3D"s=
tyled-by-prettify">Ints</span><span style=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: #660;" class=3D"styled-by-prett=
ify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=C2=A0 stream </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">&lt;&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </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">&lt;&lt;</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">get</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #606;" c=
lass=3D"styled-by-prettify">Ints</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&gt;(</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">proc</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">));</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br><=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">template</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">typename</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: #606;" class=3D"styled-by-prettify">Args</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" c=
lass=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"st=
yled-by-prettify"> concat</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">(</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">string_pr=
ocessing</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&l=
t;</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Args</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">...&gt;</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">&amp;&amp;</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify">proc</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br>=C2=A0 std</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">ostringstream stream</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br>=C2=A0 concat_items</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"sty=
led-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">move</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">proc</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">),</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">make_index_sequence</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">size</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">...(</span><span style=3D"color: #606;" class=3D"st=
yled-by-prettify">Args</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">)&gt;{});</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br>=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">return</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">move</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">stream</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">).</span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">get</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><span style=3D"color: #660;" class=
=3D"styled-by-prettify">}</span></div></code></div><br>This isn&#39;t the h=
ardest code to write in the world, but it is much more complex than the pre=
vious one. Also, perfect forwarding doesn&#39;t really work here.<br><br>Al=
so, the variadic version of `concat` can be used with stuff that isn&#39;t =
the result of string interpolation. Or with multiple interpolated strings. =
And so forth. Whereas your `string_processing` type is a magic type that on=
ly the compiler can create. And we already have a type that does what `stri=
ng_processing` does; it&#39;s called `tuple`.<br><br>The <i>only advantage<=
/i> your method has over mine is that it allows UDLs to define the aggregat=
ion operation. Why is this so important to so many people?<br></div><br></d=
iv>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/f8f4407b-ecf6-4a4a-b3f6-c65813e3f843%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/f8f4407b-ecf6-4a4a-b3f6-c65813e3f843=
%40isocpp.org</a>.<br />

------=_Part_9307_1016462171.1518447372739--

------=_Part_9306_726954476.1518447372737--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 12 Feb 2018 07:00:43 -0800 (PST)
Raw View
------=_Part_9705_1539551662.1518447643198
Content-Type: multipart/alternative;
 boundary="----=_Part_9706_2127361518.1518447643198"

------=_Part_9706_2127361518.1518447643198
Content-Type: text/plain; charset="UTF-8"



On Monday, February 12, 2018 at 9:38:50 AM UTC-5, Jake Arkinstall wrote:
>
> Is recursion a reasonable request in the proposal too? I actually can't
> think of WHY one would want it, but it might be worth a discussion for
> completeness.
>
> Nicol, what are your thoughts on Florian's suggestion?
>
> In the interest of grounding ourselves (although I'm getting quite excited
> here), does anybody from the compiler community have any input as to any
> stumbling blocks in the implementation of this?
>

Implementation of what, exactly?

The most important implementation-based question that hasn't been answered
here is what exactly can go in the {} part. Is it just variable names in
scope, similar to how lambda capture lists can only name variables? Is it
arbitrary expressions (and therefore potentially including lambdas that can
resolve to statements?)

I imagine that the former will be a lot easier to implement than the latter.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/48d4dcd6-4235-405a-9a2e-b38853d3c525%40isocpp.org.

------=_Part_9706_2127361518.1518447643198
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Monday, February 12, 2018 at 9:38:50 AM UTC-5, =
Jake Arkinstall 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"auto"><div dir=3D"auto">Is recursion a reasonable request in the propos=
al too? I actually can&#39;t think of WHY one would want it, but it might b=
e worth a discussion for completeness.</div><div dir=3D"auto"><br></div>Nic=
ol, what are your thoughts on Florian&#39;s suggestion?<div dir=3D"auto"><b=
r></div><div dir=3D"auto">In the interest of grounding ourselves (although =
I&#39;m getting quite excited here), does anybody from the compiler communi=
ty have any input as to any stumbling blocks in the implementation of this?=
</div></div></blockquote><div><br>Implementation of what, exactly?<br><br>T=
he most important implementation-based question that hasn&#39;t been answer=
ed here is what exactly can go in the {} part. Is it just variable names in=
 scope, similar to how lambda capture lists can only name variables? Is it =
arbitrary expressions (and therefore potentially including lambdas that can=
 resolve to statements?)<br></div><br>I imagine that the former will be a l=
ot easier to implement than the latter.<br></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/48d4dcd6-4235-405a-9a2e-b38853d3c525%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/48d4dcd6-4235-405a-9a2e-b38853d3c525=
%40isocpp.org</a>.<br />

------=_Part_9706_2127361518.1518447643198--

------=_Part_9705_1539551662.1518447643198--

.


Author: florian.csdt@gmail.com
Date: Mon, 12 Feb 2018 07:14:25 -0800 (PST)
Raw View
------=_Part_2482_912265039.1518448465785
Content-Type: multipart/alternative;
 boundary="----=_Part_2483_716547820.1518448465786"

------=_Part_2483_716547820.1518448465786
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



Le lundi 12 f=C3=A9vrier 2018 15:56:12 UTC+1, Nicol Bolas a =C3=A9crit :
>
> On Monday, February 12, 2018 at 5:17:45 AM UTC-5, floria...@gmail.com=20
> wrote:
>>
>> Let me suggest something close to Nicol's solution, but not quite.
>>
>> The F"" operator returns a special type that could be like a simple tupl=
e=20
>> (let's name it std::string_processing for now).
>>
>> Then the user can use it directly into its own functions.
>>
>>
>> auto column =3D "col"s;
>> auto table =3D "tab"sv;
>> auto req =3D sql(F"select {column} from {table};");
>>
>> // would be equivalent to:
>> auto req =3D sql(std::string_processing<const char[8]&, std::string&, co=
nst=20
>> char[7]&, std::string_view&, const char[2]&>("select ", column, " from "=
,=20
>> table, ";"));
>>
>> Now, if we want, we could also support UDL (but not mandatory) by=20
>> allowing to call UDL on the std::string_processing:
>>
>> auto column =3D "col"s;
>> auto table =3D "tab"sv;
>> auto req =3D F"select {column} from {table};"_sql;
>>
>> // would be equivalent to:
>> auto req =3D operator ""_sql (std::string_processing<const char[8]&, std=
::
>> string&, const char[7]&, std::string_view&, const char[2]&>("select ",=
=20
>> column, " from ", table, ";"));
>>
>> Now let's have some examples of it could be:
>>
>> Simple string concatenation would be simple
>> auto concatenated =3D F"{str1}{str2}{str3}"s;
>> // converted into an efficient concatenation of the 3 strings
>>
>> We could print it into an iostream if we want (but would be here only fo=
r=20
>> convenience on legacy code)
>> std::cout << F"{str1}{str2}\n";
>> // equivalent to:
>> std::cout << str1 << str2 << "\n";
>>
>> It could be implicitly convertible to a std::string (only if variables=
=20
>> are implicitly convertible to std::string)
>> std::string concatenated =3D F"{str1}{str2}";
>>
>> (No example with FMT as I don't know how it works, but I don't see any=
=20
>> reason for it not to be compatible with FMT.)
>>
>> And this would be constexpr-able.
>>
>> Now, formatting would require a bit more elaborated type that could stor=
e=20
>> formatting information.
>> But in the end, only the user will know what to do with it.
>> However, I would prefer *not* to embed formatting in such a type, just=
=20
>> to keep it simple. And use a library based solution when I really need=
=20
>> formatting.
>>
>> It has all the advantages of Nicol's solution, while being more versatil=
e.
>>
>
> I fail to see the versatility here, and it does not have all of the=20
> advantages of my method.
>
> Remember, in my version, UDLs only apply to the string fragments. In your=
=20
> version, you *cannot* apply UDLs to string fragments; the string=20
> fragments will be packed into your `string_processing` type as views or=
=20
> some such.
>
> Then there's ease of use. Let's see how to implement stream-based string=
=20
> concatenation with my method:
>
> template<typename ...Args>
> auto concat(Args ...&&args)
> {
>   std::ostringstream stream;
>   stream << ... << std::forward<Args>(args);
>   return std::move(stream).get();
> }
>
> Simple and obvious, a standard bit of C++17 variadic template programming=
..
>
> Now, how would you go about doing that with `string_processing`? That=20
> would require template metaprogramming:
>
> template<typename ...Args, size_t ...Ints>
> void concat_items(std::ostringstream &stream, std::string_processing<Args
> ...> &&proc, std::index_sequence<Ints...>)
> {
>   stream << ... << get<Ints>(proc));
> }
>
> template<typename ...Args>
> auto concat(std::string_processing<Args...> &&proc)
> {
>   std::ostringstream stream;
>   concat_items(stream, std::move(proc), std::make_index_sequence<size...(
> Args)>{});
>   return std::move(stream).get();
> }
>
> This isn't the hardest code to write in the world, but it is much more=20
> complex than the previous one. Also, perfect forwarding doesn't really wo=
rk=20
> here.
>
> Also, the variadic version of `concat` can be used with stuff that isn't=
=20
> the result of string interpolation. Or with multiple interpolated strings=
..=20
> And so forth. Whereas your `string_processing` type is a magic type that=
=20
> only the compiler can create. And we already have a type that does what=
=20
> `string_processing` does; it's called `tuple`.
>
> The *only advantage* your method has over mine is that it allows UDLs to=
=20
> define the aggregation operation. Why is this so important to so many=20
> people?
>
>

Well, my solution is more versatile in the following sense: the result is a=
=20
plain object that can be stored in a variable, returned from a function.
You could envision functions to transform std::string_processing into=20
another std::string_processing easily.

Moreover, I know that some proposals try to enable creating a parameter=20
pack from a tuple (like an operator... ).
With that in mind, the implementation of your concat function with my=20
approach would be exactly the same as with your approach (with a call to=20
"operator..." of std::string_processing ).

And then, with only c++17 metaprogramming capabilities, you could also use=
=20
std::apply.

UDL the aggregate is not important to me, but it was easy to include and=20
allows neat syntax (in my opinion).


--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/5b5435db-772e-4c38-8867-f6fbc66d7cec%40isocpp.or=
g.

------=_Part_2483_716547820.1518448465786
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le lundi 12 f=C3=A9vrier 2018 15:56:12 UTC+1, Nico=
l Bolas a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v dir=3D"ltr">On Monday, February 12, 2018 at 5:17:45 AM UTC-5, <a>floria..=
..@gmail.com</a> wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;m=
argin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr">Let me suggest something close to Nicol&#39;s solution, but not quite.<=
br><br>The F&quot;&quot; operator returns a special type that could be like=
 a simple tuple (let&#39;s name it std::string_processing for now).<br><br>=
Then the user can use it directly into its own functions.<br><br><br><div s=
tyle=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);bor=
der-style:solid;border-width:1px"><code><div><span style=3D"color:#008">aut=
o</span><span style=3D"color:#000"> column </span><span style=3D"color:#660=
">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#080">&=
quot;col&quot;</span><span style=3D"color:#000">s</span><span style=3D"colo=
r:#660">;</span><span style=3D"color:#000"><br></span><span style=3D"color:=
#008">auto</span><span style=3D"color:#000"> table </span><span style=3D"co=
lor:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D"color=
:#080">&quot;tab&quot;</span><span style=3D"color:#000">sv</span><span styl=
e=3D"color:#660">;</span><span style=3D"color:#000"><br></span><span style=
=3D"color:#008">auto</span><span style=3D"color:#000"> req </span><span sty=
le=3D"color:#660">=3D</span><span style=3D"color:#000"> sql</span><span sty=
le=3D"color:#660">(</span><span style=3D"color:#000">F</span><span style=3D=
"color:#080">&quot;select {column} from {table};&quot;</span><span style=3D=
"color:#660">);</span><span style=3D"color:#000"><br><br></span><span style=
=3D"color:#800">// would be equivalent to:</span><span style=3D"color:#000"=
><br></span><span style=3D"color:#008">auto</span><span style=3D"color:#000=
"> req </span><span style=3D"color:#660">=3D</span><span style=3D"color:#00=
0"> sql</span><span style=3D"color:#660">(</span><span style=3D"color:#000"=
>std</span><span style=3D"color:#660">::</span><span style=3D"color:#000">s=
tring_processing</span><span style=3D"color:#660">&lt;</span><span style=3D=
"color:#008">con<wbr>st</span><span style=3D"color:#000"> </span><span styl=
e=3D"color:#008">char</span><span style=3D"color:#660">[</span><span style=
=3D"color:#066">8</span><span style=3D"color:#660">]&amp;,</span><span styl=
e=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span style=
=3D"color:#008">string</span><span style=3D"color:#660">&amp;,</span><span =
style=3D"color:#000"> </span><span style=3D"color:#008">const</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#008">char</span><span sty=
le=3D"color:#660">[</span><span style=3D"color:#066">7</span><span style=3D=
"color:#660">]&amp;,</span><span style=3D"color:#000"> std</span><span styl=
e=3D"color:#660">::</span><span style=3D"color:#000">string_view</span><spa=
n style=3D"color:#660">&amp;,</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#008">const</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#008">char</span><span style=3D"color:#660">[</span><span s=
tyle=3D"color:#066">2</span><span style=3D"color:#660">]&amp;&gt;(</span><s=
pan style=3D"color:#080">&quot;select &quot;</span><span style=3D"color:#66=
0">,</span><span style=3D"color:#000"> column</span><span style=3D"color:#6=
60">,</span><span style=3D"color:#000"> </span><span style=3D"color:#080">&=
quot; from &quot;</span><span style=3D"color:#660">,</span><span style=3D"c=
olor:#000"> table</span><span style=3D"color:#660">,</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#080">&quot;;&quot;</span><span sty=
le=3D"color:#660">));</span><span style=3D"color:#000"><br></span></div></c=
ode></div><br>Now, if we want, we could also support UDL (but not mandatory=
) by allowing to call UDL on the std::string_processing:<br><br><div style=
=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-=
style:solid;border-width:1px"><code><div><span style=3D"color:#008">auto</s=
pan><span style=3D"color:#000"> column </span><span style=3D"color:#660">=
=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#080">&qu=
ot;col&quot;</span><span style=3D"color:#000">s</span><span style=3D"color:=
#660">;</span><span style=3D"color:#000"><br></span><span style=3D"color:#0=
08">auto</span><span style=3D"color:#000"> table </span><span style=3D"colo=
r:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#=
080">&quot;tab&quot;</span><span style=3D"color:#000">sv</span><span style=
=3D"color:#660">;</span><span style=3D"color:#000"><br></span><span style=
=3D"color:#008">auto</span><span style=3D"color:#000"> req </span><span sty=
le=3D"color:#660">=3D</span><span style=3D"color:#000"> F</span><span style=
=3D"color:#080">&quot;select {column} from {table};&quot;</span><span style=
=3D"color:#000">_sql</span><span style=3D"color:#660">;</span><span style=
=3D"color:#000"><br><br></span><span style=3D"color:#800">// would be equiv=
alent to:</span><span style=3D"color:#000"><br></span><span style=3D"color:=
#008">auto</span><span style=3D"color:#000"> req </span><span style=3D"colo=
r:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#=
008">operator</span><span style=3D"color:#000"> </span><span style=3D"color=
:#080">&quot;&quot;</span><span style=3D"color:#000">_sql </span><span styl=
e=3D"color:#660">(</span><span style=3D"color:#000">std</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">string_processing</span=
><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">const</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#008">char</span=
><span style=3D"color:#660">[</span><span style=3D"color:#066">8</span><spa=
n style=3D"color:#660">]&amp;,</span><span style=3D"color:#000"> std</span>=
<span style=3D"color:#660">::</span><span style=3D"color:#008">string</span=
><span style=3D"color:#660">&amp;,</span><span style=3D"color:#000"> </span=
><span style=3D"color:#008">const</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#008">char</span><span style=3D"color:#660">[</span><s=
pan style=3D"color:#066">7</span><span style=3D"color:#660">]&amp;,</span><=
span style=3D"color:#000"> std</span><span style=3D"color:#660">::</span><s=
pan style=3D"color:#000">string_view</span><span style=3D"color:#660">&amp;=
,</span><span style=3D"color:#000"> </span><span style=3D"color:#008">const=
</span><span style=3D"color:#000"> </span><span style=3D"color:#008">char</=
span><span style=3D"color:#660">[</span><span style=3D"color:#066">2</span>=
<span style=3D"color:#660">]&amp;&gt;(</span><span style=3D"color:#080">&qu=
ot;select &quot;</span><span style=3D"color:#660">,</span><span style=3D"co=
lor:#000"> column</span><span style=3D"color:#660">,</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#080">&quot; from &quot;</span><spa=
n style=3D"color:#660">,</span><span style=3D"color:#000"> table</span><spa=
n style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#080">&quot;;&quot;</span><span style=3D"color:#660">));</span>=
<span style=3D"color:#000"><br></span></div></code></div><br>Now let&#39;s =
have some examples of it could be:<br><br>Simple string concatenation would=
 be simple<br><div style=3D"background-color:rgb(250,250,250);border-color:=
rgb(187,187,187);border-style:solid;border-width:1px"><code><div><span styl=
e=3D"color:#008">auto</span><span style=3D"color:#000"> concatenated </span=
><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> F</span><=
span style=3D"color:#080">&quot;{str1}{str2}{str3}&quot;</span><span style=
=3D"color:#000">s</span><span style=3D"color:#660">;</span><span style=3D"c=
olor:#000"><br></span><span style=3D"color:#800">// converted into an effic=
ient concatenation of the 3 strings</span><span style=3D"color:#000"><br></=
span></div></code></div><br>We could print it into an iostream if we want (=
but would be here only for convenience on legacy code)<br><div style=3D"bac=
kground-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:s=
olid;border-width:1px"><code><div><span style=3D"color:#000">std</span><spa=
n style=3D"color:#660">::</span><span style=3D"color:#000">cout </span><spa=
n style=3D"color:#660">&lt;&lt;</span><span style=3D"color:#000"> F</span><=
span style=3D"color:#080">&quot;{str1}{str2}\n&quot;</span><span style=3D"c=
olor:#660">;</span><span style=3D"color:#000"><br></span><span style=3D"col=
or:#800">// equivalent to:</span><span style=3D"color:#000"><br>std</span><=
span style=3D"color:#660">::</span><span style=3D"color:#000">cout </span><=
span style=3D"color:#660">&lt;&lt;</span><span style=3D"color:#000"> str1 <=
/span><span style=3D"color:#660">&lt;&lt;</span><span style=3D"color:#000">=
 str2 </span><span style=3D"color:#660">&lt;&lt;</span><span style=3D"color=
:#000"> </span><span style=3D"color:#080">&quot;\n&quot;</span><span style=
=3D"color:#660">;</span><span style=3D"color:#000"><br></span></div></code>=
</div><br>It could be implicitly convertible to a std::string (only if vari=
ables are implicitly convertible to std::string)<br><div style=3D"backgroun=
d-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;b=
order-width:1px"><code><div><span style=3D"color:#000">std</span><span styl=
e=3D"color:#660">::</span><span style=3D"color:#008">string</span><span sty=
le=3D"color:#000"> concatenated </span><span style=3D"color:#660">=3D</span=
><span style=3D"color:#000"> F</span><span style=3D"color:#080">&quot;{str1=
}{str2}&quot;</span><span style=3D"color:#660">;</span><span style=3D"color=
:#000"><br></span></div></code></div><br>(No example with FMT as I don&#39;=
t know how it works, but I don&#39;t see any reason for it not to be compat=
ible with FMT.)<br><br>And this would be constexpr-able.<br><br>Now, format=
ting would require a bit more elaborated type that could store formatting i=
nformation.<br>But in the end, only the user will know what to do with it.<=
br>However, I would prefer <b>not</b> to embed formatting in such a type, j=
ust to keep it simple. And use a library based solution when I really need =
formatting.<br><br>It has all the advantages of Nicol&#39;s solution, while=
 being more versatile.<br></div></blockquote><div><br>I fail to see the ver=
satility here, and it does not have all of the advantages of my method.<br>=
<br>Remember, in my version, UDLs only apply to the string fragments. In yo=
ur version, you <i>cannot</i> apply UDLs to string fragments; the string fr=
agments will be packed into your `string_processing` type as views or some =
such.<br><br>Then there&#39;s ease of use. Let&#39;s see how to implement s=
tream-based string concatenation with my method:<br><br><div style=3D"backg=
round-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:sol=
id;border-width:1px"><code><div><span style=3D"color:#008">template</span><=
span style=3D"color:#660">&lt;</span><span style=3D"color:#008">typename</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#660">...</span=
><span style=3D"color:#606">Args</span><span style=3D"color:#660">&gt;</spa=
n><span style=3D"color:#000"><br></span><span style=3D"color:#008">auto</sp=
an><span style=3D"color:#000"> concat</span><span style=3D"color:#660">(</s=
pan><span style=3D"color:#606">Args</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#660">...&amp;&amp;</span><span style=3D"color:#000"=
>args</span><span style=3D"color:#660">)</span><span style=3D"color:#000"><=
br></span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br=
>=C2=A0 std</span><span style=3D"color:#660">::</span><span style=3D"color:=
#000">ostringstream stream</span><span style=3D"color:#660">;</span><span s=
tyle=3D"color:#000"><br>=C2=A0 stream </span><span style=3D"color:#660">&lt=
;&lt;</span><span style=3D"color:#000"> </span><span style=3D"color:#660">.=
...</span><span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;=
&lt;</span><span style=3D"color:#000"> std</span><span style=3D"color:#660"=
>::</span><span style=3D"color:#000">forward</span><span style=3D"color:#66=
0">&lt;</span><span style=3D"color:#606">Args</span><span style=3D"color:#6=
60">&gt;(</span><span style=3D"color:#000">args</span><span style=3D"color:=
#660">);</span><span style=3D"color:#000"><br>=C2=A0 </span><span style=3D"=
color:#008">return</span><span style=3D"color:#000"> std</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">move</span><span style=
=3D"color:#660">(</span><span style=3D"color:#000">stream</span><span style=
=3D"color:#660">).</span><span style=3D"color:#008">get</span><span style=
=3D"color:#660">();</span><span style=3D"color:#000"><br></span><span style=
=3D"color:#660">}</span></div></code></div><br>Simple and obvious, a standa=
rd bit of C++17 variadic template programming.<br><br>Now, how would you go=
 about doing that with `string_processing`? That would require template met=
aprogramming:<br><br><div style=3D"background-color:rgb(250,250,250);border=
-color:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><sp=
an style=3D"color:#008">template</span><span style=3D"color:#660">&lt;</spa=
n><span style=3D"color:#008">typename</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#660">...</span><span style=3D"color:#606">Args</s=
pan><span style=3D"color:#660">,</span><span style=3D"color:#000"> size_t <=
/span><span style=3D"color:#660">...</span><span style=3D"color:#606">Ints<=
/span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"><br>=
</span><span style=3D"color:#008">void</span><span style=3D"color:#000"> co=
ncat_items</span><span style=3D"color:#660">(</span><span style=3D"color:#0=
00">std</span><span style=3D"color:#660">::</span><span style=3D"color:#000=
">ostringstrea<wbr>m </span><span style=3D"color:#660">&amp;</span><span st=
yle=3D"color:#000">stream</span><span style=3D"color:#660">,</span><span st=
yle=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span sty=
le=3D"color:#000">string_processing</span><span style=3D"color:#660">&lt;</=
span><span style=3D"color:#606">Args</span><span style=3D"color:#660">...<w=
br>&gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#660"=
>&amp;&amp;</span><span style=3D"color:#000">proc</span><span style=3D"colo=
r:#660">,</span><span style=3D"color:#000"> std</span><span style=3D"color:=
#660">::</span><span style=3D"color:#000">index_sequence</span><span style=
=3D"color:#660">&lt;</span><span style=3D"color:#606">Ints</span><span styl=
e=3D"color:#660">...&gt;)</span><span style=3D"color:#000"><br></span><span=
 style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 stream =
</span><span style=3D"color:#660">&lt;&lt;</span><span style=3D"color:#000"=
> </span><span style=3D"color:#660">...</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#660">&lt;&lt;</span><span style=3D"color:#000">=
 </span><span style=3D"color:#008">get</span><span style=3D"color:#660">&lt=
;</span><span style=3D"color:#606">Ints</span><span style=3D"color:#660">&g=
t;(</span><span style=3D"color:#000">proc</span><span style=3D"color:#660">=
));</span><span style=3D"color:#000"><br></span><span style=3D"color:#660">=
}</span><span style=3D"color:#000"><br><br></span><span style=3D"color:#008=
">template</span><span style=3D"color:#660">&lt;</span><span style=3D"color=
:#008">typename</span><span style=3D"color:#000"> </span><span style=3D"col=
or:#660">...</span><span style=3D"color:#606">Args</span><span style=3D"col=
or:#660">&gt;</span><span style=3D"color:#000"><br></span><span style=3D"co=
lor:#008">auto</span><span style=3D"color:#000"> concat</span><span style=
=3D"color:#660">(</span><span style=3D"color:#000">std</span><span style=3D=
"color:#660">::</span><span style=3D"color:#000">string_processing</span><s=
pan style=3D"color:#660">&lt;</span><span style=3D"color:#606"><wbr>Args</s=
pan><span style=3D"color:#660">...&gt;</span><span style=3D"color:#000"> </=
span><span style=3D"color:#660">&amp;&amp;</span><span style=3D"color:#000"=
>proc</span><span style=3D"color:#660">)</span><span style=3D"color:#000"><=
br></span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br=
>=C2=A0 std</span><span style=3D"color:#660">::</span><span style=3D"color:=
#000">ostringstream stream</span><span style=3D"color:#660">;</span><span s=
tyle=3D"color:#000"><br>=C2=A0 concat_items</span><span style=3D"color:#660=
">(</span><span style=3D"color:#000">stream</span><span style=3D"color:#660=
">,</span><span style=3D"color:#000"> std</span><span style=3D"color:#660">=
::</span><span style=3D"color:#000">move</span><span style=3D"color:#660">(=
</span><span style=3D"color:#000">proc</span><span style=3D"color:#660">),<=
/span><span style=3D"color:#000"> std</span><span style=3D"color:#660">::</=
span><span style=3D"color:#000">make_index_sequence</span><span style=3D"co=
lor:#660">&lt;</span><span style=3D"color:#000">size</span><span style=3D"c=
olor:#660">.<wbr>..(</span><span style=3D"color:#606">Args</span><span styl=
e=3D"color:#660">)&gt;{});</span><span style=3D"color:#000"><br>=C2=A0 </sp=
an><span style=3D"color:#008">return</span><span style=3D"color:#000"> std<=
/span><span style=3D"color:#660">::</span><span style=3D"color:#000">move</=
span><span style=3D"color:#660">(</span><span style=3D"color:#000">stream</=
span><span style=3D"color:#660">).</span><span style=3D"color:#008">get</sp=
an><span style=3D"color:#660">();</span><span style=3D"color:#000"><br></sp=
an><span style=3D"color:#660">}</span></div></code></div><br>This isn&#39;t=
 the hardest code to write in the world, but it is much more complex than t=
he previous one. Also, perfect forwarding doesn&#39;t really work here.<br>=
<br>Also, the variadic version of `concat` can be used with stuff that isn&=
#39;t the result of string interpolation. Or with multiple interpolated str=
ings. And so forth. Whereas your `string_processing` type is a magic type t=
hat only the compiler can create. And we already have a type that does what=
 `string_processing` does; it&#39;s called `tuple`.<br><br>The <i>only adva=
ntage</i> your method has over mine is that it allows UDLs to define the ag=
gregation operation. Why is this so important to so many people?<br></div><=
br></div></blockquote><div><br></div><br><div>Well, my solution is more ver=
satile in the following sense: the=20
result is a plain object that can be stored in a variable, returned from
 a function.</div><div>You could envision functions to transform std::strin=
g_processing into another std::string_processing easily.</div><div><br></di=
v><div>Moreover, I know that some proposals try to enable creating a parame=
ter pack from a tuple (like an operator... ).</div><div>With that in mind, =
the implementation of your concat function with my approach would be exactl=
y the same as with your approach (with a call to &quot;operator...&quot; of=
 std::string_processing ).</div><div><br></div><div>And then, with only c++=
17 metaprogramming capabilities, you could also use std::apply.<br></div><d=
iv><br></div>UDL the aggregate is not important to me, but it was easy to i=
nclude and allows neat syntax (in my opinion).<br><br><br></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/5b5435db-772e-4c38-8867-f6fbc66d7cec%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/5b5435db-772e-4c38-8867-f6fbc66d7cec=
%40isocpp.org</a>.<br />

------=_Part_2483_716547820.1518448465786--

------=_Part_2482_912265039.1518448465785--

.


Author: Todd Fleming <tbfleming@gmail.com>
Date: Mon, 12 Feb 2018 07:26:03 -0800 (PST)
Raw View
------=_Part_6430_1761843223.1518449163117
Content-Type: multipart/alternative;
 boundary="----=_Part_6431_339884627.1518449163117"

------=_Part_6431_339884627.1518449163117
Content-Type: text/plain; charset="UTF-8"

On Monday, February 12, 2018 at 9:38:50 AM UTC-5, Jake Arkinstall wrote:
>
> Is recursion a reasonable request in the proposal too? I actually can't
> think of WHY one would want it, but it might be worth a discussion for
> completeness.
>

I'd want it. I'd also want multiline:

auto h = html(F"
    <div>
        <h1>{generate_header(a, b, c)}</h1>
        {notice.empty() ? "" : F"<b>{notice}</b>"}
        {generate_foo(e, f, g)}
    </div>
");


--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/aaed9da4-f416-4ac0-9b7a-2449f847526f%40isocpp.org.

------=_Part_6431_339884627.1518449163117
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Monday, February 12, 2018 at 9:38:50 AM UTC-5, Jake Ark=
install wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"auto=
"><div dir=3D"auto">Is recursion a reasonable request in the proposal too? =
I actually can&#39;t think of WHY one would want it, but it might be worth =
a discussion for completeness.</div></div></blockquote><div><br></div><div>=
I&#39;d want it. I&#39;d also want multiline:</div><div><br></div><div><div=
 class=3D"prettyprint" style=3D"border-width: 1px; border-style: solid; bor=
der-color: rgb(187, 187, 187); background-color: rgb(250, 250, 250); word-w=
rap: 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"> h </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> html</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">F</span><span style=3D"color: #080;" class=3D"sty=
led-by-prettify">&quot;<br>=C2=A0 =C2=A0 &lt;div&gt;<br>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 &lt;h1&gt;{generate_header(a, b, c)}&lt;/h1&gt;<br>=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 {notice.empty() ? &quot;&quot; : F&quot;&lt;b&gt;</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">notice</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">}&lt;/</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">b</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #080;" class=
=3D"styled-by-prettify">&quot;}<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 {generate_fo=
o(e, f, g)}<br></span><span style=3D"color: #080;" class=3D"styled-by-prett=
ify">=C2=A0 =C2=A0 &lt;/div&gt;<br>&quot;</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">);</span></div></code></div></div><div>=C2=
=A0</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/aaed9da4-f416-4ac0-9b7a-2449f847526f%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/aaed9da4-f416-4ac0-9b7a-2449f847526f=
%40isocpp.org</a>.<br />

------=_Part_6431_339884627.1518449163117--

------=_Part_6430_1761843223.1518449163117--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 12 Feb 2018 07:45:41 -0800 (PST)
Raw View
------=_Part_9609_446297566.1518450341499
Content-Type: multipart/alternative;
 boundary="----=_Part_9610_952126848.1518450341501"

------=_Part_9610_952126848.1518450341501
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Monday, February 12, 2018 at 10:14:25 AM UTC-5, floria...@gmail.com=20
wrote:
>
> Le lundi 12 f=C3=A9vrier 2018 15:56:12 UTC+1, Nicol Bolas a =C3=A9crit :
>>
>> On Monday, February 12, 2018 at 5:17:45 AM UTC-5, floria...@gmail.com=20
>> wrote:
>>>
>>> Let me suggest something close to Nicol's solution, but not quite.
>>>
>>> The F"" operator returns a special type that could be like a simple=20
>>> tuple (let's name it std::string_processing for now).
>>>
>>> Then the user can use it directly into its own functions.
>>>
>>>
>>> auto column =3D "col"s;
>>> auto table =3D "tab"sv;
>>> auto req =3D sql(F"select {column} from {table};");
>>>
>>> // would be equivalent to:
>>> auto req =3D sql(std::string_processing<const char[8]&, std::string&,=
=20
>>> const char[7]&, std::string_view&, const char[2]&>("select ", column, "=
=20
>>> from ", table, ";"));
>>>
>>> Now, if we want, we could also support UDL (but not mandatory) by=20
>>> allowing to call UDL on the std::string_processing:
>>>
>>> auto column =3D "col"s;
>>> auto table =3D "tab"sv;
>>> auto req =3D F"select {column} from {table};"_sql;
>>>
>>> // would be equivalent to:
>>> auto req =3D operator ""_sql (std::string_processing<const char[8]&, st=
d::
>>> string&, const char[7]&, std::string_view&, const char[2]&>("select ",=
=20
>>> column, " from ", table, ";"));
>>>
>>> Now let's have some examples of it could be:
>>>
>>> Simple string concatenation would be simple
>>> auto concatenated =3D F"{str1}{str2}{str3}"s;
>>> // converted into an efficient concatenation of the 3 strings
>>>
>>> We could print it into an iostream if we want (but would be here only=
=20
>>> for convenience on legacy code)
>>> std::cout << F"{str1}{str2}\n";
>>> // equivalent to:
>>> std::cout << str1 << str2 << "\n";
>>>
>>> It could be implicitly convertible to a std::string (only if variables=
=20
>>> are implicitly convertible to std::string)
>>> std::string concatenated =3D F"{str1}{str2}";
>>>
>>> (No example with FMT as I don't know how it works, but I don't see any=
=20
>>> reason for it not to be compatible with FMT.)
>>>
>>> And this would be constexpr-able.
>>>
>>> Now, formatting would require a bit more elaborated type that could=20
>>> store formatting information.
>>> But in the end, only the user will know what to do with it.
>>> However, I would prefer *not* to embed formatting in such a type, just=
=20
>>> to keep it simple. And use a library based solution when I really need=
=20
>>> formatting.
>>>
>>> It has all the advantages of Nicol's solution, while being more=20
>>> versatile.
>>>
>>
>> I fail to see the versatility here, and it does not have all of the=20
>> advantages of my method.
>>
>> Remember, in my version, UDLs only apply to the string fragments. In you=
r=20
>> version, you *cannot* apply UDLs to string fragments; the string=20
>> fragments will be packed into your `string_processing` type as views or=
=20
>> some such.
>>
>> Then there's ease of use. Let's see how to implement stream-based string=
=20
>> concatenation with my method:
>>
>> template<typename ...Args>
>> auto concat(Args ...&&args)
>> {
>>   std::ostringstream stream;
>>   stream << ... << std::forward<Args>(args);
>>   return std::move(stream).get();
>> }
>>
>> Simple and obvious, a standard bit of C++17 variadic template programmin=
g.
>>
>> Now, how would you go about doing that with `string_processing`? That=20
>> would require template metaprogramming:
>>
>> template<typename ...Args, size_t ...Ints>
>> void concat_items(std::ostringstream &stream, std::string_processing<Arg=
s
>> ...> &&proc, std::index_sequence<Ints...>)
>> {
>>   stream << ... << get<Ints>(proc));
>> }
>>
>> template<typename ...Args>
>> auto concat(std::string_processing<Args...> &&proc)
>> {
>>   std::ostringstream stream;
>>   concat_items(stream, std::move(proc), std::make_index_sequence<size...=
(
>> Args)>{});
>>   return std::move(stream).get();
>> }
>>
>> This isn't the hardest code to write in the world, but it is much more=
=20
>> complex than the previous one. Also, perfect forwarding doesn't really w=
ork=20
>> here.
>>
>> Also, the variadic version of `concat` can be used with stuff that isn't=
=20
>> the result of string interpolation. Or with multiple interpolated string=
s.=20
>> And so forth. Whereas your `string_processing` type is a magic type that=
=20
>> only the compiler can create. And we already have a type that does what=
=20
>> `string_processing` does; it's called `tuple`.
>>
>> The *only advantage* your method has over mine is that it allows UDLs to=
=20
>> define the aggregation operation. Why is this so important to so many=20
>> people?
>>
>>
>
> Well, my solution is more versatile in the following sense: the result is=
=20
> a plain object that can be stored in a variable, returned from a function=
..
>

tuple(F"interpolated {string}")

Oh look, "a plain object that can be stored in a variable, returned from a=
=20
function". It required a whole 7 characters more.

"Versatility" typically refers to the ability to do more things with=20
something. My way can be put into an object, but your way cannot be put=20
into a function's parameters as separate values nearly as easily. Mine=20
seems more versatile.

You could envision functions to transform std::string_processing into=20
> another std::string_processing easily.
>
> Moreover, I know that some proposals try to enable creating a parameter=
=20
> pack from a tuple (like an operator... ).
>

And sadly, none of them have advanced or even received additional revised=
=20
proposals. My way works just fine with C++ as it is.

And even if we had that, most use-cases you don't need to pass the values=
=20
around as a collective object. And if you did, you can make one trivially,=
=20
as above.

And again, it still doesn't deal with the fact that you lose perfect=20
forwarding.

With that in mind, the implementation of your concat function with my=20
> approach would be exactly the same as with your approach (with a call to=
=20
> "operator..." of std::string_processing ).
>
> And then, with only c++17 metaprogramming capabilities, you could also us=
e=20
> std::apply.
>

You cannot `apply` things to operators. Not without creating a lambda=20
function that gets called with it.

The fact is, it's a *lot* easier in C++ as it currently stands to go from=
=20
parameter pack of values to an object than it is to go from an object to a=
=20
parameter pack of values. I wish that were not the case, but so long as it=
=20
is the case, parameter packs will remain the easier-to-use option.

UDL the aggregate is not important to me, but it was easy to include and=20
> allows neat syntax (in my opinion).
>

But it makes it impossible to apply a UDL to the string fragments. And=20
that's important if you do want to use template metaprogramming on string=
=20
literals.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/5c51d89a-54b6-490b-87f2-09ed263d8322%40isocpp.or=
g.

------=_Part_9610_952126848.1518450341501
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Monday, February 12, 2018 at 10:14:25 AM UTC-5, floria.=
...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr">Le lundi 12 f=C3=A9vrier 2018 15:56:12 UTC+1, Nicol Bolas a =C3=A9cri=
t=C2=A0:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Monday,=
 February 12, 2018 at 5:17:45 AM UTC-5, <a>floria...@gmail.com</a> wrote:<b=
lockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-=
left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">Let me suggest somet=
hing close to Nicol&#39;s solution, but not quite.<br><br>The F&quot;&quot;=
 operator returns a special type that could be like a simple tuple (let&#39=
;s name it std::string_processing for now).<br><br>Then the user can use it=
 directly into its own functions.<br><br><br><div style=3D"background-color=
:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-w=
idth:1px"><code><div><span style=3D"color:#008">auto</span><span style=3D"c=
olor:#000"> column </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> </span><span style=3D"color:#080">&quot;col&quot;</span><s=
pan style=3D"color:#000">s</span><span style=3D"color:#660">;</span><span s=
tyle=3D"color:#000"><br></span><span style=3D"color:#008">auto</span><span =
style=3D"color:#000"> table </span><span style=3D"color:#660">=3D</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#080">&quot;tab&quot;<=
/span><span style=3D"color:#000">sv</span><span style=3D"color:#660">;</spa=
n><span style=3D"color:#000"><br></span><span style=3D"color:#008">auto</sp=
an><span style=3D"color:#000"> req </span><span style=3D"color:#660">=3D</s=
pan><span style=3D"color:#000"> sql</span><span style=3D"color:#660">(</spa=
n><span style=3D"color:#000">F</span><span style=3D"color:#080">&quot;selec=
t {column} from {table};&quot;</span><span style=3D"color:#660">);</span><s=
pan style=3D"color:#000"><br><br></span><span style=3D"color:#800">// would=
 be equivalent to:</span><span style=3D"color:#000"><br></span><span style=
=3D"color:#008">auto</span><span style=3D"color:#000"> req </span><span sty=
le=3D"color:#660">=3D</span><span style=3D"color:#000"> sql</span><span sty=
le=3D"color:#660">(</span><span style=3D"color:#000">std</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">string_processing</span=
><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">con<wbr>s=
t</span><span style=3D"color:#000"> </span><span style=3D"color:#008">char<=
/span><span style=3D"color:#660">[</span><span style=3D"color:#066">8</span=
><span style=3D"color:#660">]&amp;,</span><span style=3D"color:#000"> std</=
span><span style=3D"color:#660">::</span><span style=3D"color:#008">string<=
/span><span style=3D"color:#660">&amp;,</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#008">const</span><span style=3D"color:#000"> </=
span><span style=3D"color:#008">char</span><span style=3D"color:#660">[</sp=
an><span style=3D"color:#066">7</span><span style=3D"color:#660">]&amp;,</s=
pan><span style=3D"color:#000"> std</span><span style=3D"color:#660">::</sp=
an><span style=3D"color:#000">string_view</span><span style=3D"color:#660">=
&amp;,</span><span style=3D"color:#000"> </span><span style=3D"color:#008">=
const</span><span style=3D"color:#000"> </span><span style=3D"color:#008">c=
har</span><span style=3D"color:#660">[</span><span style=3D"color:#066">2</=
span><span style=3D"color:#660">]&amp;&gt;(</span><span style=3D"color:#080=
">&quot;select &quot;</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> column</span><span style=3D"color:#660">,</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#080">&quot; from &quot;</spa=
n><span style=3D"color:#660">,</span><span style=3D"color:#000"> table</spa=
n><span style=3D"color:#660">,</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#080">&quot;;&quot;</span><span style=3D"color:#660">));<=
/span><span style=3D"color:#000"><br></span></div></code></div><br>Now, if =
we want, we could also support UDL (but not mandatory) by allowing to call =
UDL on the std::string_processing:<br><br><div style=3D"background-color:rg=
b(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-widt=
h:1px"><code><div><span style=3D"color:#008">auto</span><span style=3D"colo=
r:#000"> column </span><span style=3D"color:#660">=3D</span><span style=3D"=
color:#000"> </span><span style=3D"color:#080">&quot;col&quot;</span><span =
style=3D"color:#000">s</span><span style=3D"color:#660">;</span><span style=
=3D"color:#000"><br></span><span style=3D"color:#008">auto</span><span styl=
e=3D"color:#000"> table </span><span style=3D"color:#660">=3D</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#080">&quot;tab&quot;</spa=
n><span style=3D"color:#000">sv</span><span style=3D"color:#660">;</span><s=
pan style=3D"color:#000"><br></span><span style=3D"color:#008">auto</span><=
span style=3D"color:#000"> req </span><span style=3D"color:#660">=3D</span>=
<span style=3D"color:#000"> F</span><span style=3D"color:#080">&quot;select=
 {column} from {table};&quot;</span><span style=3D"color:#000">_sql</span><=
span style=3D"color:#660">;</span><span style=3D"color:#000"><br><br></span=
><span style=3D"color:#800">// would be equivalent to:</span><span style=3D=
"color:#000"><br></span><span style=3D"color:#008">auto</span><span style=
=3D"color:#000"> req </span><span style=3D"color:#660">=3D</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#008">operator</span><span st=
yle=3D"color:#000"> </span><span style=3D"color:#080">&quot;&quot;</span><s=
pan style=3D"color:#000">_sql </span><span style=3D"color:#660">(</span><sp=
an style=3D"color:#000">std</span><span style=3D"color:#660">::</span><span=
 style=3D"color:#000">string_processing</span><span style=3D"color:#660">&l=
t;</span><span style=3D"color:#008">const</span><span style=3D"color:#000">=
 </span><span style=3D"color:#008">char</span><span style=3D"color:#660">[<=
/span><span style=3D"color:#066">8</span><span style=3D"color:#660">]&amp;,=
</span><span style=3D"color:#000"> std</span><span style=3D"color:#660">::<=
/span><span style=3D"color:#008">string</span><span style=3D"color:#660">&a=
mp;,</span><span style=3D"color:#000"> </span><span style=3D"color:#008">co=
nst</span><span style=3D"color:#000"> </span><span style=3D"color:#008">cha=
r</span><span style=3D"color:#660">[</span><span style=3D"color:#066">7</sp=
an><span style=3D"color:#660">]&amp;,</span><span style=3D"color:#000"> std=
</span><span style=3D"color:#660">::</span><span style=3D"color:#000">strin=
g_view</span><span style=3D"color:#660">&amp;,</span><span style=3D"color:#=
000"> </span><span style=3D"color:#008">const</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#008">char</span><span style=3D"color:#660=
">[</span><span style=3D"color:#066">2</span><span style=3D"color:#660">]&a=
mp;&gt;(</span><span style=3D"color:#080">&quot;select &quot;</span><span s=
tyle=3D"color:#660">,</span><span style=3D"color:#000"> column</span><span =
style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=
=3D"color:#080">&quot; from &quot;</span><span style=3D"color:#660">,</span=
><span style=3D"color:#000"> table</span><span style=3D"color:#660">,</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"><br=
></span></div></code></div><br>Now let&#39;s have some examples of it could=
 be:<br><br>Simple string concatenation would be simple<br><div style=3D"ba=
ckground-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:=
solid;border-width:1px"><code><div><span style=3D"color:#008">auto</span><s=
pan style=3D"color:#000"> concatenated </span><span style=3D"color:#660">=
=3D</span><span style=3D"color:#000"> F</span><span style=3D"color:#080">&q=
uot;{str1}{str2}{str3}&quot;</span><span style=3D"color:#000">s</span><span=
 style=3D"color:#660">;</span><span style=3D"color:#000"><br></span><span s=
tyle=3D"color:#800">// converted into an efficient concatenation of the 3 s=
trings</span><span style=3D"color:#000"><br></span></div></code></div><br>W=
e could print it into an iostream if we want (but would be here only for co=
nvenience on legacy code)<br><div style=3D"background-color:rgb(250,250,250=
);border-color:rgb(187,187,187);border-style:solid;border-width:1px"><code>=
<div><span style=3D"color:#000">std</span><span style=3D"color:#660">::</sp=
an><span style=3D"color:#000">cout </span><span style=3D"color:#660">&lt;&l=
t;</span><span style=3D"color:#000"> F</span><span style=3D"color:#080">&qu=
ot;{str1}{str2}\n&quot;</span><span style=3D"color:#660">;</span><span styl=
e=3D"color:#000"><br></span><span style=3D"color:#800">// equivalent to:</s=
pan><span style=3D"color:#000"><br>std</span><span style=3D"color:#660">::<=
/span><span style=3D"color:#000">cout </span><span style=3D"color:#660">&lt=
;&lt;</span><span style=3D"color:#000"> str1 </span><span style=3D"color:#6=
60">&lt;&lt;</span><span style=3D"color:#000"> str2 </span><span style=3D"c=
olor:#660">&lt;&lt;</span><span style=3D"color:#000"> </span><span style=3D=
"color:#080">&quot;\n&quot;</span><span style=3D"color:#660">;</span><span =
style=3D"color:#000"><br></span></div></code></div><br>It could be implicit=
ly convertible to a std::string (only if variables are implicitly convertib=
le to std::string)<br><div style=3D"background-color:rgb(250,250,250);borde=
r-color:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><s=
pan style=3D"color:#000">std</span><span style=3D"color:#660">::</span><spa=
n style=3D"color:#008">string</span><span style=3D"color:#000"> concatenate=
d </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> F=
</span><span style=3D"color:#080">&quot;{str1}{str2}&quot;</span><span styl=
e=3D"color:#660">;</span><span style=3D"color:#000"><br></span></div></code=
></div><br>(No example with FMT as I don&#39;t know how it works, but I don=
&#39;t see any reason for it not to be compatible with FMT.)<br><br>And thi=
s would be constexpr-able.<br><br>Now, formatting would require a bit more =
elaborated type that could store formatting information.<br>But in the end,=
 only the user will know what to do with it.<br>However, I would prefer <b>=
not</b> to embed formatting in such a type, just to keep it simple. And use=
 a library based solution when I really need formatting.<br><br>It has all =
the advantages of Nicol&#39;s solution, while being more versatile.<br></di=
v></blockquote><div><br>I fail to see the versatility here, and it does not=
 have all of the advantages of my method.<br><br>Remember, in my version, U=
DLs only apply to the string fragments. In your version, you <i>cannot</i> =
apply UDLs to string fragments; the string fragments will be packed into yo=
ur `string_processing` type as views or some such.<br><br>Then there&#39;s =
ease of use. Let&#39;s see how to implement stream-based string concatenati=
on with my method:<br><br><div style=3D"background-color:rgb(250,250,250);b=
order-color:rgb(187,187,187);border-style:solid;border-width:1px"><code><di=
v><span style=3D"color:#008">template</span><span style=3D"color:#660">&lt;=
</span><span style=3D"color:#008">typename</span><span style=3D"color:#000"=
> </span><span style=3D"color:#660">...</span><span style=3D"color:#606">Ar=
gs</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"><=
br></span><span style=3D"color:#008">auto</span><span style=3D"color:#000">=
 concat</span><span style=3D"color:#660">(</span><span style=3D"color:#606"=
>Args</span><span style=3D"color:#000"> </span><span style=3D"color:#660">.=
...&amp;&amp;</span><span style=3D"color:#000">args</span><span style=3D"col=
or:#660">)</span><span style=3D"color:#000"><br></span><span style=3D"color=
:#660">{</span><span style=3D"color:#000"><br>=C2=A0 std</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">ostringstream stream</s=
pan><span style=3D"color:#660">;</span><span style=3D"color:#000"><br>=C2=
=A0 stream </span><span style=3D"color:#660">&lt;&lt;</span><span style=3D"=
color:#000"> </span><span style=3D"color:#660">...</span><span style=3D"col=
or:#000"> </span><span style=3D"color:#660">&lt;&lt;</span><span style=3D"c=
olor:#000"> std</span><span style=3D"color:#660">::</span><span style=3D"co=
lor:#000">forward</span><span style=3D"color:#660">&lt;</span><span style=
=3D"color:#606">Args</span><span style=3D"color:#660">&gt;(</span><span sty=
le=3D"color:#000">args</span><span style=3D"color:#660">);</span><span styl=
e=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#008">return</span>=
<span style=3D"color:#000"> std</span><span style=3D"color:#660">::</span><=
span style=3D"color:#000">move</span><span style=3D"color:#660">(</span><sp=
an style=3D"color:#000">stream</span><span style=3D"color:#660">).</span><s=
pan style=3D"color:#008">get</span><span style=3D"color:#660">();</span><sp=
an style=3D"color:#000"><br></span><span style=3D"color:#660">}</span></div=
></code></div><br>Simple and obvious, a standard bit of C++17 variadic temp=
late programming.<br><br>Now, how would you go about doing that with `strin=
g_processing`? That would require template metaprogramming:<br><br><div sty=
le=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);borde=
r-style:solid;border-width:1px"><code><div><span style=3D"color:#008">templ=
ate</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">=
typename</span><span style=3D"color:#000"> </span><span style=3D"color:#660=
">...</span><span style=3D"color:#606">Args</span><span style=3D"color:#660=
">,</span><span style=3D"color:#000"> size_t </span><span style=3D"color:#6=
60">...</span><span style=3D"color:#606">Ints</span><span style=3D"color:#6=
60">&gt;</span><span style=3D"color:#000"><br></span><span style=3D"color:#=
008">void</span><span style=3D"color:#000"> concat_items</span><span style=
=3D"color:#660">(</span><span style=3D"color:#000">std</span><span style=3D=
"color:#660">::</span><span style=3D"color:#000">ostringstrea<wbr>m </span>=
<span style=3D"color:#660">&amp;</span><span style=3D"color:#000">stream</s=
pan><span style=3D"color:#660">,</span><span style=3D"color:#000"> std</spa=
n><span style=3D"color:#660">::</span><span style=3D"color:#000">string_pro=
cessing</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#6=
06">Args</span><span style=3D"color:#660">...<wbr>&gt;</span><span style=3D=
"color:#000"> </span><span style=3D"color:#660">&amp;&amp;</span><span styl=
e=3D"color:#000">proc</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">index_sequence</span><span style=3D"color:#660">&lt;</span>=
<span style=3D"color:#606">Ints</span><span style=3D"color:#660">...&gt;)</=
span><span style=3D"color:#000"><br></span><span style=3D"color:#660">{</sp=
an><span style=3D"color:#000"><br>=C2=A0 stream </span><span style=3D"color=
:#660">&lt;&lt;</span><span style=3D"color:#000"> </span><span style=3D"col=
or:#660">...</span><span style=3D"color:#000"> </span><span style=3D"color:=
#660">&lt;&lt;</span><span style=3D"color:#000"> </span><span style=3D"colo=
r:#008">get</span><span style=3D"color:#660">&lt;</span><span style=3D"colo=
r:#606">Ints</span><span style=3D"color:#660">&gt;(</span><span style=3D"co=
lor:#000">proc</span><span style=3D"color:#660">));</span><span style=3D"co=
lor:#000"><br></span><span style=3D"color:#660">}</span><span style=3D"colo=
r:#000"><br><br></span><span style=3D"color:#008">template</span><span styl=
e=3D"color:#660">&lt;</span><span style=3D"color:#008">typename</span><span=
 style=3D"color:#000"> </span><span style=3D"color:#660">...</span><span st=
yle=3D"color:#606">Args</span><span style=3D"color:#660">&gt;</span><span s=
tyle=3D"color:#000"><br></span><span style=3D"color:#008">auto</span><span =
style=3D"color:#000"> concat</span><span style=3D"color:#660">(</span><span=
 style=3D"color:#000">std</span><span style=3D"color:#660">::</span><span s=
tyle=3D"color:#000">string_processing</span><span style=3D"color:#660">&lt;=
</span><span style=3D"color:#606"><wbr>Args</span><span style=3D"color:#660=
">...&gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#66=
0">&amp;&amp;</span><span style=3D"color:#000">proc</span><span style=3D"co=
lor:#660">)</span><span style=3D"color:#000"><br></span><span style=3D"colo=
r:#660">{</span><span style=3D"color:#000"><br>=C2=A0 std</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">ostringstream stream</s=
pan><span style=3D"color:#660">;</span><span style=3D"color:#000"><br>=C2=
=A0 concat_items</span><span style=3D"color:#660">(</span><span style=3D"co=
lor:#000">stream</span><span style=3D"color:#660">,</span><span style=3D"co=
lor:#000"> std</span><span style=3D"color:#660">::</span><span style=3D"col=
or:#000">move</span><span style=3D"color:#660">(</span><span style=3D"color=
:#000">proc</span><span style=3D"color:#660">),</span><span style=3D"color:=
#000"> std</span><span style=3D"color:#660">::</span><span style=3D"color:#=
000">make_index_sequence</span><span style=3D"color:#660">&lt;</span><span =
style=3D"color:#000">size</span><span style=3D"color:#660">.<wbr>..(</span>=
<span style=3D"color:#606">Args</span><span style=3D"color:#660">)&gt;{});<=
/span><span style=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#00=
8">return</span><span style=3D"color:#000"> std</span><span style=3D"color:=
#660">::</span><span style=3D"color:#000">move</span><span style=3D"color:#=
660">(</span><span style=3D"color:#000">stream</span><span style=3D"color:#=
660">).</span><span style=3D"color:#008">get</span><span style=3D"color:#66=
0">();</span><span style=3D"color:#000"><br></span><span style=3D"color:#66=
0">}</span></div></code></div><br>This isn&#39;t the hardest code to write =
in the world, but it is much more complex than the previous one. Also, perf=
ect forwarding doesn&#39;t really work here.<br><br>Also, the variadic vers=
ion of `concat` can be used with stuff that isn&#39;t the result of string =
interpolation. Or with multiple interpolated strings. And so forth. Whereas=
 your `string_processing` type is a magic type that only the compiler can c=
reate. And we already have a type that does what `string_processing` does; =
it&#39;s called `tuple`.<br><br>The <i>only advantage</i> your method has o=
ver mine is that it allows UDLs to define the aggregation operation. Why is=
 this so important to so many people?<br></div><br></div></blockquote><div>=
<br></div><br><div>Well, my solution is more versatile in the following sen=
se: the=20
result is a plain object that can be stored in a variable, returned from
 a function.</div></div></blockquote><div><br><div style=3D"background-colo=
r: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: soli=
d; border-width: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><co=
de class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color=
: #000;" class=3D"styled-by-prettify">tuple</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">F</span><span style=3D"color: #080;" class=3D"style=
d-by-prettify">&quot;interpolated {string}&quot;</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">)</span></div></code></div><br>Oh loo=
k, &quot;a plain object that can be stored in a variable, returned from
 a function&quot;. It required a whole 7 characters more.<br><br>&quot;Vers=
atility&quot; typically refers to the ability to do more things with someth=
ing. My way can be put into an object, but your way cannot be put into a fu=
nction&#39;s parameters as separate values nearly as easily. Mine seems mor=
e versatile.<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>You could envision functions to transform std::string_pro=
cessing into another std::string_processing easily.</div><div><br></div><di=
v>Moreover, I know that some proposals try to enable creating a parameter p=
ack from a tuple (like an operator... ).</div></div></blockquote><div><br>A=
nd sadly, none of them have advanced or even received additional revised pr=
oposals. My way works just fine with C++ as it is.<br><br>And even if we ha=
d that, most use-cases you don&#39;t need to pass the values around as a co=
llective object. And if you did, you can make one trivially, as above.<br><=
br>And again, it still doesn&#39;t deal with the fact that you lose perfect=
 forwarding.<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>With that in mind, the implementation of your concat func=
tion with my approach would be exactly the same as with your approach (with=
 a call to &quot;operator...&quot; of std::string_processing ).</div><div><=
br></div><div>And then, with only c++17 metaprogramming capabilities, you c=
ould also use std::apply.<br></div></div></blockquote><div><br>You cannot `=
apply` things to operators. Not without creating a lambda function that get=
s called with it.<br><br>The fact is, it&#39;s a <i>lot</i> easier in C++ a=
s it currently stands to go from parameter pack of values to an object than=
 it is to go from an object to a parameter pack of values. I wish that were=
 not the case, but so long as it is the case, parameter packs will remain t=
he easier-to-use option.<br><br></div><blockquote class=3D"gmail_quote" sty=
le=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left=
: 1ex;"><div dir=3D"ltr"><div></div><div></div>UDL the aggregate is not imp=
ortant to me, but it was easy to include and allows neat syntax (in my opin=
ion).<br></div></blockquote><div><br>But it makes it impossible to apply a =
UDL to the string fragments. And that&#39;s important if you do want to use=
 template metaprogramming on string literals.<br><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/5c51d89a-54b6-490b-87f2-09ed263d8322%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/5c51d89a-54b6-490b-87f2-09ed263d8322=
%40isocpp.org</a>.<br />

------=_Part_9610_952126848.1518450341501--

------=_Part_9609_446297566.1518450341499--

.


Author: florian.csdt@gmail.com
Date: Mon, 12 Feb 2018 08:15:33 -0800 (PST)
Raw View
------=_Part_9940_1758140889.1518452133069
Content-Type: multipart/alternative;
 boundary="----=_Part_9941_2001226193.1518452133071"

------=_Part_9941_2001226193.1518452133071
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



Le lundi 12 f=C3=A9vrier 2018 16:45:41 UTC+1, Nicol Bolas a =C3=A9crit :
>
> On Monday, February 12, 2018 at 10:14:25 AM UTC-5, floria...@gmail.com=20
> wrote:
>>
>> Le lundi 12 f=C3=A9vrier 2018 15:56:12 UTC+1, Nicol Bolas a =C3=A9crit :
>>>
>>> On Monday, February 12, 2018 at 5:17:45 AM UTC-5, floria...@gmail.com=
=20
>>> wrote:
>>>>
>>>> Let me suggest something close to Nicol's solution, but not quite.
>>>>
>>>> The F"" operator returns a special type that could be like a simple=20
>>>> tuple (let's name it std::string_processing for now).
>>>>
>>>> Then the user can use it directly into its own functions.
>>>>
>>>>
>>>> auto column =3D "col"s;
>>>> auto table =3D "tab"sv;
>>>> auto req =3D sql(F"select {column} from {table};");
>>>>
>>>> // would be equivalent to:
>>>> auto req =3D sql(std::string_processing<const char[8]&, std::string&,=
=20
>>>> const char[7]&, std::string_view&, const char[2]&>("select ", column, =
"=20
>>>> from ", table, ";"));
>>>>
>>>> Now, if we want, we could also support UDL (but not mandatory) by=20
>>>> allowing to call UDL on the std::string_processing:
>>>>
>>>> auto column =3D "col"s;
>>>> auto table =3D "tab"sv;
>>>> auto req =3D F"select {column} from {table};"_sql;
>>>>
>>>> // would be equivalent to:
>>>> auto req =3D operator ""_sql (std::string_processing<const char[8]&, s=
td
>>>> ::string&, const char[7]&, std::string_view&, const char[2]&>("select =
"
>>>> , column, " from ", table, ";"));
>>>>
>>>> Now let's have some examples of it could be:
>>>>
>>>> Simple string concatenation would be simple
>>>> auto concatenated =3D F"{str1}{str2}{str3}"s;
>>>> // converted into an efficient concatenation of the 3 strings
>>>>
>>>> We could print it into an iostream if we want (but would be here only=
=20
>>>> for convenience on legacy code)
>>>> std::cout << F"{str1}{str2}\n";
>>>> // equivalent to:
>>>> std::cout << str1 << str2 << "\n";
>>>>
>>>> It could be implicitly convertible to a std::string (only if variables=
=20
>>>> are implicitly convertible to std::string)
>>>> std::string concatenated =3D F"{str1}{str2}";
>>>>
>>>> (No example with FMT as I don't know how it works, but I don't see any=
=20
>>>> reason for it not to be compatible with FMT.)
>>>>
>>>> And this would be constexpr-able.
>>>>
>>>> Now, formatting would require a bit more elaborated type that could=20
>>>> store formatting information.
>>>> But in the end, only the user will know what to do with it.
>>>> However, I would prefer *not* to embed formatting in such a type, just=
=20
>>>> to keep it simple. And use a library based solution when I really need=
=20
>>>> formatting.
>>>>
>>>> It has all the advantages of Nicol's solution, while being more=20
>>>> versatile.
>>>>
>>>
>>> I fail to see the versatility here, and it does not have all of the=20
>>> advantages of my method.
>>>
>>> Remember, in my version, UDLs only apply to the string fragments. In=20
>>> your version, you *cannot* apply UDLs to string fragments; the string=
=20
>>> fragments will be packed into your `string_processing` type as views or=
=20
>>> some such.
>>>
>>> Then there's ease of use. Let's see how to implement stream-based strin=
g=20
>>> concatenation with my method:
>>>
>>> template<typename ...Args>
>>> auto concat(Args ...&&args)
>>> {
>>>   std::ostringstream stream;
>>>   stream << ... << std::forward<Args>(args);
>>>   return std::move(stream).get();
>>> }
>>>
>>> Simple and obvious, a standard bit of C++17 variadic template=20
>>> programming.
>>>
>>> Now, how would you go about doing that with `string_processing`? That=
=20
>>> would require template metaprogramming:
>>>
>>> template<typename ...Args, size_t ...Ints>
>>> void concat_items(std::ostringstream &stream, std::string_processing<
>>> Args...> &&proc, std::index_sequence<Ints...>)
>>> {
>>>   stream << ... << get<Ints>(proc));
>>> }
>>>
>>> template<typename ...Args>
>>> auto concat(std::string_processing<Args...> &&proc)
>>> {
>>>   std::ostringstream stream;
>>>   concat_items(stream, std::move(proc), std::make_index_sequence<size
>>> ...(Args)>{});
>>>   return std::move(stream).get();
>>> }
>>>
>>> This isn't the hardest code to write in the world, but it is much more=
=20
>>> complex than the previous one. Also, perfect forwarding doesn't really =
work=20
>>> here.
>>>
>>> Also, the variadic version of `concat` can be used with stuff that isn'=
t=20
>>> the result of string interpolation. Or with multiple interpolated strin=
gs.=20
>>> And so forth. Whereas your `string_processing` type is a magic type tha=
t=20
>>> only the compiler can create. And we already have a type that does what=
=20
>>> `string_processing` does; it's called `tuple`.
>>>
>>> The *only advantage* your method has over mine is that it allows UDLs=
=20
>>> to define the aggregation operation. Why is this so important to so man=
y=20
>>> people?
>>>
>>>
>>
>> Well, my solution is more versatile in the following sense: the result i=
s=20
>> a plain object that can be stored in a variable, returned from a functio=
n.
>>
>
> tuple(F"interpolated {string}")
>
> Oh look, "a plain object that can be stored in a variable, returned from =
a=20
> function". It required a whole 7 characters more.
>
> "Versatility" typically refers to the ability to do more things with=20
> something. My way can be put into an object, but your way cannot be put=
=20
> into a function's parameters as separate values nearly as easily. Mine=20
> seems more versatile.
>
> You could envision functions to transform std::string_processing into=20
>> another std::string_processing easily.
>>
>> Moreover, I know that some proposals try to enable creating a parameter=
=20
>> pack from a tuple (like an operator... ).
>>
>
> And sadly, none of them have advanced or even received additional revised=
=20
> proposals. My way works just fine with C++ as it is.
>
> And even if we had that, most use-cases you don't need to pass the values=
=20
> around as a collective object. And if you did, you can make one trivially=
,=20
> as above.
>
> And again, it still doesn't deal with the fact that you lose perfect=20
> forwarding.
>
=20
I understand your point about creating a tuple from a parameter pack to be=
=20
able to do what is natural with my proposal. Fair enough.

However, I don't see how we lose perfect forwarding. I mean, if the=20
variable is a lvalue, it is stored as an lvalue reference, and if it is a=
=20
rvalue, it is stored as an rvalue reference.
This would be the exact same rules as for std::forward_as_tuple.


> With that in mind, the implementation of your concat function with my=20
>> approach would be exactly the same as with your approach (with a call to=
=20
>> "operator..." of std::string_processing ).
>>
>> And then, with only c++17 metaprogramming capabilities, you could also=
=20
>> use std::apply.
>>
>
> You cannot `apply` things to operators. Not without creating a lambda=20
> function that gets called with it.
>
=20
Why not? You can get the address of an operator, and this is a callable=20
object.


> The fact is, it's a *lot* easier in C++ as it currently stands to go from=
=20
> parameter pack of values to an object than it is to go from an object to =
a=20
> parameter pack of values. I wish that were not the case, but so long as i=
t=20
> is the case, parameter packs will remain the easier-to-use option.
>
=20
You have a point.=20


> UDL the aggregate is not important to me, but it was easy to include and=
=20
>> allows neat syntax (in my opinion).
>>
>
> But it makes it impossible to apply a UDL to the string fragments. And=20
> that's important if you do want to use template metaprogramming on string=
=20
> literals.
>

I'm not sure to see the use case here. When you use UDL, you want the whole=
=20
literal to be what you say it would be.
auto s =3D "something"s; // s is a string
auto sv =3D "some other"sv; // s is a string view
We are not interested in what is happening in the middle. I don't why it=20
should be different with string interpolation (or whatever the name is).

And with my proposal, you can always apply a function to every single=20
element, and this function can be a UDL if you really want.


To sum up, F"something" returning a parameter pack is probably the way to=
=20
go because of the current C++, but would not bring that much with a proper=
=20
C++.
And then, I think UDL should apply to the whole stuff and not its part.

Assuming operator F"" returns a parameter pack:
auto s =3D F"{args}..."s;
// equivalent to:
auto s =3D operator ""s(args...);

// If you want to apply a UDL to part of it:
operator ""s(F"{args}...")...
// would be equiavlent to:
operator ""s(args)...

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/305b7669-0744-473e-9715-807b7e8051b6%40isocpp.or=
g.

------=_Part_9941_2001226193.1518452133071
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le lundi 12 f=C3=A9vrier 2018 16:45:41 UTC+1, Nico=
l Bolas a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v dir=3D"ltr">On Monday, February 12, 2018 at 10:14:25 AM UTC-5, <a>floria.=
...@gmail.com</a> 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">Le lundi 12 f=C3=A9vrier 2018 15:56:12 UTC+1, Nicol Bolas a =C3=A9crit=
=C2=A0:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Monday, =
February 12, 2018 at 5:17:45 AM UTC-5, <a>floria...@gmail.com</a> wrote:<bl=
ockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">Let me suggest someth=
ing close to Nicol&#39;s solution, but not quite.<br><br>The F&quot;&quot; =
operator returns a special type that could be like a simple tuple (let&#39;=
s name it std::string_processing for now).<br><br>Then the user can use it =
directly into its own functions.<br><br><br><div style=3D"background-color:=
rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-wi=
dth:1px"><code><div><span style=3D"color:#008">auto</span><span style=3D"co=
lor:#000"> column </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> </span><span style=3D"color:#080">&quot;col&quot;</span><s=
pan style=3D"color:#000">s</span><span style=3D"color:#660">;</span><span s=
tyle=3D"color:#000"><br></span><span style=3D"color:#008">auto</span><span =
style=3D"color:#000"> table </span><span style=3D"color:#660">=3D</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#080">&quot;tab&quot;<=
/span><span style=3D"color:#000">sv</span><span style=3D"color:#660">;</spa=
n><span style=3D"color:#000"><br></span><span style=3D"color:#008">auto</sp=
an><span style=3D"color:#000"> req </span><span style=3D"color:#660">=3D</s=
pan><span style=3D"color:#000"> sql</span><span style=3D"color:#660">(</spa=
n><span style=3D"color:#000">F</span><span style=3D"color:#080">&quot;selec=
t {column} from {table};&quot;</span><span style=3D"color:#660">);</span><s=
pan style=3D"color:#000"><br><br></span><span style=3D"color:#800">// would=
 be equivalent to:</span><span style=3D"color:#000"><br></span><span style=
=3D"color:#008">auto</span><span style=3D"color:#000"> req </span><span sty=
le=3D"color:#660">=3D</span><span style=3D"color:#000"> sql</span><span sty=
le=3D"color:#660">(</span><span style=3D"color:#000">std</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">string_processing</span=
><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">con<wbr>s=
t</span><span style=3D"color:#000"> </span><span style=3D"color:#008">char<=
/span><span style=3D"color:#660">[</span><span style=3D"color:#066">8</span=
><span style=3D"color:#660">]&amp;,</span><span style=3D"color:#000"> std</=
span><span style=3D"color:#660">::</span><span style=3D"color:#008">string<=
/span><span style=3D"color:#660">&amp;,</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#008">const</span><span style=3D"color:#000"> </=
span><span style=3D"color:#008">char</span><span style=3D"color:#660">[</sp=
an><span style=3D"color:#066">7</span><span style=3D"color:#660">]&amp;,</s=
pan><span style=3D"color:#000"> std</span><span style=3D"color:#660">::</sp=
an><span style=3D"color:#000">string_view</span><span style=3D"color:#660">=
&amp;,</span><span style=3D"color:#000"> </span><span style=3D"color:#008">=
const</span><span style=3D"color:#000"> </span><span style=3D"color:#008">c=
har</span><span style=3D"color:#660">[</span><span style=3D"color:#066">2</=
span><span style=3D"color:#660">]&amp;&gt;(</span><span style=3D"color:#080=
">&quot;select &quot;</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> column</span><span style=3D"color:#660">,</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#080">&quot; from &quot;</spa=
n><span style=3D"color:#660">,</span><span style=3D"color:#000"> table</spa=
n><span style=3D"color:#660">,</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#080">&quot;;&quot;</span><span style=3D"color:#660">));<=
/span><span style=3D"color:#000"><br></span></div></code></div><br>Now, if =
we want, we could also support UDL (but not mandatory) by allowing to call =
UDL on the std::string_processing:<br><br><div style=3D"background-color:rg=
b(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-widt=
h:1px"><code><div><span style=3D"color:#008">auto</span><span style=3D"colo=
r:#000"> column </span><span style=3D"color:#660">=3D</span><span style=3D"=
color:#000"> </span><span style=3D"color:#080">&quot;col&quot;</span><span =
style=3D"color:#000">s</span><span style=3D"color:#660">;</span><span style=
=3D"color:#000"><br></span><span style=3D"color:#008">auto</span><span styl=
e=3D"color:#000"> table </span><span style=3D"color:#660">=3D</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#080">&quot;tab&quot;</spa=
n><span style=3D"color:#000">sv</span><span style=3D"color:#660">;</span><s=
pan style=3D"color:#000"><br></span><span style=3D"color:#008">auto</span><=
span style=3D"color:#000"> req </span><span style=3D"color:#660">=3D</span>=
<span style=3D"color:#000"> F</span><span style=3D"color:#080">&quot;select=
 {column} from {table};&quot;</span><span style=3D"color:#000">_sql</span><=
span style=3D"color:#660">;</span><span style=3D"color:#000"><br><br></span=
><span style=3D"color:#800">// would be equivalent to:</span><span style=3D=
"color:#000"><br></span><span style=3D"color:#008">auto</span><span style=
=3D"color:#000"> req </span><span style=3D"color:#660">=3D</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#008">operator</span><span st=
yle=3D"color:#000"> </span><span style=3D"color:#080">&quot;&quot;</span><s=
pan style=3D"color:#000">_sql </span><span style=3D"color:#660">(</span><sp=
an style=3D"color:#000">std</span><span style=3D"color:#660">::</span><span=
 style=3D"color:#000">string_processing</span><span style=3D"color:#660">&l=
t;</span><span style=3D"color:#008">const</span><span style=3D"color:#000">=
 </span><span style=3D"color:#008">char</span><span style=3D"color:#660">[<=
/span><span style=3D"color:#066">8</span><span style=3D"color:#660">]&amp;,=
</span><span style=3D"color:#000"> std</span><span style=3D"color:#660">::<=
/span><span style=3D"color:#008">string</span><span style=3D"color:#660">&a=
mp;,</span><span style=3D"color:#000"> </span><span style=3D"color:#008">co=
nst</span><span style=3D"color:#000"> </span><span style=3D"color:#008">cha=
r</span><span style=3D"color:#660">[</span><span style=3D"color:#066">7</sp=
an><span style=3D"color:#660">]&amp;,</span><span style=3D"color:#000"> std=
</span><span style=3D"color:#660">::</span><span style=3D"color:#000">strin=
g_view</span><span style=3D"color:#660">&amp;,</span><span style=3D"color:#=
000"> </span><span style=3D"color:#008">const</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#008">char</span><span style=3D"color:#660=
">[</span><span style=3D"color:#066">2</span><span style=3D"color:#660">]&a=
mp;&gt;(</span><span style=3D"color:#080">&quot;select &quot;</span><span s=
tyle=3D"color:#660">,</span><span style=3D"color:#000"> column</span><span =
style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=
=3D"color:#080">&quot; from &quot;</span><span style=3D"color:#660">,</span=
><span style=3D"color:#000"> table</span><span style=3D"color:#660">,</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"><br=
></span></div></code></div><br>Now let&#39;s have some examples of it could=
 be:<br><br>Simple string concatenation would be simple<br><div style=3D"ba=
ckground-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:=
solid;border-width:1px"><code><div><span style=3D"color:#008">auto</span><s=
pan style=3D"color:#000"> concatenated </span><span style=3D"color:#660">=
=3D</span><span style=3D"color:#000"> F</span><span style=3D"color:#080">&q=
uot;{str1}{str2}{str3}&quot;</span><span style=3D"color:#000">s</span><span=
 style=3D"color:#660">;</span><span style=3D"color:#000"><br></span><span s=
tyle=3D"color:#800">// converted into an efficient concatenation of the 3 s=
trings</span><span style=3D"color:#000"><br></span></div></code></div><br>W=
e could print it into an iostream if we want (but would be here only for co=
nvenience on legacy code)<br><div style=3D"background-color:rgb(250,250,250=
);border-color:rgb(187,187,187);border-style:solid;border-width:1px"><code>=
<div><span style=3D"color:#000">std</span><span style=3D"color:#660">::</sp=
an><span style=3D"color:#000">cout </span><span style=3D"color:#660">&lt;&l=
t;</span><span style=3D"color:#000"> F</span><span style=3D"color:#080">&qu=
ot;{str1}{str2}\n&quot;</span><span style=3D"color:#660">;</span><span styl=
e=3D"color:#000"><br></span><span style=3D"color:#800">// equivalent to:</s=
pan><span style=3D"color:#000"><br>std</span><span style=3D"color:#660">::<=
/span><span style=3D"color:#000">cout </span><span style=3D"color:#660">&lt=
;&lt;</span><span style=3D"color:#000"> str1 </span><span style=3D"color:#6=
60">&lt;&lt;</span><span style=3D"color:#000"> str2 </span><span style=3D"c=
olor:#660">&lt;&lt;</span><span style=3D"color:#000"> </span><span style=3D=
"color:#080">&quot;\n&quot;</span><span style=3D"color:#660">;</span><span =
style=3D"color:#000"><br></span></div></code></div><br>It could be implicit=
ly convertible to a std::string (only if variables are implicitly convertib=
le to std::string)<br><div style=3D"background-color:rgb(250,250,250);borde=
r-color:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><s=
pan style=3D"color:#000">std</span><span style=3D"color:#660">::</span><spa=
n style=3D"color:#008">string</span><span style=3D"color:#000"> concatenate=
d </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> F=
</span><span style=3D"color:#080">&quot;{str1}{str2}&quot;</span><span styl=
e=3D"color:#660">;</span><span style=3D"color:#000"><br></span></div></code=
></div><br>(No example with FMT as I don&#39;t know how it works, but I don=
&#39;t see any reason for it not to be compatible with FMT.)<br><br>And thi=
s would be constexpr-able.<br><br>Now, formatting would require a bit more =
elaborated type that could store formatting information.<br>But in the end,=
 only the user will know what to do with it.<br>However, I would prefer <b>=
not</b> to embed formatting in such a type, just to keep it simple. And use=
 a library based solution when I really need formatting.<br><br>It has all =
the advantages of Nicol&#39;s solution, while being more versatile.<br></di=
v></blockquote><div><br>I fail to see the versatility here, and it does not=
 have all of the advantages of my method.<br><br>Remember, in my version, U=
DLs only apply to the string fragments. In your version, you <i>cannot</i> =
apply UDLs to string fragments; the string fragments will be packed into yo=
ur `string_processing` type as views or some such.<br><br>Then there&#39;s =
ease of use. Let&#39;s see how to implement stream-based string concatenati=
on with my method:<br><br><div style=3D"background-color:rgb(250,250,250);b=
order-color:rgb(187,187,187);border-style:solid;border-width:1px"><code><di=
v><span style=3D"color:#008">template</span><span style=3D"color:#660">&lt;=
</span><span style=3D"color:#008">typename</span><span style=3D"color:#000"=
> </span><span style=3D"color:#660">...</span><span style=3D"color:#606">Ar=
gs</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"><=
br></span><span style=3D"color:#008">auto</span><span style=3D"color:#000">=
 concat</span><span style=3D"color:#660">(</span><span style=3D"color:#606"=
>Args</span><span style=3D"color:#000"> </span><span style=3D"color:#660">.=
...&amp;&amp;</span><span style=3D"color:#000">args</span><span style=3D"col=
or:#660">)</span><span style=3D"color:#000"><br></span><span style=3D"color=
:#660">{</span><span style=3D"color:#000"><br>=C2=A0 std</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">ostringstream stream</s=
pan><span style=3D"color:#660">;</span><span style=3D"color:#000"><br>=C2=
=A0 stream </span><span style=3D"color:#660">&lt;&lt;</span><span style=3D"=
color:#000"> </span><span style=3D"color:#660">...</span><span style=3D"col=
or:#000"> </span><span style=3D"color:#660">&lt;&lt;</span><span style=3D"c=
olor:#000"> std</span><span style=3D"color:#660">::</span><span style=3D"co=
lor:#000">forward</span><span style=3D"color:#660">&lt;</span><span style=
=3D"color:#606">Args</span><span style=3D"color:#660">&gt;(</span><span sty=
le=3D"color:#000">args</span><span style=3D"color:#660">);</span><span styl=
e=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#008">return</span>=
<span style=3D"color:#000"> std</span><span style=3D"color:#660">::</span><=
span style=3D"color:#000">move</span><span style=3D"color:#660">(</span><sp=
an style=3D"color:#000">stream</span><span style=3D"color:#660">).</span><s=
pan style=3D"color:#008">get</span><span style=3D"color:#660">();</span><sp=
an style=3D"color:#000"><br></span><span style=3D"color:#660">}</span></div=
></code></div><br>Simple and obvious, a standard bit of C++17 variadic temp=
late programming.<br><br>Now, how would you go about doing that with `strin=
g_processing`? That would require template metaprogramming:<br><br><div sty=
le=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);borde=
r-style:solid;border-width:1px"><code><div><span style=3D"color:#008">templ=
ate</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">=
typename</span><span style=3D"color:#000"> </span><span style=3D"color:#660=
">...</span><span style=3D"color:#606">Args</span><span style=3D"color:#660=
">,</span><span style=3D"color:#000"> size_t </span><span style=3D"color:#6=
60">...</span><span style=3D"color:#606">Ints</span><span style=3D"color:#6=
60">&gt;</span><span style=3D"color:#000"><br></span><span style=3D"color:#=
008">void</span><span style=3D"color:#000"> concat_items</span><span style=
=3D"color:#660">(</span><span style=3D"color:#000">std</span><span style=3D=
"color:#660">::</span><span style=3D"color:#000">ostringstrea<wbr>m </span>=
<span style=3D"color:#660">&amp;</span><span style=3D"color:#000">stream</s=
pan><span style=3D"color:#660">,</span><span style=3D"color:#000"> std</spa=
n><span style=3D"color:#660">::</span><span style=3D"color:#000">string_pro=
cessing</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#6=
06">Args</span><span style=3D"color:#660">...<wbr>&gt;</span><span style=3D=
"color:#000"> </span><span style=3D"color:#660">&amp;&amp;</span><span styl=
e=3D"color:#000">proc</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">index_sequence</span><span style=3D"color:#660">&lt;</span>=
<span style=3D"color:#606">Ints</span><span style=3D"color:#660">...&gt;)</=
span><span style=3D"color:#000"><br></span><span style=3D"color:#660">{</sp=
an><span style=3D"color:#000"><br>=C2=A0 stream </span><span style=3D"color=
:#660">&lt;&lt;</span><span style=3D"color:#000"> </span><span style=3D"col=
or:#660">...</span><span style=3D"color:#000"> </span><span style=3D"color:=
#660">&lt;&lt;</span><span style=3D"color:#000"> </span><span style=3D"colo=
r:#008">get</span><span style=3D"color:#660">&lt;</span><span style=3D"colo=
r:#606">Ints</span><span style=3D"color:#660">&gt;(</span><span style=3D"co=
lor:#000">proc</span><span style=3D"color:#660">));</span><span style=3D"co=
lor:#000"><br></span><span style=3D"color:#660">}</span><span style=3D"colo=
r:#000"><br><br></span><span style=3D"color:#008">template</span><span styl=
e=3D"color:#660">&lt;</span><span style=3D"color:#008">typename</span><span=
 style=3D"color:#000"> </span><span style=3D"color:#660">...</span><span st=
yle=3D"color:#606">Args</span><span style=3D"color:#660">&gt;</span><span s=
tyle=3D"color:#000"><br></span><span style=3D"color:#008">auto</span><span =
style=3D"color:#000"> concat</span><span style=3D"color:#660">(</span><span=
 style=3D"color:#000">std</span><span style=3D"color:#660">::</span><span s=
tyle=3D"color:#000">string_processing</span><span style=3D"color:#660">&lt;=
</span><span style=3D"color:#606"><wbr>Args</span><span style=3D"color:#660=
">...&gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#66=
0">&amp;&amp;</span><span style=3D"color:#000">proc</span><span style=3D"co=
lor:#660">)</span><span style=3D"color:#000"><br></span><span style=3D"colo=
r:#660">{</span><span style=3D"color:#000"><br>=C2=A0 std</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">ostringstream stream</s=
pan><span style=3D"color:#660">;</span><span style=3D"color:#000"><br>=C2=
=A0 concat_items</span><span style=3D"color:#660">(</span><span style=3D"co=
lor:#000">stream</span><span style=3D"color:#660">,</span><span style=3D"co=
lor:#000"> std</span><span style=3D"color:#660">::</span><span style=3D"col=
or:#000">move</span><span style=3D"color:#660">(</span><span style=3D"color=
:#000">proc</span><span style=3D"color:#660">),</span><span style=3D"color:=
#000"> std</span><span style=3D"color:#660">::</span><span style=3D"color:#=
000">make_index_sequence</span><span style=3D"color:#660">&lt;</span><span =
style=3D"color:#000">size</span><span style=3D"color:#660">.<wbr>..(</span>=
<span style=3D"color:#606">Args</span><span style=3D"color:#660">)&gt;{});<=
/span><span style=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#00=
8">return</span><span style=3D"color:#000"> std</span><span style=3D"color:=
#660">::</span><span style=3D"color:#000">move</span><span style=3D"color:#=
660">(</span><span style=3D"color:#000">stream</span><span style=3D"color:#=
660">).</span><span style=3D"color:#008">get</span><span style=3D"color:#66=
0">();</span><span style=3D"color:#000"><br></span><span style=3D"color:#66=
0">}</span></div></code></div><br>This isn&#39;t the hardest code to write =
in the world, but it is much more complex than the previous one. Also, perf=
ect forwarding doesn&#39;t really work here.<br><br>Also, the variadic vers=
ion of `concat` can be used with stuff that isn&#39;t the result of string =
interpolation. Or with multiple interpolated strings. And so forth. Whereas=
 your `string_processing` type is a magic type that only the compiler can c=
reate. And we already have a type that does what `string_processing` does; =
it&#39;s called `tuple`.<br><br>The <i>only advantage</i> your method has o=
ver mine is that it allows UDLs to define the aggregation operation. Why is=
 this so important to so many people?<br></div><br></div></blockquote><div>=
<br></div><br><div>Well, my solution is more versatile in the following sen=
se: the=20
result is a plain object that can be stored in a variable, returned from
 a function.</div></div></blockquote><div><br><div style=3D"background-colo=
r:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-=
width:1px"><code><div><span style=3D"color:#000">tuple</span><span style=3D=
"color:#660">(</span><span style=3D"color:#000">F</span><span style=3D"colo=
r:#080">&quot;interpolated {string}&quot;</span><span style=3D"color:#660">=
)</span></div></code></div><br>Oh look, &quot;a plain object that can be st=
ored in a variable, returned from
 a function&quot;. It required a whole 7 characters more.<br><br>&quot;Vers=
atility&quot; typically refers to the ability to do more things with someth=
ing. My way can be put into an object, but your way cannot be put into a fu=
nction&#39;s parameters as separate values nearly as easily. Mine seems mor=
e versatile.<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>You could envision functions to transform std::string_process=
ing into another std::string_processing easily.</div><div><br></div><div>Mo=
reover, I know that some proposals try to enable creating a parameter pack =
from a tuple (like an operator... ).</div></div></blockquote><div><br>And s=
adly, none of them have advanced or even received additional revised propos=
als. My way works just fine with C++ as it is.<br><br>And even if we had th=
at, most use-cases you don&#39;t need to pass the values around as a collec=
tive object. And if you did, you can make one trivially, as above.<br><br>A=
nd again, it still doesn&#39;t deal with the fact that you lose perfect for=
warding.<br></div></div></blockquote><div>=C2=A0</div><div>I understand you=
r point about creating a tuple from a parameter pack to be able to do what =
is natural with my proposal. Fair enough.</div><div><br></div><div>However,=
 I don&#39;t see how we lose perfect forwarding. I mean, if the variable is=
 a lvalue, it is stored as an lvalue reference, and if it is a rvalue, it i=
s stored as an rvalue reference.</div><div>This would be the exact same rul=
es as for std::forward_as_tuple.</div><div> <br></div><blockquote class=3D"=
gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc so=
lid;padding-left: 1ex;"><div dir=3D"ltr"><div><br></div><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>With that in mind, the impleme=
ntation of your concat function with my approach would be exactly the same =
as with your approach (with a call to &quot;operator...&quot; of std::strin=
g_processing ).</div><div><br></div><div>And then, with only c++17 metaprog=
ramming capabilities, you could also use std::apply.<br></div></div></block=
quote><div><br>You cannot `apply` things to operators. Not without creating=
 a lambda function that gets called with it.<br></div></div></blockquote><d=
iv>=C2=A0</div><div>Why not? You can get the address of an operator, and th=
is is a callable object.</div><div><br></div><blockquote class=3D"gmail_quo=
te" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddi=
ng-left: 1ex;"><div dir=3D"ltr"><div><br>The fact is, it&#39;s a <i>lot</i>=
 easier in C++ as it currently stands to go from parameter pack of values t=
o an object than it is to go from an object to a parameter pack of values. =
I wish that were not the case, but so long as it is the case, parameter pac=
ks will remain the easier-to-use option.<br></div></div></blockquote><div>=
=C2=A0</div><div>You have a point. <br></div><div><br></div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #=
ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><br></div><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #c=
cc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><div></div>UDL the a=
ggregate is not important to me, but it was easy to include and allows neat=
 syntax (in my opinion).<br></div></blockquote><div><br>But it makes it imp=
ossible to apply a UDL to the string fragments. And that&#39;s important if=
 you do want to use template metaprogramming on string literals.<br></div><=
/div></blockquote><div><br></div><div>I&#39;m not sure to see the use case =
here. When you use UDL, you want the whole literal to be what you say it wo=
uld be.</div><div><div style=3D"background-color: rgb(250, 250, 250); borde=
r-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; overfl=
ow-wrap: break-word;" class=3D"prettyprint"><code class=3D"prettyprint"><di=
v class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-=
prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> s </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #080;" class=3D"styled-by-prettify">&quot;something&quo=
t;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">s</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #800;" class=3D"styled-by-prettify">// s is a string</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"> sv </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: #080;" class=3D"style=
d-by-prettify">&quot;some other&quot;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">sv</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify"=
>// s is a string view</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br></span></div></code></div>We are not interested in what is =
happening in the middle. I don&#39;t why it should be different with string=
 interpolation (or whatever the name is).<br></div><div><br></div><div>And =
with my proposal, you can always apply a function to every single element, =
and this function can be a UDL if you really want.</div><div><br></div><div=
><br></div><div>To sum up, F&quot;something&quot; returning a parameter pac=
k is probably the way to go because of the current C++, but would not bring=
 that much with a proper C++.</div><div>And then, I think UDL should apply =
to the whole stuff and not its part.</div><div><br></div><div>Assuming oper=
ator F&quot;&quot; returns a parameter pack:<br></div><div><div style=3D"ba=
ckground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); borde=
r-style: solid; border-width: 1px; overflow-wrap: break-word;" class=3D"pre=
ttyprint"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> s </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> F</span><span style=3D"color: #080;" clas=
s=3D"styled-by-prettify">&quot;{args}...&quot;</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify">s</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br></span><span style=3D"color: #800;" class=3D"styled-b=
y-prettify">// equivalent to:</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"> s </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: #008;" class=3D"styled-by-prettify">operator</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #080;" class=3D"styled-by-prettify">&quot;&quot;</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">s</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">args</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">...);</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br><br></span><span style=3D"color: #800;" class=3D"s=
tyled-by-prettify">// If you want to apply a UDL to part of it:</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">operator</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #080;" class=3D"styled-by-prettify">&quot;&quot;</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">s</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">F</span><span style=3D"color: #080;" class=3D"style=
d-by-prettify">&quot;{args}...&quot;</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">)...</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br></span><span style=3D"color: #800;" class=3D"styled=
-by-prettify">// would be equiavlent to:</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">operator</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #080;" class=3D"style=
d-by-prettify">&quot;&quot;</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify">s</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">a=
rgs</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)...</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></=
div></code></div><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/305b7669-0744-473e-9715-807b7e8051b6%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/305b7669-0744-473e-9715-807b7e8051b6=
%40isocpp.org</a>.<br />

------=_Part_9941_2001226193.1518452133071--

------=_Part_9940_1758140889.1518452133069--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 12 Feb 2018 08:56:48 -0800 (PST)
Raw View
------=_Part_9675_1179020735.1518454608528
Content-Type: multipart/alternative;
 boundary="----=_Part_9676_1456959997.1518454608528"

------=_Part_9676_1456959997.1518454608528
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Monday, February 12, 2018 at 11:15:33 AM UTC-5, floria...@gmail.com=20
wrote:
>
> Le lundi 12 f=C3=A9vrier 2018 16:45:41 UTC+1, Nicol Bolas a =C3=A9crit :
>>
>> And sadly, none of them have advanced or even received additional revise=
d=20
>> proposals. My way works just fine with C++ as it is.
>>
>> And even if we had that, most use-cases you don't need to pass the value=
s=20
>> around as a collective object. And if you did, you can make one triviall=
y,=20
>> as above.
>>
>> And again, it still doesn't deal with the fact that you lose perfect=20
>> forwarding.
>>
> =20
> I understand your point about creating a tuple from a parameter pack to b=
e=20
> able to do what is natural with my proposal. Fair enough.
>
> However, I don't see how we lose perfect forwarding. I mean, if the=20
> variable is a lvalue, it is stored as an lvalue reference, and if it is a=
=20
> rvalue, it is stored as an rvalue reference.
> This would be the exact same rules as for std::forward_as_tuple.
>

So what does `get` return? How do you use `get` such that it returns an=20
rvalue reference or lvalue reference appropriately?

Also, by using `forward_as_tuple` for your basis of implementation, you=20
make something as simple as this:

auto val =3D F"interpolate {5}";

Into a dangling reference. If we allow more than just variable names in=20
interpolation, then the expressions can be prvalues, and the lifetimes of=
=20
any temporaries they manifest will work the way regular C++ works. Since=20
they're bound to the parameters of an object consturctor, their lifetimes=
=20
end with the termination of the expression. So `val` will reference a=20
destroyed `int`.

You'd have to start playing games like braced-init-lists do when they=20
manifest an `initializer_list` to fix this.

I'd rather make that a straight-up error and force you to explicitly stick=
=20
such things in a specific type.


>> With that in mind, the implementation of your concat function with my=20
>>> approach would be exactly the same as with your approach (with a call t=
o=20
>>> "operator..." of std::string_processing ).
>>>
>>> And then, with only c++17 metaprogramming capabilities, you could also=
=20
>>> use std::apply.
>>>
>>
>> You cannot `apply` things to operators. Not without creating a lambda=20
>> function that gets called with it.
>>
> =20
> Why not? You can get the address of an operator, and this is a callable=
=20
> object.
>

You can only get the address of a single overload of an operator. Remember:=
=20
the whole idea is that you're dealing with a sequence of variables of=20
different types. So the second parameter to the operator has to be of=20
different types for different invocations of the operator.

The fact is, it's a *lot* easier in C++ as it currently stands to go from=
=20
>> parameter pack of values to an object than it is to go from an object to=
 a=20
>> parameter pack of values. I wish that were not the case, but so long as =
it=20
>> is the case, parameter packs will remain the easier-to-use option.
>>
> =20
> You have a point.=20
>
>
>> UDL the aggregate is not important to me, but it was easy to include and=
=20
>>> allows neat syntax (in my opinion).
>>>
>>
>> But it makes it impossible to apply a UDL to the string fragments. And=
=20
>> that's important if you do want to use template metaprogramming on strin=
g=20
>> literals.
>>
>
> I'm not sure to see the use case here. When you use UDL, you want the=20
> whole literal to be what you say it would be.
> auto s =3D "something"s; // s is a string
> auto sv =3D "some other"sv; // s is a string view
> We are not interested in what is happening in the middle. I don't why it=
=20
> should be different with string interpolation (or whatever the name is).
>

Because not all of the "literal" is actually a literal anymore. That's the=
=20
whole point of string interpolation: you're taking a literal and you're=20
augmenting it with some non-literal data. Potentially *runtime* non-literal=
=20
data. It isn't a literal anymore, so the UDL suffix can't apply to the=20
aggregate. It can only apply to the individual literal fragments of the=20
string.

Also, remember: you cannot apply a UDL suffix to a `constexpr` string=20
value. So again, if we ever want to apply interpolation to `constexpr`=20
strings, then we need to have an invocation syntax that doesn't encourage=
=20
people to use UDLs for them.

And with my proposal, you can always apply a function to every single=20
> element, and this function can be a UDL if you really want.
>
>
> To sum up, F"something" returning a parameter pack is probably the way to=
=20
> go because of the current C++, but would not bring that much with a prope=
r=20
> C++.
>

I don't agree with that. Even if we had P0535, it's still easier to work=20
with the arguments as a pack than it is to turn an object into a pack.=20
P0535 lowers the bar into the "reasonable" range, but 9 times out of 10,=20
just taking the parameters as a pack rather than unpacking an object will=
=20
be easier.

Using a pack also handily deals with the lifetime issues for prvalues, if=
=20
we allow arbitrary expressions in interpolated strings.

Also, let's not forget the other things I mentioned. That=20
`string_processing` would have to be a magic type created only by the=20
compiler like `initializer_list`. Which means you cannot call one of the=20
aggregation functions with your own parameters; they would be explicitly=20
bound to using string interpolation. By contrast, if you're just using=20
regular functions with variadic arguments, you can call them yourself=20
without invoking string interpolation.

That makes my version more flexible.

And then, I think UDL should apply to the whole stuff and not its part.
>

So how do you apply a UDL to just the string literal fragments? Without=20
creating a bunch of pointless variables, which is the antithesis of the=20
whole idea of interpolation.

The point of that discussion was a comment someone made about doing=20
template metaprogramming on string literals. To do that, you need a way to=
=20
access each literal as a distinct type, some `string_literal<char, 'c',=20
'h', 'a', 'r'>` type. And only a UDL applied to each fragment can perform=
=20
that kind of synthesis.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/0ceb2063-d7b6-4cb8-8c5c-c63aceb5b549%40isocpp.or=
g.

------=_Part_9676_1456959997.1518454608528
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Monday, February 12, 2018 at 11:15:33 AM UTC-5, floria.=
...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr">Le lundi 12 f=C3=A9vrier 2018 16:45:41 UTC+1, Nicol Bolas a =C3=A9cri=
t=C2=A0:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">And sadly,=
 none of them have advanced or even received additional revised proposals. =
My way works just fine with C++ as it is.<br><div><br>And even if we had th=
at, most use-cases you don&#39;t need to pass the values around as a collec=
tive object. And if you did, you can make one trivially, as above.<br><br>A=
nd again, it still doesn&#39;t deal with the fact that you lose perfect for=
warding.<br></div></div></blockquote><div>=C2=A0</div><div>I understand you=
r point about creating a tuple from a parameter pack to be able to do what =
is natural with my proposal. Fair enough.</div><div><br></div><div>However,=
 I don&#39;t see how we lose perfect forwarding. I mean, if the variable is=
 a lvalue, it is stored as an lvalue reference, and if it is a rvalue, it i=
s stored as an rvalue reference.</div><div>This would be the exact same rul=
es as for std::forward_as_tuple.</div></div></blockquote><div><br>So what d=
oes `get` return? How do you use `get` such that it returns an rvalue refer=
ence or lvalue reference appropriately?<br><br>Also, by using `forward_as_t=
uple` for your basis of implementation, you make something as simple as thi=
s:<br><br><div style=3D"background-color: rgb(250, 250, 250); border-color:=
 rgb(187, 187, 187); border-style: solid; border-width: 1px; overflow-wrap:=
 break-word;" class=3D"prettyprint"><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"> va=
l </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> F</span><span =
style=3D"color: #080;" class=3D"styled-by-prettify">&quot;interpolate {5}&q=
uot;</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</spa=
n></div></code></div><br>Into a dangling reference. If we allow more than j=
ust variable names in interpolation, then the expressions can be prvalues, =
and the lifetimes of any temporaries they manifest will work the way regula=
r C++ works. Since they&#39;re bound to the parameters of an object constur=
ctor, their lifetimes end with the termination of the expression. So `val` =
will reference a destroyed `int`.<br><br>You&#39;d have to start playing ga=
mes like braced-init-lists do when they manifest an `initializer_list` to f=
ix this.<br><br>I&#39;d rather make that a straight-up error and force you =
to explicitly stick such things in a specific type.<br><br></div><blockquot=
e class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: =
1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div> </div><blockquote=
 class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px =
#ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><br></div><blockquote cl=
ass=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>With that in mind, the impl=
ementation of your concat function with my approach would be exactly the sa=
me as with your approach (with a call to &quot;operator...&quot; of std::st=
ring_processing ).</div><div><br></div><div>And then, with only c++17 metap=
rogramming capabilities, you could also use std::apply.<br></div></div></bl=
ockquote><div><br>You cannot `apply` things to operators. Not without creat=
ing a lambda function that gets called with it.<br></div></div></blockquote=
><div>=C2=A0</div><div>Why not? You can get the address of an operator, and=
 this is a callable object.</div></div></blockquote><div><br>You can only g=
et the address of a single overload of an operator. Remember: the whole ide=
a is that you&#39;re dealing with a sequence of variables of different type=
s. So the second parameter to the operator has to be of different types for=
 different invocations of the operator.<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;"><div dir=3D"ltr"><div></div><blockquote class=3D"gma=
il_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pa=
dding-left:1ex"><div dir=3D"ltr"><div>The fact is, it&#39;s a <i>lot</i> ea=
sier in C++ as it currently stands to go from parameter pack of values to a=
n object than it is to go from an object to a parameter pack of values. I w=
ish that were not the case, but so long as it is the case, parameter packs =
will remain the easier-to-use option.<br></div></div></blockquote><div>=C2=
=A0</div><div>You have a point. <br></div><div><br></div><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><br></div><blockquote class=3D=
"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"ltr"><div></div><div></div>UDL the aggregat=
e is not important to me, but it was easy to include and allows neat syntax=
 (in my opinion).<br></div></blockquote><div><br>But it makes it impossible=
 to apply a UDL to the string fragments. And that&#39;s important if you do=
 want to use template metaprogramming on string literals.<br></div></div></=
blockquote><div><br></div><div>I&#39;m not sure to see the use case here. W=
hen you use UDL, you want the whole literal to be what you say it would be.=
</div><div><div style=3D"background-color:rgb(250,250,250);border-color:rgb=
(187,187,187);border-style:solid;border-width:1px"><code><div><span style=
=3D"color:#008">auto</span><span style=3D"color:#000"> s </span><span style=
=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D=
"color:#080">&quot;something&quot;</span><span style=3D"color:#000">s</span=
><span style=3D"color:#660">;</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#800">// s is a string</span><span style=3D"color:#000"><b=
r></span><span style=3D"color:#008">auto</span><span style=3D"color:#000"> =
sv </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> =
</span><span style=3D"color:#080">&quot;some other&quot;</span><span style=
=3D"color:#000">sv</span><span style=3D"color:#660">;</span><span style=3D"=
color:#000"> </span><span style=3D"color:#800">// s is a string view</span>=
<span style=3D"color:#000"><br></span></div></code></div>We are not interes=
ted in what is happening in the middle. I don&#39;t why it should be differ=
ent with string interpolation (or whatever the name is).<br></div></div></b=
lockquote><div><br>Because not all of the &quot;literal&quot; is actually a=
 literal anymore. That&#39;s the whole point of string interpolation: you&#=
39;re taking a literal and you&#39;re augmenting it with some non-literal d=
ata. Potentially <i>runtime</i> non-literal data. It isn&#39;t a literal an=
ymore, so the UDL suffix can&#39;t apply to the aggregate. It can only appl=
y to the individual literal fragments of the string.<br><br>Also, remember:=
 you cannot apply a UDL suffix to a `constexpr` string value. So again, if =
we ever want to apply interpolation to `constexpr` strings, then we need to=
 have an invocation syntax that doesn&#39;t encourage people to use UDLs fo=
r them.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><div></div><div></div><div>And with my proposal, you can always ap=
ply a function to every single element, and this function can be a UDL if y=
ou really want.</div><div><br></div><div><br></div><div>To sum up, F&quot;s=
omething&quot; returning a parameter pack is probably the way to go because=
 of the current C++, but would not bring that much with a proper C++.</div>=
</div></blockquote><div><br>I don&#39;t agree with that. Even if we had P05=
35, it&#39;s still easier to work with the arguments as a pack than it is t=
o turn an object into a pack. P0535 lowers the bar into the &quot;reasonabl=
e&quot; range, but 9 times out of 10, just taking the parameters as a pack =
rather than unpacking an object will be easier.<br><br>Using a pack also ha=
ndily deals with the lifetime issues for prvalues, if we allow arbitrary ex=
pressions in interpolated strings.<br><br>Also, let&#39;s not forget the ot=
her things I mentioned. That `string_processing` would have to be a magic t=
ype created only by the compiler like `initializer_list`. Which means you c=
annot call one of the aggregation functions with your own parameters; they =
would be explicitly bound to using string interpolation. By contrast, if yo=
u&#39;re just using regular functions with variadic arguments, you can call=
 them yourself without invoking string interpolation.<br><br>That makes my =
version more flexible.<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>And then, I think UDL should apply to the whole=
 stuff and not its part.</div></div></blockquote><div><br>So how do you app=
ly a UDL to just the string literal fragments? Without creating a bunch of =
pointless variables, which is the antithesis of the whole idea of interpola=
tion.</div><br>The point of that discussion was a comment someone made abou=
t doing template metaprogramming on string literals. To do that, you need a=
 way to access each literal as a distinct type, some `string_literal&lt;cha=
r, &#39;c&#39;, &#39;h&#39;, &#39;a&#39;, &#39;r&#39;&gt;` type. And only a=
 UDL applied to each fragment can perform that kind of synthesis.<br><br></=
div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/0ceb2063-d7b6-4cb8-8c5c-c63aceb5b549%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/0ceb2063-d7b6-4cb8-8c5c-c63aceb5b549=
%40isocpp.org</a>.<br />

------=_Part_9676_1456959997.1518454608528--

------=_Part_9675_1179020735.1518454608528--

.


Author: florian.csdt@gmail.com
Date: Mon, 12 Feb 2018 09:43:41 -0800 (PST)
Raw View
------=_Part_830_784042793.1518457421315
Content-Type: multipart/alternative;
 boundary="----=_Part_831_1164484456.1518457421316"

------=_Part_831_1164484456.1518457421316
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



Le lundi 12 f=C3=A9vrier 2018 17:56:48 UTC+1, Nicol Bolas a =C3=A9crit :
>
> On Monday, February 12, 2018 at 11:15:33 AM UTC-5, floria...@gmail.com=20
> wrote:
>>
>> Le lundi 12 f=C3=A9vrier 2018 16:45:41 UTC+1, Nicol Bolas a =C3=A9crit :
>>>
>>> And sadly, none of them have advanced or even received additional=20
>>> revised proposals. My way works just fine with C++ as it is.
>>>
>>> And even if we had that, most use-cases you don't need to pass the=20
>>> values around as a collective object. And if you did, you can make one=
=20
>>> trivially, as above.
>>>
>>> And again, it still doesn't deal with the fact that you lose perfect=20
>>> forwarding.
>>>
>> =20
>> I understand your point about creating a tuple from a parameter pack to=
=20
>> be able to do what is natural with my proposal. Fair enough.
>>
>> However, I don't see how we lose perfect forwarding. I mean, if the=20
>> variable is a lvalue, it is stored as an lvalue reference, and if it is =
a=20
>> rvalue, it is stored as an rvalue reference.
>> This would be the exact same rules as for std::forward_as_tuple.
>>
>
> So what does `get` return? How do you use `get` such that it returns an=
=20
> rvalue reference or lvalue reference appropriately?
>
> Also, by using `forward_as_tuple` for your basis of implementation, you=
=20
> make something as simple as this:
>
> auto val =3D F"interpolate {5}";
>
> Into a dangling reference. If we allow more than just variable names in=
=20
> interpolation, then the expressions can be prvalues, and the lifetimes of=
=20
> any temporaries they manifest will work the way regular C++ works. Since=
=20
> they're bound to the parameters of an object consturctor, their lifetimes=
=20
> end with the termination of the expression. So `val` will reference a=20
> destroyed `int`.
>
> You'd have to start playing games like braced-init-lists do when they=20
> manifest an `initializer_list` to fix this.
>
> I'd rather make that a straight-up error and force you to explicitly stic=
k=20
> such things in a specific type.
>

I would say it's the same problem as:
auto&& i =3D 5;

But yes, returning a parameter pack forbids that kind of use and avoid=20
dangling references. I agree.
=20

>
>
>>> With that in mind, the implementation of your concat function with my=
=20
>>>> approach would be exactly the same as with your approach (with a call =
to=20
>>>> "operator..." of std::string_processing ).
>>>>
>>>> And then, with only c++17 metaprogramming capabilities, you could also=
=20
>>>> use std::apply.
>>>>
>>>
>>> You cannot `apply` things to operators. Not without creating a lambda=
=20
>>> function that gets called with it.
>>>
>> =20
>> Why not? You can get the address of an operator, and this is a callable=
=20
>> object.
>>
>
> You can only get the address of a single overload of an operator.=20
> Remember: the whole idea is that you're dealing with a sequence of=20
> variables of different types. So the second parameter to the operator has=
=20
> to be of different types for different invocations of the operator.
>

This is another quirk of C++ that should be fixed.
=20

>
> The fact is, it's a *lot* easier in C++ as it currently stands to go from=
=20
>>> parameter pack of values to an object than it is to go from an object t=
o a=20
>>> parameter pack of values. I wish that were not the case, but so long as=
 it=20
>>> is the case, parameter packs will remain the easier-to-use option.
>>>
>> =20
>> You have a point.=20
>>
>>
>>> UDL the aggregate is not important to me, but it was easy to include an=
d=20
>>>> allows neat syntax (in my opinion).
>>>>
>>>
>>> But it makes it impossible to apply a UDL to the string fragments. And=
=20
>>> that's important if you do want to use template metaprogramming on stri=
ng=20
>>> literals.
>>>
>>
>> I'm not sure to see the use case here. When you use UDL, you want the=20
>> whole literal to be what you say it would be.
>> auto s =3D "something"s; // s is a string
>> auto sv =3D "some other"sv; // s is a string view
>> We are not interested in what is happening in the middle. I don't why it=
=20
>> should be different with string interpolation (or whatever the name is).
>>
>
> Because not all of the "literal" is actually a literal anymore. That's th=
e=20
> whole point of string interpolation: you're taking a literal and you're=
=20
> augmenting it with some non-literal data. Potentially *runtime*=20
> non-literal data. It isn't a literal anymore, so the UDL suffix can't app=
ly=20
> to the aggregate. It can only apply to the individual literal fragments o=
f=20
> the string.
>

Here, I don't care if it's called a literal, or if we invent a new name for=
=20
this concept that appeared to match the concept of literal when "string=20
interpolation" was not a thing.
I'm more interested in the final syntax as the end user will see it.

And I would prefer concatenate like this:
auto s =3D F"{str1}{str2}{str3}"s;
than this:
auto s =3D std::concat(F"{str1}{str2}{str3}");

The first one looks more natural in my opinion.

=20

>
> Also, remember: you cannot apply a UDL suffix to a `constexpr` string=20
> value. So again, if we ever want to apply interpolation to `constexpr`=20
> strings, then we need to have an invocation syntax that doesn't encourage=
=20
> people to use UDLs for them.
>

F"something" looks like a string literal, so it would be natural to have a=
=20
similar syntax.
And I don't think allowing this would encourage people to use UDL-like=20
syntax to do constexpr string computation that are not related to "string=
=20
interpolation".
=20

>
> And with my proposal, you can always apply a function to every single=20
>> element, and this function can be a UDL if you really want.
>>
>>
>> To sum up, F"something" returning a parameter pack is probably the way t=
o=20
>> go because of the current C++, but would not bring that much with a prop=
er=20
>> C++.
>>
>
> I don't agree with that. Even if we had P0535, it's still easier to work=
=20
> with the arguments as a pack than it is to turn an object into a pack.=20
> P0535 lowers the bar into the "reasonable" range, but 9 times out of 10,=
=20
> just taking the parameters as a pack rather than unpacking an object will=
=20
> be easier.
>
> Using a pack also handily deals with the lifetime issues for prvalues, if=
=20
> we allow arbitrary expressions in interpolated strings.
>

I got your point, and, after thinking about it, I agree with you.
=20

>
> Also, let's not forget the other things I mentioned. That=20
> `string_processing` would have to be a magic type created only by the=20
> compiler like `initializer_list`. Which means you cannot call one of the=
=20
> aggregation functions with your own parameters; they would be explicitly=
=20
> bound to using string interpolation. By contrast, if you're just using=20
> regular functions with variadic arguments, you can call them yourself=20
> without invoking string interpolation.
>
> That makes my version more flexible.
>
> And then, I think UDL should apply to the whole stuff and not its part.
>>
>
> So how do you apply a UDL to just the string literal fragments? Without=
=20
> creating a bunch of pointless variables, which is the antithesis of the=
=20
> whole idea of interpolation.
>

> The point of that discussion was a comment someone made about doing=20
> template metaprogramming on string literals. To do that, you need a way t=
o=20
> access each literal as a distinct type, some `string_literal<char, 'c',=
=20
> 'h', 'a', 'r'>` type. And only a UDL applied to each fragment can perform=
=20
> that kind of synthesis.
>
>
If we had proper string literals in c++, this would never have been a=20
problem. The same applies to proper constexpr functions (like overloadable=
=20
by constexpr-ness or requiring some inputs to be constexpr).

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/d26b85c2-707b-49a5-a007-617027506dd1%40isocpp.or=
g.

------=_Part_831_1164484456.1518457421316
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le lundi 12 f=C3=A9vrier 2018 17:56:48 UTC+1, Nico=
l Bolas a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v dir=3D"ltr">On Monday, February 12, 2018 at 11:15:33 AM UTC-5, <a>floria.=
...@gmail.com</a> 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">Le lundi 12 f=C3=A9vrier 2018 16:45:41 UTC+1, Nicol Bolas a =C3=A9crit=
=C2=A0:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">And sadly, =
none of them have advanced or even received additional revised proposals. M=
y way works just fine with C++ as it is.<br><div><br>And even if we had tha=
t, most use-cases you don&#39;t need to pass the values around as a collect=
ive object. And if you did, you can make one trivially, as above.<br><br>An=
d again, it still doesn&#39;t deal with the fact that you lose perfect forw=
arding.<br></div></div></blockquote><div>=C2=A0</div><div>I understand your=
 point about creating a tuple from a parameter pack to be able to do what i=
s natural with my proposal. Fair enough.</div><div><br></div><div>However, =
I don&#39;t see how we lose perfect forwarding. I mean, if the variable is =
a lvalue, it is stored as an lvalue reference, and if it is a rvalue, it is=
 stored as an rvalue reference.</div><div>This would be the exact same rule=
s as for std::forward_as_tuple.</div></div></blockquote><div><br>So what do=
es `get` return? How do you use `get` such that it returns an rvalue refere=
nce or lvalue reference appropriately?<br><br>Also, by using `forward_as_tu=
ple` for your basis of implementation, you make something as simple as this=
:<br><br><div style=3D"background-color:rgb(250,250,250);border-color:rgb(1=
87,187,187);border-style:solid;border-width:1px"><code><div><span style=3D"=
color:#008">auto</span><span style=3D"color:#000"> val </span><span style=
=3D"color:#660">=3D</span><span style=3D"color:#000"> F</span><span style=
=3D"color:#080">&quot;interpolate {5}&quot;</span><span style=3D"color:#660=
">;</span></div></code></div><br>Into a dangling reference. If we allow mor=
e than just variable names in interpolation, then the expressions can be pr=
values, and the lifetimes of any temporaries they manifest will work the wa=
y regular C++ works. Since they&#39;re bound to the parameters of an object=
 consturctor, their lifetimes end with the termination of the expression. S=
o `val` will reference a destroyed `int`.<br><br>You&#39;d have to start pl=
aying games like braced-init-lists do when they manifest an `initializer_li=
st` to fix this.<br><br>I&#39;d rather make that a straight-up error and fo=
rce you to explicitly stick such things in a specific type.<br></div></div>=
</blockquote><div><br></div><div>I would say it&#39;s the same problem as:<=
/div><div><div style=3D"background-color: rgb(250, 250, 250); border-color:=
 rgb(187, 187, 187); border-style: solid; border-width: 1px; overflow-wrap:=
 break-word;" class=3D"prettyprint"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">auto</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&am=
p;&amp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> i =
</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 sty=
le=3D"color: #066;" class=3D"styled-by-prettify">5</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br></span></div></code></div><br>But yes, r=
eturning a parameter pack forbids that kind of use and avoid dangling refer=
ences. I agree.<br></div><div>=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><br></div><blockquote class=3D"gmail_quot=
e" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"ltr"><div> </div><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1e=
x"><div dir=3D"ltr"><div><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>With that in mind, the implementation of your concat=
 function with my approach would be exactly the same as with your approach =
(with a call to &quot;operator...&quot; of std::string_processing ).</div><=
div><br></div><div>And then, with only c++17 metaprogramming capabilities, =
you could also use std::apply.<br></div></div></blockquote><div><br>You can=
not `apply` things to operators. Not without creating a lambda function tha=
t gets called with it.<br></div></div></blockquote><div>=C2=A0</div><div>Wh=
y not? You can get the address of an operator, and this is a callable objec=
t.</div></div></blockquote><div><br>You can only get the address of a singl=
e overload of an operator. Remember: the whole idea is that you&#39;re deal=
ing with a sequence of variables of different types. So the second paramete=
r to the operator has to be of different types for different invocations of=
 the operator.<br></div></div></blockquote><div><br></div><div>This is anot=
her quirk of C++ that should be fixed.<br></div><div>=C2=A0</div><blockquot=
e 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><br></div><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1=
px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc=
 solid;padding-left:1ex"><div dir=3D"ltr"><div>The fact is, it&#39;s a <i>l=
ot</i> easier in C++ as it currently stands to go from parameter pack of va=
lues to an object than it is to go from an object to a parameter pack of va=
lues. I wish that were not the case, but so long as it is the case, paramet=
er packs will remain the easier-to-use option.<br></div></div></blockquote>=
<div>=C2=A0</div><div>You have a point. <br></div><div><br></div><blockquot=
e 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><br></div><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #c=
cc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><div></div>UDL the a=
ggregate is not important to me, but it was easy to include and allows neat=
 syntax (in my opinion).<br></div></blockquote><div><br>But it makes it imp=
ossible to apply a UDL to the string fragments. And that&#39;s important if=
 you do want to use template metaprogramming on string literals.<br></div><=
/div></blockquote><div><br></div><div>I&#39;m not sure to see the use case =
here. When you use UDL, you want the whole literal to be what you say it wo=
uld be.</div><div><div style=3D"background-color:rgb(250,250,250);border-co=
lor:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><span =
style=3D"color:#008">auto</span><span style=3D"color:#000"> s </span><span =
style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#080">&quot;something&quot;</span><span style=3D"color:#000">s<=
/span><span style=3D"color:#660">;</span><span style=3D"color:#000"> </span=
><span style=3D"color:#800">// s is a string</span><span style=3D"color:#00=
0"><br></span><span style=3D"color:#008">auto</span><span style=3D"color:#0=
00"> sv </span><span style=3D"color:#660">=3D</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#080">&quot;some other&quot;</span><span s=
tyle=3D"color:#000">sv</span><span style=3D"color:#660">;</span><span style=
=3D"color:#000"> </span><span style=3D"color:#800">// s is a string view</s=
pan><span style=3D"color:#000"><br></span></div></code></div>We are not int=
erested in what is happening in the middle. I don&#39;t why it should be di=
fferent with string interpolation (or whatever the name is).<br></div></div=
></blockquote><div><br>Because not all of the &quot;literal&quot; is actual=
ly a literal anymore. That&#39;s the whole point of string interpolation: y=
ou&#39;re taking a literal and you&#39;re augmenting it with some non-liter=
al data. Potentially <i>runtime</i> non-literal data. It isn&#39;t a litera=
l anymore, so the UDL suffix can&#39;t apply to the aggregate. It can only =
apply to the individual literal fragments of the string.<br></div></div></b=
lockquote><div><br></div><div>Here, I don&#39;t care if it&#39;s called a l=
iteral, or if we invent a new name for this concept that appeared to match =
the concept of literal when &quot;string interpolation&quot; was not a thin=
g.</div><div>I&#39;m more interested in the final syntax as the end user wi=
ll see it.</div><div><br></div><div>And I would prefer concatenate like thi=
s:</div><div><div style=3D"background-color: rgb(250, 250, 250); border-col=
or: rgb(187, 187, 187); border-style: solid; border-width: 1px; overflow-wr=
ap: break-word;" class=3D"prettyprint"><code class=3D"prettyprint"><div cla=
ss=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
s </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> F</span><span =
style=3D"color: #080;" class=3D"styled-by-prettify">&quot;{str1}{str2}{str3=
}&quot;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">s</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div></co=
de></div></div><div>than this:</div><div><div style=3D"background-color: rg=
b(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; bo=
rder-width: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code cl=
ass=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> s </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> std</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">c=
oncat</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">F</span><span =
style=3D"color: #080;" class=3D"styled-by-prettify">&quot;{str1}{str2}{str3=
}&quot;</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span>=
</div></code></div><br>The first one looks more natural in my opinion.<br><=
/div><div><br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" styl=
e=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left:=
 1ex;"><div dir=3D"ltr"><div><br>Also, remember: you cannot apply a UDL suf=
fix to a `constexpr` string value. So again, if we ever want to apply inter=
polation to `constexpr` strings, then we need to have an invocation syntax =
that doesn&#39;t encourage people to use UDLs for them.<br></div></div></bl=
ockquote><div><br></div><div>F&quot;something&quot; looks like a string lit=
eral, so it would be natural to have a similar syntax.</div><div>And I don&=
#39;t think allowing this would encourage people to use UDL-like syntax to =
do constexpr string computation that are not related to &quot;string interp=
olation&quot;.<br></div><div>=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;"><div dir=3D"ltr"><div><br></div><blockquote class=3D"gmail_quote=
" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div dir=3D"ltr"><div></div><div></div><div>And with my proposal, y=
ou can always apply a function to every single element, and this function c=
an be a UDL if you really want.</div><div><br></div><div><br></div><div>To =
sum up, F&quot;something&quot; returning a parameter pack is probably the w=
ay to go because of the current C++, but would not bring that much with a p=
roper C++.</div></div></blockquote><div><br>I don&#39;t agree with that. Ev=
en if we had P0535, it&#39;s still easier to work with the arguments as a p=
ack than it is to turn an object into a pack. P0535 lowers the bar into the=
 &quot;reasonable&quot; range, but 9 times out of 10, just taking the param=
eters as a pack rather than unpacking an object will be easier.<br><br>Usin=
g a pack also handily deals with the lifetime issues for prvalues, if we al=
low arbitrary expressions in interpolated strings.<br></div></div></blockqu=
ote><div><br></div><div>I got your point, and, after thinking about it, I a=
gree with you.<br></div><div>=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;"><div dir=3D"ltr"><div><br>Also, let&#39;s not forget the other t=
hings I mentioned. That `string_processing` would have to be a magic type c=
reated only by the compiler like `initializer_list`. Which means you cannot=
 call one of the aggregation functions with your own parameters; they would=
 be explicitly bound to using string interpolation. By contrast, if you&#39=
;re just using regular functions with variadic arguments, you can call them=
 yourself without invoking string interpolation.<br><br>That makes my versi=
on more flexible.<br><br></div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div=
 dir=3D"ltr"><div>And then, I think UDL should apply to the whole stuff and=
 not its part.</div></div></blockquote><div><br>So how do you apply a UDL t=
o just the string literal fragments? Without creating a bunch of pointless =
variables, which is the antithesis of the whole idea of interpolation.</div=
></div></blockquote><blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><br>The point of that discussion was a comment someone made about =
doing template metaprogramming on string literals. To do that, you need a w=
ay to access each literal as a distinct type, some `string_literal&lt;char,=
 &#39;c&#39;, &#39;h&#39;, &#39;a&#39;, &#39;r&#39;&gt;` type. And only a U=
DL applied to each fragment can perform that kind of synthesis.<br><br></di=
v></blockquote><div><br></div><div>If we had proper string literals in c++,=
 this would never have been a problem. The same applies to proper constexpr=
 functions (like overloadable by constexpr-ness or requiring some inputs to=
 be constexpr).<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/d26b85c2-707b-49a5-a007-617027506dd1%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/d26b85c2-707b-49a5-a007-617027506dd1=
%40isocpp.org</a>.<br />

------=_Part_831_1164484456.1518457421316--

------=_Part_830_784042793.1518457421315--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 12 Feb 2018 12:11:14 -0800 (PST)
Raw View
------=_Part_1121_1201974013.1518466274401
Content-Type: multipart/alternative;
 boundary="----=_Part_1122_2022522906.1518466274402"

------=_Part_1122_2022522906.1518466274402
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Monday, February 12, 2018 at 12:43:41 PM UTC-5, floria...@gmail.com=20
wrote:
>
> Le lundi 12 f=C3=A9vrier 2018 17:56:48 UTC+1, Nicol Bolas a =C3=A9crit :
>>
>> On Monday, February 12, 2018 at 11:15:33 AM UTC-5, floria...@gmail.com=
=20
>> wrote:
>>
> With that in mind, the implementation of your concat function with my=20
>>>>> approach would be exactly the same as with your approach (with a call=
 to=20
>>>>> "operator..." of std::string_processing ).
>>>>>
>>>>> And then, with only c++17 metaprogramming capabilities, you could als=
o=20
>>>>> use std::apply.
>>>>>
>>>>
>>>> You cannot `apply` things to operators. Not without creating a lambda=
=20
>>>> function that gets called with it.
>>>>
>>> =20
>>> Why not? You can get the address of an operator, and this is a callable=
=20
>>> object.
>>>
>>
>> You can only get the address of a single overload of an operator.=20
>> Remember: the whole idea is that you're dealing with a sequence of=20
>> variables of different types. So the second parameter to the operator ha=
s=20
>> to be of different types for different invocations of the operator.
>>
>
> This is another quirk of C++ that should be fixed.
>

Which incidentally is yet another proposal (lifting lambdas) that stalled.

The fact is, it's a *lot* easier in C++ as it currently stands to go from=
=20
>>>> parameter pack of values to an object than it is to go from an object =
to a=20
>>>> parameter pack of values. I wish that were not the case, but so long a=
s it=20
>>>> is the case, parameter packs will remain the easier-to-use option.
>>>>
>>> =20
>>> You have a point.=20
>>>
>>>
>>>> UDL the aggregate is not important to me, but it was easy to include=
=20
>>>>> and allows neat syntax (in my opinion).
>>>>>
>>>>
>>>> But it makes it impossible to apply a UDL to the string fragments. And=
=20
>>>> that's important if you do want to use template metaprogramming on str=
ing=20
>>>> literals.
>>>>
>>>
>>> I'm not sure to see the use case here. When you use UDL, you want the=
=20
>>> whole literal to be what you say it would be.
>>> auto s =3D "something"s; // s is a string
>>> auto sv =3D "some other"sv; // s is a string view
>>> We are not interested in what is happening in the middle. I don't why i=
t=20
>>> should be different with string interpolation (or whatever the name is)=
..
>>>
>>
>> Because not all of the "literal" is actually a literal anymore. That's=
=20
>> the whole point of string interpolation: you're taking a literal and you=
're=20
>> augmenting it with some non-literal data. Potentially *runtime*=20
>> non-literal data. It isn't a literal anymore, so the UDL suffix can't ap=
ply=20
>> to the aggregate. It can only apply to the individual literal fragments =
of=20
>> the string.
>>
>
> Here, I don't care if it's called a literal, or if we invent a new name=
=20
> for this concept that appeared to match the concept of literal when "stri=
ng=20
> interpolation" was not a thing.
> I'm more interested in the final syntax as the end user will see it.
>
> And I would prefer concatenate like this:
> auto s =3D F"{str1}{str2}{str3}"s;
> than this:
> auto s =3D std::concat(F"{str1}{str2}{str3}");
>
> The first one looks more natural in my opinion.
>

It only looks more natural for the trivial cases. Consider what=20
`std::concat` would look like. It creates an `ostringstream`, applies it to=
=20
each parameter, and moves its result out. Why pick `ostringstream`? Why not=
=20
allow the user to decide which kind of stream to use and therefore which=20
resulting string type to build?

You can't do that with a UDL; they can't take an extra template parameter.=
=20
`std::concat` can.

However more "natural" the UDL version *appears*, it's ultimately much more=
=20
limiting to *use*. And while appearance is important, usability ought to be=
=20
more important.

You can't even do this in a header:

struct Foo
{
  std::string value =3D F"{str1}{str2}{str3}"s;
};

That's due to having to `using namespace` the literals before you can use=
=20
them. Calling a function directly requires no such gymnastics.

Oh sure, modules will (thankfully) remedy this situation to a degree. But=
=20
until everyone's codebase is modularized, that's going to be a problem. And=
=20
even then, you shouldn't have to `using namespace blah` to be able to use=
=20
string interpolation.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/41b87b07-1a91-4bca-ba00-5734c09dbe77%40isocpp.or=
g.

------=_Part_1122_2022522906.1518466274402
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Monday, February 12, 2018 at 12:43:41 PM UTC-5, floria.=
...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr">Le lundi 12 f=C3=A9vrier 2018 17:56:48 UTC+1, Nicol Bolas a =C3=A9cri=
t=C2=A0:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Monday,=
 February 12, 2018 at 11:15:33 AM UTC-5, <a>floria...@gmail.com</a> wrote:<=
/div></blockquote><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"ltr">=
<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;borde=
r-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div> </div><block=
quote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left=
:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><blockquote class=3D"gma=
il_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pa=
dding-left:1ex"><div dir=3D"ltr"><div>With that in mind, the implementation=
 of your concat function with my approach would be exactly the same as with=
 your approach (with a call to &quot;operator...&quot; of std::string_proce=
ssing ).</div><div><br></div><div>And then, with only c++17 metaprogramming=
 capabilities, you could also use std::apply.<br></div></div></blockquote><=
div><br>You cannot `apply` things to operators. Not without creating a lamb=
da function that gets called with it.<br></div></div></blockquote><div>=C2=
=A0</div><div>Why not? You can get the address of an operator, and this is =
a callable object.</div></div></blockquote><div><br>You can only get the ad=
dress of a single overload of an operator. Remember: the whole idea is that=
 you&#39;re dealing with a sequence of variables of different types. So the=
 second parameter to the operator has to be of different types for differen=
t invocations of the operator.<br></div></div></blockquote><div><br></div><=
div>This is another quirk of C++ that should be fixed.<br></div></div></blo=
ckquote><div><br>Which incidentally is yet another proposal (lifting lambda=
s) that stalled.<br><br></div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">=
<div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" style=3D"marg=
in:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div di=
r=3D"ltr"><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></d=
iv><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bo=
rder-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>The fact i=
s, it&#39;s a <i>lot</i> easier in C++ as it currently stands to go from pa=
rameter pack of values to an object than it is to go from an object to a pa=
rameter pack of values. I wish that were not the case, but so long as it is=
 the case, parameter packs will remain the easier-to-use option.<br></div><=
/div></blockquote><div>=C2=A0</div><div>You have a point. <br></div><div><b=
r></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><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><d=
iv></div>UDL the aggregate is not important to me, but it was easy to inclu=
de and allows neat syntax (in my opinion).<br></div></blockquote><div><br>B=
ut it makes it impossible to apply a UDL to the string fragments. And that&=
#39;s important if you do want to use template metaprogramming on string li=
terals.<br></div></div></blockquote><div><br></div><div>I&#39;m not sure to=
 see the use case here. When you use UDL, you want the whole literal to be =
what you say it would be.</div><div><div style=3D"background-color:rgb(250,=
250,250);border-color:rgb(187,187,187);border-style:solid;border-width:1px"=
><code><div><span style=3D"color:#008">auto</span><span style=3D"color:#000=
"> s </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"=
> </span><span style=3D"color:#080">&quot;something&quot;</span><span style=
=3D"color:#000">s</span><span style=3D"color:#660">;</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#800">// s is a string</span><span =
style=3D"color:#000"><br></span><span style=3D"color:#008">auto</span><span=
 style=3D"color:#000"> sv </span><span style=3D"color:#660">=3D</span><span=
 style=3D"color:#000"> </span><span style=3D"color:#080">&quot;some other&q=
uot;</span><span style=3D"color:#000">sv</span><span style=3D"color:#660">;=
</span><span style=3D"color:#000"> </span><span style=3D"color:#800">// s i=
s a string view</span><span style=3D"color:#000"><br></span></div></code></=
div>We are not interested in what is happening in the middle. I don&#39;t w=
hy it should be different with string interpolation (or whatever the name i=
s).<br></div></div></blockquote><div><br>Because not all of the &quot;liter=
al&quot; is actually a literal anymore. That&#39;s the whole point of strin=
g interpolation: you&#39;re taking a literal and you&#39;re augmenting it w=
ith some non-literal data. Potentially <i>runtime</i> non-literal data. It =
isn&#39;t a literal anymore, so the UDL suffix can&#39;t apply to the aggre=
gate. It can only apply to the individual literal fragments of the string.<=
br></div></div></blockquote><div><br></div><div>Here, I don&#39;t care if i=
t&#39;s called a literal, or if we invent a new name for this concept that =
appeared to match the concept of literal when &quot;string interpolation&qu=
ot; was not a thing.</div><div>I&#39;m more interested in the final syntax =
as the end user will see it.</div><div><br></div><div>And I would prefer co=
ncatenate like this:</div><div><div style=3D"background-color:rgb(250,250,2=
50);border-color:rgb(187,187,187);border-style:solid;border-width:1px"><cod=
e><div><span style=3D"color:#008">auto</span><span style=3D"color:#000"> s =
</span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> F</=
span><span style=3D"color:#080">&quot;{str1}{str2}{str3}&quot;</span><span =
style=3D"color:#000">s</span><span style=3D"color:#660">;</span><span style=
=3D"color:#000"><br></span></div></code></div></div><div>than this:</div><d=
iv><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187=
,187);border-style:solid;border-width:1px"><code><div><span style=3D"color:=
#008">auto</span><span style=3D"color:#000"> s </span><span style=3D"color:=
#660">=3D</span><span style=3D"color:#000"> std</span><span style=3D"color:=
#660">::</span><span style=3D"color:#000">concat</span><span style=3D"color=
:#660">(</span><span style=3D"color:#000">F</span><span style=3D"color:#080=
">&quot;{str1}{str2}{<wbr>str3}&quot;</span><span style=3D"color:#660">);</=
span><span style=3D"color:#000"><br></span></div></code></div><br>The first=
 one looks more natural in my opinion.<br></div></div></blockquote><div><br=
>It only looks more natural for the trivial cases. Consider what `std::conc=
at` would look like. It creates an `ostringstream`, applies it to each para=
meter, and moves its result out. Why pick `ostringstream`? Why not allow th=
e user to decide which kind of stream to use and therefore which resulting =
string type to build?<br><br>You can&#39;t do that with a UDL; they can&#39=
;t take an extra template parameter. `std::concat` can.<br><br>However more=
 &quot;natural&quot; the UDL version <i>appears</i>, it&#39;s ultimately mu=
ch more limiting to <i>use</i>. And while appearance is important, usabilit=
y ought to be more important.<br><br>You can&#39;t even do this in a header=
:<br><br><div style=3D"background-color: rgb(250, 250, 250); border-color: =
rgb(187, 187, 187); border-style: solid; border-width: 1px; overflow-wrap: =
break-word;" class=3D"prettyprint"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">struct</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Foo</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 std</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">string</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> value </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> F</span><span style=3D"color: #080;" class=3D"sty=
led-by-prettify">&quot;{str1}{str2}{str3}&quot;</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify">s</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">};</span></div></code></div><br>That&#39;s due to having to `u=
sing namespace` the literals before you can use them. Calling a function di=
rectly requires no such gymnastics.<br><br>Oh sure, modules will (thankfull=
y) remedy this situation to a degree. But until everyone&#39;s codebase is =
modularized, that&#39;s going to be a problem. And even then, you shouldn&#=
39;t have to `using namespace blah` to be able to use string interpolation.=
</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/41b87b07-1a91-4bca-ba00-5734c09dbe77%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/41b87b07-1a91-4bca-ba00-5734c09dbe77=
%40isocpp.org</a>.<br />

------=_Part_1122_2022522906.1518466274402--

------=_Part_1121_1201974013.1518466274401--

.


Author: florian.csdt@gmail.com
Date: Mon, 12 Feb 2018 13:08:36 -0800 (PST)
Raw View
------=_Part_10474_1553800702.1518469716932
Content-Type: multipart/alternative;
 boundary="----=_Part_10475_1336774937.1518469716933"

------=_Part_10475_1336774937.1518469716933
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



Le lundi 12 f=C3=A9vrier 2018 21:11:14 UTC+1, Nicol Bolas a =C3=A9crit :
>
> On Monday, February 12, 2018 at 12:43:41 PM UTC-5, floria...@gmail.com=20
> wrote:
>>
>> Le lundi 12 f=C3=A9vrier 2018 17:56:48 UTC+1, Nicol Bolas a =C3=A9crit :
>>>
>>> On Monday, February 12, 2018 at 11:15:33 AM UTC-5, floria...@gmail.com=
=20
>>> wrote:
>>>
>> With that in mind, the implementation of your concat function with my=20
>>>>>> approach would be exactly the same as with your approach (with a cal=
l to=20
>>>>>> "operator..." of std::string_processing ).
>>>>>>
>>>>>> And then, with only c++17 metaprogramming capabilities, you could=20
>>>>>> also use std::apply.
>>>>>>
>>>>>
>>>>> You cannot `apply` things to operators. Not without creating a lambda=
=20
>>>>> function that gets called with it.
>>>>>
>>>> =20
>>>> Why not? You can get the address of an operator, and this is a callabl=
e=20
>>>> object.
>>>>
>>>
>>> You can only get the address of a single overload of an operator.=20
>>> Remember: the whole idea is that you're dealing with a sequence of=20
>>> variables of different types. So the second parameter to the operator h=
as=20
>>> to be of different types for different invocations of the operator.
>>>
>>
>> This is another quirk of C++ that should be fixed.
>>
>
> Which incidentally is yet another proposal (lifting lambdas) that stalled=
..
>
> The fact is, it's a *lot* easier in C++ as it currently stands to go from=
=20
>>>>> parameter pack of values to an object than it is to go from an object=
 to a=20
>>>>> parameter pack of values. I wish that were not the case, but so long =
as it=20
>>>>> is the case, parameter packs will remain the easier-to-use option.
>>>>>
>>>> =20
>>>> You have a point.=20
>>>>
>>>>
>>>>> UDL the aggregate is not important to me, but it was easy to include=
=20
>>>>>> and allows neat syntax (in my opinion).
>>>>>>
>>>>>
>>>>> But it makes it impossible to apply a UDL to the string fragments. An=
d=20
>>>>> that's important if you do want to use template metaprogramming on st=
ring=20
>>>>> literals.
>>>>>
>>>>
>>>> I'm not sure to see the use case here. When you use UDL, you want the=
=20
>>>> whole literal to be what you say it would be.
>>>> auto s =3D "something"s; // s is a string
>>>> auto sv =3D "some other"sv; // s is a string view
>>>> We are not interested in what is happening in the middle. I don't why=
=20
>>>> it should be different with string interpolation (or whatever the name=
 is).
>>>>
>>>
>>> Because not all of the "literal" is actually a literal anymore. That's=
=20
>>> the whole point of string interpolation: you're taking a literal and yo=
u're=20
>>> augmenting it with some non-literal data. Potentially *runtime*=20
>>> non-literal data. It isn't a literal anymore, so the UDL suffix can't a=
pply=20
>>> to the aggregate. It can only apply to the individual literal fragments=
 of=20
>>> the string.
>>>
>>
>> Here, I don't care if it's called a literal, or if we invent a new name=
=20
>> for this concept that appeared to match the concept of literal when "str=
ing=20
>> interpolation" was not a thing.
>> I'm more interested in the final syntax as the end user will see it.
>>
>> And I would prefer concatenate like this:
>> auto s =3D F"{str1}{str2}{str3}"s;
>> than this:
>> auto s =3D std::concat(F"{str1}{str2}{str3}");
>>
>> The first one looks more natural in my opinion.
>>
>
> It only looks more natural for the trivial cases. Consider what=20
> `std::concat` would look like. It creates an `ostringstream`, applies it =
to=20
> each parameter, and moves its result out. Why pick `ostringstream`? Why n=
ot=20
> allow the user to decide which kind of stream to use and therefore which=
=20
> resulting string type to build?
>

I never said this should work only with UDL. I just said that I think it is=
=20
more natural if UDL worked like that.
But I really think the user should keep control over what can be done with=
=20
this syntax.
So I totally agree with you: users should be able to call their own=20
functions with it.

And then, even considering F"{str1}{str2}{str3}"s for concatenating, I=20
never mentionned std::ostringstream, I just said converted into an=20
efficient way of concatenating strings.
In that case, I just considered that when we use operator ""s, we want a=20
std::string.
=20

>
> You can't do that with a UDL; they can't take an extra template parameter=
..=20
> `std::concat` can.
>

To do that, just use a function. We can have multiple syntaxes to do the=20
same thing.
The closest example I can think of is:
auto s =3D std::string("str");
// is equivalent to
auto s =3D "str"s;

We could have exatcly the situation with string interpolation:
auto s =3D std::concat(F"{str1}{str2}{str3}");
// would be equivalent to
auto s =3D F"{str1}{str2}{str3}"s;

I don't see why allowing UDL to work like that would decrease usability as=
=20
we could always use regular functions.
=20

>
> However more "natural" the UDL version *appears*, it's ultimately much=20
> more limiting to *use*. And while appearance is important, usability=20
> ought to be more important.
>
> You can't even do this in a header:
>
> struct Foo
> {
>   std::string value =3D F"{str1}{str2}{str3}"s;
> };
>
> That's due to having to `using namespace` the literals before you can use=
=20
> them. Calling a function directly requires no such gymnastics.
>

But you could always do this:
struct Foo
{
  std::string value =3D std::literals::string_literals::operator ""s(F
"{str1}{str2}{str3}");
};
At least if the UDL is not templated. But as templated UDLs are not made=20
for string literals according to the standard (and this is completely=20
stupid, btw), we are completely fine here.
And it goes in the same direction as your previous post: we should not try=
=20
to make UDL easier to use for regular string computation. In that case, it=
=20
is not easier, just possible.
=20

>
> Oh sure, modules will (thankfully) remedy this situation to a degree. But=
=20
> until everyone's codebase is modularized, that's going to be a problem. A=
nd=20
> even then, you shouldn't have to `using namespace blah` to be able to use=
=20
> string interpolation.
>

I never ever said we should use a namespace or rely on UDL to be able to=20
use string interpolation.
I just said how I tried to see how UDL would/should/could interact with=20
string interpolation.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/ef8fbc4c-08c0-409e-815b-28e161101231%40isocpp.or=
g.

------=_Part_10475_1336774937.1518469716933
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le lundi 12 f=C3=A9vrier 2018 21:11:14 UTC+1, Nico=
l Bolas a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v dir=3D"ltr">On Monday, February 12, 2018 at 12:43:41 PM UTC-5, <a>floria.=
...@gmail.com</a> 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">Le lundi 12 f=C3=A9vrier 2018 17:56:48 UTC+1, Nicol Bolas a =C3=A9crit=
=C2=A0:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Monday, =
February 12, 2018 at 11:15:33 AM UTC-5, <a>floria...@gmail.com</a> wrote:</=
div></blockquote><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"><=
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><blockq=
uote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:=
1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><blockquote class=3D"gmai=
l_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr"><div>With that in mind, the implementation =
of your concat function with my approach would be exactly the same as with =
your approach (with a call to &quot;operator...&quot; of std::string_proces=
sing ).</div><div><br></div><div>And then, with only c++17 metaprogramming =
capabilities, you could also use std::apply.<br></div></div></blockquote><d=
iv><br>You cannot `apply` things to operators. Not without creating a lambd=
a function that gets called with it.<br></div></div></blockquote><div>=C2=
=A0</div><div>Why not? You can get the address of an operator, and this is =
a callable object.</div></div></blockquote><div><br>You can only get the ad=
dress of a single overload of an operator. Remember: the whole idea is that=
 you&#39;re dealing with a sequence of variables of different types. So the=
 second parameter to the operator has to be of different types for differen=
t invocations of the operator.<br></div></div></blockquote><div><br></div><=
div>This is another quirk of C++ that should be fixed.<br></div></div></blo=
ckquote><div><br>Which incidentally is yet another proposal (lifting lambda=
s) that stalled.<br><br></div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" style=3D"margin:0;=
margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"=
ltr"><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><b=
lockquote 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>The fact is, it=
&#39;s a <i>lot</i> easier in C++ as it currently stands to go from paramet=
er pack of values to an object than it is to go from an object to a paramet=
er pack of values. I wish that were not the case, but so long as it is the =
case, parameter packs will remain the easier-to-use option.<br></div></div>=
</blockquote><div>=C2=A0</div><div>You have a point. <br></div><div><br></d=
iv><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bo=
rder-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><br></div>=
<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;borde=
r-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><div></=
div>UDL the aggregate is not important to me, but it was easy to include an=
d allows neat syntax (in my opinion).<br></div></blockquote><div><br>But it=
 makes it impossible to apply a UDL to the string fragments. And that&#39;s=
 important if you do want to use template metaprogramming on string literal=
s.<br></div></div></blockquote><div><br></div><div>I&#39;m not sure to see =
the use case here. When you use UDL, you want the whole literal to be what =
you say it would be.</div><div><div style=3D"background-color:rgb(250,250,2=
50);border-color:rgb(187,187,187);border-style:solid;border-width:1px"><cod=
e><div><span style=3D"color:#008">auto</span><span style=3D"color:#000"> s =
</span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#080">&quot;something&quot;</span><span style=3D"c=
olor:#000">s</span><span style=3D"color:#660">;</span><span style=3D"color:=
#000"> </span><span style=3D"color:#800">// s is a string</span><span style=
=3D"color:#000"><br></span><span style=3D"color:#008">auto</span><span styl=
e=3D"color:#000"> sv </span><span style=3D"color:#660">=3D</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#080">&quot;some other&quot;<=
/span><span style=3D"color:#000">sv</span><span style=3D"color:#660">;</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#800">// s is a s=
tring view</span><span style=3D"color:#000"><br></span></div></code></div>W=
e are not interested in what is happening in the middle. I don&#39;t why it=
 should be different with string interpolation (or whatever the name is).<b=
r></div></div></blockquote><div><br>Because not all of the &quot;literal&qu=
ot; is actually a literal anymore. That&#39;s the whole point of string int=
erpolation: you&#39;re taking a literal and you&#39;re augmenting it with s=
ome non-literal data. Potentially <i>runtime</i> non-literal data. It isn&#=
39;t a literal anymore, so the UDL suffix can&#39;t apply to the aggregate.=
 It can only apply to the individual literal fragments of the string.<br></=
div></div></blockquote><div><br></div><div>Here, I don&#39;t care if it&#39=
;s called a literal, or if we invent a new name for this concept that appea=
red to match the concept of literal when &quot;string interpolation&quot; w=
as not a thing.</div><div>I&#39;m more interested in the final syntax as th=
e end user will see it.</div><div><br></div><div>And I would prefer concate=
nate like this:</div><div><div style=3D"background-color:rgb(250,250,250);b=
order-color:rgb(187,187,187);border-style:solid;border-width:1px"><code><di=
v><span style=3D"color:#008">auto</span><span style=3D"color:#000"> s </spa=
n><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> F</span>=
<span style=3D"color:#080">&quot;{str1}{str2}{str3}&quot;</span><span style=
=3D"color:#000">s</span><span style=3D"color:#660">;</span><span style=3D"c=
olor:#000"><br></span></div></code></div></div><div>than this:</div><div><d=
iv style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187)=
;border-style:solid;border-width:1px"><code><div><span style=3D"color:#008"=
>auto</span><span style=3D"color:#000"> s </span><span style=3D"color:#660"=
>=3D</span><span style=3D"color:#000"> std</span><span style=3D"color:#660"=
>::</span><span style=3D"color:#000">concat</span><span style=3D"color:#660=
">(</span><span style=3D"color:#000">F</span><span style=3D"color:#080">&qu=
ot;{str1}{str2}{<wbr>str3}&quot;</span><span style=3D"color:#660">);</span>=
<span style=3D"color:#000"><br></span></div></code></div><br>The first one =
looks more natural in my opinion.<br></div></div></blockquote><div><br>It o=
nly looks more natural for the trivial cases. Consider what `std::concat` w=
ould look like. It creates an `ostringstream`, applies it to each parameter=
, and moves its result out. Why pick `ostringstream`? Why not allow the use=
r to decide which kind of stream to use and therefore which resulting strin=
g type to build?<br></div></div></blockquote><div><br></div><div>I never sa=
id this should work only with UDL. I just said that I think it is more natu=
ral if UDL worked like that.</div><div>But I really think the user should k=
eep control over what can be done with this syntax.</div><div>So I totally =
agree with you: users should be able to call their own functions with it.</=
div><div><br></div><div>And then, even considering F&quot;{str1}{str2}{str3=
}&quot;s for concatenating, I never mentionned std::ostringstream, I just s=
aid converted into an efficient way of concatenating strings.</div><div>In =
that case, I just considered that when we use operator &quot;&quot;s, we wa=
nt a std::string.<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quot=
e" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddin=
g-left: 1ex;"><div dir=3D"ltr"><div><br>You can&#39;t do that with a UDL; t=
hey can&#39;t take an extra template parameter. `std::concat` can.<br></div=
></div></blockquote><div><br></div><div>To do that, just use a function. We=
 can have multiple syntaxes to do the same thing.</div><div>The closest exa=
mple I can think of is:</div><div><div style=3D"background-color: rgb(250, =
250, 250); border-color: rgb(187, 187, 187); border-style: solid; border-wi=
dth: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"=
prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> s </span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> 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;" class=3D"styled-by-prettify">(</span><spa=
n style=3D"color: #080;" class=3D"styled-by-prettify">&quot;str&quot;</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">// is equivalent to</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> s </span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> </span><span style=3D"color: #080;" class=3D=
"styled-by-prettify">&quot;str&quot;</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">s</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></div></code></div></div><div><br></div><div>We could ha=
ve exatcly the situation with string interpolation:</div><div><div style=3D=
"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); bo=
rder-style: solid; border-width: 1px; overflow-wrap: break-word;" class=3D"=
prettyprint"><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"> s </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"> std</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">concat</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">F</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&q=
uot;{str1}{str2}{str3}&quot;</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br></span><span style=3D"color: #800;" class=3D"styled-by-pretti=
fy">// would be equivalent to</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"> s </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> F</spa=
n><span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;{str1}{st=
r2}{str3}&quot;</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">s</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></=
div></code></div><br>I don&#39;t see why allowing UDL to work like that wou=
ld decrease usability as we could always use regular functions.<br></div><d=
iv>=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><br>However more &quot;natural&quot; the UDL version <i>appears</i>,=
 it&#39;s ultimately much more limiting to <i>use</i>. And while appearance=
 is important, usability ought to be more important.<br><br>You can&#39;t e=
ven do this in a header:<br><br><div style=3D"background-color:rgb(250,250,=
250);border-color:rgb(187,187,187);border-style:solid;border-width:1px"><co=
de><div><span style=3D"color:#008">struct</span><span style=3D"color:#000">=
 </span><span style=3D"color:#606">Foo</span><span style=3D"color:#000"><br=
></span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=
=C2=A0 std</span><span style=3D"color:#660">::</span><span style=3D"color:#=
008">string</span><span style=3D"color:#000"> value </span><span style=3D"c=
olor:#660">=3D</span><span style=3D"color:#000"> F</span><span style=3D"col=
or:#080">&quot;{str1}{str2}{str3}&quot;</span><span style=3D"color:#000">s<=
/span><span style=3D"color:#660">;</span><span style=3D"color:#000"><br></s=
pan><span style=3D"color:#660">};</span></div></code></div><br>That&#39;s d=
ue to having to `using namespace` the literals before you can use them. Cal=
ling a function directly requires no such gymnastics.<br></div></div></bloc=
kquote><div><br></div><div>But you could always do this:</div><div><div sty=
le=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187=
); border-style: solid; border-width: 1px; overflow-wrap: break-word;" clas=
s=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subprettyprint"=
><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,1=
87);border-style:solid;border-width:1px"><code><div><span style=3D"color:#0=
08"><span style=3D"color: #008;" class=3D"styled-by-prettify">struct</span>=
</span><span style=3D"color:#000"><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span></span><span style=3D"color:#606"><span style=3D"c=
olor: #606;" class=3D"styled-by-prettify">Foo</span></span><span style=3D"c=
olor:#000"><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></=
span></span><span style=3D"color:#660"><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span></span><span style=3D"color:#000"><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 std</span></spa=
n><span style=3D"color:#660"><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">::</span></span><span style=3D"color:#008"><span style=3D"color=
: #008;" class=3D"styled-by-prettify">string</span></span><span style=3D"co=
lor:#000"><span style=3D"color: #000;" class=3D"styled-by-prettify"> value =
</span></span><span style=3D"color:#660"><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> std</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">literals</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">string_=
literals</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::=
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">operator</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #080;" class=3D"styled-by-prettify">&quot;&quot;</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">s</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span></span><span style=
=3D"color:#000"><span style=3D"color: #000;" class=3D"styled-by-prettify">F=
</span></span><span style=3D"color:#080"><span style=3D"color: #080;" class=
=3D"styled-by-prettify">&quot;{str1}{str2}{str3}&quot;</span></span><span s=
tyle=3D"color:#000"><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">)</span></span><span style=3D"color:#660"><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">;</span></span><span style=3D"color:#000"><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></span><spa=
n style=3D"color:#660"><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">};</span></span></div></code></div></div></code></div>At least if the=
 UDL is not templated. But as templated UDLs are not made for string litera=
ls according to the standard (and this is completely stupid, btw), we are c=
ompletely fine here.<br>And it goes in the same direction as your previous =
post: we should not try to make UDL easier to use for regular string comput=
ation. In that case, it is not easier, just possible.<br></div><div>=C2=A0<=
/div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><br=
>Oh sure, modules will (thankfully) remedy this situation to a degree. But =
until everyone&#39;s codebase is modularized, that&#39;s going to be a prob=
lem. And even then, you shouldn&#39;t have to `using namespace blah` to be =
able to use string interpolation.</div></div></blockquote><div><br></div><d=
iv>I never ever said we should use a namespace or rely on UDL to be able to=
 use string interpolation.</div><div>I just said how I tried to see how UDL=
 would/should/could interact with string interpolation.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/ef8fbc4c-08c0-409e-815b-28e161101231%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/ef8fbc4c-08c0-409e-815b-28e161101231=
%40isocpp.org</a>.<br />

------=_Part_10475_1336774937.1518469716933--

------=_Part_10474_1553800702.1518469716932--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 12 Feb 2018 22:28:45 -0800 (PST)
Raw View
------=_Part_11142_338305851.1518503325765
Content-Type: multipart/alternative;
 boundary="----=_Part_11143_774229816.1518503325766"

------=_Part_11143_774229816.1518503325766
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Monday, February 12, 2018 at 4:08:37 PM UTC-5, floria...@gmail.com wrote=
:
>
> Le lundi 12 f=C3=A9vrier 2018 21:11:14 UTC+1, Nicol Bolas a =C3=A9crit :
>>
>> On Monday, February 12, 2018 at 12:43:41 PM UTC-5, floria...@gmail.com=
=20
>> wrote:
>>>
>>> Le lundi 12 f=C3=A9vrier 2018 17:56:48 UTC+1, Nicol Bolas a =C3=A9crit =
:
>>>>
>>>> On Monday, February 12, 2018 at 11:15:33 AM UTC-5, floria...@gmail.com=
=20
>>>> wrote:
>>>>
>>> With that in mind, the implementation of your concat function with my=
=20
>>>>>>> approach would be exactly the same as with your approach (with a ca=
ll to=20
>>>>>>> "operator..." of std::string_processing ).
>>>>>>>
>>>>>>> And then, with only c++17 metaprogramming capabilities, you could=
=20
>>>>>>> also use std::apply.
>>>>>>>
>>>>>>
>>>>>> You cannot `apply` things to operators. Not without creating a lambd=
a=20
>>>>>> function that gets called with it.
>>>>>>
>>>>> =20
>>>>> Why not? You can get the address of an operator, and this is a=20
>>>>> callable object.
>>>>>
>>>>
>>>> You can only get the address of a single overload of an operator.=20
>>>> Remember: the whole idea is that you're dealing with a sequence of=20
>>>> variables of different types. So the second parameter to the operator =
has=20
>>>> to be of different types for different invocations of the operator.
>>>>
>>>
>>> This is another quirk of C++ that should be fixed.
>>>
>>
>> Which incidentally is yet another proposal (lifting lambdas) that stalle=
d.
>>
>> The fact is, it's a *lot* easier in C++ as it currently stands to go=20
>>>>>> from parameter pack of values to an object than it is to go from an =
object=20
>>>>>> to a parameter pack of values. I wish that were not the case, but so=
 long=20
>>>>>> as it is the case, parameter packs will remain the easier-to-use opt=
ion.
>>>>>>
>>>>> =20
>>>>> You have a point.=20
>>>>>
>>>>>
>>>>>> UDL the aggregate is not important to me, but it was easy to include=
=20
>>>>>>> and allows neat syntax (in my opinion).
>>>>>>>
>>>>>>
>>>>>> But it makes it impossible to apply a UDL to the string fragments.=
=20
>>>>>> And that's important if you do want to use template metaprogramming =
on=20
>>>>>> string literals.
>>>>>>
>>>>>
>>>>> I'm not sure to see the use case here. When you use UDL, you want the=
=20
>>>>> whole literal to be what you say it would be.
>>>>> auto s =3D "something"s; // s is a string
>>>>> auto sv =3D "some other"sv; // s is a string view
>>>>> We are not interested in what is happening in the middle. I don't why=
=20
>>>>> it should be different with string interpolation (or whatever the nam=
e is).
>>>>>
>>>>
>>>> Because not all of the "literal" is actually a literal anymore. That's=
=20
>>>> the whole point of string interpolation: you're taking a literal and y=
ou're=20
>>>> augmenting it with some non-literal data. Potentially *runtime*=20
>>>> non-literal data. It isn't a literal anymore, so the UDL suffix can't =
apply=20
>>>> to the aggregate. It can only apply to the individual literal fragment=
s of=20
>>>> the string.
>>>>
>>>
>>> Here, I don't care if it's called a literal, or if we invent a new name=
=20
>>> for this concept that appeared to match the concept of literal when "st=
ring=20
>>> interpolation" was not a thing.
>>> I'm more interested in the final syntax as the end user will see it.
>>>
>>> And I would prefer concatenate like this:
>>> auto s =3D F"{str1}{str2}{str3}"s;
>>> than this:
>>> auto s =3D std::concat(F"{str1}{str2}{str3}");
>>>
>>> The first one looks more natural in my opinion.
>>>
>>
>> It only looks more natural for the trivial cases. Consider what=20
>> `std::concat` would look like. It creates an `ostringstream`, applies it=
 to=20
>> each parameter, and moves its result out. Why pick `ostringstream`? Why =
not=20
>> allow the user to decide which kind of stream to use and therefore which=
=20
>> resulting string type to build?
>>
>
> I never said this should work only with UDL. I just said that I think it=
=20
> is more natural if UDL worked like that.
> But I really think the user should keep control over what can be done wit=
h=20
> this syntax.
> So I totally agree with you: users should be able to call their own=20
> functions with it.
>
> And then, even considering F"{str1}{str2}{str3}"s for concatenating, I=20
> never mentionned std::ostringstream, I just said converted into an=20
> efficient way of concatenating strings.
> In that case, I just considered that when we use operator ""s, we want a=
=20
> std::string.
>

You say that the literal `s` means you want a `std::string`. But that's not=
=20
enough information, because you now have to define how to *get* a=20
`std::string` from values that aren't `std::string`. That's why you need=20
more information than a mere literal can provide.

There are many ways to get a std::string from an interpolated string. Your=
=20
`operator""s` will only be doing one of them. That mechanism will be *fixed=
*.=20
Inflexible. Unchangeable.

That's bad. A function call will be more versatile.

You can't do that with a UDL; they can't take an extra template parameter.=
=20
>> `std::concat` can.
>>
>
> To do that, just use a function. We can have multiple syntaxes to do the=
=20
> same thing.
> The closest example I can think of is:
> auto s =3D std::string("str");
> // is equivalent to
> auto s =3D "str"s;
>
>
No, it's not:

auto s1 =3D std::string("str\0str");
auto s2 =3D "str\0str"s;

In `s1` the constructor has to do `char_traits<char>::length` to compute=20
the number of characters in the string. That will terminate the string at=
=20
the first NUL character. In the second case, the UDL gets the size from the=
=20
literal parameter directly.

Things like this are why it is important to separate literal operations=20
from string interpolation. So that UDLs can do the job they exist to do=20
(literal synthesis) and string interpolation can do the job its meant to do=
=20
(breaking down literals into sequences of values). And the aggregation can=
=20
do the job its meant to do (take sequences of values and act on them).

It's a 3 step process; let's not interfere in that.
=20

> We could have exatcly the situation with string interpolation:
> auto s =3D std::concat(F"{str1}{str2}{str3}");
> // would be equivalent to
> auto s =3D F"{str1}{str2}{str3}"s;
>
> I don't see why allowing UDL to work like that would decrease usability a=
s=20
> we could always use regular functions.
>

Because you can't do this:

std::concat(F"some string {variable} other string"sv);

Under my system, the UDL employed here allows you to decide how to process=
=20
each of the literal fragments. The UDL applies to the parts of the literal=
=20
that are actually strings. So `concat` would get `string_view`s, rather=20
than `const char[X]` parameters.

Under your system, the processing of the literal fragments is controlled=20
entirely by the system that computes the aggregation.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/1a7f714d-4a91-4a95-8da4-0c688d18c4c4%40isocpp.or=
g.

------=_Part_11143_774229816.1518503325766
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Monday, February 12, 2018 at 4:08:37 PM UTC-5, floria..=
..@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"=
ltr">Le lundi 12 f=C3=A9vrier 2018 21:11:14 UTC+1, Nicol Bolas a =C3=A9crit=
=C2=A0:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Monday, =
February 12, 2018 at 12:43:41 PM UTC-5, <a>floria...@gmail.com</a> wrote:<b=
lockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-=
left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">Le lundi 12 f=C3=A9v=
rier 2018 17:56:48 UTC+1, Nicol Bolas a =C3=A9crit=C2=A0:<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">On Monday, February 12, 2018 at 11:=
15:33 AM UTC-5, <a>floria...@gmail.com</a> wrote:</div></blockquote><blockq=
uote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:=
1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><blockquote class=3D"gmai=
l_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr"><div> </div><blockquote class=3D"gmail_quot=
e" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"ltr"><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>With that in mind, the implementation of your concat function=
 with my approach would be exactly the same as with your approach (with a c=
all to &quot;operator...&quot; of std::string_processing ).</div><div><br><=
/div><div>And then, with only c++17 metaprogramming capabilities, you could=
 also use std::apply.<br></div></div></blockquote><div><br>You cannot `appl=
y` things to operators. Not without creating a lambda function that gets ca=
lled with it.<br></div></div></blockquote><div>=C2=A0</div><div>Why not? Yo=
u can get the address of an operator, and this is a callable object.</div><=
/div></blockquote><div><br>You can only get the address of a single overloa=
d of an operator. Remember: the whole idea is that you&#39;re dealing with =
a sequence of variables of different types. So the second parameter to the =
operator has to be of different types for different invocations of the oper=
ator.<br></div></div></blockquote><div><br></div><div>This is another quirk=
 of C++ that should be fixed.<br></div></div></blockquote><div><br>Which in=
cidentally is yet another proposal (lifting lambdas) that stalled.<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><b=
lockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-=
left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><blockquote class=3D=
"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_=
quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddi=
ng-left:1ex"><div dir=3D"ltr"><div>The fact is, it&#39;s a <i>lot</i> easie=
r in C++ as it currently stands to go from parameter pack of values to an o=
bject than it is to go from an object to a parameter pack of values. I wish=
 that were not the case, but so long as it is the case, parameter packs wil=
l remain the easier-to-use option.<br></div></div></blockquote><div>=C2=A0<=
/div><div>You have a point. <br></div><div><br></div><blockquote class=3D"g=
mail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;=
padding-left:1ex"><div dir=3D"ltr"><div><br></div><blockquote class=3D"gmai=
l_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr"><div></div><div></div>UDL the aggregate is =
not important to me, but it was easy to include and allows neat syntax (in =
my opinion).<br></div></blockquote><div><br>But it makes it impossible to a=
pply a UDL to the string fragments. And that&#39;s important if you do want=
 to use template metaprogramming on string literals.<br></div></div></block=
quote><div><br></div><div>I&#39;m not sure to see the use case here. When y=
ou use UDL, you want the whole literal to be what you say it would be.</div=
><div><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,=
187,187);border-style:solid;border-width:1px"><code><div><span style=3D"col=
or:#008">auto</span><span style=3D"color:#000"> s </span><span style=3D"col=
or:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:=
#080">&quot;something&quot;</span><span style=3D"color:#000">s</span><span =
style=3D"color:#660">;</span><span style=3D"color:#000"> </span><span style=
=3D"color:#800">// s is a string</span><span style=3D"color:#000"><br></spa=
n><span style=3D"color:#008">auto</span><span style=3D"color:#000"> sv </sp=
an><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#080">&quot;some other&quot;</span><span style=3D"colo=
r:#000">sv</span><span style=3D"color:#660">;</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#800">// s is a string view</span><span st=
yle=3D"color:#000"><br></span></div></code></div>We are not interested in w=
hat is happening in the middle. I don&#39;t why it should be different with=
 string interpolation (or whatever the name is).<br></div></div></blockquot=
e><div><br>Because not all of the &quot;literal&quot; is actually a literal=
 anymore. That&#39;s the whole point of string interpolation: you&#39;re ta=
king a literal and you&#39;re augmenting it with some non-literal data. Pot=
entially <i>runtime</i> non-literal data. It isn&#39;t a literal anymore, s=
o the UDL suffix can&#39;t apply to the aggregate. It can only apply to the=
 individual literal fragments of the string.<br></div></div></blockquote><d=
iv><br></div><div>Here, I don&#39;t care if it&#39;s called a literal, or i=
f we invent a new name for this concept that appeared to match the concept =
of literal when &quot;string interpolation&quot; was not a thing.</div><div=
>I&#39;m more interested in the final syntax as the end user will see it.</=
div><div><br></div><div>And I would prefer concatenate like this:</div><div=
><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,1=
87);border-style:solid;border-width:1px"><code><div><span style=3D"color:#0=
08">auto</span><span style=3D"color:#000"> s </span><span style=3D"color:#6=
60">=3D</span><span style=3D"color:#000"> F</span><span style=3D"color:#080=
">&quot;{str1}{str2}{str3}&quot;</span><span style=3D"color:#000">s</span><=
span style=3D"color:#660">;</span><span style=3D"color:#000"><br></span></d=
iv></code></div></div><div>than this:</div><div><div style=3D"background-co=
lor:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;borde=
r-width:1px"><code><div><span style=3D"color:#008">auto</span><span style=
=3D"color:#000"> s </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">concat</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">F</span><span style=3D"color:#080">&quot;{str1}{str2}{<wbr>=
str3}&quot;</span><span style=3D"color:#660">);</span><span style=3D"color:=
#000"><br></span></div></code></div><br>The first one looks more natural in=
 my opinion.<br></div></div></blockquote><div><br>It only looks more natura=
l for the trivial cases. Consider what `std::concat` would look like. It cr=
eates an `ostringstream`, applies it to each parameter, and moves its resul=
t out. Why pick `ostringstream`? Why not allow the user to decide which kin=
d of stream to use and therefore which resulting string type to build?<br><=
/div></div></blockquote><div><br></div><div>I never said this should work o=
nly with UDL. I just said that I think it is more natural if UDL worked lik=
e that.</div><div>But I really think the user should keep control over what=
 can be done with this syntax.</div><div>So I totally agree with you: users=
 should be able to call their own functions with it.</div><div><br></div><d=
iv>And then, even considering F&quot;{str1}{str2}{str3}&quot;s for concaten=
ating, I never mentionned std::ostringstream, I just said converted into an=
 efficient way of concatenating strings.</div><div>In that case, I just con=
sidered that when we use operator &quot;&quot;s, we want a std::string.<br>=
</div></div></blockquote><div><br>You say that the literal `s` means you wa=
nt a `std::string`. But that&#39;s not enough information, because you now =
have to define how to <i>get</i> a `std::string` from values that aren&#39;=
t `std::string`. That&#39;s why you need more information than a mere liter=
al can provide.<br><br>There are many ways to get a std::string from an int=
erpolated string. Your `operator&quot;&quot;s` will only be doing one of th=
em. That mechanism will be <i>fixed</i>. Inflexible. Unchangeable.<br><br>T=
hat&#39;s bad. A function call will be more versatile.<br><br></div><blockq=
uote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-lef=
t: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><blockquo=
te class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>You can&#39;t do that =
with a UDL; they can&#39;t take an extra template parameter. `std::concat` =
can.<br></div></div></blockquote><div><br></div><div>To do that, just use a=
 function. We can have multiple syntaxes to do the same thing.</div><div>Th=
e closest example I can think of is:</div><div><div style=3D"background-col=
or:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border=
-width:1px"><code><div><span style=3D"color:#008">auto</span><span style=3D=
"color:#000"> s </span><span style=3D"color:#660">=3D</span><span style=3D"=
color:#000"> std</span><span style=3D"color:#660">::</span><span style=3D"c=
olor:#008">string</span><span style=3D"color:#660">(</span><span style=3D"c=
olor:#080">&quot;str&quot;</span><span style=3D"color:#660">);</span><span =
style=3D"color:#000"><br></span><span style=3D"color:#800">// is equivalent=
 to</span><span style=3D"color:#000"><br></span><span style=3D"color:#008">=
auto</span><span style=3D"color:#000"> s </span><span style=3D"color:#660">=
=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#080">&qu=
ot;str&quot;</span><span style=3D"color:#000">s</span><span style=3D"color:=
#660">;</span><span style=3D"color:#000"><br></span></div></code></div></di=
v><div><br></div></div></blockquote><div><br>No, it&#39;s not:<br><br><div =
style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, =
187); border-style: solid; border-width: 1px; overflow-wrap: break-word;" c=
lass=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subprettypri=
nt"><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> s1 </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">=3D</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">(</span><span style=3D"color: #080;" class=3D"styl=
ed-by-prettify">&quot;str\0str&quot;</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> s2 </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: #080;" class=3D"styled-by-prettify">&quot;str\0str&q=
uot;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">s</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span></div><=
/code></div><br>In `s1` the constructor has to do `char_traits&lt;char&gt;:=
:length` to compute the number of characters in the string. That will termi=
nate the string at the first NUL character. In the second case, the UDL get=
s the size from the literal parameter directly.<br><br>Things like this are=
 why it is important to separate literal operations from string interpolati=
on. So that UDLs can do the job they exist to do (literal synthesis) and st=
ring interpolation can do the job its meant to do (breaking down literals i=
nto sequences of values). And the aggregation can do the job its meant to d=
o (take sequences of values and act on them).<br><br>It&#39;s a 3 step proc=
ess; let&#39;s not interfere in that.<br>=C2=A0</div><blockquote class=3D"g=
mail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc sol=
id;padding-left: 1ex;"><div dir=3D"ltr"><div></div><div>We could have exatc=
ly the situation with string interpolation:</div><div><div style=3D"backgro=
und-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid=
;border-width:1px"><code><div><span style=3D"color:#008">auto</span><span s=
tyle=3D"color:#000"> s </span><span style=3D"color:#660">=3D</span><span st=
yle=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span sty=
le=3D"color:#000">concat</span><span style=3D"color:#660">(</span><span sty=
le=3D"color:#000">F</span><span style=3D"color:#080">&quot;{str1}{str2}{<wb=
r>str3}&quot;</span><span style=3D"color:#660">);</span><span style=3D"colo=
r:#000"><br></span><span style=3D"color:#800">// would be equivalent to</sp=
an><span style=3D"color:#000"><br></span><span style=3D"color:#008">auto</s=
pan><span style=3D"color:#000"> s </span><span style=3D"color:#660">=3D</sp=
an><span style=3D"color:#000"> F</span><span style=3D"color:#080">&quot;{st=
r1}{str2}{str3}&quot;</span><span style=3D"color:#000">s</span><span style=
=3D"color:#660">;</span><span style=3D"color:#000"><br></span></div></code>=
</div><br>I don&#39;t see why allowing UDL to work like that would decrease=
 usability as we could always use regular functions.<br></div></div></block=
quote><div><br>Because you can&#39;t do this:<br><br><div style=3D"backgrou=
nd-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-styl=
e: solid; border-width: 1px; overflow-wrap: break-word;" class=3D"prettypri=
nt"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=
=3D"color: #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">concat</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">F</span><span style=3D"color: #080;" class=3D"styled-by-=
prettify">&quot;some string {variable} other string&quot;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">sv</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">);</span></div></code></div><br>Unde=
r my system, the UDL employed here allows you to decide how to process each=
 of the literal fragments. The UDL applies to the parts of the literal that=
 are actually strings. So `concat` would get `string_view`s, rather than `c=
onst char[X]` parameters.<br><br>Under your system, the processing of the l=
iteral fragments is controlled entirely by the system that computes the agg=
regation.</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/1a7f714d-4a91-4a95-8da4-0c688d18c4c4%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/1a7f714d-4a91-4a95-8da4-0c688d18c4c4=
%40isocpp.org</a>.<br />

------=_Part_11143_774229816.1518503325766--

------=_Part_11142_338305851.1518503325765--

.


Author: florian.csdt@gmail.com
Date: Tue, 13 Feb 2018 01:49:59 -0800 (PST)
Raw View
------=_Part_11246_456222789.1518515400041
Content-Type: multipart/alternative;
 boundary="----=_Part_11247_380355209.1518515400042"

------=_Part_11247_380355209.1518515400042
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



Le mardi 13 f=C3=A9vrier 2018 07:28:45 UTC+1, Nicol Bolas a =C3=A9crit :
>
> On Monday, February 12, 2018 at 4:08:37 PM UTC-5, floria...@gmail.com=20
> wrote:
>>
>> Le lundi 12 f=C3=A9vrier 2018 21:11:14 UTC+1, Nicol Bolas a =C3=A9crit :
>>>
>>> On Monday, February 12, 2018 at 12:43:41 PM UTC-5, floria...@gmail.com=
=20
>>> wrote:
>>>>
>>>> Le lundi 12 f=C3=A9vrier 2018 17:56:48 UTC+1, Nicol Bolas a =C3=A9crit=
 :
>>>>>
>>>>> On Monday, February 12, 2018 at 11:15:33 AM UTC-5, floria...@gmail.co=
m=20
>>>>> wrote:
>>>>>
>>>> With that in mind, the implementation of your concat function with my=
=20
>>>>>>>> approach would be exactly the same as with your approach (with a c=
all to=20
>>>>>>>> "operator..." of std::string_processing ).
>>>>>>>>
>>>>>>>> And then, with only c++17 metaprogramming capabilities, you could=
=20
>>>>>>>> also use std::apply.
>>>>>>>>
>>>>>>>
>>>>>>> You cannot `apply` things to operators. Not without creating a=20
>>>>>>> lambda function that gets called with it.
>>>>>>>
>>>>>> =20
>>>>>> Why not? You can get the address of an operator, and this is a=20
>>>>>> callable object.
>>>>>>
>>>>>
>>>>> You can only get the address of a single overload of an operator.=20
>>>>> Remember: the whole idea is that you're dealing with a sequence of=20
>>>>> variables of different types. So the second parameter to the operator=
 has=20
>>>>> to be of different types for different invocations of the operator.
>>>>>
>>>>
>>>> This is another quirk of C++ that should be fixed.
>>>>
>>>
>>> Which incidentally is yet another proposal (lifting lambdas) that=20
>>> stalled.
>>>
>>> The fact is, it's a *lot* easier in C++ as it currently stands to go=20
>>>>>>> from parameter pack of values to an object than it is to go from an=
 object=20
>>>>>>> to a parameter pack of values. I wish that were not the case, but s=
o long=20
>>>>>>> as it is the case, parameter packs will remain the easier-to-use op=
tion.
>>>>>>>
>>>>>> =20
>>>>>> You have a point.=20
>>>>>>
>>>>>>
>>>>>>> UDL the aggregate is not important to me, but it was easy to includ=
e=20
>>>>>>>> and allows neat syntax (in my opinion).
>>>>>>>>
>>>>>>>
>>>>>>> But it makes it impossible to apply a UDL to the string fragments.=
=20
>>>>>>> And that's important if you do want to use template metaprogramming=
 on=20
>>>>>>> string literals.
>>>>>>>
>>>>>>
>>>>>> I'm not sure to see the use case here. When you use UDL, you want th=
e=20
>>>>>> whole literal to be what you say it would be.
>>>>>> auto s =3D "something"s; // s is a string
>>>>>> auto sv =3D "some other"sv; // s is a string view
>>>>>> We are not interested in what is happening in the middle. I don't wh=
y=20
>>>>>> it should be different with string interpolation (or whatever the na=
me is).
>>>>>>
>>>>>
>>>>> Because not all of the "literal" is actually a literal anymore. That'=
s=20
>>>>> the whole point of string interpolation: you're taking a literal and =
you're=20
>>>>> augmenting it with some non-literal data. Potentially *runtime*=20
>>>>> non-literal data. It isn't a literal anymore, so the UDL suffix can't=
 apply=20
>>>>> to the aggregate. It can only apply to the individual literal fragmen=
ts of=20
>>>>> the string.
>>>>>
>>>>
>>>> Here, I don't care if it's called a literal, or if we invent a new nam=
e=20
>>>> for this concept that appeared to match the concept of literal when "s=
tring=20
>>>> interpolation" was not a thing.
>>>> I'm more interested in the final syntax as the end user will see it.
>>>>
>>>> And I would prefer concatenate like this:
>>>> auto s =3D F"{str1}{str2}{str3}"s;
>>>> than this:
>>>> auto s =3D std::concat(F"{str1}{str2}{str3}");
>>>>
>>>> The first one looks more natural in my opinion.
>>>>
>>>
>>> It only looks more natural for the trivial cases. Consider what=20
>>> `std::concat` would look like. It creates an `ostringstream`, applies i=
t to=20
>>> each parameter, and moves its result out. Why pick `ostringstream`? Why=
 not=20
>>> allow the user to decide which kind of stream to use and therefore whic=
h=20
>>> resulting string type to build?
>>>
>>
>> I never said this should work only with UDL. I just said that I think it=
=20
>> is more natural if UDL worked like that.
>> But I really think the user should keep control over what can be done=20
>> with this syntax.
>> So I totally agree with you: users should be able to call their own=20
>> functions with it.
>>
>> And then, even considering F"{str1}{str2}{str3}"s for concatenating, I=
=20
>> never mentionned std::ostringstream, I just said converted into an=20
>> efficient way of concatenating strings.
>> In that case, I just considered that when we use operator ""s, we want a=
=20
>> std::string.
>>
>
> You say that the literal `s` means you want a `std::string`. But that's=
=20
> not enough information, because you now have to define how to *get* a=20
> `std::string` from values that aren't `std::string`. That's why you need=
=20
> more information than a mere literal can provide.
>
> There are many ways to get a std::string from an interpolated string. You=
r=20
> `operator""s` will only be doing one of them. That mechanism will be=20
> *fixed*. Inflexible. Unchangeable.
>

I never said here the this operator ""s should work with this: F"foo {5}=20
bar"s... To be fair, I have been thinking this should work only if every=20
single part is convertible to std::string. So the result is unambiguous, so=
=20
it doesn't matter if it is fixed, unchangeable.
And if you want a function call, do a function call, it will work.
=20

>
> That's bad. A function call will be more versatile.
>
> You can't do that with a UDL; they can't take an extra template parameter=
..=20
>>> `std::concat` can.
>>>
>>
>> To do that, just use a function. We can have multiple syntaxes to do the=
=20
>> same thing.
>> The closest example I can think of is:
>> auto s =3D std::string("str");
>> // is equivalent to
>> auto s =3D "str"s;
>>
>>
> No, it's not:
>
> auto s1 =3D std::string("str\0str");
> auto s2 =3D "str\0str"s;
>
> In `s1` the constructor has to do `char_traits<char>::length` to compute=
=20
> the number of characters in the string. That will terminate the string at=
=20
> the first NUL character. In the second case, the UDL gets the size from t=
he=20
> literal parameter directly.
>
> Things like this are why it is important to separate literal operations=
=20
> from string interpolation. So that UDLs can do the job they exist to do=
=20
> (literal synthesis) and string interpolation can do the job its meant to =
do=20
> (breaking down literals into sequences of values). And the aggregation ca=
n=20
> do the job its meant to do (take sequences of values and act on them).
>

String literals are broken now. This is not fixable by UDL currently. So=20
all in all, we are doomed here.

If you write a function that need to take std::string_view for literal=20
parts, let's do that, you don't need to force the literal to be a=20
string_view to work, as they are implicitly convertible from const char[]&.=
=20
The same with std::string.
No, forget about that. Even that is not true (why?). It's funny how the=20
more I dig in C++, the more bulky it appears to be just because of these=20
very small annoyances.
=20

>
> It's a 3 step process; let's not interfere in that.
> =20
>
>> We could have exatcly the situation with string interpolation:
>> auto s =3D std::concat(F"{str1}{str2}{str3}");
>> // would be equivalent to
>> auto s =3D F"{str1}{str2}{str3}"s;
>>
>> I don't see why allowing UDL to work like that would decrease usability=
=20
>> as we could always use regular functions.
>>
>
> Because you can't do this:
>
> std::concat(F"some string {variable} other string"sv);
>
> Under my system, the UDL employed here allows you to decide how to proces=
s=20
> each of the literal fragments. The UDL applies to the parts of the litera=
l=20
> that are actually strings. So `concat` would get `string_view`s, rather=
=20
> than `const char[X]` parameters.
>
> Under your system, the processing of the literal fragments is controlled=
=20
> entirely by the system that computes the aggregation.
>

Let's sum up, string literals are broken today. So we should probably try=
=20
to solve this big issue before trying to see how we can cripple=20
string_interpolation in order to fit in current-ish C++.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/5f8efcc0-f4e9-4518-abe5-5fffeab55083%40isocpp.or=
g.

------=_Part_11247_380355209.1518515400042
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le mardi 13 f=C3=A9vrier 2018 07:28:45 UTC+1, Nico=
l Bolas a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v dir=3D"ltr">On Monday, February 12, 2018 at 4:08:37 PM UTC-5, <a>floria..=
..@gmail.com</a> wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;m=
argin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr">Le lundi 12 f=C3=A9vrier 2018 21:11:14 UTC+1, Nicol Bolas a =C3=A9crit=
=C2=A0:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Monday, =
February 12, 2018 at 12:43:41 PM UTC-5, <a>floria...@gmail.com</a> wrote:<b=
lockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-=
left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">Le lundi 12 f=C3=A9v=
rier 2018 17:56:48 UTC+1, Nicol Bolas a =C3=A9crit=C2=A0:<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">On Monday, February 12, 2018 at 11:=
15:33 AM UTC-5, <a>floria...@gmail.com</a> wrote:</div></blockquote><blockq=
uote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:=
1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><blockquote class=3D"gmai=
l_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr"><div> </div><blockquote class=3D"gmail_quot=
e" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"ltr"><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>With that in mind, the implementation of your concat function=
 with my approach would be exactly the same as with your approach (with a c=
all to &quot;operator...&quot; of std::string_processing ).</div><div><br><=
/div><div>And then, with only c++17 metaprogramming capabilities, you could=
 also use std::apply.<br></div></div></blockquote><div><br>You cannot `appl=
y` things to operators. Not without creating a lambda function that gets ca=
lled with it.<br></div></div></blockquote><div>=C2=A0</div><div>Why not? Yo=
u can get the address of an operator, and this is a callable object.</div><=
/div></blockquote><div><br>You can only get the address of a single overloa=
d of an operator. Remember: the whole idea is that you&#39;re dealing with =
a sequence of variables of different types. So the second parameter to the =
operator has to be of different types for different invocations of the oper=
ator.<br></div></div></blockquote><div><br></div><div>This is another quirk=
 of C++ that should be fixed.<br></div></div></blockquote><div><br>Which in=
cidentally is yet another proposal (lifting lambdas) that stalled.<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><b=
lockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-=
left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><blockquote class=3D=
"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_=
quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddi=
ng-left:1ex"><div dir=3D"ltr"><div>The fact is, it&#39;s a <i>lot</i> easie=
r in C++ as it currently stands to go from parameter pack of values to an o=
bject than it is to go from an object to a parameter pack of values. I wish=
 that were not the case, but so long as it is the case, parameter packs wil=
l remain the easier-to-use option.<br></div></div></blockquote><div>=C2=A0<=
/div><div>You have a point. <br></div><div><br></div><blockquote class=3D"g=
mail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;=
padding-left:1ex"><div dir=3D"ltr"><div><br></div><blockquote class=3D"gmai=
l_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr"><div></div><div></div>UDL the aggregate is =
not important to me, but it was easy to include and allows neat syntax (in =
my opinion).<br></div></blockquote><div><br>But it makes it impossible to a=
pply a UDL to the string fragments. And that&#39;s important if you do want=
 to use template metaprogramming on string literals.<br></div></div></block=
quote><div><br></div><div>I&#39;m not sure to see the use case here. When y=
ou use UDL, you want the whole literal to be what you say it would be.</div=
><div><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,=
187,187);border-style:solid;border-width:1px"><code><div><span style=3D"col=
or:#008">auto</span><span style=3D"color:#000"> s </span><span style=3D"col=
or:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:=
#080">&quot;something&quot;</span><span style=3D"color:#000">s</span><span =
style=3D"color:#660">;</span><span style=3D"color:#000"> </span><span style=
=3D"color:#800">// s is a string</span><span style=3D"color:#000"><br></spa=
n><span style=3D"color:#008">auto</span><span style=3D"color:#000"> sv </sp=
an><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#080">&quot;some other&quot;</span><span style=3D"colo=
r:#000">sv</span><span style=3D"color:#660">;</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#800">// s is a string view</span><span st=
yle=3D"color:#000"><br></span></div></code></div>We are not interested in w=
hat is happening in the middle. I don&#39;t why it should be different with=
 string interpolation (or whatever the name is).<br></div></div></blockquot=
e><div><br>Because not all of the &quot;literal&quot; is actually a literal=
 anymore. That&#39;s the whole point of string interpolation: you&#39;re ta=
king a literal and you&#39;re augmenting it with some non-literal data. Pot=
entially <i>runtime</i> non-literal data. It isn&#39;t a literal anymore, s=
o the UDL suffix can&#39;t apply to the aggregate. It can only apply to the=
 individual literal fragments of the string.<br></div></div></blockquote><d=
iv><br></div><div>Here, I don&#39;t care if it&#39;s called a literal, or i=
f we invent a new name for this concept that appeared to match the concept =
of literal when &quot;string interpolation&quot; was not a thing.</div><div=
>I&#39;m more interested in the final syntax as the end user will see it.</=
div><div><br></div><div>And I would prefer concatenate like this:</div><div=
><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,1=
87);border-style:solid;border-width:1px"><code><div><span style=3D"color:#0=
08">auto</span><span style=3D"color:#000"> s </span><span style=3D"color:#6=
60">=3D</span><span style=3D"color:#000"> F</span><span style=3D"color:#080=
">&quot;{str1}{str2}{str3}&quot;</span><span style=3D"color:#000">s</span><=
span style=3D"color:#660">;</span><span style=3D"color:#000"><br></span></d=
iv></code></div></div><div>than this:</div><div><div style=3D"background-co=
lor:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;borde=
r-width:1px"><code><div><span style=3D"color:#008">auto</span><span style=
=3D"color:#000"> s </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">concat</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">F</span><span style=3D"color:#080">&quot;{str1}{str2}{<wbr>=
str3}&quot;</span><span style=3D"color:#660">);</span><span style=3D"color:=
#000"><br></span></div></code></div><br>The first one looks more natural in=
 my opinion.<br></div></div></blockquote><div><br>It only looks more natura=
l for the trivial cases. Consider what `std::concat` would look like. It cr=
eates an `ostringstream`, applies it to each parameter, and moves its resul=
t out. Why pick `ostringstream`? Why not allow the user to decide which kin=
d of stream to use and therefore which resulting string type to build?<br><=
/div></div></blockquote><div><br></div><div>I never said this should work o=
nly with UDL. I just said that I think it is more natural if UDL worked lik=
e that.</div><div>But I really think the user should keep control over what=
 can be done with this syntax.</div><div>So I totally agree with you: users=
 should be able to call their own functions with it.</div><div><br></div><d=
iv>And then, even considering F&quot;{str1}{str2}{str3}&quot;s for concaten=
ating, I never mentionned std::ostringstream, I just said converted into an=
 efficient way of concatenating strings.</div><div>In that case, I just con=
sidered that when we use operator &quot;&quot;s, we want a std::string.<br>=
</div></div></blockquote><div><br>You say that the literal `s` means you wa=
nt a `std::string`. But that&#39;s not enough information, because you now =
have to define how to <i>get</i> a `std::string` from values that aren&#39;=
t `std::string`. That&#39;s why you need more information than a mere liter=
al can provide.<br><br>There are many ways to get a std::string from an int=
erpolated string. Your `operator&quot;&quot;s` will only be doing one of th=
em. That mechanism will be <i>fixed</i>. Inflexible. Unchangeable.<br></div=
></div></blockquote><div><br></div><div>I never said here the this operator=
 &quot;&quot;s should work with this: F&quot;foo {5} bar&quot;s... To be fa=
ir, I have been thinking this should work only if every single part is conv=
ertible to std::string. So the result is unambiguous, so it doesn&#39;t mat=
ter if it is fixed, unchangeable.</div><div>And if you want a function call=
, do a function call, it will work.<br></div><div>=C2=A0</div><blockquote c=
lass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px=
 #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><br>That&#39;s bad. A=
 function call will be more versatile.<br><br></div><blockquote class=3D"gm=
ail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quo=
te" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-=
left:1ex"><div dir=3D"ltr"><div>You can&#39;t do that with a UDL; they can&=
#39;t take an extra template parameter. `std::concat` can.<br></div></div><=
/blockquote><div><br></div><div>To do that, just use a function. We can hav=
e multiple syntaxes to do the same thing.</div><div>The closest example I c=
an think of is:</div><div><div style=3D"background-color:rgb(250,250,250);b=
order-color:rgb(187,187,187);border-style:solid;border-width:1px"><code><di=
v><span style=3D"color:#008">auto</span><span style=3D"color:#000"> s </spa=
n><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> std</spa=
n><span style=3D"color:#660">::</span><span style=3D"color:#008">string</sp=
an><span style=3D"color:#660">(</span><span style=3D"color:#080">&quot;str&=
quot;</span><span style=3D"color:#660">);</span><span style=3D"color:#000">=
<br></span><span style=3D"color:#800">// is equivalent to</span><span style=
=3D"color:#000"><br></span><span style=3D"color:#008">auto</span><span styl=
e=3D"color:#000"> s </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> </span><span style=3D"color:#080">&quot;str&quot;</span><s=
pan style=3D"color:#000">s</span><span style=3D"color:#660">;</span><span s=
tyle=3D"color:#000"><br></span></div></code></div></div><div><br></div></di=
v></blockquote><div><br>No, it&#39;s not:<br><br><div style=3D"background-c=
olor:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;bord=
er-width:1px"><code><div><span style=3D"color:#008">auto</span><span style=
=3D"color:#000"> s1 </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span style=
=3D"color:#008">string</span><span style=3D"color:#660">(</span><span style=
=3D"color:#080">&quot;str\0str&quot;</span><span style=3D"color:#660">);</s=
pan><span style=3D"color:#000"><br></span><span style=3D"color:#008">auto</=
span><span style=3D"color:#000"> s2 </span><span style=3D"color:#660">=3D</=
span><span style=3D"color:#000"> </span><span style=3D"color:#080">&quot;st=
r\0str&quot;</span><span style=3D"color:#000">s</span><span style=3D"color:=
#660">;</span></div></code></div><br>In `s1` the constructor has to do `cha=
r_traits&lt;char&gt;::length` to compute the number of characters in the st=
ring. That will terminate the string at the first NUL character. In the sec=
ond case, the UDL gets the size from the literal parameter directly.<br><br=
>Things like this are why it is important to separate literal operations fr=
om string interpolation. So that UDLs can do the job they exist to do (lite=
ral synthesis) and string interpolation can do the job its meant to do (bre=
aking down literals into sequences of values). And the aggregation can do t=
he job its meant to do (take sequences of values and act on them).<br></div=
></div></blockquote><div><br></div><div>String literals are broken now. Thi=
s is not fixable by UDL currently. So all in all, we are doomed here.</div>=
<div><br></div><div>If you write a function that need to take std::string_v=
iew for literal parts, let&#39;s do that, you don&#39;t need to force the l=
iteral to be a string_view to work, as they are implicitly convertible from=
 const char[]&amp;. The same with std::string.</div><div>No, forget about t=
hat. Even that is not true (why?). It&#39;s funny how the more I dig in C++=
, the more bulky it appears to be just because of these very small annoyanc=
es.<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">=
<div dir=3D"ltr"><div><br>It&#39;s a 3 step process; let&#39;s not interfer=
e in 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><div>We could have exatcly the situation with string in=
terpolation:</div><div><div style=3D"background-color:rgb(250,250,250);bord=
er-color:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><=
span style=3D"color:#008">auto</span><span style=3D"color:#000"> s </span><=
span style=3D"color:#660">=3D</span><span style=3D"color:#000"> std</span><=
span style=3D"color:#660">::</span><span style=3D"color:#000">concat</span>=
<span style=3D"color:#660">(</span><span style=3D"color:#000">F</span><span=
 style=3D"color:#080">&quot;{str1}{str2}{<wbr>str3}&quot;</span><span style=
=3D"color:#660">);</span><span style=3D"color:#000"><br></span><span style=
=3D"color:#800">// would be equivalent to</span><span style=3D"color:#000">=
<br></span><span style=3D"color:#008">auto</span><span style=3D"color:#000"=
> s </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000">=
 F</span><span style=3D"color:#080">&quot;{str1}{str2}{str3}&quot;</span><s=
pan style=3D"color:#000">s</span><span style=3D"color:#660">;</span><span s=
tyle=3D"color:#000"><br></span></div></code></div><br>I don&#39;t see why a=
llowing UDL to work like that would decrease usability as we could always u=
se regular functions.<br></div></div></blockquote><div><br>Because you can&=
#39;t do this:<br><br><div style=3D"background-color:rgb(250,250,250);borde=
r-color:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><s=
pan style=3D"color:#000">std</span><span style=3D"color:#660">::</span><spa=
n style=3D"color:#000">concat</span><span style=3D"color:#660">(</span><spa=
n style=3D"color:#000">F</span><span style=3D"color:#080">&quot;some string=
 {variable} other string&quot;</span><span style=3D"color:#000">sv</span><s=
pan style=3D"color:#660">);</span></div></code></div><br>Under my system, t=
he UDL employed here allows you to decide how to process each of the litera=
l fragments. The UDL applies to the parts of the literal that are actually =
strings. So `concat` would get `string_view`s, rather than `const char[X]` =
parameters.<br><br>Under your system, the processing of the literal fragmen=
ts is controlled entirely by the system that computes the aggregation.</div=
></div></blockquote><div><br></div><div>Let&#39;s sum up, string literals a=
re broken today. So we should probably try to solve this big issue before t=
rying to see how we can cripple string_interpolation in order to fit in cur=
rent-ish C++.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/5f8efcc0-f4e9-4518-abe5-5fffeab55083%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/5f8efcc0-f4e9-4518-abe5-5fffeab55083=
%40isocpp.org</a>.<br />

------=_Part_11247_380355209.1518515400042--

------=_Part_11246_456222789.1518515400041--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 13 Feb 2018 08:35:49 -0800 (PST)
Raw View
------=_Part_5991_505544240.1518539749571
Content-Type: multipart/alternative;
 boundary="----=_Part_5992_217892087.1518539749572"

------=_Part_5992_217892087.1518539749572
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Tuesday, February 13, 2018 at 4:50:00 AM UTC-5, floria...@gmail.com=20
wrote:
>
> Le mardi 13 f=C3=A9vrier 2018 07:28:45 UTC+1, Nicol Bolas a =C3=A9crit :
>>
>> On Monday, February 12, 2018 at 4:08:37 PM UTC-5, floria...@gmail.com=20
>> wrote:
>>>
>>> Le lundi 12 f=C3=A9vrier 2018 21:11:14 UTC+1, Nicol Bolas a =C3=A9crit =
:
>>>>
>>>> On Monday, February 12, 2018 at 12:43:41 PM UTC-5, floria...@gmail.com=
=20
>>>> wrote:
>>>>>
>>>>> Le lundi 12 f=C3=A9vrier 2018 17:56:48 UTC+1, Nicol Bolas a =C3=A9cri=
t :
>>>>>>
>>>>>> On Monday, February 12, 2018 at 11:15:33 AM UTC-5,=20
>>>>>> floria...@gmail.com wrote:
>>>>>>
>>>>> With that in mind, the implementation of your concat function with my=
=20
>>>>>>>>> approach would be exactly the same as with your approach (with a =
call to=20
>>>>>>>>> "operator..." of std::string_processing ).
>>>>>>>>>
>>>>>>>>> And then, with only c++17 metaprogramming capabilities, you could=
=20
>>>>>>>>> also use std::apply.
>>>>>>>>>
>>>>>>>>
>>>>>>>> You cannot `apply` things to operators. Not without creating a=20
>>>>>>>> lambda function that gets called with it.
>>>>>>>>
>>>>>>> =20
>>>>>>> Why not? You can get the address of an operator, and this is a=20
>>>>>>> callable object.
>>>>>>>
>>>>>>
>>>>>> You can only get the address of a single overload of an operator.=20
>>>>>> Remember: the whole idea is that you're dealing with a sequence of=
=20
>>>>>> variables of different types. So the second parameter to the operato=
r has=20
>>>>>> to be of different types for different invocations of the operator.
>>>>>>
>>>>>
>>>>> This is another quirk of C++ that should be fixed.
>>>>>
>>>>
>>>> Which incidentally is yet another proposal (lifting lambdas) that=20
>>>> stalled.
>>>>
>>>> The fact is, it's a *lot* easier in C++ as it currently stands to go=
=20
>>>>>>>> from parameter pack of values to an object than it is to go from a=
n object=20
>>>>>>>> to a parameter pack of values. I wish that were not the case, but =
so long=20
>>>>>>>> as it is the case, parameter packs will remain the easier-to-use o=
ption.
>>>>>>>>
>>>>>>> =20
>>>>>>> You have a point.=20
>>>>>>>
>>>>>>>
>>>>>>>> UDL the aggregate is not important to me, but it was easy to=20
>>>>>>>>> include and allows neat syntax (in my opinion).
>>>>>>>>>
>>>>>>>>
>>>>>>>> But it makes it impossible to apply a UDL to the string fragments.=
=20
>>>>>>>> And that's important if you do want to use template metaprogrammin=
g on=20
>>>>>>>> string literals.
>>>>>>>>
>>>>>>>
>>>>>>> I'm not sure to see the use case here. When you use UDL, you want=
=20
>>>>>>> the whole literal to be what you say it would be.
>>>>>>> auto s =3D "something"s; // s is a string
>>>>>>> auto sv =3D "some other"sv; // s is a string view
>>>>>>> We are not interested in what is happening in the middle. I don't=
=20
>>>>>>> why it should be different with string interpolation (or whatever t=
he name=20
>>>>>>> is).
>>>>>>>
>>>>>>
>>>>>> Because not all of the "literal" is actually a literal anymore.=20
>>>>>> That's the whole point of string interpolation: you're taking a lite=
ral and=20
>>>>>> you're augmenting it with some non-literal data. Potentially=20
>>>>>> *runtime* non-literal data. It isn't a literal anymore, so the UDL=
=20
>>>>>> suffix can't apply to the aggregate. It can only apply to the indivi=
dual=20
>>>>>> literal fragments of the string.
>>>>>>
>>>>>
>>>>> Here, I don't care if it's called a literal, or if we invent a new=20
>>>>> name for this concept that appeared to match the concept of literal w=
hen=20
>>>>> "string interpolation" was not a thing.
>>>>> I'm more interested in the final syntax as the end user will see it.
>>>>>
>>>>> And I would prefer concatenate like this:
>>>>> auto s =3D F"{str1}{str2}{str3}"s;
>>>>> than this:
>>>>> auto s =3D std::concat(F"{str1}{str2}{str3}");
>>>>>
>>>>> The first one looks more natural in my opinion.
>>>>>
>>>>
>>>> It only looks more natural for the trivial cases. Consider what=20
>>>> `std::concat` would look like. It creates an `ostringstream`, applies =
it to=20
>>>> each parameter, and moves its result out. Why pick `ostringstream`? Wh=
y not=20
>>>> allow the user to decide which kind of stream to use and therefore whi=
ch=20
>>>> resulting string type to build?
>>>>
>>>
>>> I never said this should work only with UDL. I just said that I think i=
t=20
>>> is more natural if UDL worked like that.
>>> But I really think the user should keep control over what can be done=
=20
>>> with this syntax.
>>> So I totally agree with you: users should be able to call their own=20
>>> functions with it.
>>>
>>> And then, even considering F"{str1}{str2}{str3}"s for concatenating, I=
=20
>>> never mentionned std::ostringstream, I just said converted into an=20
>>> efficient way of concatenating strings.
>>> In that case, I just considered that when we use operator ""s, we want =
a=20
>>> std::string.
>>>
>>
>> You say that the literal `s` means you want a `std::string`. But that's=
=20
>> not enough information, because you now have to define how to *get* a=20
>> `std::string` from values that aren't `std::string`. That's why you need=
=20
>> more information than a mere literal can provide.
>>
>> There are many ways to get a std::string from an interpolated string.=20
>> Your `operator""s` will only be doing one of them. That mechanism will b=
e=20
>> *fixed*. Inflexible. Unchangeable.
>>
>
> I never said here the this operator ""s should work with this: F"foo {5}=
=20
> bar"s... To be fair, I have been thinking this should work only if every=
=20
> single part is convertible to std::string. So the result is unambiguous, =
so=20
> it doesn't matter if it is fixed, unchangeable.
> And if you want a function call, do a function call, it will work.
> =20
>
>>
>> That's bad. A function call will be more versatile.
>>
>> You can't do that with a UDL; they can't take an extra template=20
>>>> parameter. `std::concat` can.
>>>>
>>>
>>> To do that, just use a function. We can have multiple syntaxes to do th=
e=20
>>> same thing.
>>> The closest example I can think of is:
>>> auto s =3D std::string("str");
>>> // is equivalent to
>>> auto s =3D "str"s;
>>>
>>>
>> No, it's not:
>>
>> auto s1 =3D std::string("str\0str");
>> auto s2 =3D "str\0str"s;
>>
>> In `s1` the constructor has to do `char_traits<char>::length` to compute=
=20
>> the number of characters in the string. That will terminate the string a=
t=20
>> the first NUL character. In the second case, the UDL gets the size from =
the=20
>> literal parameter directly.
>>
>> Things like this are why it is important to separate literal operations=
=20
>> from string interpolation. So that UDLs can do the job they exist to do=
=20
>> (literal synthesis) and string interpolation can do the job its meant to=
 do=20
>> (breaking down literals into sequences of values). And the aggregation c=
an=20
>> do the job its meant to do (take sequences of values and act on them).
>>
>
> String literals are broken now. This is not fixable by UDL currently. So=
=20
> all in all, we are doomed here.
>
If you write a function that need to take std::string_view for literal=20
> parts, let's do that, you don't need to force the literal to be a=20
> string_view to work, as they are implicitly convertible from const char[]=
&.=20
> The same with std::string.
> No, forget about that. Even that is not true (why?).
>

Because it would never be called. Basically, what you'd need is this=20
constructor:

template<size_t N>
string_view(const char s[N]);

But you already have this constructor:

string_view(const char *s);

An array decays into a pointer. And since the pointer constructor is not a=
=20
template, it is considered a better match than the array version. And=20
therefore, any ltieral you pass will go through the pointer version rather=
=20
than the array template.

And it should be noted that this has nothing to do with being a literal. If=
=20
you used a `const char[]` variable, it *still* would prefer the pointer=20
version due to array->pointer conversion. So this is not a case of "string=
=20
literals are broken now".

But there's no "fix" for this, since any array->pointer "fix" would be both=
=20
wildly incompatible with C and break tons and tons of code. So you can=20
either accept the language and work with what we have, or rail against it.

It's funny how the more I dig in C++, the more bulky it appears to be just=
=20
> because of these very small annoyances.
> =20
>
>>
>> It's a 3 step process; let's not interfere in that.
>> =20
>>
>>> We could have exatcly the situation with string interpolation:
>>> auto s =3D std::concat(F"{str1}{str2}{str3}");
>>> // would be equivalent to
>>> auto s =3D F"{str1}{str2}{str3}"s;
>>>
>>> I don't see why allowing UDL to work like that would decrease usability=
=20
>>> as we could always use regular functions.
>>>
>>
>> Because you can't do this:
>>
>> std::concat(F"some string {variable} other string"sv);
>>
>> Under my system, the UDL employed here allows you to decide how to=20
>> process each of the literal fragments. The UDL applies to the parts of t=
he=20
>> literal that are actually strings. So `concat` would get `string_view`s,=
=20
>> rather than `const char[X]` parameters.
>>
>> Under your system, the processing of the literal fragments is controlled=
=20
>> entirely by the system that computes the aggregation.
>>
>
> Let's sum up, string literals are broken today. So we should probably try=
=20
> to solve this big issue before trying to see how we can cripple=20
> string_interpolation in order to fit in current-ish C++.
>

I fail to see why applying a UDL to the literal fragments rather than the=
=20
interpolation aggregation operation should be considered "crippling" string=
=20
interpolation.

Whatever breakage you see in literals isn't standing in the way of string=
=20
interpolation. It's just standing in the way of string interpolation=20
working the way *you* want it to.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/0e0876bb-7a44-45ff-ab9b-6443e78ea59c%40isocpp.or=
g.

------=_Part_5992_217892087.1518539749572
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Tuesday, February 13, 2018 at 4:50:00 AM UTC-5, floria.=
...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr">Le mardi 13 f=C3=A9vrier 2018 07:28:45 UTC+1, Nicol Bolas a =C3=A9cri=
t=C2=A0:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Monday,=
 February 12, 2018 at 4:08:37 PM UTC-5, <a>floria...@gmail.com</a> wrote:<b=
lockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-=
left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">Le lundi 12 f=C3=A9v=
rier 2018 21:11:14 UTC+1, Nicol Bolas a =C3=A9crit=C2=A0:<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">On Monday, February 12, 2018 at 12:=
43:41 PM UTC-5, <a>floria...@gmail.com</a> wrote:<blockquote class=3D"gmail=
_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr">Le lundi 12 f=C3=A9vrier 2018 17:56:48 UTC+1=
, Nicol Bolas a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D=
"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr">On Monday, February 12, 2018 at 11:15:33 AM UTC-5, <a>floria=
....@gmail.com</a> wrote:</div></blockquote><blockquote class=3D"gmail_quote=
" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:=
0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div> </div><blockquote class=3D"gmail_quote" style=3D"margin:0;ma=
rgin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"lt=
r"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bo=
rder-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>With that =
in mind, the implementation of your concat function with my approach would =
be exactly the same as with your approach (with a call to &quot;operator...=
&quot; of std::string_processing ).</div><div><br></div><div>And then, with=
 only c++17 metaprogramming capabilities, you could also use std::apply.<br=
></div></div></blockquote><div><br>You cannot `apply` things to operators. =
Not without creating a lambda function that gets called with it.<br></div><=
/div></blockquote><div>=C2=A0</div><div>Why not? You can get the address of=
 an operator, and this is a callable object.</div></div></blockquote><div><=
br>You can only get the address of a single overload of an operator. Rememb=
er: the whole idea is that you&#39;re dealing with a sequence of variables =
of different types. So the second parameter to the operator has to be of di=
fferent types for different invocations of the operator.<br></div></div></b=
lockquote><div><br></div><div>This is another quirk of C++ that should be f=
ixed.<br></div></div></blockquote><div><br>Which incidentally is yet anothe=
r proposal (lifting lambdas) that stalled.<br><br></div><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></div><blockquote class=3D"gma=
il_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pa=
dding-left:1ex"><div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D=
"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" style=3D"margin=
:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div>The fact is, it&#39;s a <i>lot</i> easier in C++ as it curren=
tly stands to go from parameter pack of values to an object than it is to g=
o from an object to a parameter pack of values. I wish that were not the ca=
se, but so long as it is the case, parameter packs will remain the easier-t=
o-use option.<br></div></div></blockquote><div>=C2=A0</div><div>You have a =
point. <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"><di=
v dir=3D"ltr"><div><br></div><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div d=
ir=3D"ltr"><div></div><div></div>UDL the aggregate is not important to me, =
but it was easy to include and allows neat syntax (in my opinion).<br></div=
></blockquote><div><br>But it makes it impossible to apply a UDL to the str=
ing fragments. And that&#39;s important if you do want to use template meta=
programming on string literals.<br></div></div></blockquote><div><br></div>=
<div>I&#39;m not sure to see the use case here. When you use UDL, you want =
the whole literal to be what you say it would be.</div><div><div style=3D"b=
ackground-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style=
:solid;border-width:1px"><code><div><span style=3D"color:#008">auto</span><=
span style=3D"color:#000"> s </span><span style=3D"color:#660">=3D</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#080">&quot;something=
&quot;</span><span style=3D"color:#000">s</span><span style=3D"color:#660">=
;</span><span style=3D"color:#000"> </span><span style=3D"color:#800">// s =
is a string</span><span style=3D"color:#000"><br></span><span style=3D"colo=
r:#008">auto</span><span style=3D"color:#000"> sv </span><span style=3D"col=
or:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:=
#080">&quot;some other&quot;</span><span style=3D"color:#000">sv</span><spa=
n style=3D"color:#660">;</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#800">// s is a string view</span><span style=3D"color:#000"><b=
r></span></div></code></div>We are not interested in what is happening in t=
he middle. I don&#39;t why it should be different with string interpolation=
 (or whatever the name is).<br></div></div></blockquote><div><br>Because no=
t all of the &quot;literal&quot; is actually a literal anymore. That&#39;s =
the whole point of string interpolation: you&#39;re taking a literal and yo=
u&#39;re augmenting it with some non-literal data. Potentially <i>runtime</=
i> non-literal data. It isn&#39;t a literal anymore, so the UDL suffix can&=
#39;t apply to the aggregate. It can only apply to the individual literal f=
ragments of the string.<br></div></div></blockquote><div><br></div><div>Her=
e, I don&#39;t care if it&#39;s called a literal, or if we invent a new nam=
e for this concept that appeared to match the concept of literal when &quot=
;string interpolation&quot; was not a thing.</div><div>I&#39;m more interes=
ted in the final syntax as the end user will see it.</div><div><br></div><d=
iv>And I would prefer concatenate like this:</div><div><div style=3D"backgr=
ound-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:soli=
d;border-width:1px"><code><div><span style=3D"color:#008">auto</span><span =
style=3D"color:#000"> s </span><span style=3D"color:#660">=3D</span><span s=
tyle=3D"color:#000"> F</span><span style=3D"color:#080">&quot;{str1}{str2}{=
str3}&quot;</span><span style=3D"color:#000">s</span><span style=3D"color:#=
660">;</span><span style=3D"color:#000"><br></span></div></code></div></div=
><div>than this:</div><div><div style=3D"background-color:rgb(250,250,250);=
border-color:rgb(187,187,187);border-style:solid;border-width:1px"><code><d=
iv><span style=3D"color:#008">auto</span><span style=3D"color:#000"> s </sp=
an><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> std</sp=
an><span style=3D"color:#660">::</span><span style=3D"color:#000">concat</s=
pan><span style=3D"color:#660">(</span><span style=3D"color:#000">F</span><=
span style=3D"color:#080">&quot;{str1}{str2}{<wbr>str3}&quot;</span><span s=
tyle=3D"color:#660">);</span><span style=3D"color:#000"><br></span></div></=
code></div><br>The first one looks more natural in my opinion.<br></div></d=
iv></blockquote><div><br>It only looks more natural for the trivial cases. =
Consider what `std::concat` would look like. It creates an `ostringstream`,=
 applies it to each parameter, and moves its result out. Why pick `ostrings=
tream`? Why not allow the user to decide which kind of stream to use and th=
erefore which resulting string type to build?<br></div></div></blockquote><=
div><br></div><div>I never said this should work only with UDL. I just said=
 that I think it is more natural if UDL worked like that.</div><div>But I r=
eally think the user should keep control over what can be done with this sy=
ntax.</div><div>So I totally agree with you: users should be able to call t=
heir own functions with it.</div><div><br></div><div>And then, even conside=
ring F&quot;{str1}{str2}{str3}&quot;s for concatenating, I never mentionned=
 std::ostringstream, I just said converted into an efficient way of concate=
nating strings.</div><div>In that case, I just considered that when we use =
operator &quot;&quot;s, we want a std::string.<br></div></div></blockquote>=
<div><br>You say that the literal `s` means you want a `std::string`. But t=
hat&#39;s not enough information, because you now have to define how to <i>=
get</i> a `std::string` from values that aren&#39;t `std::string`. That&#39=
;s why you need more information than a mere literal can provide.<br><br>Th=
ere are many ways to get a std::string from an interpolated string. Your `o=
perator&quot;&quot;s` will only be doing one of them. That mechanism will b=
e <i>fixed</i>. Inflexible. Unchangeable.<br></div></div></blockquote><div>=
<br></div><div>I never said here the this operator &quot;&quot;s should wor=
k with this: F&quot;foo {5} bar&quot;s... To be fair, I have been thinking =
this should work only if every single part is convertible to std::string. S=
o the result is unambiguous, so it doesn&#39;t matter if it is fixed, uncha=
ngeable.</div><div>And if you want a function call, do a function call, it =
will work.<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex=
"><div dir=3D"ltr"><div><br>That&#39;s bad. A function call will be more ve=
rsatile.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;m=
argin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr"><div></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-l=
eft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><di=
v>You can&#39;t do that with a UDL; they can&#39;t take an extra template p=
arameter. `std::concat` can.<br></div></div></blockquote><div><br></div><di=
v>To do that, just use a function. We can have multiple syntaxes to do the =
same thing.</div><div>The closest example I can think of is:</div><div><div=
 style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);b=
order-style:solid;border-width:1px"><code><div><span style=3D"color:#008">a=
uto</span><span style=3D"color:#000"> s </span><span style=3D"color:#660">=
=3D</span><span style=3D"color:#000"> std</span><span style=3D"color:#660">=
::</span><span style=3D"color:#008">string</span><span style=3D"color:#660"=
>(</span><span style=3D"color:#080">&quot;str&quot;</span><span style=3D"co=
lor:#660">);</span><span style=3D"color:#000"><br></span><span style=3D"col=
or:#800">// is equivalent to</span><span style=3D"color:#000"><br></span><s=
pan style=3D"color:#008">auto</span><span style=3D"color:#000"> s </span><s=
pan style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#080">&quot;str&quot;</span><span style=3D"color:#000">s</s=
pan><span style=3D"color:#660">;</span><span style=3D"color:#000"><br></spa=
n></div></code></div></div><div><br></div></div></blockquote><div><br>No, i=
t&#39;s not:<br><br><div style=3D"background-color:rgb(250,250,250);border-=
color:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><spa=
n style=3D"color:#008">auto</span><span style=3D"color:#000"> s1 </span><sp=
an style=3D"color:#660">=3D</span><span style=3D"color:#000"> std</span><sp=
an style=3D"color:#660">::</span><span style=3D"color:#008">string</span><s=
pan style=3D"color:#660">(</span><span style=3D"color:#080">&quot;str\0str&=
quot;</span><span style=3D"color:#660">);</span><span style=3D"color:#000">=
<br></span><span style=3D"color:#008">auto</span><span style=3D"color:#000"=
> s2 </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"=
> </span><span style=3D"color:#080">&quot;str\0str&quot;</span><span style=
=3D"color:#000">s</span><span style=3D"color:#660">;</span></div></code></d=
iv><br>In `s1` the constructor has to do `char_traits&lt;char&gt;::length` =
to compute the number of characters in the string. That will terminate the =
string at the first NUL character. In the second case, the UDL gets the siz=
e from the literal parameter directly.<br><br>Things like this are why it i=
s important to separate literal operations from string interpolation. So th=
at UDLs can do the job they exist to do (literal synthesis) and string inte=
rpolation can do the job its meant to do (breaking down literals into seque=
nces of values). And the aggregation can do the job its meant to do (take s=
equences of values and act on them).<br></div></div></blockquote><div><br><=
/div><div>String literals are broken now. This is not fixable by UDL curren=
tly. So all in all, we are doomed here.</div></div></blockquote><blockquote=
 class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1=
px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>If you write a func=
tion that need to take std::string_view for literal parts, let&#39;s do tha=
t, you don&#39;t need to force the literal to be a string_view to work, as =
they are implicitly convertible from const char[]&amp;. The same with std::=
string.</div><div>No, forget about that. Even that is not true (why?).</div=
></div></blockquote><div><br>Because it would never be called. Basically, w=
hat you&#39;d need is this constructor:<br><br><div style=3D"background-col=
or: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: sol=
id; border-width: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><c=
ode class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">template</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">size_t N</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>string_view</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">const</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">char</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 s</span><span style=3D"color: #660;" class=3D"styled-by-prettify">[</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">N</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">]);</span></div></code></d=
iv><br>But you already have this constructor:<br><br><div style=3D"backgrou=
nd-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-styl=
e: solid; border-width: 1px; overflow-wrap: break-word;" class=3D"prettypri=
nt"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=
=3D"color: #000;" class=3D"styled-by-prettify">string_view</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">const</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">char</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"=
>s</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span=
></div></code></div><br>An array decays into a pointer. And since the point=
er constructor is not a template, it is considered a better match than the =
array version. And therefore, any ltieral you pass will go through the poin=
ter version rather than the array template.<br><br>And it should be noted t=
hat this has nothing to do with being a literal. If you used a `const char[=
]` variable, it <i>still</i> would prefer the pointer version due to array-=
&gt;pointer conversion. So this is not a case of &quot;string literals are =
broken now&quot;.<br><br>But there&#39;s no &quot;fix&quot; for this, since=
 any array-&gt;pointer &quot;fix&quot; would be both wildly incompatible wi=
th C and break tons and tons of code. So you can either accept the language=
 and work with what we have, or rail against it.<br><br></div><blockquote c=
lass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px=
 #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>It&#39;s funny how th=
e more I dig in C++, the more bulky it appears to be just because of these =
very small annoyances.<br></div><div>=C2=A0</div><blockquote class=3D"gmail=
_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"><div><br>It&#39;s a 3 step process; let&#39;=
s not interfere in that.<br>=C2=A0</div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:=
1ex"><div dir=3D"ltr"><div></div><div>We could have exatcly the situation w=
ith string interpolation:</div><div><div style=3D"background-color:rgb(250,=
250,250);border-color:rgb(187,187,187);border-style:solid;border-width:1px"=
><code><div><span style=3D"color:#008">auto</span><span style=3D"color:#000=
"> s </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"=
> std</span><span style=3D"color:#660">::</span><span style=3D"color:#000">=
concat</span><span style=3D"color:#660">(</span><span style=3D"color:#000">=
F</span><span style=3D"color:#080">&quot;{str1}{str2}{<wbr>str3}&quot;</spa=
n><span style=3D"color:#660">);</span><span style=3D"color:#000"><br></span=
><span style=3D"color:#800">// would be equivalent to</span><span style=3D"=
color:#000"><br></span><span style=3D"color:#008">auto</span><span style=3D=
"color:#000"> s </span><span style=3D"color:#660">=3D</span><span style=3D"=
color:#000"> F</span><span style=3D"color:#080">&quot;{str1}{str2}{str3}&qu=
ot;</span><span style=3D"color:#000">s</span><span style=3D"color:#660">;</=
span><span style=3D"color:#000"><br></span></div></code></div><br>I don&#39=
;t see why allowing UDL to work like that would decrease usability as we co=
uld always use regular functions.<br></div></div></blockquote><div><br>Beca=
use you can&#39;t do this:<br><br><div style=3D"background-color:rgb(250,25=
0,250);border-color:rgb(187,187,187);border-style:solid;border-width:1px"><=
code><div><span style=3D"color:#000">std</span><span style=3D"color:#660">:=
:</span><span style=3D"color:#000">concat</span><span style=3D"color:#660">=
(</span><span style=3D"color:#000">F</span><span style=3D"color:#080">&quot=
;some string {variable} other string&quot;</span><span style=3D"color:#000"=
>sv</span><span style=3D"color:#660">);</span></div></code></div><br>Under =
my system, the UDL employed here allows you to decide how to process each o=
f the literal fragments. The UDL applies to the parts of the literal that a=
re actually strings. So `concat` would get `string_view`s, rather than `con=
st char[X]` parameters.<br><br>Under your system, the processing of the lit=
eral fragments is controlled entirely by the system that computes the aggre=
gation.</div></div></blockquote><div><br></div><div>Let&#39;s sum up, strin=
g literals are broken today. So we should probably try to solve this big is=
sue before trying to see how we can cripple string_interpolation in order t=
o fit in current-ish C++.<br></div></div></blockquote><div><br>I fail to se=
e why applying a UDL to the literal fragments rather than the interpolation=
 aggregation operation should be considered &quot;crippling&quot; string in=
terpolation.<br><br>Whatever breakage you see in literals isn&#39;t standin=
g in the way of string interpolation. It&#39;s just standing in the way of =
string interpolation working the way <i>you</i> want it to.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/0e0876bb-7a44-45ff-ab9b-6443e78ea59c%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/0e0876bb-7a44-45ff-ab9b-6443e78ea59c=
%40isocpp.org</a>.<br />

------=_Part_5992_217892087.1518539749572--

------=_Part_5991_505544240.1518539749571--

.


Author: florian.csdt@gmail.com
Date: Tue, 13 Feb 2018 09:18:59 -0800 (PST)
Raw View
------=_Part_11923_890054300.1518542339405
Content-Type: multipart/alternative;
 boundary="----=_Part_11924_21200749.1518542339406"

------=_Part_11924_21200749.1518542339406
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



Le mardi 13 f=C3=A9vrier 2018 17:35:49 UTC+1, Nicol Bolas a =C3=A9crit :
>
> On Tuesday, February 13, 2018 at 4:50:00 AM UTC-5, floria...@gmail.com=20
> wrote:
>>
>> Le mardi 13 f=C3=A9vrier 2018 07:28:45 UTC+1, Nicol Bolas a =C3=A9crit :
>>>
>>> On Monday, February 12, 2018 at 4:08:37 PM UTC-5, floria...@gmail.com=
=20
>>> wrote:
>>>>
>>>> Le lundi 12 f=C3=A9vrier 2018 21:11:14 UTC+1, Nicol Bolas a =C3=A9crit=
 :
>>>>>
>>>>> On Monday, February 12, 2018 at 12:43:41 PM UTC-5, floria...@gmail.co=
m=20
>>>>> wrote:
>>>>>>
>>>>>> Le lundi 12 f=C3=A9vrier 2018 17:56:48 UTC+1, Nicol Bolas a =C3=A9cr=
it :
>>>>>>>
>>>>>>> On Monday, February 12, 2018 at 11:15:33 AM UTC-5,=20
>>>>>>> floria...@gmail.com wrote:
>>>>>>>
>>>>>> With that in mind, the implementation of your concat function with m=
y=20
>>>>>>>>>> approach would be exactly the same as with your approach (with a=
 call to=20
>>>>>>>>>> "operator..." of std::string_processing ).
>>>>>>>>>>
>>>>>>>>>> And then, with only c++17 metaprogramming capabilities, you coul=
d=20
>>>>>>>>>> also use std::apply.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> You cannot `apply` things to operators. Not without creating a=20
>>>>>>>>> lambda function that gets called with it.
>>>>>>>>>
>>>>>>>> =20
>>>>>>>> Why not? You can get the address of an operator, and this is a=20
>>>>>>>> callable object.
>>>>>>>>
>>>>>>>
>>>>>>> You can only get the address of a single overload of an operator.=
=20
>>>>>>> Remember: the whole idea is that you're dealing with a sequence of=
=20
>>>>>>> variables of different types. So the second parameter to the operat=
or has=20
>>>>>>> to be of different types for different invocations of the operator.
>>>>>>>
>>>>>>
>>>>>> This is another quirk of C++ that should be fixed.
>>>>>>
>>>>>
>>>>> Which incidentally is yet another proposal (lifting lambdas) that=20
>>>>> stalled.
>>>>>
>>>>> The fact is, it's a *lot* easier in C++ as it currently stands to go=
=20
>>>>>>>>> from parameter pack of values to an object than it is to go from =
an object=20
>>>>>>>>> to a parameter pack of values. I wish that were not the case, but=
 so long=20
>>>>>>>>> as it is the case, parameter packs will remain the easier-to-use =
option.
>>>>>>>>>
>>>>>>>> =20
>>>>>>>> You have a point.=20
>>>>>>>>
>>>>>>>>
>>>>>>>>> UDL the aggregate is not important to me, but it was easy to=20
>>>>>>>>>> include and allows neat syntax (in my opinion).
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> But it makes it impossible to apply a UDL to the string fragments=
..=20
>>>>>>>>> And that's important if you do want to use template metaprogrammi=
ng on=20
>>>>>>>>> string literals.
>>>>>>>>>
>>>>>>>>
>>>>>>>> I'm not sure to see the use case here. When you use UDL, you want=
=20
>>>>>>>> the whole literal to be what you say it would be.
>>>>>>>> auto s =3D "something"s; // s is a string
>>>>>>>> auto sv =3D "some other"sv; // s is a string view
>>>>>>>> We are not interested in what is happening in the middle. I don't=
=20
>>>>>>>> why it should be different with string interpolation (or whatever =
the name=20
>>>>>>>> is).
>>>>>>>>
>>>>>>>
>>>>>>> Because not all of the "literal" is actually a literal anymore.=20
>>>>>>> That's the whole point of string interpolation: you're taking a lit=
eral and=20
>>>>>>> you're augmenting it with some non-literal data. Potentially=20
>>>>>>> *runtime* non-literal data. It isn't a literal anymore, so the UDL=
=20
>>>>>>> suffix can't apply to the aggregate. It can only apply to the indiv=
idual=20
>>>>>>> literal fragments of the string.
>>>>>>>
>>>>>>
>>>>>> Here, I don't care if it's called a literal, or if we invent a new=
=20
>>>>>> name for this concept that appeared to match the concept of literal =
when=20
>>>>>> "string interpolation" was not a thing.
>>>>>> I'm more interested in the final syntax as the end user will see it.
>>>>>>
>>>>>> And I would prefer concatenate like this:
>>>>>> auto s =3D F"{str1}{str2}{str3}"s;
>>>>>> than this:
>>>>>> auto s =3D std::concat(F"{str1}{str2}{str3}");
>>>>>>
>>>>>> The first one looks more natural in my opinion.
>>>>>>
>>>>>
>>>>> It only looks more natural for the trivial cases. Consider what=20
>>>>> `std::concat` would look like. It creates an `ostringstream`, applies=
 it to=20
>>>>> each parameter, and moves its result out. Why pick `ostringstream`? W=
hy not=20
>>>>> allow the user to decide which kind of stream to use and therefore wh=
ich=20
>>>>> resulting string type to build?
>>>>>
>>>>
>>>> I never said this should work only with UDL. I just said that I think=
=20
>>>> it is more natural if UDL worked like that.
>>>> But I really think the user should keep control over what can be done=
=20
>>>> with this syntax.
>>>> So I totally agree with you: users should be able to call their own=20
>>>> functions with it.
>>>>
>>>> And then, even considering F"{str1}{str2}{str3}"s for concatenating, I=
=20
>>>> never mentionned std::ostringstream, I just said converted into an=20
>>>> efficient way of concatenating strings.
>>>> In that case, I just considered that when we use operator ""s, we want=
=20
>>>> a std::string.
>>>>
>>>
>>> You say that the literal `s` means you want a `std::string`. But that's=
=20
>>> not enough information, because you now have to define how to *get* a=
=20
>>> `std::string` from values that aren't `std::string`. That's why you nee=
d=20
>>> more information than a mere literal can provide.
>>>
>>> There are many ways to get a std::string from an interpolated string.=
=20
>>> Your `operator""s` will only be doing one of them. That mechanism will =
be=20
>>> *fixed*. Inflexible. Unchangeable.
>>>
>>
>> I never said here the this operator ""s should work with this: F"foo {5}=
=20
>> bar"s... To be fair, I have been thinking this should work only if every=
=20
>> single part is convertible to std::string. So the result is unambiguous,=
 so=20
>> it doesn't matter if it is fixed, unchangeable.
>> And if you want a function call, do a function call, it will work.
>> =20
>>
>>>
>>> That's bad. A function call will be more versatile.
>>>
>>> You can't do that with a UDL; they can't take an extra template=20
>>>>> parameter. `std::concat` can.
>>>>>
>>>>
>>>> To do that, just use a function. We can have multiple syntaxes to do=
=20
>>>> the same thing.
>>>> The closest example I can think of is:
>>>> auto s =3D std::string("str");
>>>> // is equivalent to
>>>> auto s =3D "str"s;
>>>>
>>>>
>>> No, it's not:
>>>
>>> auto s1 =3D std::string("str\0str");
>>> auto s2 =3D "str\0str"s;
>>>
>>> In `s1` the constructor has to do `char_traits<char>::length` to comput=
e=20
>>> the number of characters in the string. That will terminate the string =
at=20
>>> the first NUL character. In the second case, the UDL gets the size from=
 the=20
>>> literal parameter directly.
>>>
>>> Things like this are why it is important to separate literal operations=
=20
>>> from string interpolation. So that UDLs can do the job they exist to do=
=20
>>> (literal synthesis) and string interpolation can do the job its meant t=
o do=20
>>> (breaking down literals into sequences of values). And the aggregation =
can=20
>>> do the job its meant to do (take sequences of values and act on them).
>>>
>>
>> String literals are broken now. This is not fixable by UDL currently. So=
=20
>> all in all, we are doomed here.
>>
> If you write a function that need to take std::string_view for literal=20
>> parts, let's do that, you don't need to force the literal to be a=20
>> string_view to work, as they are implicitly convertible from const char[=
]&.=20
>> The same with std::string.
>> No, forget about that. Even that is not true (why?).
>>
>
> Because it would never be called. Basically, what you'd need is this=20
> constructor:
>
> template<size_t N>
> string_view(const char s[N]);
>
> But you already have this constructor:
>
> string_view(const char *s);
>
> An array decays into a pointer. And since the pointer constructor is not =
a=20
> template, it is considered a better match than the array version. And=20
> therefore, any ltieral you pass will go through the pointer version rathe=
r=20
> than the array template.
>
> And it should be noted that this has nothing to do with being a literal.=
=20
> If you used a `const char[]` variable, it *still* would prefer the=20
> pointer version due to array->pointer conversion. So this is not a case o=
f=20
> "string literals are broken now".
>

How can you say that preferring a lossy conversion over a lossless one is=
=20
not broken? (Here, we lose the length information)
This make it impossible to work with string literal because they simply=20
don't exist in the language. This is why I said string literals are broken.
=20

>
> But there's no "fix" for this, since any array->pointer "fix" would be=20
> both wildly incompatible with C and break tons and tons of code. So you c=
an=20
> either accept the language and work with what we have, or rail against it=
..
>


Ok it's not possible to fix array decay because of backward compatibility,=
=20
but it is still possible to fix string literals if we make them something=
=20
that is not an array.
So I rail against those defects in order to be heard, and maybe, at some=20
point, they will be fixed.
If this is not the place to speak out loud about those defects, then where=
=20
should we go?

But don't get me wrong, when I code, I work with what I have, and I accept=
=20
the language as it is.
=20

>
> It's funny how the more I dig in C++, the more bulky it appears to be jus=
t=20
>> because of these very small annoyances.
>> =20
>>
>>>
>>> It's a 3 step process; let's not interfere in that.
>>> =20
>>>
>>>> We could have exatcly the situation with string interpolation:
>>>> auto s =3D std::concat(F"{str1}{str2}{str3}");
>>>> // would be equivalent to
>>>> auto s =3D F"{str1}{str2}{str3}"s;
>>>>
>>>> I don't see why allowing UDL to work like that would decrease usabilit=
y=20
>>>> as we could always use regular functions.
>>>>
>>>
>>> Because you can't do this:
>>>
>>> std::concat(F"some string {variable} other string"sv);
>>>
>>> Under my system, the UDL employed here allows you to decide how to=20
>>> process each of the literal fragments. The UDL applies to the parts of =
the=20
>>> literal that are actually strings. So `concat` would get `string_view`s=
,=20
>>> rather than `const char[X]` parameters.
>>>
>>> Under your system, the processing of the literal fragments is controlle=
d=20
>>> entirely by the system that computes the aggregation.
>>>
>>
>> Let's sum up, string literals are broken today. So we should probably tr=
y=20
>> to solve this big issue before trying to see how we can cripple=20
>> string_interpolation in order to fit in current-ish C++.
>>
>
> I fail to see why applying a UDL to the literal fragments rather than the=
=20
> interpolation aggregation operation should be considered "crippling" stri=
ng=20
> interpolation.
>
> Whatever breakage you see in literals isn't standing in the way of string=
=20
> interpolation. It's just standing in the way of string interpolation=20
> working the way *you* want it to.
>

Because string interpolation is dealing with string literals, if those=20
literals are broken (and they are), how can we have a proper string=20
interpolation?

You said:

> The point of that discussion was a comment someone made about doing=20
> template metaprogramming on string literals. To do that, you need a way t=
o=20
> access each literal as a distinct type, some `string_literal<char, 'c',=
=20
> 'h', 'a', 'r'>` type. And only a UDL applied to each fragment can perform=
=20
> that kind of synthesis.
>

UDL is the only way to do it only because string literals are broken. If we=
=20
had proper string literals, it should be possible to do it simply with=20
regular functions.
So even with your approach, broken string literals are a problem for string=
=20
interpolation. Just not at the same place.

I'm not sure if my approach is the right one (it's probably not), but most=
=20
of your arguments stand only because string literal are broken (otherwise,=
=20
it would have been simple to do the same with my approach too).

My point is: yes your approach makes it easier with current C++, but we=20
shouldn't go for something that works quite well with current C++, but=20
something that will work very well with future C++.
That's why I think it's better to first fix string literals. And then have=
=20
string interpolation right the first time.

And btw, if string literals are fixed, string interpolation could be made a=
=20
library solution only ( with a different but reasonable syntax).

PS: I think it would be preferable to stop the discussion here, as it=20
becomes more and more off-topic.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/3468ee0c-a44a-437a-a835-0156c623df2e%40isocpp.or=
g.

------=_Part_11924_21200749.1518542339406
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le mardi 13 f=C3=A9vrier 2018 17:35:49 UTC+1, Nico=
l Bolas a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v dir=3D"ltr">On Tuesday, February 13, 2018 at 4:50:00 AM UTC-5, <a>floria.=
...@gmail.com</a> 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">Le mardi 13 f=C3=A9vrier 2018 07:28:45 UTC+1, Nicol Bolas a =C3=A9crit=
=C2=A0:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Monday, =
February 12, 2018 at 4:08:37 PM UTC-5, <a>floria...@gmail.com</a> wrote:<bl=
ockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">Le lundi 12 f=C3=A9vr=
ier 2018 21:11:14 UTC+1, Nicol Bolas a =C3=A9crit=C2=A0:<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">On Monday, February 12, 2018 at 12:=
43:41 PM UTC-5, <a>floria...@gmail.com</a> wrote:<blockquote class=3D"gmail=
_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr">Le lundi 12 f=C3=A9vrier 2018 17:56:48 UTC+1=
, Nicol Bolas a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D=
"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr">On Monday, February 12, 2018 at 11:15:33 AM UTC-5, <a>floria=
....@gmail.com</a> wrote:</div></blockquote><blockquote class=3D"gmail_quote=
" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:=
0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div> </div><blockquote class=3D"gmail_quote" style=3D"margin:0;ma=
rgin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"lt=
r"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bo=
rder-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>With that =
in mind, the implementation of your concat function with my approach would =
be exactly the same as with your approach (with a call to &quot;operator...=
&quot; of std::string_processing ).</div><div><br></div><div>And then, with=
 only c++17 metaprogramming capabilities, you could also use std::apply.<br=
></div></div></blockquote><div><br>You cannot `apply` things to operators. =
Not without creating a lambda function that gets called with it.<br></div><=
/div></blockquote><div>=C2=A0</div><div>Why not? You can get the address of=
 an operator, and this is a callable object.</div></div></blockquote><div><=
br>You can only get the address of a single overload of an operator. Rememb=
er: the whole idea is that you&#39;re dealing with a sequence of variables =
of different types. So the second parameter to the operator has to be of di=
fferent types for different invocations of the operator.<br></div></div></b=
lockquote><div><br></div><div>This is another quirk of C++ that should be f=
ixed.<br></div></div></blockquote><div><br>Which incidentally is yet anothe=
r proposal (lifting lambdas) that stalled.<br><br></div><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></div><blockquote class=3D"gma=
il_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pa=
dding-left:1ex"><div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D=
"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" style=3D"margin=
:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div>The fact is, it&#39;s a <i>lot</i> easier in C++ as it curren=
tly stands to go from parameter pack of values to an object than it is to g=
o from an object to a parameter pack of values. I wish that were not the ca=
se, but so long as it is the case, parameter packs will remain the easier-t=
o-use option.<br></div></div></blockquote><div>=C2=A0</div><div>You have a =
point. <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"><di=
v dir=3D"ltr"><div><br></div><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div d=
ir=3D"ltr"><div></div><div></div>UDL the aggregate is not important to me, =
but it was easy to include and allows neat syntax (in my opinion).<br></div=
></blockquote><div><br>But it makes it impossible to apply a UDL to the str=
ing fragments. And that&#39;s important if you do want to use template meta=
programming on string literals.<br></div></div></blockquote><div><br></div>=
<div>I&#39;m not sure to see the use case here. When you use UDL, you want =
the whole literal to be what you say it would be.</div><div><div style=3D"b=
ackground-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style=
:solid;border-width:1px"><code><div><span style=3D"color:#008">auto</span><=
span style=3D"color:#000"> s </span><span style=3D"color:#660">=3D</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#080">&quot;something=
&quot;</span><span style=3D"color:#000">s</span><span style=3D"color:#660">=
;</span><span style=3D"color:#000"> </span><span style=3D"color:#800">// s =
is a string</span><span style=3D"color:#000"><br></span><span style=3D"colo=
r:#008">auto</span><span style=3D"color:#000"> sv </span><span style=3D"col=
or:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:=
#080">&quot;some other&quot;</span><span style=3D"color:#000">sv</span><spa=
n style=3D"color:#660">;</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#800">// s is a string view</span><span style=3D"color:#000"><b=
r></span></div></code></div>We are not interested in what is happening in t=
he middle. I don&#39;t why it should be different with string interpolation=
 (or whatever the name is).<br></div></div></blockquote><div><br>Because no=
t all of the &quot;literal&quot; is actually a literal anymore. That&#39;s =
the whole point of string interpolation: you&#39;re taking a literal and yo=
u&#39;re augmenting it with some non-literal data. Potentially <i>runtime</=
i> non-literal data. It isn&#39;t a literal anymore, so the UDL suffix can&=
#39;t apply to the aggregate. It can only apply to the individual literal f=
ragments of the string.<br></div></div></blockquote><div><br></div><div>Her=
e, I don&#39;t care if it&#39;s called a literal, or if we invent a new nam=
e for this concept that appeared to match the concept of literal when &quot=
;string interpolation&quot; was not a thing.</div><div>I&#39;m more interes=
ted in the final syntax as the end user will see it.</div><div><br></div><d=
iv>And I would prefer concatenate like this:</div><div><div style=3D"backgr=
ound-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:soli=
d;border-width:1px"><code><div><span style=3D"color:#008">auto</span><span =
style=3D"color:#000"> s </span><span style=3D"color:#660">=3D</span><span s=
tyle=3D"color:#000"> F</span><span style=3D"color:#080">&quot;{str1}{str2}{=
str3}&quot;</span><span style=3D"color:#000">s</span><span style=3D"color:#=
660">;</span><span style=3D"color:#000"><br></span></div></code></div></div=
><div>than this:</div><div><div style=3D"background-color:rgb(250,250,250);=
border-color:rgb(187,187,187);border-style:solid;border-width:1px"><code><d=
iv><span style=3D"color:#008">auto</span><span style=3D"color:#000"> s </sp=
an><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> std</sp=
an><span style=3D"color:#660">::</span><span style=3D"color:#000">concat</s=
pan><span style=3D"color:#660">(</span><span style=3D"color:#000">F</span><=
span style=3D"color:#080">&quot;{str1}{str2}{<wbr>str3}&quot;</span><span s=
tyle=3D"color:#660">);</span><span style=3D"color:#000"><br></span></div></=
code></div><br>The first one looks more natural in my opinion.<br></div></d=
iv></blockquote><div><br>It only looks more natural for the trivial cases. =
Consider what `std::concat` would look like. It creates an `ostringstream`,=
 applies it to each parameter, and moves its result out. Why pick `ostrings=
tream`? Why not allow the user to decide which kind of stream to use and th=
erefore which resulting string type to build?<br></div></div></blockquote><=
div><br></div><div>I never said this should work only with UDL. I just said=
 that I think it is more natural if UDL worked like that.</div><div>But I r=
eally think the user should keep control over what can be done with this sy=
ntax.</div><div>So I totally agree with you: users should be able to call t=
heir own functions with it.</div><div><br></div><div>And then, even conside=
ring F&quot;{str1}{str2}{str3}&quot;s for concatenating, I never mentionned=
 std::ostringstream, I just said converted into an efficient way of concate=
nating strings.</div><div>In that case, I just considered that when we use =
operator &quot;&quot;s, we want a std::string.<br></div></div></blockquote>=
<div><br>You say that the literal `s` means you want a `std::string`. But t=
hat&#39;s not enough information, because you now have to define how to <i>=
get</i> a `std::string` from values that aren&#39;t `std::string`. That&#39=
;s why you need more information than a mere literal can provide.<br><br>Th=
ere are many ways to get a std::string from an interpolated string. Your `o=
perator&quot;&quot;s` will only be doing one of them. That mechanism will b=
e <i>fixed</i>. Inflexible. Unchangeable.<br></div></div></blockquote><div>=
<br></div><div>I never said here the this operator &quot;&quot;s should wor=
k with this: F&quot;foo {5} bar&quot;s... To be fair, I have been thinking =
this should work only if every single part is convertible to std::string. S=
o the result is unambiguous, so it doesn&#39;t matter if it is fixed, uncha=
ngeable.</div><div>And if you want a function call, do a function call, it =
will work.<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex=
"><div dir=3D"ltr"><div><br>That&#39;s bad. A function call will be more ve=
rsatile.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;m=
argin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr"><div></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-l=
eft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><di=
v>You can&#39;t do that with a UDL; they can&#39;t take an extra template p=
arameter. `std::concat` can.<br></div></div></blockquote><div><br></div><di=
v>To do that, just use a function. We can have multiple syntaxes to do the =
same thing.</div><div>The closest example I can think of is:</div><div><div=
 style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);b=
order-style:solid;border-width:1px"><code><div><span style=3D"color:#008">a=
uto</span><span style=3D"color:#000"> s </span><span style=3D"color:#660">=
=3D</span><span style=3D"color:#000"> std</span><span style=3D"color:#660">=
::</span><span style=3D"color:#008">string</span><span style=3D"color:#660"=
>(</span><span style=3D"color:#080">&quot;str&quot;</span><span style=3D"co=
lor:#660">);</span><span style=3D"color:#000"><br></span><span style=3D"col=
or:#800">// is equivalent to</span><span style=3D"color:#000"><br></span><s=
pan style=3D"color:#008">auto</span><span style=3D"color:#000"> s </span><s=
pan style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#080">&quot;str&quot;</span><span style=3D"color:#000">s</s=
pan><span style=3D"color:#660">;</span><span style=3D"color:#000"><br></spa=
n></div></code></div></div><div><br></div></div></blockquote><div><br>No, i=
t&#39;s not:<br><br><div style=3D"background-color:rgb(250,250,250);border-=
color:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><spa=
n style=3D"color:#008">auto</span><span style=3D"color:#000"> s1 </span><sp=
an style=3D"color:#660">=3D</span><span style=3D"color:#000"> std</span><sp=
an style=3D"color:#660">::</span><span style=3D"color:#008">string</span><s=
pan style=3D"color:#660">(</span><span style=3D"color:#080">&quot;str\0str&=
quot;</span><span style=3D"color:#660">);</span><span style=3D"color:#000">=
<br></span><span style=3D"color:#008">auto</span><span style=3D"color:#000"=
> s2 </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"=
> </span><span style=3D"color:#080">&quot;str\0str&quot;</span><span style=
=3D"color:#000">s</span><span style=3D"color:#660">;</span></div></code></d=
iv><br>In `s1` the constructor has to do `char_traits&lt;char&gt;::length` =
to compute the number of characters in the string. That will terminate the =
string at the first NUL character. In the second case, the UDL gets the siz=
e from the literal parameter directly.<br><br>Things like this are why it i=
s important to separate literal operations from string interpolation. So th=
at UDLs can do the job they exist to do (literal synthesis) and string inte=
rpolation can do the job its meant to do (breaking down literals into seque=
nces of values). And the aggregation can do the job its meant to do (take s=
equences of values and act on them).<br></div></div></blockquote><div><br><=
/div><div>String literals are broken now. This is not fixable by UDL curren=
tly. So all in all, we are doomed here.</div></div></blockquote><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>If you write a function =
that need to take std::string_view for literal parts, let&#39;s do that, yo=
u don&#39;t need to force the literal to be a string_view to work, as they =
are implicitly convertible from const char[]&amp;. The same with std::strin=
g.</div><div>No, forget about that. Even that is not true (why?).</div></di=
v></blockquote><div><br>Because it would never be called. Basically, what y=
ou&#39;d need is this constructor:<br><br><div style=3D"background-color:rg=
b(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-widt=
h:1px"><code><div><span style=3D"color:#008">template</span><span style=3D"=
color:#660">&lt;</span><span style=3D"color:#000">size_t N</span><span styl=
e=3D"color:#660">&gt;</span><span style=3D"color:#000"><br>string_view</spa=
n><span style=3D"color:#660">(</span><span style=3D"color:#008">const</span=
><span style=3D"color:#000"> </span><span style=3D"color:#008">char</span><=
span style=3D"color:#000"> s</span><span style=3D"color:#660">[</span><span=
 style=3D"color:#000">N</span><span style=3D"color:#660">]);</span></div></=
code></div><br>But you already have this constructor:<br><br><div style=3D"=
background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-styl=
e:solid;border-width:1px"><code><div><span style=3D"color:#000">string_view=
</span><span style=3D"color:#660">(</span><span style=3D"color:#008">const<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#008">char</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#660">*</span><=
span style=3D"color:#000">s</span><span style=3D"color:#660">);</span></div=
></code></div><br>An array decays into a pointer. And since the pointer con=
structor is not a template, it is considered a better match than the array =
version. And therefore, any ltieral you pass will go through the pointer ve=
rsion rather than the array template.<br><br>And it should be noted that th=
is has nothing to do with being a literal. If you used a `const char[]` var=
iable, it <i>still</i> would prefer the pointer version due to array-&gt;po=
inter conversion. So this is not a case of &quot;string literals are broken=
 now&quot;.<br></div></div></blockquote><div><br></div><div>How can you say=
 that preferring a lossy conversion over a lossless one is not broken? (Her=
e, we lose the length information)<br></div><div>This make it impossible to=
 work with string literal because they simply don&#39;t exist in the langua=
ge. This is why I said string literals are broken.</div><div>=C2=A0</div><b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><br>But th=
ere&#39;s no &quot;fix&quot; for this, since any array-&gt;pointer &quot;fi=
x&quot; would be both wildly incompatible with C and break tons and tons of=
 code. So you can either accept the language and work with what we have, or=
 rail against it.<br></div></div></blockquote><div><br></div><div><div><br>=
</div>Ok it&#39;s not possible to fix array decay because of=20
backward compatibility, but it is still possible to fix string literals=20
if we make them something that is not an array.</div><div>So I rail against=
 those defects in order to be heard, and maybe, at some point, they will be=
 fixed.</div><div>If this is not the place to speak out loud about those de=
fects, then where should we go?<br></div><div><br></div><div>But don&#39;t =
get me wrong, when I code, I work with what I have, and I accept the langua=
ge as it is.<br></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;"><div dir=3D"ltr"><div><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>It&#39;s funny how the more I dig in C++, the m=
ore bulky it appears to be just because of these very small annoyances.<br>=
</div><div>=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><br>It&#39;s a 3 step process; let&#39;s not interfere in that.<b=
r>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-le=
ft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div=
></div><div>We could have exatcly the situation with string interpolation:<=
/div><div><div style=3D"background-color:rgb(250,250,250);border-color:rgb(=
187,187,187);border-style:solid;border-width:1px"><code><div><span style=3D=
"color:#008">auto</span><span style=3D"color:#000"> s </span><span style=3D=
"color:#660">=3D</span><span style=3D"color:#000"> std</span><span style=3D=
"color:#660">::</span><span style=3D"color:#000">concat</span><span style=
=3D"color:#660">(</span><span style=3D"color:#000">F</span><span style=3D"c=
olor:#080">&quot;{str1}{str2}{<wbr>str3}&quot;</span><span style=3D"color:#=
660">);</span><span style=3D"color:#000"><br></span><span style=3D"color:#8=
00">// would be equivalent to</span><span style=3D"color:#000"><br></span><=
span style=3D"color:#008">auto</span><span style=3D"color:#000"> s </span><=
span style=3D"color:#660">=3D</span><span style=3D"color:#000"> F</span><sp=
an style=3D"color:#080">&quot;{str1}{str2}{str3}&quot;</span><span style=3D=
"color:#000">s</span><span style=3D"color:#660">;</span><span style=3D"colo=
r:#000"><br></span></div></code></div><br>I don&#39;t see why allowing UDL =
to work like that would decrease usability as we could always use regular f=
unctions.<br></div></div></blockquote><div><br>Because you can&#39;t do thi=
s:<br><br><div style=3D"background-color:rgb(250,250,250);border-color:rgb(=
187,187,187);border-style:solid;border-width:1px"><code><div><span style=3D=
"color:#000">std</span><span style=3D"color:#660">::</span><span style=3D"c=
olor:#000">concat</span><span style=3D"color:#660">(</span><span style=3D"c=
olor:#000">F</span><span style=3D"color:#080">&quot;some string {variable} =
other string&quot;</span><span style=3D"color:#000">sv</span><span style=3D=
"color:#660">);</span></div></code></div><br>Under my system, the UDL emplo=
yed here allows you to decide how to process each of the literal fragments.=
 The UDL applies to the parts of the literal that are actually strings. So =
`concat` would get `string_view`s, rather than `const char[X]` parameters.<=
br><br>Under your system, the processing of the literal fragments is contro=
lled entirely by the system that computes the aggregation.</div></div></blo=
ckquote><div><br></div><div>Let&#39;s sum up, string literals are broken to=
day. So we should probably try to solve this big issue before trying to see=
 how we can cripple string_interpolation in order to fit in current-ish C++=
..<br></div></div></blockquote><div><br>I fail to see why applying a UDL to =
the literal fragments rather than the interpolation aggregation operation s=
hould be considered &quot;crippling&quot; string interpolation.<br><br>What=
ever breakage you see in literals isn&#39;t standing in the way of string i=
nterpolation. It&#39;s just standing in the way of string interpolation wor=
king the way <i>you</i> want it to.<br></div></div></blockquote><div><br></=
div><div>Because string interpolation is dealing with string literals, if t=
hose literals are broken (and they are), how can we have a proper string in=
terpolation?</div><div><br></div><div>You said:</div><blockquote class=3D"g=
mail_quote" style=3D"margin: 0px 0px 0px 0.8ex; border-left: 1px solid rgb(=
204, 204, 204); padding-left: 1ex;"><div>The point of that discussion was a=
 comment someone made about doing=20
template metaprogramming on string literals. To do that, you need a way=20
to access each literal as a distinct type, some `string_literal&lt;char,
 &#39;c&#39;, &#39;h&#39;, &#39;a&#39;, &#39;r&#39;&gt;` type. And only a U=
DL applied to each fragment=20
can perform that kind of synthesis.</div></blockquote><div><br></div><div>U=
DL is the only way to do it only because string literals are broken. If we =
had proper string literals, it should be possible to do it simply with regu=
lar functions.</div><div>So even with your approach, broken string literals=
 are a problem for string interpolation. Just not at the same place.</div><=
div><br></div><div>I&#39;m not sure if my approach is the right one (it&#39=
;s probably not), but most of your arguments stand only because string lite=
ral are broken (otherwise, it would have been simple to do the same with my=
 approach too).</div><div><br></div><div>My point is: yes your approach mak=
es it easier with current C++, but we shouldn&#39;t go for something that w=
orks quite well with current C++, but something that will work very well wi=
th future C++.</div><div>That&#39;s why I think it&#39;s better to first fi=
x string literals. And then have string interpolation right the first time.=
<br></div><div><br></div><div>And btw, if string literals are fixed, string=
 interpolation could be made a library solution only ( with a different but=
 reasonable syntax).</div><div><br></div><div>PS: I think it would be prefe=
rable to stop the discussion here, as it becomes more and more off-topic.<b=
r></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/3468ee0c-a44a-437a-a835-0156c623df2e%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/3468ee0c-a44a-437a-a835-0156c623df2e=
%40isocpp.org</a>.<br />

------=_Part_11924_21200749.1518542339406--

------=_Part_11923_890054300.1518542339405--

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Tue, 13 Feb 2018 11:32:00 -0600
Raw View
--001a114e7102b1c02f05651b6185
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Tue, Feb 13, 2018 at 11:18 AM, <florian.csdt@gmail.com> wrote:

>
>
> Le mardi 13 f=C3=A9vrier 2018 17:35:49 UTC+1, Nicol Bolas a =C3=A9crit :
>>
>> Because it would never be called. Basically, what you'd need is this
>> constructor:
>>
>> template<size_t N>
>> string_view(const char s[N]);
>>
>> But you already have this constructor:
>>
>> string_view(const char *s);
>>
>> An array decays into a pointer. And since the pointer constructor is not
>> a template, it is considered a better match than the array version. And
>> therefore, any ltieral you pass will go through the pointer version rath=
er
>> than the array template.
>>
>> And it should be noted that this has nothing to do with being a literal.
>> If you used a `const char[]` variable, it *still* would prefer the
>> pointer version due to array->pointer conversion. So this is not a case =
of
>> "string literals are broken now".
>>
>
> How can you say that preferring a lossy conversion over a lossless one is
> not broken? (Here, we lose the length information)
>

Well, you have to make a choice:

1.  What do you want to do with arrays that have embedded '\0's?
2.  What do you want to do with arrays that aren't terminated with '\0'?
3.  Given how easy it is to decay an array into a pointer, do you want
different behavior between the two?

Any choice you make for these will make some users unhappy.
--=20
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  +1-847-691-1404

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CAGg_6%2BN91RBTk2z6DdyjL0KDzF041f64Z%2BHuCB1Wdvm=
dJAak0Q%40mail.gmail.com.

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

<div dir=3D"ltr">On Tue, Feb 13, 2018 at 11:18 AM,  <span dir=3D"ltr">&lt;<=
a href=3D"mailto:florian.csdt@gmail.com" target=3D"_blank">florian.csdt@gma=
il.com</a>&gt;</span> wrote:<br><div class=3D"gmail_extra"><div class=3D"gm=
ail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div class=
=3D"h5"><br><br>Le mardi 13 f=C3=A9vrier 2018 17:35:49 UTC+1, Nicol Bolas a=
 =C3=A9crit=C2=A0:<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"ltr">=
<div>Because it would never be called. Basically, what you&#39;d need is th=
is constructor:<br><br><div style=3D"background-color:rgb(250,250,250);bord=
er-color:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><=
span style=3D"color:#008">template</span><span style=3D"color:#660">&lt;</s=
pan><span style=3D"color:#000">size_t N</span><span style=3D"color:#660">&g=
t;</span><span style=3D"color:#000"><br>string_view</span><span style=3D"co=
lor:#660">(</span><span style=3D"color:#008">const</span><span style=3D"col=
or:#000"> </span><span style=3D"color:#008">char</span><span style=3D"color=
:#000"> s</span><span style=3D"color:#660">[</span><span style=3D"color:#00=
0">N</span><span style=3D"color:#660">]);</span></div></code></div><br>But =
you already have this constructor:<br><br><div style=3D"background-color:rg=
b(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-widt=
h:1px"><code><div><span style=3D"color:#000">string_view</span><span style=
=3D"color:#660">(</span><span style=3D"color:#008">const</span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">char</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">*</span><span style=3D"c=
olor:#000">s</span><span style=3D"color:#660">);</span></div></code></div><=
br>An array decays into a pointer. And since the pointer constructor is not=
 a template, it is considered a better match than the array version. And th=
erefore, any ltieral you pass will go through the pointer version rather th=
an the array template.<br><br>And it should be noted that this has nothing =
to do with being a literal. If you used a `const char[]` variable, it <i>st=
ill</i> would prefer the pointer version due to array-&gt;pointer conversio=
n. So this is not a case of &quot;string literals are broken now&quot;.<br>=
</div></div></blockquote><div><br></div></div></div><div>How can you say th=
at preferring a lossy conversion over a lossless one is not broken? (Here, =
we lose the length information)<br></div></div></blockquote><div><br></div>=
<div>Well, you have to make a choice:</div><div><br></div><div>1.=C2=A0 Wha=
t do you want to do with arrays that have embedded &#39;\0&#39;s?</div><div=
>2.=C2=A0 What do you want to do with arrays that aren&#39;t terminated wit=
h &#39;\0&#39;?</div><div>3.=C2=A0 Given how easy it is to decay an array i=
nto a pointer, do you want different behavior between the two?</div><div><b=
r></div><div>Any choice you make for these will make some users unhappy.</d=
iv></div>-- <br><div class=3D"gmail_signature" data-smartmail=3D"gmail_sign=
ature"><div dir=3D"ltr"><div><div dir=3D"ltr"><div>=C2=A0Nevin &quot;:-)&qu=
ot; Liber=C2=A0 &lt;mailto:<a href=3D"mailto:nevin@eviloverlord.com" target=
=3D"_blank">nevin@eviloverlord.com</a>&gt; =C2=A0+1-847-691-1404</div></div=
></div></div></div>
</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAGg_6%2BN91RBTk2z6DdyjL0KDzF041f64Z%=
2BHuCB1WdvmdJAak0Q%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAGg_6%2BN91R=
BTk2z6DdyjL0KDzF041f64Z%2BHuCB1WdvmdJAak0Q%40mail.gmail.com</a>.<br />

--001a114e7102b1c02f05651b6185--

.


Author: florian.csdt@gmail.com
Date: Tue, 13 Feb 2018 09:51:15 -0800 (PST)
Raw View
------=_Part_12324_1271598919.1518544275650
Content-Type: multipart/alternative;
 boundary="----=_Part_12325_393170162.1518544275650"

------=_Part_12325_393170162.1518544275650
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



Le mardi 13 f=C3=A9vrier 2018 18:32:44 UTC+1, Nevin ":-)" Liber a =C3=A9cri=
t :
>
> On Tue, Feb 13, 2018 at 11:18 AM, <floria...@gmail.com <javascript:>>=20
> wrote:
>
>>
>>
>> Le mardi 13 f=C3=A9vrier 2018 17:35:49 UTC+1, Nicol Bolas a =C3=A9crit :
>>>
>>> Because it would never be called. Basically, what you'd need is this=20
>>> constructor:
>>>
>>> template<size_t N>
>>> string_view(const char s[N]);
>>>
>>> But you already have this constructor:
>>>
>>> string_view(const char *s);
>>>
>>> An array decays into a pointer. And since the pointer constructor is no=
t=20
>>> a template, it is considered a better match than the array version. And=
=20
>>> therefore, any ltieral you pass will go through the pointer version rat=
her=20
>>> than the array template.
>>>
>>> And it should be noted that this has nothing to do with being a literal=
..=20
>>> If you used a `const char[]` variable, it *still* would prefer the=20
>>> pointer version due to array->pointer conversion. So this is not a case=
 of=20
>>> "string literals are broken now".
>>>
>>
>> How can you say that preferring a lossy conversion over a lossless one i=
s=20
>> not broken? (Here, we lose the length information)
>>
>
> Well, you have to make a choice:
>
> 1.  What do you want to do with arrays that have embedded '\0's?
> 2.  What do you want to do with arrays that aren't terminated with '\0'?
> 3.  Given how easy it is to decay an array into a pointer, do you want=20
> different behavior between the two?
>
> Any choice you make for these will make some users unhappy.
>

4. string literals are not arrays and can have their own rules.

Any choice we make for these will make some users unhappy.
=20

> --=20
>  Nevin ":-)" Liber  <mailto:ne...@eviloverlord.com <javascript:>>=20
>  +1-847-691-1404
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/50a06b7a-bd73-4064-8422-56946338cbd1%40isocpp.or=
g.

------=_Part_12325_393170162.1518544275650
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le mardi 13 f=C3=A9vrier 2018 18:32:44 UTC+1, Nevi=
n &quot;:-)&quot; Liber a =C3=A9crit=C2=A0:<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 Tue, Feb 13, 2018 at 11:18 AM,  <span dir=
=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailt=
o=3D"EKH0bBfLCgAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascr=
ipt:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return=
 true;">floria...@gmail.com</a>&gt;</span> wrote:<br><div><div class=3D"gma=
il_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div><br><br=
>Le mardi 13 f=C3=A9vrier 2018 17:35:49 UTC+1, Nicol Bolas a =C3=A9crit=C2=
=A0:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;b=
order-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Because i=
t would never be called. Basically, what you&#39;d need is this constructor=
:<br><br><div style=3D"background-color:rgb(250,250,250);border-color:rgb(1=
87,187,187);border-style:solid;border-width:1px"><code><div><span style=3D"=
color:#008">template</span><span style=3D"color:#660">&lt;</span><span styl=
e=3D"color:#000">size_t N</span><span style=3D"color:#660">&gt;</span><span=
 style=3D"color:#000"><br>string_view</span><span style=3D"color:#660">(</s=
pan><span style=3D"color:#008">const</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#008">char</span><span style=3D"color:#000"> s</spa=
n><span style=3D"color:#660">[</span><span style=3D"color:#000">N</span><sp=
an style=3D"color:#660">]);</span></div></code></div><br>But you already ha=
ve this constructor:<br><br><div style=3D"background-color:rgb(250,250,250)=
;border-color:rgb(187,187,187);border-style:solid;border-width:1px"><code><=
div><span style=3D"color:#000">string_view</span><span style=3D"color:#660"=
>(</span><span style=3D"color:#008">const</span><span style=3D"color:#000">=
 </span><span style=3D"color:#008">char</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#660">*</span><span style=3D"color:#000">s</span=
><span style=3D"color:#660">);</span></div></code></div><br>An array decays=
 into a pointer. And since the pointer constructor is not a template, it is=
 considered a better match than the array version. And therefore, any ltier=
al you pass will go through the pointer version rather than the array templ=
ate.<br><br>And it should be noted that this has nothing to do with being a=
 literal. If you used a `const char[]` variable, it <i>still</i> would pref=
er the pointer version due to array-&gt;pointer conversion. So this is not =
a case of &quot;string literals are broken now&quot;.<br></div></div></bloc=
kquote><div><br></div></div></div><div>How can you say that preferring a lo=
ssy conversion over a lossless one is not broken? (Here, we lose the length=
 information)<br></div></div></blockquote><div><br></div><div>Well, you hav=
e to make a choice:</div><div><br></div><div>1.=C2=A0 What do you want to d=
o with arrays that have embedded &#39;\0&#39;s?</div><div>2.=C2=A0 What do =
you want to do with arrays that aren&#39;t terminated with &#39;\0&#39;?</d=
iv><div>3.=C2=A0 Given how easy it is to decay an array into a pointer, do =
you want different behavior between the two?</div><div><br></div><div>Any c=
hoice you make for these will make some users unhappy.</div></div></div></d=
iv></blockquote><div><br></div><div>4. string literals are not arrays and c=
an have their own rules.</div><div><br></div><div>Any choice we make for th=
ese will make some users unhappy.<br></div><div>=C2=A0</div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #=
ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>-- <br><div><div dir=3D=
"ltr"><div><div dir=3D"ltr"><div>=C2=A0Nevin &quot;:-)&quot; Liber=C2=A0 &l=
t;mailto:<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D=
"EKH0bBfLCgAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:=
&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return tru=
e;">ne...@eviloverlord.com</a><wbr>&gt; =C2=A0+1-847-691-1404</div></div></=
div></div></div>
</div></div>
</blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/50a06b7a-bd73-4064-8422-56946338cbd1%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/50a06b7a-bd73-4064-8422-56946338cbd1=
%40isocpp.org</a>.<br />

------=_Part_12325_393170162.1518544275650--

------=_Part_12324_1271598919.1518544275650--

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Tue, 13 Feb 2018 12:14:56 -0600
Raw View
--001a114e7102394dc505651bfbdf
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Tue, Feb 13, 2018 at 11:51 AM, <florian.csdt@gmail.com> wrote:

> Le mardi 13 f=C3=A9vrier 2018 18:32:44 UTC+1, Nevin ":-)" Liber a =C3=A9c=
rit :
>>
>> 1.  What do you want to do with arrays that have embedded '\0's?
>> 2.  What do you want to do with arrays that aren't terminated with '\0'?
>> 3.  Given how easy it is to decay an array into a pointer, do you want
>> different behavior between the two?
>>
>> 4. string literals are not arrays and can have their own rules.
>

Sure, anything can be a snowflake.  There are two choices:

A.  Invent a new syntax which fits into the language, and then convince the
committee this feature is so important that it is worth the burden of
adding a new syntax.
B.  Reuse a syntax, and then convince the committee this feature is so
important that the inconsistent rules are worth it.
--=20
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  +1-847-691-1404

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CAGg_6%2BP_7v8Bvtb1HTPtUDr365%3Di5e3F8a3eJnii3e0=
nTg2U-w%40mail.gmail.com.

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

<div dir=3D"ltr">On Tue, Feb 13, 2018 at 11:51 AM,  <span dir=3D"ltr">&lt;<=
a href=3D"mailto:florian.csdt@gmail.com" target=3D"_blank">florian.csdt@gma=
il.com</a>&gt;</span> wrote:<br><div class=3D"gmail_extra"><div class=3D"gm=
ail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">Le mardi 13 f=C3=
=A9vrier 2018 18:32:44 UTC+1, Nevin &quot;:-)&quot; Liber a =C3=A9crit=C2=
=A0:<span class=3D""><blockquote class=3D"gmail_quote" style=3D"margin:0;ma=
rgin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"lt=
r"><div><div class=3D"gmail_quote"><div>1.=C2=A0 What do you want to do wit=
h arrays that have embedded &#39;\0&#39;s?</div><div>2.=C2=A0 What do you w=
ant to do with arrays that aren&#39;t terminated with &#39;\0&#39;?</div><d=
iv>3.=C2=A0 Given how easy it is to decay an array into a pointer, do you w=
ant different behavior between the two?</div><div><br></div></div></div></d=
iv></blockquote></span><div>4. string literals are not arrays and can have =
their own rules.</div></div></blockquote><div><br></div><div>Sure, anything=
 can be a snowflake.=C2=A0 There are two choices:</div><div><br></div><div>=
A.=C2=A0 Invent a new syntax which fits into the language, and then convinc=
e the committee this feature is so important that it is worth the burden of=
 adding a new syntax.</div><div>B.=C2=A0 Reuse a syntax, and then convince =
the committee this feature is so important that the inconsistent rules are =
worth it.</div></div>-- <br><div class=3D"gmail_signature" data-smartmail=
=3D"gmail_signature"><div dir=3D"ltr"><div><div dir=3D"ltr"><div>=C2=A0Nevi=
n &quot;:-)&quot; Liber=C2=A0 &lt;mailto:<a href=3D"mailto:nevin@eviloverlo=
rd.com" target=3D"_blank">nevin@eviloverlord.com</a>&gt; =C2=A0+1-847-691-1=
404</div></div></div></div></div>
</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAGg_6%2BP_7v8Bvtb1HTPtUDr365%3Di5e3F=
8a3eJnii3e0nTg2U-w%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAGg_6%2BP_7v=
8Bvtb1HTPtUDr365%3Di5e3F8a3eJnii3e0nTg2U-w%40mail.gmail.com</a>.<br />

--001a114e7102394dc505651bfbdf--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 13 Feb 2018 13:39:35 -0800 (PST)
Raw View
------=_Part_8004_1403166943.1518557975801
Content-Type: multipart/alternative;
 boundary="----=_Part_8005_1977577940.1518557975802"

------=_Part_8005_1977577940.1518557975802
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Tuesday, February 13, 2018 at 12:18:59 PM UTC-5, floria...@gmail.com=20
wrote:
>
> Le mardi 13 f=C3=A9vrier 2018 17:35:49 UTC+1, Nicol Bolas a =C3=A9crit :
>>
>> Because it would never be called. Basically, what you'd need is this=20
>> constructor:
>>
>> template<size_t N>
>> string_view(const char s[N]);
>>
>> But you already have this constructor:
>>
>> string_view(const char *s);
>>
>> An array decays into a pointer. And since the pointer constructor is not=
=20
>> a template, it is considered a better match than the array version. And=
=20
>> therefore, any ltieral you pass will go through the pointer version rath=
er=20
>> than the array template.
>>
>> And it should be noted that this has nothing to do with being a literal.=
=20
>> If you used a `const char[]` variable, it *still* would prefer the=20
>> pointer version due to array->pointer conversion. So this is not a case =
of=20
>> "string literals are broken now".
>>
>
> How can you say that preferring a lossy conversion over a lossless one is=
=20
> not broken? (Here, we lose the length information)
>

Because the "lossy conversion" part being preferred has nothing to do with=
=20
them being string literals. The lossy conversion is not the=20
literal-to-array conversion; it's the array-to-pointer conversion.

You're complaining about the wrong problem.

This make it impossible to work with string literal because they simply=20
> don't exist in the language. This is why I said string literals are broke=
n.
> =20
>
>> But there's no "fix" for this, since any array->pointer "fix" would be=
=20
>> both wildly incompatible with C and break tons and tons of code. So you =
can=20
>> either accept the language and work with what we have, or rail against i=
t.
>>
>
> Ok it's not possible to fix array decay because of backward compatibility=
,=20
> but it is still possible to fix string literals if we make them something=
=20
> that is not an array.
>

Why would changing the behavior of string literals be any more backwards=20
compatible than changing the behavior of arrays? There's lots of code out=
=20
there that works with C++'s string literal rules. Can you find a way to=20
change those rules without breaking their code?

Let me give you a simple case: `decltype("a string literal")` is an array=
=20
type. Therefore, any BC change will have to leave it as an array type. So=
=20
what rules would you change to fix the problem you want fixed without=20
changing the result of that `decltype`?

So I rail against those defects in order to be heard, and maybe, at some=20
> point, they will be fixed.
>

Yeah, that's not how this works. You can "rail against those defects" all=
=20
you like, but unless you're willing to actually work on it (ie: finding a=
=20
solution that doesn't break the world and getting it through the=20
committee), it will not get fixed. Or you manage to convince someone who's=
=20
actually willing to put in said work to do so.

If this is not the place to speak out loud about those defects, then where=
=20
> should we go?
>
> But don't get me wrong, when I code, I work with what I have, and I accep=
t=20
> the language as it is.
> =20
>
>>
>> It's funny how the more I dig in C++, the more bulky it appears to be=20
>>> just because of these very small annoyances.
>>> =20
>>>
>>>>
>>>> It's a 3 step process; let's not interfere in that.
>>>> =20
>>>>
>>>>> We could have exatcly the situation with string interpolation:
>>>>> auto s =3D std::concat(F"{str1}{str2}{str3}");
>>>>> // would be equivalent to
>>>>> auto s =3D F"{str1}{str2}{str3}"s;
>>>>>
>>>>> I don't see why allowing UDL to work like that would decrease=20
>>>>> usability as we could always use regular functions.
>>>>>
>>>>
>>>> Because you can't do this:
>>>>
>>>> std::concat(F"some string {variable} other string"sv);
>>>>
>>>> Under my system, the UDL employed here allows you to decide how to=20
>>>> process each of the literal fragments. The UDL applies to the parts of=
 the=20
>>>> literal that are actually strings. So `concat` would get `string_view`=
s,=20
>>>> rather than `const char[X]` parameters.
>>>>
>>>> Under your system, the processing of the literal fragments is=20
>>>> controlled entirely by the system that computes the aggregation.
>>>>
>>>
>>> Let's sum up, string literals are broken today. So we should probably=
=20
>>> try to solve this big issue before trying to see how we can cripple=20
>>> string_interpolation in order to fit in current-ish C++.
>>>
>>
>> I fail to see why applying a UDL to the literal fragments rather than th=
e=20
>> interpolation aggregation operation should be considered "crippling" str=
ing=20
>> interpolation.
>>
>> Whatever breakage you see in literals isn't standing in the way of strin=
g=20
>> interpolation. It's just standing in the way of string interpolation=20
>> working the way *you* want it to.
>>
>
> Because string interpolation is dealing with string literals,
>

Why does it have to be? If constexpr strings are in the future, it'd be=20
really nice if string interpolation were defined in such a way that it=20
could be used on them. Tying interpolation to literals is not=20
forward-thinking.

if those literals are broken (and they are), how can we have a proper=20
> string interpolation?
>

Because any "brokenness" of string literals has no effect on our ability to=
=20
use string interpolation. If you want sized strings for those string=20
fragments, that's what the `sv` suffix is for.

Literal issues only are a problem for string interpolation because you=20
believe that the suffix ought to be able to define the aggregation=20
operation. If you stop believing that, then all of a sudden, your problem=
=20
with string literals becomes a non-issue for interpolation.

It should also be noted that this:

template<typename T>
void foo(const T& t);

foo("an array");

The call to `foo` will deduce `T` to be `char[9]`. So a variadic template=
=20
function that takes the results of string interpolation will get sized=20
array types, not pointers.

Note that this doesn't invalidate anything I said. The point of doing=20
`F"blah {variable} blah"sv` is not necessarily because you need them to=20
keep the size around. Using `string_view` has many other advantages, with=
=20
its member functions, `operator<<` overloads, and the like. So wanting to=
=20
apply `sv` to each of the fragments is a perfectly reasonable operation.

Also, `string_view` is a lot more convenient to use than an array of=20
characters.

You said:
>
>> The point of that discussion was a comment someone made about doing=20
>> template metaprogramming on string literals. To do that, you need a way =
to=20
>> access each literal as a distinct type, some `string_literal<char, 'c',=
=20
>> 'h', 'a', 'r'>` type. And only a UDL applied to each fragment can perfor=
m=20
>> that kind of synthesis.
>>
>
> UDL is the only way to do it only because string literals are broken. If=
=20
> we had proper string literals, it should be possible to do it simply with=
=20
> regular functions.
>

No, it would not. Even if a string literal had a non-array type with a=20
stored size, each literal value would still not have its own distinct *type=
*.=20
Even if the size is a template argument, two literals can store different=
=20
characters while still having the same size. And you cannot do type-based=
=20
metaprogramming without having a 1:1 mapping between value and type.

Remember: while UDL's *can* take strings as a sequence of character=20
template parameters, there's a good reason why they aren't *required* to do=
=20
so. We don't want to force that onto everybody, and a non-"broken" string=
=20
literal system would not force that on people.

So even with your approach, broken string literals are a problem for string=
=20
> interpolation. Just not at the same place.
>
> I'm not sure if my approach is the right one (it's probably not), but mos=
t=20
> of your arguments stand only because string literal are broken (otherwise=
,=20
> it would have been simple to do the same with my approach too).
>
> My point is: yes your approach makes it easier with current C++, but we=
=20
> shouldn't go for something that works quite well with current C++, but=20
> something that will work very well with future C++.
> That's why I think it's better to first fix string literals. And then hav=
e=20
> string interpolation right the first time.
>
> And btw, if string literals are fixed, string interpolation could be made=
=20
> a library solution only ( with a different but reasonable syntax).
>

It's impossible to do that. String interpolation, at its core, is about=20
taking the contents of a string and applying them in some way to the code=
=20
*around* that string. A library solution cannot possibly do that.

Oh sure, a `constexpr` function could do the parsing. But then what? I'm=20
fairly certain that no static reflection proposal provides a mechanism to=
=20
turn a string into a reference to a local variable. And even if they did,=
=20
the location where you're doing that conversion wouldn't have that variable=
=20
in scope (since it's in a function call), so it couldn't possibly work.

PS: I think it would be preferable to stop the discussion here, as it=20
> becomes more and more off-topic.
>

But what if we don't agree that string interpolation needs better literals?

Your premise is essentially that my suggested syntax is some kind of=20
compromise, that if literals weren't "broken" the way you feel that they=20
are, then it would *clearly* be correct to have UDLs applied to aggregation=
=20
rather than to the individual fragments.

I don't agree with that premise. Whether literals are good or broken is a=
=20
side issue. Even if we had perfect literals, I would *still* rather UDLs be=
=20
focused on individual string literal manipulation rather than string=20
interpolation aggregation.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/d2698aec-cf41-4787-8aa5-334a34868aea%40isocpp.or=
g.

------=_Part_8005_1977577940.1518557975802
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Tuesday, February 13, 2018 at 12:18:59 PM UTC-5, floria=
....@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr">Le mardi 13 f=C3=A9vrier 2018 17:35:49 UTC+1, Nicol Bolas a =C3=A9=
crit=C2=A0:<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>Be=
cause it would never be called. Basically, what you&#39;d need is this cons=
tructor:<br><br><div style=3D"background-color:rgb(250,250,250);border-colo=
r:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><span st=
yle=3D"color:#008">template</span><span style=3D"color:#660">&lt;</span><sp=
an style=3D"color:#000">size_t N</span><span style=3D"color:#660">&gt;</spa=
n><span style=3D"color:#000"><br>string_view</span><span style=3D"color:#66=
0">(</span><span style=3D"color:#008">const</span><span style=3D"color:#000=
"> </span><span style=3D"color:#008">char</span><span style=3D"color:#000">=
 s</span><span style=3D"color:#660">[</span><span style=3D"color:#000">N</s=
pan><span style=3D"color:#660">]);</span></div></code></div><br>But you alr=
eady have this constructor:<br><br><div style=3D"background-color:rgb(250,2=
50,250);border-color:rgb(187,187,187);border-style:solid;border-width:1px">=
<code><div><span style=3D"color:#000">string_view</span><span style=3D"colo=
r:#660">(</span><span style=3D"color:#008">const</span><span style=3D"color=
:#000"> </span><span style=3D"color:#008">char</span><span style=3D"color:#=
000"> </span><span style=3D"color:#660">*</span><span style=3D"color:#000">=
s</span><span style=3D"color:#660">);</span></div></code></div><br>An array=
 decays into a pointer. And since the pointer constructor is not a template=
, it is considered a better match than the array version. And therefore, an=
y ltieral you pass will go through the pointer version rather than the arra=
y template.<br><br>And it should be noted that this has nothing to do with =
being a literal. If you used a `const char[]` variable, it <i>still</i> wou=
ld prefer the pointer version due to array-&gt;pointer conversion. So this =
is not a case of &quot;string literals are broken now&quot;.<br></div></div=
></blockquote><div><br></div><div>How can you say that preferring a lossy c=
onversion over a lossless one is not broken? (Here, we lose the length info=
rmation)<br></div></div></blockquote><div><br>Because the &quot;lossy conve=
rsion&quot; part being preferred has nothing to do with them being string l=
iterals. The lossy conversion is not the literal-to-array conversion; it&#3=
9;s the array-to-pointer conversion.<br><br>You&#39;re complaining about th=
e wrong problem.<br><br></div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">=
<div dir=3D"ltr"><div></div><div>This make it impossible to work with strin=
g literal because they simply don&#39;t exist in the language. This is why =
I said string literals are broken.</div><div>=C2=A0</div><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>But there&#39;s no &quot;fix&q=
uot; for this, since any array-&gt;pointer &quot;fix&quot; would be both wi=
ldly incompatible with C and break tons and tons of code. So you can either=
 accept the language and work with what we have, or rail against it.<br></d=
iv></div></blockquote><div></div><div><div><br></div>Ok it&#39;s not possib=
le to fix array decay because of=20
backward compatibility, but it is still possible to fix string literals=20
if we make them something that is not an array.</div></div></blockquote><di=
v><br>Why would changing the behavior of string literals be any more backwa=
rds compatible than changing the behavior of arrays? There&#39;s lots of co=
de out there that works with C++&#39;s string literal rules. Can you find a=
 way to change those rules without breaking their code?<br><br>Let me give =
you a simple case: `decltype(&quot;a string literal&quot;)` is an array typ=
e. Therefore, any BC change will have to leave it as an array type. So what=
 rules would you change to fix the problem you want fixed without changing =
the result of that `decltype`?<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;"><div dir=3D"ltr"><div>So I rail against those defects in orde=
r to be heard, and maybe, at some point, they will be fixed.</div></div></b=
lockquote><div><br>Yeah, that&#39;s not how this works. You can &quot;rail =
against those defects&quot; all you like, but unless you&#39;re willing to =
actually work on it (ie: finding a solution that doesn&#39;t break the worl=
d and getting it through the committee), it will not get fixed. Or you mana=
ge to convince someone who&#39;s actually willing to put in said work to do=
 so.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"=
ltr"><div>If this is not the place to speak out loud about those defects, t=
hen where should we go?<br></div><div><br></div><div>But don&#39;t get me w=
rong, when I code, I work with what I have, and I accept the language as it=
 is.<br></div><div>=C2=A0</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><br></div><blockquote class=3D"gmail_quote" style=3D"marg=
in:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div di=
r=3D"ltr"><div>It&#39;s funny how the more I dig in C++, the more bulky it =
appears to be just because of these very small annoyances.<br></div><div>=
=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><=
br>It&#39;s a 3 step process; let&#39;s not interfere in that.<br>=C2=A0</d=
iv><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bo=
rder-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><div=
>We could have exatcly the situation with string interpolation:</div><div><=
div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187=
);border-style:solid;border-width:1px"><code><div><span style=3D"color:#008=
">auto</span><span style=3D"color:#000"> s </span><span style=3D"color:#660=
">=3D</span><span style=3D"color:#000"> std</span><span style=3D"color:#660=
">::</span><span style=3D"color:#000">concat</span><span style=3D"color:#66=
0">(</span><span style=3D"color:#000">F</span><span style=3D"color:#080">&q=
uot;{str1}{str2}{<wbr>str3}&quot;</span><span style=3D"color:#660">);</span=
><span style=3D"color:#000"><br></span><span style=3D"color:#800">// would =
be equivalent to</span><span style=3D"color:#000"><br></span><span style=3D=
"color:#008">auto</span><span style=3D"color:#000"> s </span><span style=3D=
"color:#660">=3D</span><span style=3D"color:#000"> F</span><span style=3D"c=
olor:#080">&quot;{str1}{str2}{str3}&quot;</span><span style=3D"color:#000">=
s</span><span style=3D"color:#660">;</span><span style=3D"color:#000"><br><=
/span></div></code></div><br>I don&#39;t see why allowing UDL to work like =
that would decrease usability as we could always use regular functions.<br>=
</div></div></blockquote><div><br>Because you can&#39;t do this:<br><br><di=
v style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);=
border-style:solid;border-width:1px"><code><div><span style=3D"color:#000">=
std</span><span style=3D"color:#660">::</span><span style=3D"color:#000">co=
ncat</span><span style=3D"color:#660">(</span><span style=3D"color:#000">F<=
/span><span style=3D"color:#080">&quot;some string {variable} other string&=
quot;</span><span style=3D"color:#000">sv</span><span style=3D"color:#660">=
);</span></div></code></div><br>Under my system, the UDL employed here allo=
ws you to decide how to process each of the literal fragments. The UDL appl=
ies to the parts of the literal that are actually strings. So `concat` woul=
d get `string_view`s, rather than `const char[X]` parameters.<br><br>Under =
your system, the processing of the literal fragments is controlled entirely=
 by the system that computes the aggregation.</div></div></blockquote><div>=
<br></div><div>Let&#39;s sum up, string literals are broken today. So we sh=
ould probably try to solve this big issue before trying to see how we can c=
ripple string_interpolation in order to fit in current-ish C++.<br></div></=
div></blockquote><div><br>I fail to see why applying a UDL to the literal f=
ragments rather than the interpolation aggregation operation should be cons=
idered &quot;crippling&quot; string interpolation.<br><br>Whatever breakage=
 you see in literals isn&#39;t standing in the way of string interpolation.=
 It&#39;s just standing in the way of string interpolation working the way =
<i>you</i> want it to.<br></div></div></blockquote><div><br></div><div>Beca=
use string interpolation is dealing with string literals,</div></div></bloc=
kquote><div><br>Why does it have to be? If constexpr strings are in the fut=
ure, it&#39;d be really nice if string interpolation were defined in such a=
 way that it could be used on them. Tying interpolation to literals is not =
forward-thinking.<br><br></div><blockquote class=3D"gmail_quote" style=3D"m=
argin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"=
><div dir=3D"ltr"><div>if those literals are broken (and they are), how can=
 we have a proper string interpolation?</div></div></blockquote><div><br>Be=
cause any &quot;brokenness&quot; of string literals has no effect on our ab=
ility to use string interpolation. If you want sized strings for those stri=
ng fragments, that&#39;s what the `sv` suffix is for.<br><br>Literal issues=
 only are a problem for string interpolation because you believe that the s=
uffix ought to be able to define the aggregation operation. If you stop bel=
ieving that, then all of a sudden, your problem with string literals become=
s a non-issue for interpolation.<br><br>It should also be noted that this:<=
br><br><div style=3D"background-color: rgb(250, 250, 250); border-color: rg=
b(187, 187, 187); border-style: solid; border-width: 1px; overflow-wrap: br=
eak-word;" class=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"=
subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">t=
emplate</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt=
;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">typename<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span st=
yle=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"> foo</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">const</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> T</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">&amp;</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> t</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>fo=
o</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><=
span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;an array&quo=
t;</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div=
></code></div><br>The call to `foo` will deduce `T` to be `char[9]`. So a v=
ariadic template function that takes the results of string interpolation wi=
ll get sized array types, not pointers.<br><br>Note that this doesn&#39;t i=
nvalidate anything I said. The point of doing `F&quot;blah {variable} blah&=
quot;sv` is not necessarily because you need them to keep the size around. =
Using `string_view` has many other advantages, with its member functions, `=
operator&lt;&lt;` overloads, and the like. So wanting to apply `sv` to each=
 of the fragments is a perfectly reasonable operation.<br><br>Also, `string=
_view` is a lot more convenient to use than an array of characters.<br><br>=
</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></=
div><div>You said:</div><blockquote class=3D"gmail_quote" style=3D"margin:0=
px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><=
div>The point of that discussion was a comment someone made about doing=20
template metaprogramming on string literals. To do that, you need a way=20
to access each literal as a distinct type, some `string_literal&lt;char,
 &#39;c&#39;, &#39;h&#39;, &#39;a&#39;, &#39;r&#39;&gt;` type. And only a U=
DL applied to each fragment=20
can perform that kind of synthesis.</div></blockquote><div><br></div><div>U=
DL is the only way to do it only because string literals are broken. If we =
had proper string literals, it should be possible to do it simply with regu=
lar functions.</div></div></blockquote><div><br>No, it would not. Even if a=
 string literal had a non-array type with a stored size, each literal value=
 would still not have its own distinct <i>type</i>. Even if the size is a t=
emplate argument, two literals can store different characters while still h=
aving the same size. And you cannot do type-based metaprogramming without h=
aving a 1:1 mapping between value and type.<br><br>Remember: while UDL&#39;=
s <i>can</i> take strings as a sequence of character template parameters, t=
here&#39;s a good reason why they aren&#39;t <i>required</i> to do so. We d=
on&#39;t want to force that onto everybody, and a non-&quot;broken&quot; st=
ring literal system would not force that on people.<br><br></div><blockquot=
e 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>So even with your =
approach, broken string literals are a problem for string interpolation. Ju=
st not at the same place.</div><div><br></div><div>I&#39;m not sure if my a=
pproach is the right one (it&#39;s probably not), but most of your argument=
s stand only because string literal are broken (otherwise, it would have be=
en simple to do the same with my approach too).</div><div><br></div><div>My=
 point is: yes your approach makes it easier with current C++, but we shoul=
dn&#39;t go for something that works quite well with current C++, but somet=
hing that will work very well with future C++.</div><div>That&#39;s why I t=
hink it&#39;s better to first fix string literals. And then have string int=
erpolation right the first time.<br></div><div><br></div><div>And btw, if s=
tring literals are fixed, string interpolation could be made a library solu=
tion only ( with a different but reasonable syntax).</div></div></blockquot=
e><div><br>It&#39;s impossible to do that. String interpolation, at its cor=
e, is about taking the contents of a string and applying them in some way t=
o the code <i>around</i> that string. A library solution cannot possibly do=
 that.<br><br>Oh sure, a `constexpr` function could do the parsing. But the=
n what? I&#39;m fairly certain that no static reflection proposal provides =
a mechanism to turn a string into a reference to a local variable. And even=
 if they did, the location where you&#39;re doing that conversion wouldn&#3=
9;t have that variable in scope (since it&#39;s in a function call), so it =
couldn&#39;t possibly work.<br><br></div><blockquote class=3D"gmail_quote" =
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-l=
eft: 1ex;"><div dir=3D"ltr"><div></div><div>PS: I think it would be prefera=
ble to stop the discussion here, as it becomes more and more off-topic.<br>=
</div></div></blockquote><div><br>But what if we don&#39;t agree that strin=
g interpolation needs better literals?<br><br>Your premise is essentially t=
hat my suggested syntax is some kind of compromise, that if literals weren&=
#39;t &quot;broken&quot; the way you feel that they are, then it would <i>c=
learly</i> be correct to have UDLs applied to aggregation rather than to th=
e individual fragments.<br><br>I don&#39;t agree with that premise. Whether=
 literals are good or broken is a side issue. Even if we had perfect litera=
ls, I would <i>still</i> rather UDLs be focused on individual string litera=
l manipulation rather than string interpolation aggregation.<br></div></div=
>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/d2698aec-cf41-4787-8aa5-334a34868aea%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/d2698aec-cf41-4787-8aa5-334a34868aea=
%40isocpp.org</a>.<br />

------=_Part_8005_1977577940.1518557975802--

------=_Part_8004_1403166943.1518557975801--

.


Author: inkwizytoryankes@gmail.com
Date: Tue, 13 Feb 2018 15:55:47 -0800 (PST)
Raw View
------=_Part_11091_867363171.1518566147732
Content-Type: multipart/alternative;
 boundary="----=_Part_11092_1010458152.1518566147733"

------=_Part_11092_1010458152.1518566147733
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



On Tuesday, February 13, 2018 at 10:39:35 PM UTC+1, Nicol Bolas wrote:
>
> On Tuesday, February 13, 2018 at 12:18:59 PM UTC-5, floria...@gmail.com=
=20
> wrote:
>>
>> Le mardi 13 f=C3=A9vrier 2018 17:35:49 UTC+1, Nicol Bolas a =C3=A9crit :
>>>
>>> Because it would never be called. Basically, what you'd need is this=20
>>> constructor:
>>>
>>> template<size_t N>
>>> string_view(const char s[N]);
>>>
>>> But you already have this constructor:
>>>
>>> string_view(const char *s);
>>>
>>> An array decays into a pointer. And since the pointer constructor is no=
t=20
>>> a template, it is considered a better match than the array version. And=
=20
>>> therefore, any ltieral you pass will go through the pointer version rat=
her=20
>>> than the array template.
>>>
>>> And it should be noted that this has nothing to do with being a literal=
..=20
>>> If you used a `const char[]` variable, it *still* would prefer the=20
>>> pointer version due to array->pointer conversion. So this is not a case=
 of=20
>>> "string literals are broken now".
>>>
>>
>> How can you say that preferring a lossy conversion over a lossless one i=
s=20
>> not broken? (Here, we lose the length information)
>>
>
> Because the "lossy conversion" part being preferred has nothing to do wit=
h=20
> them being string literals. The lossy conversion is not the=20
> literal-to-array conversion; it's the array-to-pointer conversion.
>
> You're complaining about the wrong problem.
>
> This make it impossible to work with string literal because they simply=
=20
>> don't exist in the language. This is why I said string literals are brok=
en.
>> =20
>>
>>> But there's no "fix" for this, since any array->pointer "fix" would be=
=20
>>> both wildly incompatible with C and break tons and tons of code. So you=
 can=20
>>> either accept the language and work with what we have, or rail against =
it.
>>>
>>
>> Ok it's not possible to fix array decay because of backward=20
>> compatibility, but it is still possible to fix string literals if we mak=
e=20
>> them something that is not an array.
>>
>
> Why would changing the behavior of string literals be any more backwards=
=20
> compatible than changing the behavior of arrays? There's lots of code out=
=20
> there that works with C++'s string literal rules. Can you find a way to=
=20
> change those rules without breaking their code?
>
> Let me give you a simple case: `decltype("a string literal")` is an array=
=20
> type. Therefore, any BC change will have to leave it as an array type. So=
=20
> what rules would you change to fix the problem you want fixed without=20
> changing the result of that `decltype`?
>
> So I rail against those defects in order to be heard, and maybe, at some=
=20
>> point, they will be fixed.
>>
>
> Yeah, that's not how this works. You can "rail against those defects" all=
=20
> you like, but unless you're willing to actually work on it (ie: finding a=
=20
> solution that doesn't break the world and getting it through the=20
> committee), it will not get fixed. Or you manage to convince someone who'=
s=20
> actually willing to put in said work to do so.
>
> If this is not the place to speak out loud about those defects, then wher=
e=20
>> should we go?
>>
>> But don't get me wrong, when I code, I work with what I have, and I=20
>> accept the language as it is.
>> =20
>>
>>>
>>> It's funny how the more I dig in C++, the more bulky it appears to be=
=20
>>>> just because of these very small annoyances.
>>>> =20
>>>>
>>>>>
>>>>> It's a 3 step process; let's not interfere in that.
>>>>> =20
>>>>>
>>>>>> We could have exatcly the situation with string interpolation:
>>>>>> auto s =3D std::concat(F"{str1}{str2}{str3}");
>>>>>> // would be equivalent to
>>>>>> auto s =3D F"{str1}{str2}{str3}"s;
>>>>>>
>>>>>> I don't see why allowing UDL to work like that would decrease=20
>>>>>> usability as we could always use regular functions.
>>>>>>
>>>>>
>>>>> Because you can't do this:
>>>>>
>>>>> std::concat(F"some string {variable} other string"sv);
>>>>>
>>>>> Under my system, the UDL employed here allows you to decide how to=20
>>>>> process each of the literal fragments. The UDL applies to the parts o=
f the=20
>>>>> literal that are actually strings. So `concat` would get `string_view=
`s,=20
>>>>> rather than `const char[X]` parameters.
>>>>>
>>>>> Under your system, the processing of the literal fragments is=20
>>>>> controlled entirely by the system that computes the aggregation.
>>>>>
>>>>
>>>> Let's sum up, string literals are broken today. So we should probably=
=20
>>>> try to solve this big issue before trying to see how we can cripple=20
>>>> string_interpolation in order to fit in current-ish C++.
>>>>
>>>
>>> I fail to see why applying a UDL to the literal fragments rather than=
=20
>>> the interpolation aggregation operation should be considered "crippling=
"=20
>>> string interpolation.
>>>
>>> Whatever breakage you see in literals isn't standing in the way of=20
>>> string interpolation. It's just standing in the way of string interpola=
tion=20
>>> working the way *you* want it to.
>>>
>>
>> Because string interpolation is dealing with string literals,
>>
>
> Why does it have to be? If constexpr strings are in the future, it'd be=
=20
> really nice if string interpolation were defined in such a way that it=20
> could be used on them. Tying interpolation to literals is not=20
> forward-thinking.
>
> if those literals are broken (and they are), how can we have a proper=20
>> string interpolation?
>>
>
> Because any "brokenness" of string literals has no effect on our ability=
=20
> to use string interpolation. If you want sized strings for those string=
=20
> fragments, that's what the `sv` suffix is for.
>
> Literal issues only are a problem for string interpolation because you=20
> believe that the suffix ought to be able to define the aggregation=20
> operation. If you stop believing that, then all of a sudden, your problem=
=20
> with string literals becomes a non-issue for interpolation.
>
> It should also be noted that this:
>
> template<typename T>
> void foo(const T& t);
>
> foo("an array");
>
> The call to `foo` will deduce `T` to be `char[9]`. So a variadic template=
=20
> function that takes the results of string interpolation will get sized=20
> array types, not pointers.
>
> Note that this doesn't invalidate anything I said. The point of doing=20
> `F"blah {variable} blah"sv` is not necessarily because you need them to=
=20
> keep the size around. Using `string_view` has many other advantages, with=
=20
> its member functions, `operator<<` overloads, and the like. So wanting to=
=20
> apply `sv` to each of the fragments is a perfectly reasonable operation.
>
> Also, `string_view` is a lot more convenient to use than an array of=20
> characters.
>
> You said:
>>
>>> The point of that discussion was a comment someone made about doing=20
>>> template metaprogramming on string literals. To do that, you need a way=
 to=20
>>> access each literal as a distinct type, some `string_literal<char, 'c',=
=20
>>> 'h', 'a', 'r'>` type. And only a UDL applied to each fragment can perfo=
rm=20
>>> that kind of synthesis.
>>>
>>
>> UDL is the only way to do it only because string literals are broken. If=
=20
>> we had proper string literals, it should be possible to do it simply wit=
h=20
>> regular functions.
>>
>
> No, it would not. Even if a string literal had a non-array type with a=20
> stored size, each literal value would still not have its own distinct=20
> *type*. Even if the size is a template argument, two literals can store=
=20
> different characters while still having the same size. And you cannot do=
=20
> type-based metaprogramming without having a 1:1 mapping between value and=
=20
> type.
>
> Remember: while UDL's *can* take strings as a sequence of character=20
> template parameters, there's a good reason why they aren't *required* to=
=20
> do so. We don't want to force that onto everybody, and a non-"broken"=20
> string literal system would not force that on people.
>
> So even with your approach, broken string literals are a problem for=20
>> string interpolation. Just not at the same place.
>>
>> I'm not sure if my approach is the right one (it's probably not), but=20
>> most of your arguments stand only because string literal are broken=20
>> (otherwise, it would have been simple to do the same with my approach to=
o).
>>
>> My point is: yes your approach makes it easier with current C++, but we=
=20
>> shouldn't go for something that works quite well with current C++, but=
=20
>> something that will work very well with future C++.
>> That's why I think it's better to first fix string literals. And then=20
>> have string interpolation right the first time.
>>
>> And btw, if string literals are fixed, string interpolation could be mad=
e=20
>> a library solution only ( with a different but reasonable syntax).
>>
>
> It's impossible to do that. String interpolation, at its core, is about=
=20
> taking the contents of a string and applying them in some way to the code=
=20
> *around* that string. A library solution cannot possibly do that.
>
> Oh sure, a `constexpr` function could do the parsing. But then what? I'm=
=20
> fairly certain that no static reflection proposal provides a mechanism to=
=20
> turn a string into a reference to a local variable. And even if they did,=
=20
> the location where you're doing that conversion wouldn't have that variab=
le=20
> in scope (since it's in a function call), so it couldn't possibly work.
>
> PS: I think it would be preferable to stop the discussion here, as it=20
>> becomes more and more off-topic.
>>
>
> But what if we don't agree that string interpolation needs better literal=
s?
>
> Your premise is essentially that my suggested syntax is some kind of=20
> compromise, that if literals weren't "broken" the way you feel that they=
=20
> are, then it would *clearly* be correct to have UDLs applied to=20
> aggregation rather than to the individual fragments.
>
> I don't agree with that premise. Whether literals are good or broken is a=
=20
> side issue. Even if we had perfect literals, I would *still* rather UDLs=
=20
> be focused on individual string literal manipulation rather than string=
=20
> interpolation aggregation.
>
=20

After some toughs I come to conclusion that mixing interpolation with UDL=
=20
is limiting thing and this is good thing. Why? Because beside good things=
=20
it limit bad things too.
I start from high metaprograming starting point where I made all trader=20
offs to make it work, you start from basic usage and use opposite options.
As consequence all my example of use of string interpolation become=20
unusable in your approach.

We can start with sql, you suggest that version:
db.exec(F"some sql stuff {var1} more sql {var2};");

I can quote someone: "Have we learned nothing from Little Bobby Tables?",=
=20
how you want disquisition between `const char*`s parameters?
I did not had this problem because I can limit how parameters are pass to=
=20
UDL and I can relay on it.
One way to avoid it is add new literal that will help with that but in some=
=20
corner cases it could still break.

db.exec("select sth"_sql);
db.exec(F"select sth when {name}"_sqlp); //as you point outs, "select x" is=
=20
not sql, we need diffrent postfix.
tuple(F"{name1}{name2}"); //this is `tuple<const char*, const char*>` or=20
`tuple<const char*, const char*, const char*, const char*, const char*>`?
tuple(F"{name1} {name2}"); //same type as above?
translate(F"With {part} to {change}? Can I {change}{order} in any way?",=20
"fr"); //BTW "fr" is part of interpolated string from perspective of this=
=20
function
In my case all this things can be enclosed in UDL and will not leak outside=
..

Another problem is that even if your version is more flexible you still=20
repeat in multiple of place usage of specialization point functions=20
otherwise you cant use interpolation without it, in my version you only=20
would need use them in UDL.

Probably without lot of limitation, many quirks will prevent any serous=20
metaprograming. I'm inclined to thinking that whole idea will not go far.

btw
f(F"T{{a}}"); //is `f("T{{a}}")` or `f("T", {a})`?
Where both version could compile. Probably safer would be follow JS version=
=20
where we it use `${` to start interpolation.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/589a55c8-d886-4bb1-b991-96c5e9fe910a%40isocpp.or=
g.

------=_Part_11092_1010458152.1518566147733
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Tuesday, February 13, 2018 at 10:39:35 PM UTC+1=
, Nicol Bolas wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr">On Tuesday, February 13, 2018 at 12:18:59 PM UTC-5, <a>floria...@g=
mail.com</a> wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;marg=
in-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"=
>Le mardi 13 f=C3=A9vrier 2018 17:35:49 UTC+1, Nicol Bolas a =C3=A9crit=C2=
=A0:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;b=
order-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Because i=
t would never be called. Basically, what you&#39;d need is this constructor=
:<br><br><div style=3D"background-color:rgb(250,250,250);border-color:rgb(1=
87,187,187);border-style:solid;border-width:1px"><code><div><span style=3D"=
color:#008">template</span><span style=3D"color:#660">&lt;</span><span styl=
e=3D"color:#000">size_t N</span><span style=3D"color:#660">&gt;</span><span=
 style=3D"color:#000"><br>string_view</span><span style=3D"color:#660">(</s=
pan><span style=3D"color:#008">const</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#008">char</span><span style=3D"color:#000"> s</spa=
n><span style=3D"color:#660">[</span><span style=3D"color:#000">N</span><sp=
an style=3D"color:#660">]);</span></div></code></div><br>But you already ha=
ve this constructor:<br><br><div style=3D"background-color:rgb(250,250,250)=
;border-color:rgb(187,187,187);border-style:solid;border-width:1px"><code><=
div><span style=3D"color:#000">string_view</span><span style=3D"color:#660"=
>(</span><span style=3D"color:#008">const</span><span style=3D"color:#000">=
 </span><span style=3D"color:#008">char</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#660">*</span><span style=3D"color:#000">s</span=
><span style=3D"color:#660">);</span></div></code></div><br>An array decays=
 into a pointer. And since the pointer constructor is not a template, it is=
 considered a better match than the array version. And therefore, any ltier=
al you pass will go through the pointer version rather than the array templ=
ate.<br><br>And it should be noted that this has nothing to do with being a=
 literal. If you used a `const char[]` variable, it <i>still</i> would pref=
er the pointer version due to array-&gt;pointer conversion. So this is not =
a case of &quot;string literals are broken now&quot;.<br></div></div></bloc=
kquote><div><br></div><div>How can you say that preferring a lossy conversi=
on over a lossless one is not broken? (Here, we lose the length information=
)<br></div></div></blockquote><div><br>Because the &quot;lossy conversion&q=
uot; part being preferred has nothing to do with them being string literals=
.. The lossy conversion is not the literal-to-array conversion; it&#39;s the=
 array-to-pointer conversion.<br><br>You&#39;re complaining about the wrong=
 problem.<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><div>This make it impossible to work with string literal be=
cause they simply don&#39;t exist in the language. This is why I said strin=
g literals are broken.</div><div>=C2=A0</div><blockquote class=3D"gmail_quo=
te" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-=
left:1ex"><div dir=3D"ltr"><div>But there&#39;s no &quot;fix&quot; for this=
, since any array-&gt;pointer &quot;fix&quot; would be both wildly incompat=
ible with C and break tons and tons of code. So you can either accept the l=
anguage and work with what we have, or rail against it.<br></div></div></bl=
ockquote><div></div><div><div><br></div>Ok it&#39;s not possible to fix arr=
ay decay because of=20
backward compatibility, but it is still possible to fix string literals=20
if we make them something that is not an array.</div></div></blockquote><di=
v><br>Why would changing the behavior of string literals be any more backwa=
rds compatible than changing the behavior of arrays? There&#39;s lots of co=
de out there that works with C++&#39;s string literal rules. Can you find a=
 way to change those rules without breaking their code?<br><br>Let me give =
you a simple case: `decltype(&quot;a string literal&quot;)` is an array typ=
e. Therefore, any BC change will have to leave it as an array type. So what=
 rules would you change to fix the problem you want fixed without changing =
the result of that `decltype`?<br><br></div><blockquote class=3D"gmail_quot=
e" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"ltr"><div>So I rail against those defects in order to =
be heard, and maybe, at some point, they will be fixed.</div></div></blockq=
uote><div><br>Yeah, that&#39;s not how this works. You can &quot;rail again=
st those defects&quot; all you like, but unless you&#39;re willing to actua=
lly work on it (ie: finding a solution that doesn&#39;t break the world and=
 getting it through the committee), it will not get fixed. Or you manage to=
 convince someone who&#39;s actually willing to put in said work to do so.<=
br><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-lef=
t:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>=
If this is not the place to speak out loud about those defects, then where =
should we go?<br></div><div><br></div><div>But don&#39;t get me wrong, when=
 I code, I work with what I have, and I accept the language as it is.<br></=
div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0;ma=
rgin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"lt=
r"><div><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"ltr">=
<div>It&#39;s funny how the more I dig in C++, the more bulky it appears to=
 be just because of these very small annoyances.<br></div><div>=C2=A0</div>=
<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;borde=
r-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><br>It&#39;s =
a 3 step process; let&#39;s not interfere in that.<br>=C2=A0</div><blockquo=
te class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><div>We could ha=
ve exatcly the situation with string interpolation:</div><div><div style=3D=
"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-sty=
le:solid;border-width:1px"><code><div><span style=3D"color:#008">auto</span=
><span style=3D"color:#000"> s </span><span style=3D"color:#660">=3D</span>=
<span style=3D"color:#000"> std</span><span style=3D"color:#660">::</span><=
span style=3D"color:#000">concat</span><span style=3D"color:#660">(</span><=
span style=3D"color:#000">F</span><span style=3D"color:#080">&quot;{str1}{s=
tr2}{<wbr>str3}&quot;</span><span style=3D"color:#660">);</span><span style=
=3D"color:#000"><br></span><span style=3D"color:#800">// would be equivalen=
t to</span><span style=3D"color:#000"><br></span><span style=3D"color:#008"=
>auto</span><span style=3D"color:#000"> s </span><span style=3D"color:#660"=
>=3D</span><span style=3D"color:#000"> F</span><span style=3D"color:#080">&=
quot;{str1}{str2}{str3}&quot;</span><span style=3D"color:#000">s</span><spa=
n style=3D"color:#660">;</span><span style=3D"color:#000"><br></span></div>=
</code></div><br>I don&#39;t see why allowing UDL to work like that would d=
ecrease usability as we could always use regular functions.<br></div></div>=
</blockquote><div><br>Because you can&#39;t do this:<br><br><div style=3D"b=
ackground-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style=
:solid;border-width:1px"><code><div><span style=3D"color:#000">std</span><s=
pan style=3D"color:#660">::</span><span style=3D"color:#000">concat</span><=
span style=3D"color:#660">(</span><span style=3D"color:#000">F</span><span =
style=3D"color:#080">&quot;some string {variable} other string&quot;</span>=
<span style=3D"color:#000">sv</span><span style=3D"color:#660">);</span></d=
iv></code></div><br>Under my system, the UDL employed here allows you to de=
cide how to process each of the literal fragments. The UDL applies to the p=
arts of the literal that are actually strings. So `concat` would get `strin=
g_view`s, rather than `const char[X]` parameters.<br><br>Under your system,=
 the processing of the literal fragments is controlled entirely by the syst=
em that computes the aggregation.</div></div></blockquote><div><br></div><d=
iv>Let&#39;s sum up, string literals are broken today. So we should probabl=
y try to solve this big issue before trying to see how we can cripple strin=
g_interpolation in order to fit in current-ish C++.<br></div></div></blockq=
uote><div><br>I fail to see why applying a UDL to the literal fragments rat=
her than the interpolation aggregation operation should be considered &quot=
;crippling&quot; string interpolation.<br><br>Whatever breakage you see in =
literals isn&#39;t standing in the way of string interpolation. It&#39;s ju=
st standing in the way of string interpolation working the way <i>you</i> w=
ant it to.<br></div></div></blockquote><div><br></div><div>Because string i=
nterpolation is dealing with string literals,</div></div></blockquote><div>=
<br>Why does it have to be? If constexpr strings are in the future, it&#39;=
d be really nice if string interpolation were defined in such a way that it=
 could be used on them. Tying interpolation to literals is not forward-thin=
king.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;marg=
in-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"=
><div>if those literals are broken (and they are), how can we have a proper=
 string interpolation?</div></div></blockquote><div><br>Because any &quot;b=
rokenness&quot; of string literals has no effect on our ability to use stri=
ng interpolation. If you want sized strings for those string fragments, tha=
t&#39;s what the `sv` suffix is for.<br><br>Literal issues only are a probl=
em for string interpolation because you believe that the suffix ought to be=
 able to define the aggregation operation. If you stop believing that, then=
 all of a sudden, your problem with string literals becomes a non-issue for=
 interpolation.<br><br>It should also be noted that this:<br><br><div style=
=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-=
style:solid;border-width:1px"><code><div><span style=3D"color:#008">templat=
e</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">ty=
pename</span><span style=3D"color:#000"> T</span><span style=3D"color:#660"=
>&gt;</span><span style=3D"color:#000"><br></span><span style=3D"color:#008=
">void</span><span style=3D"color:#000"> foo</span><span style=3D"color:#66=
0">(</span><span style=3D"color:#008">const</span><span style=3D"color:#000=
"> T</span><span style=3D"color:#660">&amp;</span><span style=3D"color:#000=
"> t</span><span style=3D"color:#660">);</span><span style=3D"color:#000"><=
br><br>foo</span><span style=3D"color:#660">(</span><span style=3D"color:#0=
80">&quot;an array&quot;</span><span style=3D"color:#660">);</span><span st=
yle=3D"color:#000"><br></span></div></code></div><br>The call to `foo` will=
 deduce `T` to be `char[9]`. So a variadic template function that takes the=
 results of string interpolation will get sized array types, not pointers.<=
br><br>Note that this doesn&#39;t invalidate anything I said. The point of =
doing `F&quot;blah {variable} blah&quot;sv` is not necessarily because you =
need them to keep the size around. Using `string_view` has many other advan=
tages, with its member functions, `operator&lt;&lt;` overloads, and the lik=
e. So wanting to apply `sv` to each of the fragments is a perfectly reasona=
ble operation.<br><br>Also, `string_view` is a lot more convenient to use t=
han an array of characters.<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><div>You said:</div><blockquote class=3D"=
gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(20=
4,204,204);padding-left:1ex"><div>The point of that discussion was a commen=
t someone made about doing=20
template metaprogramming on string literals. To do that, you need a way=20
to access each literal as a distinct type, some `string_literal&lt;char,
 &#39;c&#39;, &#39;h&#39;, &#39;a&#39;, &#39;r&#39;&gt;` type. And only a U=
DL applied to each fragment=20
can perform that kind of synthesis.</div></blockquote><div><br></div><div>U=
DL is the only way to do it only because string literals are broken. If we =
had proper string literals, it should be possible to do it simply with regu=
lar functions.</div></div></blockquote><div><br>No, it would not. Even if a=
 string literal had a non-array type with a stored size, each literal value=
 would still not have its own distinct <i>type</i>. Even if the size is a t=
emplate argument, two literals can store different characters while still h=
aving the same size. And you cannot do type-based metaprogramming without h=
aving a 1:1 mapping between value and type.<br><br>Remember: while UDL&#39;=
s <i>can</i> take strings as a sequence of character template parameters, t=
here&#39;s a good reason why they aren&#39;t <i>required</i> to do so. We d=
on&#39;t want to force that onto everybody, and a non-&quot;broken&quot; st=
ring literal system would not force that on people.<br><br></div><blockquot=
e 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>So even with your appro=
ach, broken string literals are a problem for string interpolation. Just no=
t at the same place.</div><div><br></div><div>I&#39;m not sure if my approa=
ch is the right one (it&#39;s probably not), but most of your arguments sta=
nd only because string literal are broken (otherwise, it would have been si=
mple to do the same with my approach too).</div><div><br></div><div>My poin=
t is: yes your approach makes it easier with current C++, but we shouldn&#3=
9;t go for something that works quite well with current C++, but something =
that will work very well with future C++.</div><div>That&#39;s why I think =
it&#39;s better to first fix string literals. And then have string interpol=
ation right the first time.<br></div><div><br></div><div>And btw, if string=
 literals are fixed, string interpolation could be made a library solution =
only ( with a different but reasonable syntax).</div></div></blockquote><di=
v><br>It&#39;s impossible to do that. String interpolation, at its core, is=
 about taking the contents of a string and applying them in some way to the=
 code <i>around</i> that string. A library solution cannot possibly do that=
..<br><br>Oh sure, a `constexpr` function could do the parsing. But then wha=
t? I&#39;m fairly certain that no static reflection proposal provides a mec=
hanism to turn a string into a reference to a local variable. And even if t=
hey did, the location where you&#39;re doing that conversion wouldn&#39;t h=
ave that variable in scope (since it&#39;s in a function call), so it could=
n&#39;t possibly work.<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><div>PS: I think it would be preferable to sto=
p the discussion here, as it becomes more and more off-topic.<br></div></di=
v></blockquote><div><br>But what if we don&#39;t agree that string interpol=
ation needs better literals?<br><br>Your premise is essentially that my sug=
gested syntax is some kind of compromise, that if literals weren&#39;t &quo=
t;broken&quot; the way you feel that they are, then it would <i>clearly</i>=
 be correct to have UDLs applied to aggregation rather than to the individu=
al fragments.<br><br>I don&#39;t agree with that premise. Whether literals =
are good or broken is a side issue. Even if we had perfect literals, I woul=
d <i>still</i> rather UDLs be focused on individual string literal manipula=
tion rather than string interpolation aggregation.<br></div></div></blockqu=
ote><div>=C2=A0<br><br>After some toughs I come to conclusion that mixing i=
nterpolation with UDL is limiting thing and this is good thing. Why? Becaus=
e beside good things it limit bad things too.<br>I start from high metaprog=
raming starting point where I made all trader offs to make it work, you sta=
rt from basic usage and use opposite options.<br>As consequence all my exam=
ple of use of string interpolation become unusable in your approach.<br><br=
>We can start with sql, you suggest that version:<br><div style=3D"backgrou=
nd-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-styl=
e: solid; border-width: 1px; overflow-wrap: break-word;" class=3D"prettypri=
nt"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=
=3D"color: #000;" class=3D"styled-by-prettify">db</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">.</span><span style=3D"color: #008;"=
 class=3D"styled-by-prettify">exec</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">F</span><span style=3D"color: #080;" class=3D"styled-by-pret=
tify">&quot;some sql stuff {var1} more sql {var2};&quot;</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">);</span></div></code></div>=
<br>I can quote someone: &quot;Have we learned nothing from Little Bobby Ta=
bles?&quot;, how you want disquisition between `const char*`s parameters?<b=
r>I did not had this problem because I can limit how parameters are pass to=
 UDL and I can relay on it.<br>One way to avoid it is add new literal that =
will help with that but in some corner cases it could still break.<br><br><=
div style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 1=
87, 187); border-style: solid; border-width: 1px; overflow-wrap: break-word=
;" class=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subprett=
yprint"><span style=3D"color: #000;" class=3D"styled-by-prettify">db</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">exec</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #0=
80;" class=3D"styled-by-prettify">&quot;select sth&quot;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">_sql</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br>db</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">.</span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">exec</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">F</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&quo=
t;select sth when {name}&quot;</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">_sqlp</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">//=
as you point outs, &quot;select x&quot; is not sql, we need diffrent postfi=
x.</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>tupl=
e</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify">F</span><span styl=
e=3D"color: #080;" class=3D"styled-by-prettify">&quot;{name1}{name2}&quot;<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">//this is `tuple&lt;const ch=
ar*, const char*&gt;` or `tuple&lt;const char*, const char*, const char*, c=
onst char*, const char*&gt;`?</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br>tuple</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">F</span><span style=3D"color: #080;" class=3D"styled-by-prettify">=
&quot;{name1} {name2}&quot;</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">=
//same type as above?</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br>translate</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">F</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&quo=
t;With {part} to {change}? Can I {change}{order} in any way?&quot;</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=
: #080;" class=3D"styled-by-prettify">&quot;fr&quot;</span><span style=3D"c=
olor: #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">//BTW &quot;fr&quot; is part of interpolated strin=
g from perspective of this function</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br></span></div></code></div>In my case all this =
things can be enclosed in UDL and will not leak outside.<br><br>Another pro=
blem is that even if your version is more flexible you still repeat in mult=
iple of place usage of specialization point functions otherwise you cant us=
e interpolation without it, in my version you only would need use them in U=
DL.<br><br>Probably without lot of limitation, many quirks will prevent any=
 serous metaprograming. I&#39;m inclined to thinking that whole idea will n=
ot go far.<br><br>btw<br><div style=3D"background-color: rgb(250, 250, 250)=
; border-color: rgb(187, 187, 187); border-style: solid; border-width: 1px;=
 overflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"prettypri=
nt"><div class=3D"subprettyprint"><span style=3D"color: #000;" class=3D"sty=
led-by-prettify">f</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">F=
</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;T{{a=
}}&quot;</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">//is `f(&quot;T{{a}=
}&quot;)` or `f(&quot;T&quot;, {a})`?</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br></span></div></code></div>Where both version=
 could compile. Probably safer would be follow JS version where we it use `=
${` to start interpolation.<br><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/589a55c8-d886-4bb1-b991-96c5e9fe910a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/589a55c8-d886-4bb1-b991-96c5e9fe910a=
%40isocpp.org</a>.<br />

------=_Part_11092_1010458152.1518566147733--

------=_Part_11091_867363171.1518566147732--

.


Author: Todd Fleming <tbfleming@gmail.com>
Date: Tue, 13 Feb 2018 17:03:16 -0800 (PST)
Raw View
------=_Part_12615_215957504.1518570196677
Content-Type: multipart/alternative;
 boundary="----=_Part_12616_1502680122.1518570196678"

------=_Part_12616_1502680122.1518570196678
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Tuesday, February 13, 2018 at 6:55:47 PM UTC-5, Marcin Jaczewski wrote:
>
>
>
> On Tuesday, February 13, 2018 at 10:39:35 PM UTC+1, Nicol Bolas wrote:
>>
>> On Tuesday, February 13, 2018 at 12:18:59 PM UTC-5, floria...@gmail.com=
=20
>> wrote:
>>>
>>> Le mardi 13 f=C3=A9vrier 2018 17:35:49 UTC+1, Nicol Bolas a =C3=A9crit =
:
>>>>
>>>> Because it would never be called. Basically, what you'd need is this=
=20
>>>> constructor:
>>>>
>>>> template<size_t N>
>>>> string_view(const char s[N]);
>>>>
>>>> But you already have this constructor:
>>>>
>>>> string_view(const char *s);
>>>>
>>>> An array decays into a pointer. And since the pointer constructor is=
=20
>>>> not a template, it is considered a better match than the array version=
.. And=20
>>>> therefore, any ltieral you pass will go through the pointer version ra=
ther=20
>>>> than the array template.
>>>>
>>>> And it should be noted that this has nothing to do with being a=20
>>>> literal. If you used a `const char[]` variable, it *still* would=20
>>>> prefer the pointer version due to array->pointer conversion. So this i=
s not=20
>>>> a case of "string literals are broken now".
>>>>
>>>
>>> How can you say that preferring a lossy conversion over a lossless one=
=20
>>> is not broken? (Here, we lose the length information)
>>>
>>
>> Because the "lossy conversion" part being preferred has nothing to do=20
>> with them being string literals. The lossy conversion is not the=20
>> literal-to-array conversion; it's the array-to-pointer conversion.
>>
>> You're complaining about the wrong problem.
>>
>> This make it impossible to work with string literal because they simply=
=20
>>> don't exist in the language. This is why I said string literals are bro=
ken.
>>> =20
>>>
>>>> But there's no "fix" for this, since any array->pointer "fix" would be=
=20
>>>> both wildly incompatible with C and break tons and tons of code. So yo=
u can=20
>>>> either accept the language and work with what we have, or rail against=
 it.
>>>>
>>>
>>> Ok it's not possible to fix array decay because of backward=20
>>> compatibility, but it is still possible to fix string literals if we ma=
ke=20
>>> them something that is not an array.
>>>
>>
>> Why would changing the behavior of string literals be any more backwards=
=20
>> compatible than changing the behavior of arrays? There's lots of code ou=
t=20
>> there that works with C++'s string literal rules. Can you find a way to=
=20
>> change those rules without breaking their code?
>>
>> Let me give you a simple case: `decltype("a string literal")` is an arra=
y=20
>> type. Therefore, any BC change will have to leave it as an array type. S=
o=20
>> what rules would you change to fix the problem you want fixed without=20
>> changing the result of that `decltype`?
>>
>> So I rail against those defects in order to be heard, and maybe, at some=
=20
>>> point, they will be fixed.
>>>
>>
>> Yeah, that's not how this works. You can "rail against those defects" al=
l=20
>> you like, but unless you're willing to actually work on it (ie: finding =
a=20
>> solution that doesn't break the world and getting it through the=20
>> committee), it will not get fixed. Or you manage to convince someone who=
's=20
>> actually willing to put in said work to do so.
>>
>> If this is not the place to speak out loud about those defects, then=20
>>> where should we go?
>>>
>>> But don't get me wrong, when I code, I work with what I have, and I=20
>>> accept the language as it is.
>>> =20
>>>
>>>>
>>>> It's funny how the more I dig in C++, the more bulky it appears to be=
=20
>>>>> just because of these very small annoyances.
>>>>> =20
>>>>>
>>>>>>
>>>>>> It's a 3 step process; let's not interfere in that.
>>>>>> =20
>>>>>>
>>>>>>> We could have exatcly the situation with string interpolation:
>>>>>>> auto s =3D std::concat(F"{str1}{str2}{str3}");
>>>>>>> // would be equivalent to
>>>>>>> auto s =3D F"{str1}{str2}{str3}"s;
>>>>>>>
>>>>>>> I don't see why allowing UDL to work like that would decrease=20
>>>>>>> usability as we could always use regular functions.
>>>>>>>
>>>>>>
>>>>>> Because you can't do this:
>>>>>>
>>>>>> std::concat(F"some string {variable} other string"sv);
>>>>>>
>>>>>> Under my system, the UDL employed here allows you to decide how to=
=20
>>>>>> process each of the literal fragments. The UDL applies to the parts =
of the=20
>>>>>> literal that are actually strings. So `concat` would get `string_vie=
w`s,=20
>>>>>> rather than `const char[X]` parameters.
>>>>>>
>>>>>> Under your system, the processing of the literal fragments is=20
>>>>>> controlled entirely by the system that computes the aggregation.
>>>>>>
>>>>>
>>>>> Let's sum up, string literals are broken today. So we should probably=
=20
>>>>> try to solve this big issue before trying to see how we can cripple=
=20
>>>>> string_interpolation in order to fit in current-ish C++.
>>>>>
>>>>
>>>> I fail to see why applying a UDL to the literal fragments rather than=
=20
>>>> the interpolation aggregation operation should be considered "cripplin=
g"=20
>>>> string interpolation.
>>>>
>>>> Whatever breakage you see in literals isn't standing in the way of=20
>>>> string interpolation. It's just standing in the way of string interpol=
ation=20
>>>> working the way *you* want it to.
>>>>
>>>
>>> Because string interpolation is dealing with string literals,
>>>
>>
>> Why does it have to be? If constexpr strings are in the future, it'd be=
=20
>> really nice if string interpolation were defined in such a way that it=
=20
>> could be used on them. Tying interpolation to literals is not=20
>> forward-thinking.
>>
>> if those literals are broken (and they are), how can we have a proper=20
>>> string interpolation?
>>>
>>
>> Because any "brokenness" of string literals has no effect on our ability=
=20
>> to use string interpolation. If you want sized strings for those string=
=20
>> fragments, that's what the `sv` suffix is for.
>>
>> Literal issues only are a problem for string interpolation because you=
=20
>> believe that the suffix ought to be able to define the aggregation=20
>> operation. If you stop believing that, then all of a sudden, your proble=
m=20
>> with string literals becomes a non-issue for interpolation.
>>
>> It should also be noted that this:
>>
>> template<typename T>
>> void foo(const T& t);
>>
>> foo("an array");
>>
>> The call to `foo` will deduce `T` to be `char[9]`. So a variadic templat=
e=20
>> function that takes the results of string interpolation will get sized=
=20
>> array types, not pointers.
>>
>> Note that this doesn't invalidate anything I said. The point of doing=20
>> `F"blah {variable} blah"sv` is not necessarily because you need them to=
=20
>> keep the size around. Using `string_view` has many other advantages, wit=
h=20
>> its member functions, `operator<<` overloads, and the like. So wanting t=
o=20
>> apply `sv` to each of the fragments is a perfectly reasonable operation.
>>
>> Also, `string_view` is a lot more convenient to use than an array of=20
>> characters.
>>
>> You said:
>>>
>>>> The point of that discussion was a comment someone made about doing=20
>>>> template metaprogramming on string literals. To do that, you need a wa=
y to=20
>>>> access each literal as a distinct type, some `string_literal<char, 'c'=
,=20
>>>> 'h', 'a', 'r'>` type. And only a UDL applied to each fragment can perf=
orm=20
>>>> that kind of synthesis.
>>>>
>>>
>>> UDL is the only way to do it only because string literals are broken. I=
f=20
>>> we had proper string literals, it should be possible to do it simply wi=
th=20
>>> regular functions.
>>>
>>
>> No, it would not. Even if a string literal had a non-array type with a=
=20
>> stored size, each literal value would still not have its own distinct=20
>> *type*. Even if the size is a template argument, two literals can store=
=20
>> different characters while still having the same size. And you cannot do=
=20
>> type-based metaprogramming without having a 1:1 mapping between value an=
d=20
>> type.
>>
>> Remember: while UDL's *can* take strings as a sequence of character=20
>> template parameters, there's a good reason why they aren't *required* to=
=20
>> do so. We don't want to force that onto everybody, and a non-"broken"=20
>> string literal system would not force that on people.
>>
>> So even with your approach, broken string literals are a problem for=20
>>> string interpolation. Just not at the same place.
>>>
>>> I'm not sure if my approach is the right one (it's probably not), but=
=20
>>> most of your arguments stand only because string literal are broken=20
>>> (otherwise, it would have been simple to do the same with my approach t=
oo).
>>>
>>> My point is: yes your approach makes it easier with current C++, but we=
=20
>>> shouldn't go for something that works quite well with current C++, but=
=20
>>> something that will work very well with future C++.
>>> That's why I think it's better to first fix string literals. And then=
=20
>>> have string interpolation right the first time.
>>>
>>> And btw, if string literals are fixed, string interpolation could be=20
>>> made a library solution only ( with a different but reasonable syntax).
>>>
>>
>> It's impossible to do that. String interpolation, at its core, is about=
=20
>> taking the contents of a string and applying them in some way to the cod=
e=20
>> *around* that string. A library solution cannot possibly do that.
>>
>> Oh sure, a `constexpr` function could do the parsing. But then what? I'm=
=20
>> fairly certain that no static reflection proposal provides a mechanism t=
o=20
>> turn a string into a reference to a local variable. And even if they did=
,=20
>> the location where you're doing that conversion wouldn't have that varia=
ble=20
>> in scope (since it's in a function call), so it couldn't possibly work.
>>
>> PS: I think it would be preferable to stop the discussion here, as it=20
>>> becomes more and more off-topic.
>>>
>>
>> But what if we don't agree that string interpolation needs better=20
>> literals?
>>
>> Your premise is essentially that my suggested syntax is some kind of=20
>> compromise, that if literals weren't "broken" the way you feel that they=
=20
>> are, then it would *clearly* be correct to have UDLs applied to=20
>> aggregation rather than to the individual fragments.
>>
>> I don't agree with that premise. Whether literals are good or broken is =
a=20
>> side issue. Even if we had perfect literals, I would *still* rather UDLs=
=20
>> be focused on individual string literal manipulation rather than string=
=20
>> interpolation aggregation.
>>
> =20
>
> After some toughs I come to conclusion that mixing interpolation with UDL=
=20
> is limiting thing and this is good thing. Why? Because beside good things=
=20
> it limit bad things too.
> I start from high metaprograming starting point where I made all trader=
=20
> offs to make it work, you start from basic usage and use opposite options=
..
> As consequence all my example of use of string interpolation become=20
> unusable in your approach.
>
> We can start with sql, you suggest that version:
> db.exec(F"some sql stuff {var1} more sql {var2};");
>
> I can quote someone: "Have we learned nothing from Little Bobby Tables?",=
=20
> how you want disquisition between `const char*`s parameters?
> I did not had this problem because I can limit how parameters are pass to=
=20
> UDL and I can relay on it.
> One way to avoid it is add new literal that will help with that but in=20
> some corner cases it could still break.
>
> db.exec("select sth"_sql);
> db.exec(F"select sth when {name}"_sqlp); //as you point outs, "select x"=
=20
> is not sql, we need diffrent postfix.
> tuple(F"{name1}{name2}"); //this is `tuple<const char*, const char*>` or=
=20
> `tuple<const char*, const char*, const char*, const char*, const char*>`?
> tuple(F"{name1} {name2}"); //same type as above?
> translate(F"With {part} to {change}? Can I {change}{order} in any way?",=
=20
> "fr"); //BTW "fr" is part of interpolated string from perspective of this=
=20
> function
> In my case all this things can be enclosed in UDL and will not leak=20
> outside.
>
> Another problem is that even if your version is more flexible you still=
=20
> repeat in multiple of place usage of specialization point functions=20
> otherwise you cant use interpolation without it, in my version you only=
=20
> would need use them in UDL.
>
> Probably without lot of limitation, many quirks will prevent any serous=
=20
> metaprograming. I'm inclined to thinking that whole idea will not go far.
>
> btw
> f(F"T{{a}}"); //is `f("T{{a}}")` or `f("T", {a})`?
> Where both version could compile. Probably safer would be follow JS=20
> version where we it use `${` to start interpolation.
>
>
This could stop Little Bobby Tables:

f(F"{a}{b}");

could translate to

f("", a, "", b, "");


arguments 0, ..., 2n are always literals and 1, ..., 2n-1 are always=20
expressions.

f(F"T{{a}}");

would be=20

f("", {a}, "")


--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/c753942d-be11-4cc0-bde1-7f71b6184367%40isocpp.or=
g.

------=_Part_12616_1502680122.1518570196678
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Tuesday, February 13, 2018 at 6:55:47 PM UTC-5, Marcin =
Jaczewski 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"><br><br>On Tuesday, February 13, 2018 at 10:39:35 PM UTC+1, Nicol Bolas =
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 Tuesday, =
February 13, 2018 at 12:18:59 PM UTC-5, <a>floria...@gmail.com</a> wrote:<b=
lockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-=
left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">Le mardi 13 f=C3=A9v=
rier 2018 17:35:49 UTC+1, Nicol Bolas a =C3=A9crit=C2=A0:<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>Because it would never be call=
ed. Basically, what you&#39;d need is this constructor:<br><br><div style=
=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-=
style:solid;border-width:1px"><code><div><span style=3D"color:#008">templat=
e</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">si=
ze_t N</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#00=
0"><br>string_view</span><span style=3D"color:#660">(</span><span style=3D"=
color:#008">const</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#008">char</span><span style=3D"color:#000"> s</span><span style=3D"co=
lor:#660">[</span><span style=3D"color:#000">N</span><span style=3D"color:#=
660">]);</span></div></code></div><br>But you already have this constructor=
:<br><br><div style=3D"background-color:rgb(250,250,250);border-color:rgb(1=
87,187,187);border-style:solid;border-width:1px"><code><div><span style=3D"=
color:#000">string_view</span><span style=3D"color:#660">(</span><span styl=
e=3D"color:#008">const</span><span style=3D"color:#000"> </span><span style=
=3D"color:#008">char</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">*</span><span style=3D"color:#000">s</span><span style=3D"c=
olor:#660">);</span></div></code></div><br>An array decays into a pointer. =
And since the pointer constructor is not a template, it is considered a bet=
ter match than the array version. And therefore, any ltieral you pass will =
go through the pointer version rather than the array template.<br><br>And i=
t should be noted that this has nothing to do with being a literal. If you =
used a `const char[]` variable, it <i>still</i> would prefer the pointer ve=
rsion due to array-&gt;pointer conversion. So this is not a case of &quot;s=
tring literals are broken now&quot;.<br></div></div></blockquote><div><br><=
/div><div>How can you say that preferring a lossy conversion over a lossles=
s one is not broken? (Here, we lose the length information)<br></div></div>=
</blockquote><div><br>Because the &quot;lossy conversion&quot; part being p=
referred has nothing to do with them being string literals. The lossy conve=
rsion is not the literal-to-array conversion; it&#39;s the array-to-pointer=
 conversion.<br><br>You&#39;re complaining about the wrong problem.<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><=
div>This make it impossible to work with string literal because they simply=
 don&#39;t exist in the language. This is why I said string literals are br=
oken.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"marg=
in:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div di=
r=3D"ltr"><div>But there&#39;s no &quot;fix&quot; for this, since any array=
-&gt;pointer &quot;fix&quot; would be both wildly incompatible with C and b=
reak tons and tons of code. So you can either accept the language and work =
with what we have, or rail against it.<br></div></div></blockquote><div></d=
iv><div><div><br></div>Ok it&#39;s not possible to fix array decay because =
of=20
backward compatibility, but it is still possible to fix string literals=20
if we make them something that is not an array.</div></div></blockquote><di=
v><br>Why would changing the behavior of string literals be any more backwa=
rds compatible than changing the behavior of arrays? There&#39;s lots of co=
de out there that works with C++&#39;s string literal rules. Can you find a=
 way to change those rules without breaking their code?<br><br>Let me give =
you a simple case: `decltype(&quot;a string literal&quot;)` is an array typ=
e. Therefore, any BC change will have to leave it as an array type. So what=
 rules would you change to fix the problem you want fixed without changing =
the result of that `decltype`?<br><br></div><blockquote class=3D"gmail_quot=
e" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"ltr"><div>So I rail against those defects in order to =
be heard, and maybe, at some point, they will be fixed.</div></div></blockq=
uote><div><br>Yeah, that&#39;s not how this works. You can &quot;rail again=
st those defects&quot; all you like, but unless you&#39;re willing to actua=
lly work on it (ie: finding a solution that doesn&#39;t break the world and=
 getting it through the committee), it will not get fixed. Or you manage to=
 convince someone who&#39;s actually willing to put in said work to do so.<=
br><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-lef=
t:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>=
If this is not the place to speak out loud about those defects, then where =
should we go?<br></div><div><br></div><div>But don&#39;t get me wrong, when=
 I code, I work with what I have, and I accept the language as it is.<br></=
div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0;ma=
rgin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"lt=
r"><div><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"ltr">=
<div>It&#39;s funny how the more I dig in C++, the more bulky it appears to=
 be just because of these very small annoyances.<br></div><div>=C2=A0</div>=
<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;borde=
r-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><br>It&#39;s =
a 3 step process; let&#39;s not interfere in that.<br>=C2=A0</div><blockquo=
te class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><div>We could ha=
ve exatcly the situation with string interpolation:</div><div><div style=3D=
"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-sty=
le:solid;border-width:1px"><code><div><span style=3D"color:#008">auto</span=
><span style=3D"color:#000"> s </span><span style=3D"color:#660">=3D</span>=
<span style=3D"color:#000"> std</span><span style=3D"color:#660">::</span><=
span style=3D"color:#000">concat</span><span style=3D"color:#660">(</span><=
span style=3D"color:#000">F</span><span style=3D"color:#080">&quot;{str1}{s=
tr2}{<wbr>str3}&quot;</span><span style=3D"color:#660">);</span><span style=
=3D"color:#000"><br></span><span style=3D"color:#800">// would be equivalen=
t to</span><span style=3D"color:#000"><br></span><span style=3D"color:#008"=
>auto</span><span style=3D"color:#000"> s </span><span style=3D"color:#660"=
>=3D</span><span style=3D"color:#000"> F</span><span style=3D"color:#080">&=
quot;{str1}{str2}{str3}&quot;</span><span style=3D"color:#000">s</span><spa=
n style=3D"color:#660">;</span><span style=3D"color:#000"><br></span></div>=
</code></div><br>I don&#39;t see why allowing UDL to work like that would d=
ecrease usability as we could always use regular functions.<br></div></div>=
</blockquote><div><br>Because you can&#39;t do this:<br><br><div style=3D"b=
ackground-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style=
:solid;border-width:1px"><code><div><span style=3D"color:#000">std</span><s=
pan style=3D"color:#660">::</span><span style=3D"color:#000">concat</span><=
span style=3D"color:#660">(</span><span style=3D"color:#000">F</span><span =
style=3D"color:#080">&quot;some string {variable} other string&quot;</span>=
<span style=3D"color:#000">sv</span><span style=3D"color:#660">);</span></d=
iv></code></div><br>Under my system, the UDL employed here allows you to de=
cide how to process each of the literal fragments. The UDL applies to the p=
arts of the literal that are actually strings. So `concat` would get `strin=
g_view`s, rather than `const char[X]` parameters.<br><br>Under your system,=
 the processing of the literal fragments is controlled entirely by the syst=
em that computes the aggregation.</div></div></blockquote><div><br></div><d=
iv>Let&#39;s sum up, string literals are broken today. So we should probabl=
y try to solve this big issue before trying to see how we can cripple strin=
g_interpolation in order to fit in current-ish C++.<br></div></div></blockq=
uote><div><br>I fail to see why applying a UDL to the literal fragments rat=
her than the interpolation aggregation operation should be considered &quot=
;crippling&quot; string interpolation.<br><br>Whatever breakage you see in =
literals isn&#39;t standing in the way of string interpolation. It&#39;s ju=
st standing in the way of string interpolation working the way <i>you</i> w=
ant it to.<br></div></div></blockquote><div><br></div><div>Because string i=
nterpolation is dealing with string literals,</div></div></blockquote><div>=
<br>Why does it have to be? If constexpr strings are in the future, it&#39;=
d be really nice if string interpolation were defined in such a way that it=
 could be used on them. Tying interpolation to literals is not forward-thin=
king.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;marg=
in-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"=
><div>if those literals are broken (and they are), how can we have a proper=
 string interpolation?</div></div></blockquote><div><br>Because any &quot;b=
rokenness&quot; of string literals has no effect on our ability to use stri=
ng interpolation. If you want sized strings for those string fragments, tha=
t&#39;s what the `sv` suffix is for.<br><br>Literal issues only are a probl=
em for string interpolation because you believe that the suffix ought to be=
 able to define the aggregation operation. If you stop believing that, then=
 all of a sudden, your problem with string literals becomes a non-issue for=
 interpolation.<br><br>It should also be noted that this:<br><br><div style=
=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-=
style:solid;border-width:1px"><code><div><span style=3D"color:#008">templat=
e</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">ty=
pename</span><span style=3D"color:#000"> T</span><span style=3D"color:#660"=
>&gt;</span><span style=3D"color:#000"><br></span><span style=3D"color:#008=
">void</span><span style=3D"color:#000"> foo</span><span style=3D"color:#66=
0">(</span><span style=3D"color:#008">const</span><span style=3D"color:#000=
"> T</span><span style=3D"color:#660">&amp;</span><span style=3D"color:#000=
"> t</span><span style=3D"color:#660">);</span><span style=3D"color:#000"><=
br><br>foo</span><span style=3D"color:#660">(</span><span style=3D"color:#0=
80">&quot;an array&quot;</span><span style=3D"color:#660">);</span><span st=
yle=3D"color:#000"><br></span></div></code></div><br>The call to `foo` will=
 deduce `T` to be `char[9]`. So a variadic template function that takes the=
 results of string interpolation will get sized array types, not pointers.<=
br><br>Note that this doesn&#39;t invalidate anything I said. The point of =
doing `F&quot;blah {variable} blah&quot;sv` is not necessarily because you =
need them to keep the size around. Using `string_view` has many other advan=
tages, with its member functions, `operator&lt;&lt;` overloads, and the lik=
e. So wanting to apply `sv` to each of the fragments is a perfectly reasona=
ble operation.<br><br>Also, `string_view` is a lot more convenient to use t=
han an array of characters.<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><div>You said:</div><blockquote class=3D"=
gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(20=
4,204,204);padding-left:1ex"><div>The point of that discussion was a commen=
t someone made about doing=20
template metaprogramming on string literals. To do that, you need a way=20
to access each literal as a distinct type, some `string_literal&lt;char,
 &#39;c&#39;, &#39;h&#39;, &#39;a&#39;, &#39;r&#39;&gt;` type. And only a U=
DL applied to each fragment=20
can perform that kind of synthesis.</div></blockquote><div><br></div><div>U=
DL is the only way to do it only because string literals are broken. If we =
had proper string literals, it should be possible to do it simply with regu=
lar functions.</div></div></blockquote><div><br>No, it would not. Even if a=
 string literal had a non-array type with a stored size, each literal value=
 would still not have its own distinct <i>type</i>. Even if the size is a t=
emplate argument, two literals can store different characters while still h=
aving the same size. And you cannot do type-based metaprogramming without h=
aving a 1:1 mapping between value and type.<br><br>Remember: while UDL&#39;=
s <i>can</i> take strings as a sequence of character template parameters, t=
here&#39;s a good reason why they aren&#39;t <i>required</i> to do so. We d=
on&#39;t want to force that onto everybody, and a non-&quot;broken&quot; st=
ring literal system would not force that on people.<br><br></div><blockquot=
e 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>So even with your appro=
ach, broken string literals are a problem for string interpolation. Just no=
t at the same place.</div><div><br></div><div>I&#39;m not sure if my approa=
ch is the right one (it&#39;s probably not), but most of your arguments sta=
nd only because string literal are broken (otherwise, it would have been si=
mple to do the same with my approach too).</div><div><br></div><div>My poin=
t is: yes your approach makes it easier with current C++, but we shouldn&#3=
9;t go for something that works quite well with current C++, but something =
that will work very well with future C++.</div><div>That&#39;s why I think =
it&#39;s better to first fix string literals. And then have string interpol=
ation right the first time.<br></div><div><br></div><div>And btw, if string=
 literals are fixed, string interpolation could be made a library solution =
only ( with a different but reasonable syntax).</div></div></blockquote><di=
v><br>It&#39;s impossible to do that. String interpolation, at its core, is=
 about taking the contents of a string and applying them in some way to the=
 code <i>around</i> that string. A library solution cannot possibly do that=
..<br><br>Oh sure, a `constexpr` function could do the parsing. But then wha=
t? I&#39;m fairly certain that no static reflection proposal provides a mec=
hanism to turn a string into a reference to a local variable. And even if t=
hey did, the location where you&#39;re doing that conversion wouldn&#39;t h=
ave that variable in scope (since it&#39;s in a function call), so it could=
n&#39;t possibly work.<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><div>PS: I think it would be preferable to sto=
p the discussion here, as it becomes more and more off-topic.<br></div></di=
v></blockquote><div><br>But what if we don&#39;t agree that string interpol=
ation needs better literals?<br><br>Your premise is essentially that my sug=
gested syntax is some kind of compromise, that if literals weren&#39;t &quo=
t;broken&quot; the way you feel that they are, then it would <i>clearly</i>=
 be correct to have UDLs applied to aggregation rather than to the individu=
al fragments.<br><br>I don&#39;t agree with that premise. Whether literals =
are good or broken is a side issue. Even if we had perfect literals, I woul=
d <i>still</i> rather UDLs be focused on individual string literal manipula=
tion rather than string interpolation aggregation.<br></div></div></blockqu=
ote><div>=C2=A0<br><br>After some toughs I come to conclusion that mixing i=
nterpolation with UDL is limiting thing and this is good thing. Why? Becaus=
e beside good things it limit bad things too.<br>I start from high metaprog=
raming starting point where I made all trader offs to make it work, you sta=
rt from basic usage and use opposite options.<br>As consequence all my exam=
ple of use of string interpolation become unusable in your approach.<br><br=
>We can start with sql, you suggest that version:<br><div style=3D"backgrou=
nd-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;=
border-width:1px"><code><div><span style=3D"color:#000">db</span><span styl=
e=3D"color:#660">.</span><span style=3D"color:#008">exec</span><span style=
=3D"color:#660">(</span><span style=3D"color:#000">F</span><span style=3D"c=
olor:#080">&quot;some sql stuff {var1} more sql {var2};&quot;</span><span s=
tyle=3D"color:#660">);</span></div></code></div><br>I can quote someone: &q=
uot;Have we learned nothing from Little Bobby Tables?&quot;, how you want d=
isquisition between `const char*`s parameters?<br>I did not had this proble=
m because I can limit how parameters are pass to UDL and I can relay on it.=
<br>One way to avoid it is add new literal that will help with that but in =
some corner cases it could still break.<br><br><div style=3D"background-col=
or:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border=
-width:1px"><code><div><span style=3D"color:#000">db</span><span style=3D"c=
olor:#660">.</span><span style=3D"color:#008">exec</span><span style=3D"col=
or:#660">(</span><span style=3D"color:#080">&quot;select sth&quot;</span><s=
pan style=3D"color:#000">_sql</span><span style=3D"color:#660">);</span><sp=
an style=3D"color:#000"><br>db</span><span style=3D"color:#660">.</span><sp=
an style=3D"color:#008">exec</span><span style=3D"color:#660">(</span><span=
 style=3D"color:#000">F</span><span style=3D"color:#080">&quot;select sth w=
hen {name}&quot;</span><span style=3D"color:#000">_sqlp</span><span style=
=3D"color:#660">);</span><span style=3D"color:#000"> </span><span style=3D"=
color:#800">//as you point outs, &quot;select x&quot; is not sql, we need d=
iffrent postfix.</span><span style=3D"color:#000"><br>tuple</span><span sty=
le=3D"color:#660">(</span><span style=3D"color:#000">F</span><span style=3D=
"color:#080">&quot;{name1}{name2}&quot;</span><span style=3D"color:#660">);=
</span><span style=3D"color:#000"> </span><span style=3D"color:#800">//this=
 is `tuple&lt;const char*, const char*&gt;` or `tuple&lt;const char*, const=
 char*, const char*, const char*, const char*&gt;`?</span><span style=3D"co=
lor:#000"><br>tuple</span><span style=3D"color:#660">(</span><span style=3D=
"color:#000">F</span><span style=3D"color:#080">&quot;{name1} {name2}&quot;=
</span><span style=3D"color:#660">);</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#800">//same type as above?</span><span style=3D"co=
lor:#000"><br>translate</span><span style=3D"color:#660">(</span><span styl=
e=3D"color:#000">F</span><span style=3D"color:#080">&quot;With {part} to {c=
hange}? Can I {change}{order} in any way?&quot;</span><span style=3D"color:=
#660">,</span><span style=3D"color:#000"> </span><span style=3D"color:#080"=
>&quot;fr&quot;</span><span style=3D"color:#660">);</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#800">//BTW &quot;fr&quot; is part o=
f interpolated string from perspective of this function</span><span style=
=3D"color:#000"><br></span></div></code></div>In my case all this things ca=
n be enclosed in UDL and will not leak outside.<br><br>Another problem is t=
hat even if your version is more flexible you still repeat in multiple of p=
lace usage of specialization point functions otherwise you cant use interpo=
lation without it, in my version you only would need use them in UDL.<br><b=
r>Probably without lot of limitation, many quirks will prevent any serous m=
etaprograming. I&#39;m inclined to thinking that whole idea will not go far=
..<br><br>btw<br><div style=3D"background-color:rgb(250,250,250);border-colo=
r:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><span st=
yle=3D"color:#000">f</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">F</span><span style=3D"color:#080">&quot;T{{a}}&quot;</span=
><span style=3D"color:#660">);</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#800">//is `f(&quot;T{{a}}&quot;)` or `f(&quot;T&quot;, {=
a})`?</span><span style=3D"color:#000"><br></span></div></code></div>Where =
both version could compile. Probably safer would be follow JS version where=
 we it use `${` to start interpolation.<br><br></div></div></blockquote><di=
v><br></div><div>This could stop Little Bobby Tables:</div><div><br></div><=
div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); bo=
rder-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; wor=
d-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettypri=
nt"><span style=3D"color: #000;" class=3D"styled-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">F</span><span style=3D"color: #=
080;" class=3D"styled-by-prettify">&quot;{a}{b}&quot;</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br></span></div></code></div><div><br><=
/div><div>could translate to</div><div><br></div><div class=3D"prettyprint"=
 style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187,=
 187); border-style: solid; border-width: 1px; word-wrap: break-word;"><cod=
e class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color:=
 #000;" class=3D"styled-by-prettify">f</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">(</span><span style=3D"color: #080;" class=3D"s=
tyled-by-prettify">&quot;&quot;</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> a</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: #080;" class=3D"styled-by-prettify">&quot;&quot;</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> b</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: #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"><br></span></div></code></div><div><br><br></div><d=
iv>arguments 0, ..., 2n are always literals and 1, ..., 2n-1 are always exp=
ressions.</div><div><br></div><div><div class=3D"prettyprint" style=3D"back=
ground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-=
style: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"pre=
ttyprint"><div class=3D"subprettyprint"><span style=3D"color: #000;" class=
=3D"styled-by-prettify">f</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">F</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&qu=
ot;T{{a}}&quot;</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">);</span></div></code></div><span style=3D"font-family: monospace; bac=
kground-color: rgb(250, 250, 250); color: rgb(102, 102, 0);"><br></span></d=
iv><div>would be=C2=A0</div><div><br></div><div class=3D"prettyprint" style=
=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187);=
 border-style: solid; border-width: 1px; word-wrap: break-word;"><code clas=
s=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #000;=
" class=3D"styled-by-prettify">f</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #080;" class=3D"style=
d-by-prettify">&quot;&quot;</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">,</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">a</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">},</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #080;" class=3D"styled-by-prettify">&quot;&quot;</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br></span></div></code></div><div><br></di=
v><div><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/c753942d-be11-4cc0-bde1-7f71b6184367%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/c753942d-be11-4cc0-bde1-7f71b6184367=
%40isocpp.org</a>.<br />

------=_Part_12616_1502680122.1518570196678--

------=_Part_12615_215957504.1518570196677--

.


Author: Jake Arkinstall <jake.arkinstall@gmail.com>
Date: Wed, 14 Feb 2018 01:25:49 +0000
Raw View
--94eb2c04f868cc4418056521fdc6
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

I certainly see some benefit of string literals separating parameters for
ease, but at the same time I can imagine that there will be some situations
where meaningless empty strings complicate matters. It has the potential to
be a quirk, rather than a feature. Parsing the parameters in a one by one
manner could be a pain; I guess it would involve splitting the handling
into two functions - one for literals, one for variables, and each
recursively calls the other with the next parameter iff it exists.

The alternative is a monad approach. Wrap the literal values in some
template literal_string<> and the injected variables in some template
injected_variable<T>, or just one of the two (I guess the latter makes more
sense). That could get ugly real quick, but it helps distinguish the two.
At least then one could use template specialisation to handle the
situations differently, without needing to rely on a fixed every-other
structure.



On 14 Feb 2018 01:03, "Todd Fleming" <tbfleming@gmail.com> wrote:

> On Tuesday, February 13, 2018 at 6:55:47 PM UTC-5, Marcin Jaczewski wrote=
:
>>
>>
>>
>> On Tuesday, February 13, 2018 at 10:39:35 PM UTC+1, Nicol Bolas wrote:
>>>
>>> On Tuesday, February 13, 2018 at 12:18:59 PM UTC-5, floria...@gmail.com
>>> wrote:
>>>>
>>>> Le mardi 13 f=C3=A9vrier 2018 17:35:49 UTC+1, Nicol Bolas a =C3=A9crit=
 :
>>>>>
>>>>> Because it would never be called. Basically, what you'd need is this
>>>>> constructor:
>>>>>
>>>>> template<size_t N>
>>>>> string_view(const char s[N]);
>>>>>
>>>>> But you already have this constructor:
>>>>>
>>>>> string_view(const char *s);
>>>>>
>>>>> An array decays into a pointer. And since the pointer constructor is
>>>>> not a template, it is considered a better match than the array versio=
n. And
>>>>> therefore, any ltieral you pass will go through the pointer version r=
ather
>>>>> than the array template.
>>>>>
>>>>> And it should be noted that this has nothing to do with being a
>>>>> literal. If you used a `const char[]` variable, it *still* would
>>>>> prefer the pointer version due to array->pointer conversion. So this =
is not
>>>>> a case of "string literals are broken now".
>>>>>
>>>>
>>>> How can you say that preferring a lossy conversion over a lossless one
>>>> is not broken? (Here, we lose the length information)
>>>>
>>>
>>> Because the "lossy conversion" part being preferred has nothing to do
>>> with them being string literals. The lossy conversion is not the
>>> literal-to-array conversion; it's the array-to-pointer conversion.
>>>
>>> You're complaining about the wrong problem.
>>>
>>> This make it impossible to work with string literal because they simply
>>>> don't exist in the language. This is why I said string literals are br=
oken.
>>>>
>>>>
>>>>> But there's no "fix" for this, since any array->pointer "fix" would b=
e
>>>>> both wildly incompatible with C and break tons and tons of code. So y=
ou can
>>>>> either accept the language and work with what we have, or rail agains=
t it.
>>>>>
>>>>
>>>> Ok it's not possible to fix array decay because of backward
>>>> compatibility, but it is still possible to fix string literals if we m=
ake
>>>> them something that is not an array.
>>>>
>>>
>>> Why would changing the behavior of string literals be any more backward=
s
>>> compatible than changing the behavior of arrays? There's lots of code o=
ut
>>> there that works with C++'s string literal rules. Can you find a way to
>>> change those rules without breaking their code?
>>>
>>> Let me give you a simple case: `decltype("a string literal")` is an
>>> array type. Therefore, any BC change will have to leave it as an array
>>> type. So what rules would you change to fix the problem you want fixed
>>> without changing the result of that `decltype`?
>>>
>>> So I rail against those defects in order to be heard, and maybe, at som=
e
>>>> point, they will be fixed.
>>>>
>>>
>>> Yeah, that's not how this works. You can "rail against those defects"
>>> all you like, but unless you're willing to actually work on it (ie: fin=
ding
>>> a solution that doesn't break the world and getting it through the
>>> committee), it will not get fixed. Or you manage to convince someone wh=
o's
>>> actually willing to put in said work to do so.
>>>
>>> If this is not the place to speak out loud about those defects, then
>>>> where should we go?
>>>>
>>>> But don't get me wrong, when I code, I work with what I have, and I
>>>> accept the language as it is.
>>>>
>>>>
>>>>>
>>>>> It's funny how the more I dig in C++, the more bulky it appears to be
>>>>>> just because of these very small annoyances.
>>>>>>
>>>>>>
>>>>>>>
>>>>>>> It's a 3 step process; let's not interfere in that.
>>>>>>>
>>>>>>>
>>>>>>>> We could have exatcly the situation with string interpolation:
>>>>>>>> auto s =3D std::concat(F"{str1}{str2}{str3}");
>>>>>>>> // would be equivalent to
>>>>>>>> auto s =3D F"{str1}{str2}{str3}"s;
>>>>>>>>
>>>>>>>> I don't see why allowing UDL to work like that would decrease
>>>>>>>> usability as we could always use regular functions.
>>>>>>>>
>>>>>>>
>>>>>>> Because you can't do this:
>>>>>>>
>>>>>>> std::concat(F"some string {variable} other string"sv);
>>>>>>>
>>>>>>> Under my system, the UDL employed here allows you to decide how to
>>>>>>> process each of the literal fragments. The UDL applies to the parts=
 of the
>>>>>>> literal that are actually strings. So `concat` would get `string_vi=
ew`s,
>>>>>>> rather than `const char[X]` parameters.
>>>>>>>
>>>>>>> Under your system, the processing of the literal fragments is
>>>>>>> controlled entirely by the system that computes the aggregation.
>>>>>>>
>>>>>>
>>>>>> Let's sum up, string literals are broken today. So we should probabl=
y
>>>>>> try to solve this big issue before trying to see how we can cripple
>>>>>> string_interpolation in order to fit in current-ish C++.
>>>>>>
>>>>>
>>>>> I fail to see why applying a UDL to the literal fragments rather than
>>>>> the interpolation aggregation operation should be considered "crippli=
ng"
>>>>> string interpolation.
>>>>>
>>>>> Whatever breakage you see in literals isn't standing in the way of
>>>>> string interpolation. It's just standing in the way of string interpo=
lation
>>>>> working the way *you* want it to.
>>>>>
>>>>
>>>> Because string interpolation is dealing with string literals,
>>>>
>>>
>>> Why does it have to be? If constexpr strings are in the future, it'd be
>>> really nice if string interpolation were defined in such a way that it
>>> could be used on them. Tying interpolation to literals is not
>>> forward-thinking.
>>>
>>> if those literals are broken (and they are), how can we have a proper
>>>> string interpolation?
>>>>
>>>
>>> Because any "brokenness" of string literals has no effect on our abilit=
y
>>> to use string interpolation. If you want sized strings for those string
>>> fragments, that's what the `sv` suffix is for.
>>>
>>> Literal issues only are a problem for string interpolation because you
>>> believe that the suffix ought to be able to define the aggregation
>>> operation. If you stop believing that, then all of a sudden, your probl=
em
>>> with string literals becomes a non-issue for interpolation.
>>>
>>> It should also be noted that this:
>>>
>>> template<typename T>
>>> void foo(const T& t);
>>>
>>> foo("an array");
>>>
>>> The call to `foo` will deduce `T` to be `char[9]`. So a variadic
>>> template function that takes the results of string interpolation will g=
et
>>> sized array types, not pointers.
>>>
>>> Note that this doesn't invalidate anything I said. The point of doing
>>> `F"blah {variable} blah"sv` is not necessarily because you need them to
>>> keep the size around. Using `string_view` has many other advantages, wi=
th
>>> its member functions, `operator<<` overloads, and the like. So wanting =
to
>>> apply `sv` to each of the fragments is a perfectly reasonable operation=
..
>>>
>>> Also, `string_view` is a lot more convenient to use than an array of
>>> characters.
>>>
>>> You said:
>>>>
>>>>> The point of that discussion was a comment someone made about doing
>>>>> template metaprogramming on string literals. To do that, you need a w=
ay to
>>>>> access each literal as a distinct type, some `string_literal<char, 'c=
',
>>>>> 'h', 'a', 'r'>` type. And only a UDL applied to each fragment can per=
form
>>>>> that kind of synthesis.
>>>>>
>>>>
>>>> UDL is the only way to do it only because string literals are broken.
>>>> If we had proper string literals, it should be possible to do it simpl=
y
>>>> with regular functions.
>>>>
>>>
>>> No, it would not. Even if a string literal had a non-array type with a
>>> stored size, each literal value would still not have its own distinct
>>> *type*. Even if the size is a template argument, two literals can store
>>> different characters while still having the same size. And you cannot d=
o
>>> type-based metaprogramming without having a 1:1 mapping between value a=
nd
>>> type.
>>>
>>> Remember: while UDL's *can* take strings as a sequence of character
>>> template parameters, there's a good reason why they aren't *required*
>>> to do so. We don't want to force that onto everybody, and a non-"broken=
"
>>> string literal system would not force that on people.
>>>
>>> So even with your approach, broken string literals are a problem for
>>>> string interpolation. Just not at the same place.
>>>>
>>>> I'm not sure if my approach is the right one (it's probably not), but
>>>> most of your arguments stand only because string literal are broken
>>>> (otherwise, it would have been simple to do the same with my approach =
too).
>>>>
>>>> My point is: yes your approach makes it easier with current C++, but w=
e
>>>> shouldn't go for something that works quite well with current C++, but
>>>> something that will work very well with future C++.
>>>> That's why I think it's better to first fix string literals. And then
>>>> have string interpolation right the first time.
>>>>
>>>> And btw, if string literals are fixed, string interpolation could be
>>>> made a library solution only ( with a different but reasonable syntax)=
..
>>>>
>>>
>>> It's impossible to do that. String interpolation, at its core, is about
>>> taking the contents of a string and applying them in some way to the co=
de
>>> *around* that string. A library solution cannot possibly do that.
>>>
>>> Oh sure, a `constexpr` function could do the parsing. But then what? I'=
m
>>> fairly certain that no static reflection proposal provides a mechanism =
to
>>> turn a string into a reference to a local variable. And even if they di=
d,
>>> the location where you're doing that conversion wouldn't have that vari=
able
>>> in scope (since it's in a function call), so it couldn't possibly work.
>>>
>>> PS: I think it would be preferable to stop the discussion here, as it
>>>> becomes more and more off-topic.
>>>>
>>>
>>> But what if we don't agree that string interpolation needs better
>>> literals?
>>>
>>> Your premise is essentially that my suggested syntax is some kind of
>>> compromise, that if literals weren't "broken" the way you feel that the=
y
>>> are, then it would *clearly* be correct to have UDLs applied to
>>> aggregation rather than to the individual fragments.
>>>
>>> I don't agree with that premise. Whether literals are good or broken is
>>> a side issue. Even if we had perfect literals, I would *still* rather
>>> UDLs be focused on individual string literal manipulation rather than
>>> string interpolation aggregation.
>>>
>>
>>
>> After some toughs I come to conclusion that mixing interpolation with UD=
L
>> is limiting thing and this is good thing. Why? Because beside good thing=
s
>> it limit bad things too.
>> I start from high metaprograming starting point where I made all trader
>> offs to make it work, you start from basic usage and use opposite option=
s.
>> As consequence all my example of use of string interpolation become
>> unusable in your approach.
>>
>> We can start with sql, you suggest that version:
>> db.exec(F"some sql stuff {var1} more sql {var2};");
>>
>> I can quote someone: "Have we learned nothing from Little Bobby Tables?"=
,
>> how you want disquisition between `const char*`s parameters?
>> I did not had this problem because I can limit how parameters are pass t=
o
>> UDL and I can relay on it.
>> One way to avoid it is add new literal that will help with that but in
>> some corner cases it could still break.
>>
>> db.exec("select sth"_sql);
>> db.exec(F"select sth when {name}"_sqlp); //as you point outs, "select x"
>> is not sql, we need diffrent postfix.
>> tuple(F"{name1}{name2}"); //this is `tuple<const char*, const char*>` or
>> `tuple<const char*, const char*, const char*, const char*, const char*>`=
?
>> tuple(F"{name1} {name2}"); //same type as above?
>> translate(F"With {part} to {change}? Can I {change}{order} in any way?",
>> "fr"); //BTW "fr" is part of interpolated string from perspective of
>> this function
>> In my case all this things can be enclosed in UDL and will not leak
>> outside.
>>
>> Another problem is that even if your version is more flexible you still
>> repeat in multiple of place usage of specialization point functions
>> otherwise you cant use interpolation without it, in my version you only
>> would need use them in UDL.
>>
>> Probably without lot of limitation, many quirks will prevent any serous
>> metaprograming. I'm inclined to thinking that whole idea will not go far=
..
>>
>> btw
>> f(F"T{{a}}"); //is `f("T{{a}}")` or `f("T", {a})`?
>> Where both version could compile. Probably safer would be follow JS
>> version where we it use `${` to start interpolation.
>>
>>
> This could stop Little Bobby Tables:
>
> f(F"{a}{b}");
>
> could translate to
>
> f("", a, "", b, "");
>
>
> arguments 0, ..., 2n are always literals and 1, ..., 2n-1 are always
> expressions.
>
> f(F"T{{a}}");
>
> would be
>
> f("", {a}, "")
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit https://groups.google.com/a/
> isocpp.org/d/msgid/std-proposals/c753942d-be11-4cc0-
> bde1-7f71b6184367%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/c753942d-be=
11-4cc0-bde1-7f71b6184367%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoot=
er>
> .
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CAC%2B0CCPrAspxkZJXbhJyc9UCXS3FAw3UU0GEvAzURwKG1=
-pvoA%40mail.gmail.com.

--94eb2c04f868cc4418056521fdc6
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"auto">I certainly see some benefit of string literals separatin=
g parameters for ease, but at the same time I can imagine that there will b=
e some situations where meaningless empty strings complicate matters. It ha=
s the potential to be a quirk, rather than a feature. Parsing the parameter=
s in a one by one manner could be a pain; I guess it would involve splittin=
g the handling into two functions - one for literals, one for variables, an=
d each recursively calls the other with the next parameter iff it exists.<d=
iv dir=3D"auto"><br></div><div dir=3D"auto">The alternative is a monad appr=
oach. Wrap the literal values in some template literal_string&lt;&gt; and t=
he injected variables in some template injected_variable&lt;T&gt;, or just =
one of the two (I guess the latter makes more sense). That could get ugly r=
eal quick, but it helps distinguish the two. At least then one could use te=
mplate specialisation to handle the situations differently, without needing=
 to rely on a fixed every-other structure.</div><div dir=3D"auto"><br></div=
><div dir=3D"auto"><br></div></div><div class=3D"gmail_extra"><br><div clas=
s=3D"gmail_quote">On 14 Feb 2018 01:03, &quot;Todd Fleming&quot; &lt;<a hre=
f=3D"mailto:tbfleming@gmail.com">tbfleming@gmail.com</a>&gt; wrote:<br type=
=3D"attribution"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Tuesday=
, February 13, 2018 at 6:55:47 PM UTC-5, Marcin Jaczewski 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"><br><br>On Tuesday, February =
13, 2018 at 10:39:35 PM UTC+1, Nicol Bolas wrote:<blockquote class=3D"gmail=
_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr">On Tuesday, February 13, 2018 at 12:18:59 PM=
 UTC-5, <a>floria...@gmail.com</a> 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">Le mardi 13 f=C3=A9vrier 2018 17:35:49 UTC+1, Nicol =
Bolas a =C3=A9crit=C2=A0:<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>Because it would never be called. Basically, what you&#39;d n=
eed is this constructor:<br><br><div style=3D"background-color:rgb(250,250,=
250);border-color:rgb(187,187,187);border-style:solid;border-width:1px"><co=
de><div><span style=3D"color:#008">template</span><span style=3D"color:#660=
">&lt;</span><span style=3D"color:#000">size_t N</span><span style=3D"color=
:#660">&gt;</span><span style=3D"color:#000"><br>string_view</span><span st=
yle=3D"color:#660">(</span><span style=3D"color:#008">const</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#008">char</span><span style=
=3D"color:#000"> s</span><span style=3D"color:#660">[</span><span style=3D"=
color:#000">N</span><span style=3D"color:#660">]);</span></div></code></div=
><br>But you already have this constructor:<br><br><div style=3D"background=
-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;bo=
rder-width:1px"><code><div><span style=3D"color:#000">string_view</span><sp=
an style=3D"color:#660">(</span><span style=3D"color:#008">const</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#008">char</span><span =
style=3D"color:#000"> </span><span style=3D"color:#660">*</span><span style=
=3D"color:#000">s</span><span style=3D"color:#660">);</span></div></code></=
div><br>An array decays into a pointer. And since the pointer constructor i=
s not a template, it is considered a better match than the array version. A=
nd therefore, any ltieral you pass will go through the pointer version rath=
er than the array template.<br><br>And it should be noted that this has not=
hing to do with being a literal. If you used a `const char[]` variable, it =
<i>still</i> would prefer the pointer version due to array-&gt;pointer conv=
ersion. So this is not a case of &quot;string literals are broken now&quot;=
..<br></div></div></blockquote><div><br></div><div>How can you say that pref=
erring a lossy conversion over a lossless one is not broken? (Here, we lose=
 the length information)<br></div></div></blockquote><div><br>Because the &=
quot;lossy conversion&quot; part being preferred has nothing to do with the=
m being string literals. The lossy conversion is not the literal-to-array c=
onversion; it&#39;s the array-to-pointer conversion.<br><br>You&#39;re comp=
laining about the wrong problem.<br><br></div><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding=
-left:1ex"><div dir=3D"ltr"><div></div><div>This make it impossible to work=
 with string literal because they simply don&#39;t exist in the language. T=
his is why I said string literals are broken.</div><div>=C2=A0</div><blockq=
uote 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>But there&#39;s no &=
quot;fix&quot; for this, since any array-&gt;pointer &quot;fix&quot; would =
be both wildly incompatible with C and break tons and tons of code. So you =
can either accept the language and work with what we have, or rail against =
it.<br></div></div></blockquote><div></div><div><div><br></div>Ok it&#39;s =
not possible to fix array decay because of=20
backward compatibility, but it is still possible to fix string literals=20
if we make them something that is not an array.</div></div></blockquote><di=
v><br>Why would changing the behavior of string literals be any more backwa=
rds compatible than changing the behavior of arrays? There&#39;s lots of co=
de out there that works with C++&#39;s string literal rules. Can you find a=
 way to change those rules without breaking their code?<br><br>Let me give =
you a simple case: `decltype(&quot;a string literal&quot;)` is an array typ=
e. Therefore, any BC change will have to leave it as an array type. So what=
 rules would you change to fix the problem you want fixed without changing =
the result of that `decltype`?<br><br></div><blockquote class=3D"gmail_quot=
e" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"ltr"><div>So I rail against those defects in order to =
be heard, and maybe, at some point, they will be fixed.</div></div></blockq=
uote><div><br>Yeah, that&#39;s not how this works. You can &quot;rail again=
st those defects&quot; all you like, but unless you&#39;re willing to actua=
lly work on it (ie: finding a solution that doesn&#39;t break the world and=
 getting it through the committee), it will not get fixed. Or you manage to=
 convince someone who&#39;s actually willing to put in said work to do so.<=
br><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-lef=
t:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>=
If this is not the place to speak out loud about those defects, then where =
should we go?<br></div><div><br></div><div>But don&#39;t get me wrong, when=
 I code, I work with what I have, and I accept the language as it is.<br></=
div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0;ma=
rgin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"lt=
r"><div><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"ltr">=
<div>It&#39;s funny how the more I dig in C++, the more bulky it appears to=
 be just because of these very small annoyances.<br></div><div>=C2=A0</div>=
<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;borde=
r-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><br>It&#39;s =
a 3 step process; let&#39;s not interfere in that.<br>=C2=A0</div><blockquo=
te class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><div>We could ha=
ve exatcly the situation with string interpolation:</div><div><div style=3D=
"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-sty=
le:solid;border-width:1px"><code><div><span style=3D"color:#008">auto</span=
><span style=3D"color:#000"> s </span><span style=3D"color:#660">=3D</span>=
<span style=3D"color:#000"> std</span><span style=3D"color:#660">::</span><=
span style=3D"color:#000">concat</span><span style=3D"color:#660">(</span><=
span style=3D"color:#000">F</span><span style=3D"color:#080">&quot;{str1}{s=
tr2}{str<wbr>3}&quot;</span><span style=3D"color:#660">);</span><span style=
=3D"color:#000"><br></span><span style=3D"color:#800">// would be equivalen=
t to</span><span style=3D"color:#000"><br></span><span style=3D"color:#008"=
>auto</span><span style=3D"color:#000"> s </span><span style=3D"color:#660"=
>=3D</span><span style=3D"color:#000"> F</span><span style=3D"color:#080">&=
quot;{str1}{str2}{str3}&quot;</span><span style=3D"color:#000">s</span><spa=
n style=3D"color:#660">;</span><span style=3D"color:#000"><br></span></div>=
</code></div><br>I don&#39;t see why allowing UDL to work like that would d=
ecrease usability as we could always use regular functions.<br></div></div>=
</blockquote><div><br>Because you can&#39;t do this:<br><br><div style=3D"b=
ackground-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style=
:solid;border-width:1px"><code><div><span style=3D"color:#000">std</span><s=
pan style=3D"color:#660">::</span><span style=3D"color:#000">concat</span><=
span style=3D"color:#660">(</span><span style=3D"color:#000">F</span><span =
style=3D"color:#080">&quot;some string {variable} other string&quot;</span>=
<span style=3D"color:#000">sv</span><span style=3D"color:#660">);</span></d=
iv></code></div><br>Under my system, the UDL employed here allows you to de=
cide how to process each of the literal fragments. The UDL applies to the p=
arts of the literal that are actually strings. So `concat` would get `strin=
g_view`s, rather than `const char[X]` parameters.<br><br>Under your system,=
 the processing of the literal fragments is controlled entirely by the syst=
em that computes the aggregation.</div></div></blockquote><div><br></div><d=
iv>Let&#39;s sum up, string literals are broken today. So we should probabl=
y try to solve this big issue before trying to see how we can cripple strin=
g_interpolation in order to fit in current-ish C++.<br></div></div></blockq=
uote><div><br>I fail to see why applying a UDL to the literal fragments rat=
her than the interpolation aggregation operation should be considered &quot=
;crippling&quot; string interpolation.<br><br>Whatever breakage you see in =
literals isn&#39;t standing in the way of string interpolation. It&#39;s ju=
st standing in the way of string interpolation working the way <i>you</i> w=
ant it to.<br></div></div></blockquote><div><br></div><div>Because string i=
nterpolation is dealing with string literals,</div></div></blockquote><div>=
<br>Why does it have to be? If constexpr strings are in the future, it&#39;=
d be really nice if string interpolation were defined in such a way that it=
 could be used on them. Tying interpolation to literals is not forward-thin=
king.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;marg=
in-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"=
><div>if those literals are broken (and they are), how can we have a proper=
 string interpolation?</div></div></blockquote><div><br>Because any &quot;b=
rokenness&quot; of string literals has no effect on our ability to use stri=
ng interpolation. If you want sized strings for those string fragments, tha=
t&#39;s what the `sv` suffix is for.<br><br>Literal issues only are a probl=
em for string interpolation because you believe that the suffix ought to be=
 able to define the aggregation operation. If you stop believing that, then=
 all of a sudden, your problem with string literals becomes a non-issue for=
 interpolation.<br><br>It should also be noted that this:<br><br><div style=
=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-=
style:solid;border-width:1px"><code><div><span style=3D"color:#008">templat=
e</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">ty=
pename</span><span style=3D"color:#000"> T</span><span style=3D"color:#660"=
>&gt;</span><span style=3D"color:#000"><br></span><span style=3D"color:#008=
">void</span><span style=3D"color:#000"> foo</span><span style=3D"color:#66=
0">(</span><span style=3D"color:#008">const</span><span style=3D"color:#000=
"> T</span><span style=3D"color:#660">&amp;</span><span style=3D"color:#000=
"> t</span><span style=3D"color:#660">);</span><span style=3D"color:#000"><=
br><br>foo</span><span style=3D"color:#660">(</span><span style=3D"color:#0=
80">&quot;an array&quot;</span><span style=3D"color:#660">);</span><span st=
yle=3D"color:#000"><br></span></div></code></div><br>The call to `foo` will=
 deduce `T` to be `char[9]`. So a variadic template function that takes the=
 results of string interpolation will get sized array types, not pointers.<=
br><br>Note that this doesn&#39;t invalidate anything I said. The point of =
doing `F&quot;blah {variable} blah&quot;sv` is not necessarily because you =
need them to keep the size around. Using `string_view` has many other advan=
tages, with its member functions, `operator&lt;&lt;` overloads, and the lik=
e. So wanting to apply `sv` to each of the fragments is a perfectly reasona=
ble operation.<br><br>Also, `string_view` is a lot more convenient to use t=
han an array of characters.<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><div>You said:</div><blockquote class=3D"=
gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(20=
4,204,204);padding-left:1ex"><div>The point of that discussion was a commen=
t someone made about doing=20
template metaprogramming on string literals. To do that, you need a way=20
to access each literal as a distinct type, some `string_literal&lt;char,
 &#39;c&#39;, &#39;h&#39;, &#39;a&#39;, &#39;r&#39;&gt;` type. And only a U=
DL applied to each fragment=20
can perform that kind of synthesis.</div></blockquote><div><br></div><div>U=
DL is the only way to do it only because string literals are broken. If we =
had proper string literals, it should be possible to do it simply with regu=
lar functions.</div></div></blockquote><div><br>No, it would not. Even if a=
 string literal had a non-array type with a stored size, each literal value=
 would still not have its own distinct <i>type</i>. Even if the size is a t=
emplate argument, two literals can store different characters while still h=
aving the same size. And you cannot do type-based metaprogramming without h=
aving a 1:1 mapping between value and type.<br><br>Remember: while UDL&#39;=
s <i>can</i> take strings as a sequence of character template parameters, t=
here&#39;s a good reason why they aren&#39;t <i>required</i> to do so. We d=
on&#39;t want to force that onto everybody, and a non-&quot;broken&quot; st=
ring literal system would not force that on people.<br><br></div><blockquot=
e 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>So even with your appro=
ach, broken string literals are a problem for string interpolation. Just no=
t at the same place.</div><div><br></div><div>I&#39;m not sure if my approa=
ch is the right one (it&#39;s probably not), but most of your arguments sta=
nd only because string literal are broken (otherwise, it would have been si=
mple to do the same with my approach too).</div><div><br></div><div>My poin=
t is: yes your approach makes it easier with current C++, but we shouldn&#3=
9;t go for something that works quite well with current C++, but something =
that will work very well with future C++.</div><div>That&#39;s why I think =
it&#39;s better to first fix string literals. And then have string interpol=
ation right the first time.<br></div><div><br></div><div>And btw, if string=
 literals are fixed, string interpolation could be made a library solution =
only ( with a different but reasonable syntax).</div></div></blockquote><di=
v><br>It&#39;s impossible to do that. String interpolation, at its core, is=
 about taking the contents of a string and applying them in some way to the=
 code <i>around</i> that string. A library solution cannot possibly do that=
..<br><br>Oh sure, a `constexpr` function could do the parsing. But then wha=
t? I&#39;m fairly certain that no static reflection proposal provides a mec=
hanism to turn a string into a reference to a local variable. And even if t=
hey did, the location where you&#39;re doing that conversion wouldn&#39;t h=
ave that variable in scope (since it&#39;s in a function call), so it could=
n&#39;t possibly work.<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><div>PS: I think it would be preferable to sto=
p the discussion here, as it becomes more and more off-topic.<br></div></di=
v></blockquote><div><br>But what if we don&#39;t agree that string interpol=
ation needs better literals?<br><br>Your premise is essentially that my sug=
gested syntax is some kind of compromise, that if literals weren&#39;t &quo=
t;broken&quot; the way you feel that they are, then it would <i>clearly</i>=
 be correct to have UDLs applied to aggregation rather than to the individu=
al fragments.<br><br>I don&#39;t agree with that premise. Whether literals =
are good or broken is a side issue. Even if we had perfect literals, I woul=
d <i>still</i> rather UDLs be focused on individual string literal manipula=
tion rather than string interpolation aggregation.<br></div></div></blockqu=
ote><div>=C2=A0<br><br>After some toughs I come to conclusion that mixing i=
nterpolation with UDL is limiting thing and this is good thing. Why? Becaus=
e beside good things it limit bad things too.<br>I start from high metaprog=
raming starting point where I made all trader offs to make it work, you sta=
rt from basic usage and use opposite options.<br>As consequence all my exam=
ple of use of string interpolation become unusable in your approach.<br><br=
>We can start with sql, you suggest that version:<br><div style=3D"backgrou=
nd-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;=
border-width:1px"><code><div><span style=3D"color:#000">db</span><span styl=
e=3D"color:#660">.</span><span style=3D"color:#008">exec</span><span style=
=3D"color:#660">(</span><span style=3D"color:#000">F</span><span style=3D"c=
olor:#080">&quot;some sql stuff {var1} more sql {var2};&quot;</span><span s=
tyle=3D"color:#660">);</span></div></code></div><br>I can quote someone: &q=
uot;Have we learned nothing from Little Bobby Tables?&quot;, how you want d=
isquisition between `const char*`s parameters?<br>I did not had this proble=
m because I can limit how parameters are pass to UDL and I can relay on it.=
<br>One way to avoid it is add new literal that will help with that but in =
some corner cases it could still break.<br><br><div style=3D"background-col=
or:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border=
-width:1px"><code><div><span style=3D"color:#000">db</span><span style=3D"c=
olor:#660">.</span><span style=3D"color:#008">exec</span><span style=3D"col=
or:#660">(</span><span style=3D"color:#080">&quot;select sth&quot;</span><s=
pan style=3D"color:#000">_sql</span><span style=3D"color:#660">);</span><sp=
an style=3D"color:#000"><br>db</span><span style=3D"color:#660">.</span><sp=
an style=3D"color:#008">exec</span><span style=3D"color:#660">(</span><span=
 style=3D"color:#000">F</span><span style=3D"color:#080">&quot;select sth w=
hen {name}&quot;</span><span style=3D"color:#000">_sqlp</span><span style=
=3D"color:#660">);</span><span style=3D"color:#000"> </span><span style=3D"=
color:#800">//as you point outs, &quot;select x&quot; is not sql, we need d=
iffrent postfix.</span><span style=3D"color:#000"><br>tuple</span><span sty=
le=3D"color:#660">(</span><span style=3D"color:#000">F</span><span style=3D=
"color:#080">&quot;{name1}{name2}&quot;</span><span style=3D"color:#660">);=
</span><span style=3D"color:#000"> </span><span style=3D"color:#800">//this=
 is `tuple&lt;const char*, const char*&gt;` or `tuple&lt;const char*, const=
 char*, const char*, const char*, const char*&gt;`?</span><span style=3D"co=
lor:#000"><br>tuple</span><span style=3D"color:#660">(</span><span style=3D=
"color:#000">F</span><span style=3D"color:#080">&quot;{name1} {name2}&quot;=
</span><span style=3D"color:#660">);</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#800">//same type as above?</span><span style=3D"co=
lor:#000"><br>translate</span><span style=3D"color:#660">(</span><span styl=
e=3D"color:#000">F</span><span style=3D"color:#080">&quot;With {part} to {c=
hange}? Can I {change}{order} in any way?&quot;</span><span style=3D"color:=
#660">,</span><span style=3D"color:#000"> </span><span style=3D"color:#080"=
>&quot;fr&quot;</span><span style=3D"color:#660">);</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#800">//BTW &quot;fr&quot; is part o=
f interpolated string from perspective of this function</span><span style=
=3D"color:#000"><br></span></div></code></div>In my case all this things ca=
n be enclosed in UDL and will not leak outside.<br><br>Another problem is t=
hat even if your version is more flexible you still repeat in multiple of p=
lace usage of specialization point functions otherwise you cant use interpo=
lation without it, in my version you only would need use them in UDL.<br><b=
r>Probably without lot of limitation, many quirks will prevent any serous m=
etaprograming. I&#39;m inclined to thinking that whole idea will not go far=
..<br><br>btw<br><div style=3D"background-color:rgb(250,250,250);border-colo=
r:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><span st=
yle=3D"color:#000">f</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">F</span><span style=3D"color:#080">&quot;T{{a}}&quot;</span=
><span style=3D"color:#660">);</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#800">//is `f(&quot;T{{a}}&quot;)` or `f(&quot;T&quot;, {=
a})`?</span><span style=3D"color:#000"><br></span></div></code></div>Where =
both version could compile. Probably safer would be follow JS version where=
 we it use `${` to start interpolation.<br><br></div></div></blockquote><di=
v><br></div><div>This could stop Little Bobby Tables:</div><div><br></div><=
div class=3D"m_1712141763930148073prettyprint" style=3D"background-color:rg=
b(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-widt=
h:1px;word-wrap:break-word"><code class=3D"m_1712141763930148073prettyprint=
"><div class=3D"m_1712141763930148073subprettyprint"><span style=3D"color:#=
000" class=3D"m_1712141763930148073styled-by-prettify">f</span><span style=
=3D"color:#660" class=3D"m_1712141763930148073styled-by-prettify">(</span><=
span style=3D"color:#000" class=3D"m_1712141763930148073styled-by-prettify"=
>F</span><span style=3D"color:#080" class=3D"m_1712141763930148073styled-by=
-prettify">&quot;{a}{b}&quot;</span><span style=3D"color:#660" class=3D"m_1=
712141763930148073styled-by-prettify">);</span><span style=3D"color:#000" c=
lass=3D"m_1712141763930148073styled-by-prettify"><br></span></div></code></=
div><div><br></div><div>could translate to</div><div><br></div><div class=
=3D"m_1712141763930148073prettyprint" style=3D"background-color:rgb(250,250=
,250);border-color:rgb(187,187,187);border-style:solid;border-width:1px;wor=
d-wrap:break-word"><code class=3D"m_1712141763930148073prettyprint"><div cl=
ass=3D"m_1712141763930148073subprettyprint"><span style=3D"color:#000" clas=
s=3D"m_1712141763930148073styled-by-prettify">f</span><span style=3D"color:=
#660" class=3D"m_1712141763930148073styled-by-prettify">(</span><span style=
=3D"color:#080" class=3D"m_1712141763930148073styled-by-prettify">&quot;&qu=
ot;</span><span style=3D"color:#660" class=3D"m_1712141763930148073styled-b=
y-prettify">,</span><span style=3D"color:#000" class=3D"m_17121417639301480=
73styled-by-prettify"> a</span><span style=3D"color:#660" class=3D"m_171214=
1763930148073styled-by-prettify">,</span><span style=3D"color:#000" class=
=3D"m_1712141763930148073styled-by-prettify"> </span><span style=3D"color:#=
080" class=3D"m_1712141763930148073styled-by-prettify">&quot;&quot;</span><=
span style=3D"color:#660" class=3D"m_1712141763930148073styled-by-prettify"=
>,</span><span style=3D"color:#000" class=3D"m_1712141763930148073styled-by=
-prettify"> b</span><span style=3D"color:#660" class=3D"m_17121417639301480=
73styled-by-prettify">,</span><span style=3D"color:#000" class=3D"m_1712141=
763930148073styled-by-prettify"> </span><span style=3D"color:#080" class=3D=
"m_1712141763930148073styled-by-prettify">&quot;&quot;</span><span style=3D=
"color:#660" class=3D"m_1712141763930148073styled-by-prettify">);</span><sp=
an style=3D"color:#000" class=3D"m_1712141763930148073styled-by-prettify"><=
br></span></div></code></div><div><br><br></div><div>arguments 0, ..., 2n a=
re always literals and 1, ..., 2n-1 are always expressions.</div><div><br><=
/div><div><div class=3D"m_1712141763930148073prettyprint" style=3D"backgrou=
nd-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;=
border-width:1px;word-wrap:break-word"><code class=3D"m_1712141763930148073=
prettyprint"><div class=3D"m_1712141763930148073subprettyprint"><span style=
=3D"color:#000" class=3D"m_1712141763930148073styled-by-prettify">f</span><=
span style=3D"color:#660" class=3D"m_1712141763930148073styled-by-prettify"=
>(</span><span style=3D"color:#000" class=3D"m_1712141763930148073styled-by=
-prettify">F</span><span style=3D"color:#080" class=3D"m_171214176393014807=
3styled-by-prettify">&quot;T{{a}}&quot;</span><span style=3D"color:#660" cl=
ass=3D"m_1712141763930148073styled-by-prettify">);</span></div></code></div=
><span style=3D"font-family:monospace;background-color:rgb(250,250,250);col=
or:rgb(102,102,0)"><br></span></div><div>would be=C2=A0</div><div><br></div=
><div class=3D"m_1712141763930148073prettyprint" style=3D"background-color:=
rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-wi=
dth:1px;word-wrap:break-word"><code class=3D"m_1712141763930148073prettypri=
nt"><div class=3D"m_1712141763930148073subprettyprint"><span style=3D"color=
:#000" class=3D"m_1712141763930148073styled-by-prettify">f</span><span styl=
e=3D"color:#660" class=3D"m_1712141763930148073styled-by-prettify">(</span>=
<span style=3D"color:#080" class=3D"m_1712141763930148073styled-by-prettify=
">&quot;&quot;</span><span style=3D"color:#660" class=3D"m_1712141763930148=
073styled-by-prettify">,</span><span style=3D"color:#000" class=3D"m_171214=
1763930148073styled-by-prettify"> </span><span style=3D"color:#660" class=
=3D"m_1712141763930148073styled-by-prettify">{</span><span style=3D"color:#=
000" class=3D"m_1712141763930148073styled-by-prettify">a</span><span style=
=3D"color:#660" class=3D"m_1712141763930148073styled-by-prettify">},</span>=
<span style=3D"color:#000" class=3D"m_1712141763930148073styled-by-prettify=
"> </span><span style=3D"color:#080" class=3D"m_1712141763930148073styled-b=
y-prettify">&quot;&quot;</span><span style=3D"color:#660" class=3D"m_171214=
1763930148073styled-by-prettify">)</span><span style=3D"color:#000" class=
=3D"m_1712141763930148073styled-by-prettify"><br></span></div></code></div>=
<div><br></div><div><br></div></div>

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/c753942d-be11-4cc0-bde1-7f71b6184367%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/c753=
942d-be11-4cc0-<wbr>bde1-7f71b6184367%40isocpp.org</a><wbr>.<br>
</blockquote></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCPrAspxkZJXbhJyc9UCXS3FAw3UU0=
GEvAzURwKG1-pvoA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCPrAspx=
kZJXbhJyc9UCXS3FAw3UU0GEvAzURwKG1-pvoA%40mail.gmail.com</a>.<br />

--94eb2c04f868cc4418056521fdc6--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 13 Feb 2018 19:58:20 -0800 (PST)
Raw View
------=_Part_12856_233150783.1518580700854
Content-Type: multipart/alternative;
 boundary="----=_Part_12857_2090303732.1518580700855"

------=_Part_12857_2090303732.1518580700855
Content-Type: text/plain; charset="UTF-8"

On Tuesday, February 13, 2018 at 6:55:47 PM UTC-5, Marcin Jaczewski wrote:
>
> After some toughs I come to conclusion that mixing interpolation with UDL
> is limiting thing and this is good thing. Why? Because beside good things
> it limit bad things too.
> I start from high metaprograming starting point where I made all trader
> offs to make it work, you start from basic usage and use opposite options.
> As consequence all my example of use of string interpolation become
> unusable in your approach.
>
> We can start with sql, you suggest that version:
> db.exec(F"some sql stuff {var1} more sql {var2};");
>
> I can quote someone: "Have we learned nothing from Little Bobby Tables?",
> how you want disquisition between `const char*`s parameters?
> I did not had this problem because I can limit how parameters are pass to
> UDL and I can relay on it.
>

Um, no you can't. Your solution from here
<https://groups.google.com/a/isocpp.org/d/msg/std-proposals/5OlZbDwXoTM/InPDto0vBwAJ>
was to call a UDL, with the string fragments and variables being parameters
to that function. UDLs aren't magic; they're ordinary functions, and thus
would be no more capable of distinguishing a string literal than any other
function.

Many uses of string interpolation don't *need* to distinguish between
string fragments and non-fragments. The aggregation operation treats them
all the same; if someone provides a string array, you don't really care if
its a variable or a literal.

If there is a genuine need to distinguish these, we have a couple of
options:

1. Explicitly use a UDL to tag literal fragments: `F"some sql stuff {var1}
more sql {var2};"lit` Those processing functions that need to make this
distinction literals would fail if you don't tag your literals properly.

Note that having a UDL and distinct type specifically for string literals
is not a bad idea. We may not be able to enforce this on everyone, but in
places where they are useful, they're useful.

2. *Implicitly* use a UDL-like construct to tag literal fragments. That is,
if you *don't* use a UDL suffix in string interpolation, the compiler will
force `lit` on you. There would still need to be a suffix to allow users to
create instances of this type themselves from literals.

In both case 1 and case 2, the literal type is a type which can only be
constructed via UDL invocation. In order to ensure this is so, we would
need a language feature that allows you to define a UDL function which *cannot
be called* outside of regular UDL syntax. So no getting function pointers,
no calling it directly, nada.

3. Do what others have suggested and use empty string fragments as buffers
between code, so that every other value is always a string fragment. I
don't much care for this approach, since it requires counting values.

It's also a solution that doesn't allow you to do this:

db.exec(
  F"some sql stuff {var1} more sql {var2};",
  F"more sql stuff {var3};"
);

One of the advantages of doing string interpolation by pack expansion-like
means is that we can do things like the above.

Personally, I prefer option 2. Since string interpolation is a new thing,
it doesn't have to adhere to existing rules.


> One way to avoid it is add new literal that will help with that but in
> some corner cases it could still break.
>
> db.exec("select sth"_sql);
> db.exec(F"select sth when {name}"_sqlp); //as you point outs, "select x"
> is not sql, we need diffrent postfix.
>

A better question is why you needed a suffix in the first case.

An even better question is why you need an SQL-specific suffix in the
second case. After all, you only care whether the strings are literals or
not. All `_sqlp` will do is likely return a `string_view`-like type, just
with an SQL-specific name. Why bother; why not just use a generic one?

So you don't need two UDLs. You need at most 1. And that 1 doesn't need to
be specific to this usage.

tuple(F"{name1}{name2}"); //this is `tuple<const char*, const char*>` or
> `tuple<const char*, const char*, const char*, const char*, const char*>`?
> tuple(F"{name1} {name2}"); //same type as above?
>

That is a matter to be determined, based on how we decide to handle empty
string fragments. Whatever the answer is, it will be the same in all cases.

translate(F"With {part} to {change}? Can I {change}{order} in any way?",
> "fr"); //BTW "fr" is part of interpolated string from perspective of this
> function
> In my case all this things can be enclosed in UDL and will not leak
> outside.
>

I don't see how anything is "leaking outside" in these examples.

I don't know how you would be doing translation with string interpolation,
either in your UDL form or in this form. Translation requires something
string interpolation cannot do: move things around. Interpolation is a
compile-time construct; translation is usually runtime.

Another problem is that even if your version is more flexible you still
> repeat in multiple of place usage of specialization point functions
> otherwise you cant use interpolation without it, in my version you only
> would need use them in UDL.
>

I'm sorry, I'm having some difficult understanding what you're trying to
say here.

Probably without lot of limitation, many quirks will prevent any serous
> metaprograming.
>

I see no reason why this would be the case. Your SQL example isn't even
really "metaprogramming".

Give me an example of "serious metaprograming" with string interpolation
that cannot be done "without lot of limitation".

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/aae9229f-40e4-4b98-bcd1-804cf559107d%40isocpp.org.

------=_Part_12857_2090303732.1518580700855
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Tuesday, February 13, 2018 at 6:55:47 PM UTC-5, Marcin =
Jaczewski 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"><div>After some toughs I come to conclusion that mixing interpolation wi=
th UDL is limiting thing and this is good thing. Why? Because beside good t=
hings it limit bad things too.<br>I start from high metaprograming starting=
 point where I made all trader offs to make it work, you start from basic u=
sage and use opposite options.<br>As consequence all my example of use of s=
tring interpolation become unusable in your approach.<br><br>We can start w=
ith sql, you suggest that version:<br><div style=3D"background-color:rgb(25=
0,250,250);border-color:rgb(187,187,187);border-style:solid;border-width:1p=
x"><code><div><span style=3D"color:#000">db</span><span style=3D"color:#660=
">.</span><span style=3D"color:#008">exec</span><span style=3D"color:#660">=
(</span><span style=3D"color:#000">F</span><span style=3D"color:#080">&quot=
;some sql stuff {var1} more sql {var2};&quot;</span><span style=3D"color:#6=
60">);</span></div></code></div><br>I can quote someone: &quot;Have we lear=
ned nothing from Little Bobby Tables?&quot;, how you want disquisition betw=
een `const char*`s parameters?<br>I did not had this problem because I can =
limit how parameters are pass to UDL and I can relay on it.<br></div></div>=
</blockquote><div><br>Um, no you can&#39;t. <a href=3D"https://groups.googl=
e.com/a/isocpp.org/d/msg/std-proposals/5OlZbDwXoTM/InPDto0vBwAJ">Your solut=
ion from here</a> was to call a UDL, with the string fragments and variable=
s being parameters to that function. UDLs aren&#39;t magic; they&#39;re ord=
inary functions, and thus would be no more capable of distinguishing a stri=
ng literal than any other function.<br><br>Many uses of string interpolatio=
n don&#39;t <i>need</i> to distinguish between string fragments and non-fra=
gments. The aggregation operation treats them all the same; if someone prov=
ides a string array, you don&#39;t really care if its a variable or a liter=
al.<br><br>If there is a genuine need to distinguish these, we have a coupl=
e of options:<br><br>1. Explicitly use a UDL to tag literal fragments: `F&q=
uot;some sql stuff {var1} more sql {var2};&quot;lit` Those processing funct=
ions that need to make this distinction literals would fail if you don&#39;=
t tag your literals properly.<br><br>Note that having a UDL and distinct ty=
pe specifically for string literals is not a bad idea. We may not be able t=
o enforce this on everyone, but in places where they are useful, they&#39;r=
e useful.<br><br>2. <i>Implicitly</i> use a UDL-like construct to tag liter=
al fragments. That is, if you <i>don&#39;t</i> use a UDL suffix in string i=
nterpolation, the compiler will force `lit` on you. There would still need =
to be a suffix to allow users to create instances of this type themselves f=
rom literals.<br><br>In both case 1 and case 2, the literal type is a type =
which can only be constructed via UDL invocation. In order to ensure this i=
s so, we would need a language feature that allows you to define a UDL func=
tion which <i>cannot be called</i> outside of regular UDL syntax. So no get=
ting function pointers, no calling it directly, nada.<br><br>3. Do what oth=
ers have suggested and use empty string fragments as buffers between code, =
so that every other value is always a string fragment. I don&#39;t much car=
e for this approach, since it requires counting values.<br><br>It&#39;s als=
o a solution that doesn&#39;t allow you to do this:<br><br><div style=3D"ba=
ckground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); borde=
r-style: solid; border-width: 1px; overflow-wrap: break-word;" class=3D"pre=
ttyprint"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">db</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">.</span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">exec</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br>=C2=A0 F</span><span style=3D"color: #080;" class=3D=
"styled-by-prettify">&quot;some sql stuff {var1} more sql {var2};&quot;</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 F</span><spa=
n style=3D"color: #080;" class=3D"styled-by-prettify">&quot;more sql stuff =
{var3};&quot;</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></div></code></div><br>One of the advantages of doing string interpol=
ation by pack expansion-like means is that we can do things like the above.=
<br><br>Personally, I prefer option 2. Since string interpolation is a new =
thing, it doesn&#39;t have to adhere to existing rules.<br>=C2=A0</div><blo=
ckquote 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>One way to a=
void it is add new literal that will help with that but in some corner case=
s it could still break.<br><br><div style=3D"background-color:rgb(250,250,2=
50);border-color:rgb(187,187,187);border-style:solid;border-width:1px"><cod=
e><div><span style=3D"color:#000">db</span><span style=3D"color:#660">.</sp=
an><span style=3D"color:#008">exec</span><span style=3D"color:#660">(</span=
><span style=3D"color:#080">&quot;select sth&quot;</span><span style=3D"col=
or:#000">_sql</span><span style=3D"color:#660">);</span><span style=3D"colo=
r:#000"><br>db</span><span style=3D"color:#660">.</span><span style=3D"colo=
r:#008">exec</span><span style=3D"color:#660">(</span><span style=3D"color:=
#000">F</span><span style=3D"color:#080">&quot;select sth when {name}&quot;=
</span><span style=3D"color:#000">_sqlp</span><span style=3D"color:#660">);=
</span><span style=3D"color:#000"> </span><span style=3D"color:#800">//as y=
ou point outs, &quot;select x&quot; is not sql, we need diffrent postfix.</=
span><span style=3D"color:#000"><br></span></div></code></div></div></div><=
/blockquote><div><br>A better question is why you needed a suffix in the fi=
rst case.<br><br>An even better question is why you need an SQL-specific su=
ffix in the second case. After all, you only care whether the strings are l=
iterals or not. All `_sqlp` will do is likely return a `string_view`-like t=
ype, just with an SQL-specific name. Why bother; why not just use a generic=
 one?<br><br>So you don&#39;t need two UDLs. You need at most 1. And that 1=
 doesn&#39;t need to be specific to this usage.<br><br></div><blockquote cl=
ass=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 style=3D"backgrou=
nd-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;=
border-width:1px"><code><div><span style=3D"color:#000">tuple</span><span s=
tyle=3D"color:#660">(</span><span style=3D"color:#000">F</span><span style=
=3D"color:#080">&quot;{name1}{name2}&quot;</span><span style=3D"color:#660"=
>);</span><span style=3D"color:#000"> </span><span style=3D"color:#800">//t=
his is `tuple&lt;const char*, const char*&gt;` or `tuple&lt;const char*, co=
nst char*, const char*, const char*, const char*&gt;`?</span><span style=3D=
"color:#000"><br>tuple</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">F</span><span style=3D"color:#080">&quot;{name1} {name2}&qu=
ot;</span><span style=3D"color:#660">);</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#800">//same type as above?</span><span style=3D=
"color:#000"><br></span></div></code></div></div></div></blockquote><div><b=
r>That is a matter to be determined, based on how we decide to handle empty=
 string fragments. Whatever the answer is, it will be the same in all cases=
..<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 style=3D"background-color:rgb(250,250,250);border-color:rgb(187=
,187,187);border-style:solid;border-width:1px"><code><div><span style=3D"co=
lor:#000">translate</span><span style=3D"color:#660">(</span><span style=3D=
"color:#000">F</span><span style=3D"color:#080">&quot;With {part} to {chang=
e}? Can I {change}{order} in any way?&quot;</span><span style=3D"color:#660=
">,</span><span style=3D"color:#000"> </span><span style=3D"color:#080">&qu=
ot;fr&quot;</span><span style=3D"color:#660">);</span><span style=3D"color:=
#000"> </span><span style=3D"color:#800">//BTW &quot;fr&quot; is part of in=
terpolated string from perspective of this function</span><span style=3D"co=
lor:#000"><br></span></div></code></div>In my case all this things can be e=
nclosed in UDL and will not leak outside.<br></div></div></blockquote><div>=
<br>I don&#39;t see how anything is &quot;leaking outside&quot; in these ex=
amples.<br><br>I don&#39;t know how you would be doing translation with str=
ing interpolation, either in your UDL form or in this form. Translation req=
uires something string interpolation cannot do: move things around. Interpo=
lation is a compile-time construct; translation is usually runtime.<br><br>=
</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>An=
other problem is that even if your version is more flexible you still repea=
t in multiple of place usage of specialization point functions otherwise yo=
u cant use interpolation without it, in my version you only would need use =
them in UDL.<br></div></div></blockquote><div><br>I&#39;m sorry, I&#39;m ha=
ving some difficult understanding what you&#39;re trying to say here.<br><b=
r></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>=
Probably without lot of limitation, many quirks will prevent any serous met=
aprograming.</div></div></blockquote><div><br>I see no reason why this woul=
d be the case. Your SQL example isn&#39;t even really &quot;metaprogramming=
&quot;.<br><br>Give me an example of &quot;serious metaprograming&quot; wit=
h string interpolation that cannot be done &quot;without lot of limitation&=
quot;.<br></div><br></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/aae9229f-40e4-4b98-bcd1-804cf559107d%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/aae9229f-40e4-4b98-bcd1-804cf559107d=
%40isocpp.org</a>.<br />

------=_Part_12857_2090303732.1518580700855--

------=_Part_12856_233150783.1518580700854--

.


Author: olafvdspek@gmail.com
Date: Thu, 15 Feb 2018 01:55:10 -0800 (PST)
Raw View
------=_Part_691_101198034.1518688510260
Content-Type: multipart/alternative;
 boundary="----=_Part_692_59665894.1518688510260"

------=_Part_692_59665894.1518688510260
Content-Type: text/plain; charset="UTF-8"

Op vrijdag 9 februari 2018 23:12:26 UTC+1 schreef Marcin Jaczewski:
>
> More I think about this more it look as great addition to language:
> std::string a;
> int b = 0;
> int c = 42;
> db.run(F"select name as {a}, age as {b} from table where id = {c}"_sql);
>
>
The query could return 0, 1 or more rows. How'd that work for 0 or 2+ rows?
I find mixing expressions (or does it only work with variables) and string
literals to not work well most of the time.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/758ab0a7-8946-43d4-b2ae-5a4acea11c20%40isocpp.org.

------=_Part_692_59665894.1518688510260
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Op vrijdag 9 februari 2018 23:12:26 UTC+1 schreef Marcin J=
aczewski:<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=
>More I think about this more it look as great addition to language:<br><di=
v style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);=
border-style:solid;border-width:1px"><code><div><span style=3D"color:#000">=
std</span><span style=3D"color:#660">::</span><span style=3D"color:#008">st=
ring</span><span style=3D"color:#000"> a</span><span style=3D"color:#660">;=
</span><span style=3D"color:#000"><br></span><span style=3D"color:#008">int=
</span><span style=3D"color:#000"> b </span><span style=3D"color:#660">=3D<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#066">0</span=
><span style=3D"color:#660">;</span><span style=3D"color:#000"><br></span><=
span style=3D"color:#008">int</span><span style=3D"color:#000"> c </span><s=
pan style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#066">42</span><span style=3D"color:#660">;</span><span sty=
le=3D"color:#000"><br>db</span><span style=3D"color:#660">.</span><span sty=
le=3D"color:#000">run</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">F</span><span style=3D"color:#080">&quot;select name as {a}=
, age as {b} from table where id =3D {c}&quot;</span><span style=3D"color:#=
000">_sql</span><span style=3D"color:#660">);</span><span style=3D"color:#0=
00"><br><br></span></div></code></div></div></div></blockquote><div><br></d=
iv><div>The query could return 0, 1 or more rows. How&#39;d that work for 0=
 or 2+ rows?</div><div>I find mixing expressions (or does it only work with=
 variables) and string literals to not work well most of the time.=C2=A0</d=
iv></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/758ab0a7-8946-43d4-b2ae-5a4acea11c20%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/758ab0a7-8946-43d4-b2ae-5a4acea11c20=
%40isocpp.org</a>.<br />

------=_Part_692_59665894.1518688510260--

------=_Part_691_101198034.1518688510260--

.


Author: olafvdspek@gmail.com
Date: Thu, 15 Feb 2018 01:58:13 -0800 (PST)
Raw View
------=_Part_673_416702625.1518688694035
Content-Type: multipart/alternative;
 boundary="----=_Part_674_1111917002.1518688694035"

------=_Part_674_1111917002.1518688694035
Content-Type: text/plain; charset="UTF-8"



Op woensdag 14 februari 2018 02:03:16 UTC+1 schreef Todd Fleming:
>
> This could stop Little Bobby Tables:
>

Wasn't that solved already by db.query("select * from users where name =
?", <expression>)  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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/07cdf36e-01d1-4840-95a8-5f1193884dcf%40isocpp.org.

------=_Part_674_1111917002.1518688694035
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Op woensdag 14 februari 2018 02:03:16 UTC+1 schree=
f Todd Fleming:<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>This could stop Little Bobby Tables:</div></div></blockquote><div><b=
r></div><div>Wasn&#39;t that solved already by db.query(&quot;select * from=
 users where name =3D ?&quot;, &lt;expression&gt;)=C2=A0 syntax?</div></div=
>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/07cdf36e-01d1-4840-95a8-5f1193884dcf%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/07cdf36e-01d1-4840-95a8-5f1193884dcf=
%40isocpp.org</a>.<br />

------=_Part_674_1111917002.1518688694035--

------=_Part_673_416702625.1518688694035--

.


Author: Jake Arkinstall <jake.arkinstall@gmail.com>
Date: Thu, 15 Feb 2018 11:33:14 +0000
Raw View
--94eb2c1c00deee760c05653e97d3
Content-Type: text/plain; charset="UTF-8"

If there exists a table where a field named "ID" is not unique, someone
please fire the person who made it.

On 15 Feb 2018 09:55, <olafvdspek@gmail.com> wrote:

> Op vrijdag 9 februari 2018 23:12:26 UTC+1 schreef Marcin Jaczewski:
>>
>> More I think about this more it look as great addition to language:
>> std::string a;
>> int b = 0;
>> int c = 42;
>> db.run(F"select name as {a}, age as {b} from table where id = {c}"_sql);
>>
>>
> The query could return 0, 1 or more rows. How'd that work for 0 or 2+ rows?
> I find mixing expressions (or does it only work with variables) and string
> literals to not work well most of the time.
>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit https://groups.google.com/a/
> isocpp.org/d/msgid/std-proposals/758ab0a7-8946-43d4-
> b2ae-5a4acea11c20%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/758ab0a7-8946-43d4-b2ae-5a4acea11c20%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCOovuF%2BHGepUDQVjkSJoCbGHBNcemaUU9h_gBUPD9ns%2Bw%40mail.gmail.com.

--94eb2c1c00deee760c05653e97d3
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"auto">If there exists a table where a field named &quot;ID&quot=
; is not unique, someone please fire the person who made it.</div><div clas=
s=3D"gmail_extra"><br><div class=3D"gmail_quote">On 15 Feb 2018 09:55,  &lt=
;<a href=3D"mailto:olafvdspek@gmail.com">olafvdspek@gmail.com</a>&gt; wrote=
:<br type=3D"attribution"><blockquote class=3D"gmail_quote" style=3D"margin=
:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">O=
p vrijdag 9 februari 2018 23:12:26 UTC+1 schreef Marcin Jaczewski:<blockquo=
te class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>More I think about thi=
s more it look as great addition to language:<br><div style=3D"background-c=
olor:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;bord=
er-width:1px"><code><div><span style=3D"color:#000">std</span><span style=
=3D"color:#660">::</span><span style=3D"color:#008">string</span><span styl=
e=3D"color:#000"> a</span><span style=3D"color:#660">;</span><span style=3D=
"color:#000"><br></span><span style=3D"color:#008">int</span><span style=3D=
"color:#000"> b </span><span style=3D"color:#660">=3D</span><span style=3D"=
color:#000"> </span><span style=3D"color:#066">0</span><span style=3D"color=
:#660">;</span><span style=3D"color:#000"><br></span><span style=3D"color:#=
008">int</span><span style=3D"color:#000"> c </span><span style=3D"color:#6=
60">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#066"=
>42</span><span style=3D"color:#660">;</span><span style=3D"color:#000"><br=
>db</span><span style=3D"color:#660">.</span><span style=3D"color:#000">run=
</span><span style=3D"color:#660">(</span><span style=3D"color:#000">F</spa=
n><span style=3D"color:#080">&quot;select name as {a}, age as {b} from tabl=
e where id =3D {c}&quot;</span><span style=3D"color:#000">_sql</span><span =
style=3D"color:#660">);</span><span style=3D"color:#000"><br><br></span></d=
iv></code></div></div></div></blockquote><div><br></div><div>The query coul=
d return 0, 1 or more rows. How&#39;d that work for 0 or 2+ rows?</div><div=
>I find mixing expressions (or does it only work with variables) and string=
 literals to not work well most of the time.=C2=A0</div></div>

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&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" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/758ab0a7-8946-43d4-b2ae-5a4acea11c20%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/758a=
b0a7-8946-43d4-<wbr>b2ae-5a4acea11c20%40isocpp.org</a><wbr>.<br>
</blockquote></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCOovuF%2BHGepUDQVjkSJoCbGHBNc=
emaUU9h_gBUPD9ns%2Bw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCOo=
vuF%2BHGepUDQVjkSJoCbGHBNcemaUU9h_gBUPD9ns%2Bw%40mail.gmail.com</a>.<br />

--94eb2c1c00deee760c05653e97d3--

.


Author: j c <james.a.cooper@gmail.com>
Date: Thu, 15 Feb 2018 13:13:07 +0000
Raw View
--f403043dcd08276bc705653ffd7f
Content-Type: text/plain; charset="UTF-8"

Will the compiler be expected to be able to convert scoped enums to strings
by itself?
Currently, it cannot even convert them to their underlying type.

This doesn't compile without the 'operator<<' function


#include <iostream>
enum class MyEnum : int
{
    A = 10, B = 15
};

/*
std::ostream& operator<<(std::ostream& os, MyEnum v)
{
    return os << static_cast<std::underlying_type<MyEnum>::type>(v);
}
*/

int main()
{
    std::cout << MyEnum::A << "\n";
    return 0;
}

On Thu, Feb 15, 2018 at 11:33 AM, Jake Arkinstall <jake.arkinstall@gmail.com
> wrote:

> If there exists a table where a field named "ID" is not unique, someone
> please fire the person who made it.
>
> On 15 Feb 2018 09:55, <olafvdspek@gmail.com> wrote:
>
>> Op vrijdag 9 februari 2018 23:12:26 UTC+1 schreef Marcin Jaczewski:
>>>
>>> More I think about this more it look as great addition to language:
>>> std::string a;
>>> int b = 0;
>>> int c = 42;
>>> db.run(F"select name as {a}, age as {b} from table where id = {c}"_sql);
>>>
>>>
>> The query could return 0, 1 or more rows. How'd that work for 0 or 2+
>> rows?
>> I find mixing expressions (or does it only work with variables) and
>> string literals to not work well most of the time.
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to std-proposals+unsubscribe@isocpp.org.
>> To post to this group, send email to std-proposals@isocpp.org.
>> To view this discussion on the web visit https://groups.google.com/a/is
>> ocpp.org/d/msgid/std-proposals/758ab0a7-8946-43d4-b2ae-
>> 5a4acea11c20%40isocpp.org
>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/758ab0a7-8946-43d4-b2ae-5a4acea11c20%40isocpp.org?utm_medium=email&utm_source=footer>
>> .
>>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit https://groups.google.com/a/
> isocpp.org/d/msgid/std-proposals/CAC%2B0CCOovuF%
> 2BHGepUDQVjkSJoCbGHBNcemaUU9h_gBUPD9ns%2Bw%40mail.gmail.com
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCOovuF%2BHGepUDQVjkSJoCbGHBNcemaUU9h_gBUPD9ns%2Bw%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFQaeCBywEdaj1MD0bpyxcjXRkF1jGaCOcpk%3D4vHtSjEbYbcJw%40mail.gmail.com.

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

<div dir=3D"ltr"><div>Will the compiler be expected to be able to convert s=
coped enums to strings by itself?</div><div>Currently, it cannot even conve=
rt them to their underlying type.</div><div><br></div><div>This doesn&#39;t=
 compile without the &#39;operator&lt;&lt;&#39; function</div><div><br></di=
v><div><br></div><div>#include &lt;iostream&gt;</div><div>enum class MyEnum=
 : int<br>{<br>=C2=A0=C2=A0=C2=A0 A =3D 10, B =3D 15<br>};</div><div><br></=
div><div>/*<br>std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, MyE=
num v)<br>{<br>=C2=A0=C2=A0=C2=A0 return os &lt;&lt; static_cast&lt;std::un=
derlying_type&lt;MyEnum&gt;::type&gt;(v);<br>}<br>*/</div><div><br></div><d=
iv>int main()<br>{<br>=C2=A0=C2=A0=C2=A0 std::cout &lt;&lt; MyEnum::A &lt;&=
lt; &quot;\n&quot;;</div><div>=C2=A0=C2=A0=C2=A0 return 0;<br>}</div></div>=
<div class=3D"gmail_extra"><br><div class=3D"gmail_quote">On Thu, Feb 15, 2=
018 at 11:33 AM, Jake Arkinstall <span dir=3D"ltr">&lt;<a href=3D"mailto:ja=
ke.arkinstall@gmail.com" target=3D"_blank">jake.arkinstall@gmail.com</a>&gt=
;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 =
..8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"auto">If ther=
e exists a table where a field named &quot;ID&quot; is not unique, someone =
please fire the person who made it.</div><div><div class=3D"h5"><div class=
=3D"gmail_extra"><br><div class=3D"gmail_quote">On 15 Feb 2018 09:55,  &lt;=
<a href=3D"mailto:olafvdspek@gmail.com" target=3D"_blank">olafvdspek@gmail.=
com</a>&gt; wrote:<br type=3D"attribution"><blockquote class=3D"gmail_quote=
" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><=
div dir=3D"ltr">Op vrijdag 9 februari 2018 23:12:26 UTC+1 schreef Marcin Ja=
czewski:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>More =
I think about this more it look as great addition to language:<br><div styl=
e=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border=
-style:solid;border-width:1px"><code><div><span style=3D"color:#000">std</s=
pan><span style=3D"color:#660">::</span><span style=3D"color:#008">string</=
span><span style=3D"color:#000"> a</span><span style=3D"color:#660">;</span=
><span style=3D"color:#000"><br></span><span style=3D"color:#008">int</span=
><span style=3D"color:#000"> b </span><span style=3D"color:#660">=3D</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#066">0</span><span=
 style=3D"color:#660">;</span><span style=3D"color:#000"><br></span><span s=
tyle=3D"color:#008">int</span><span style=3D"color:#000"> c </span><span st=
yle=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span style=
=3D"color:#066">42</span><span style=3D"color:#660">;</span><span style=3D"=
color:#000"><br>db</span><span style=3D"color:#660">.</span><span style=3D"=
color:#000">run</span><span style=3D"color:#660">(</span><span style=3D"col=
or:#000">F</span><span style=3D"color:#080">&quot;select name as {a}, age a=
s {b} from table where id =3D {c}&quot;</span><span style=3D"color:#000">_s=
ql</span><span style=3D"color:#660">);</span><span style=3D"color:#000"><br=
><br></span></div></code></div></div></div></blockquote><div><br></div><div=
>The query could return 0, 1 or more rows. How&#39;d that work for 0 or 2+ =
rows?</div><div>I find mixing expressions (or does it only work with variab=
les) and string literals to not work well most of the time.=C2=A0</div></di=
v>

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isoc<wbr>pp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/758ab0a7-8946-43d4-b2ae-5a4acea11c20%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/is<wbr>ocpp.org/d/msgid/std-proposals<wbr>/758a=
b0a7-8946-43d4-b2ae-<wbr>5a4acea11c20%40isocpp.org</a>.<br>
</blockquote></div></div>

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></div></div>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCOovuF%2BHGepUDQVjkSJoCbGHBNc=
emaUU9h_gBUPD9ns%2Bw%40mail.gmail.com?utm_medium=3Demail&amp;utm_source=3Df=
ooter" target=3D"_blank">https://groups.google.com/a/<wbr>isocpp.org/d/msgi=
d/std-<wbr>proposals/CAC%2B0CCOovuF%<wbr>2BHGepUDQVjkSJoCbGHBNcemaUU9h_<wbr=
>gBUPD9ns%2Bw%40mail.gmail.com</a>.<br>
</blockquote></div><br></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAFQaeCBywEdaj1MD0bpyxcjXRkF1jGaCOcpk=
%3D4vHtSjEbYbcJw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFQaeCBywEdaj1=
MD0bpyxcjXRkF1jGaCOcpk%3D4vHtSjEbYbcJw%40mail.gmail.com</a>.<br />

--f403043dcd08276bc705653ffd7f--

.


Author: Jake Arkinstall <jake.arkinstall@gmail.com>
Date: Thu, 15 Feb 2018 13:31:14 +0000
Raw View
--001a113cd680f97ecb0565403d37
Content-Type: text/plain; charset="UTF-8"

That depends on the approach laid out by the user. There have been many
possible paths laid out in the conversation, and I must admit I have gotten
quite lost in the tangle. The two main ideas, if I remember correctly, are
compiling an interpolated string into a tuple or a parameter pack (which
can mimic the former by passing that into a tuple constructor). The result
may then be passed to a constexpr method to reduce it to a more familiar
statement.

How that is then reduced to a single type is up to the developer, so if
said operation is not valid then it it will cause an error such as in your
example code.

On 15 Feb 2018 13:13, "j c" <james.a.cooper@gmail.com> wrote:

Will the compiler be expected to be able to convert scoped enums to strings
by itself?
Currently, it cannot even convert them to their underlying type.

This doesn't compile without the 'operator<<' function


#include <iostream>
enum class MyEnum : int
{
    A = 10, B = 15
};

/*
std::ostream& operator<<(std::ostream& os, MyEnum v)
{
    return os << static_cast<std::underlying_type<MyEnum>::type>(v);
}
*/

int main()
{
    std::cout << MyEnum::A << "\n";
    return 0;
}

On Thu, Feb 15, 2018 at 11:33 AM, Jake Arkinstall <jake.arkinstall@gmail.com
> wrote:

> If there exists a table where a field named "ID" is not unique, someone
> please fire the person who made it.
>
> On 15 Feb 2018 09:55, <olafvdspek@gmail.com> wrote:
>
>> Op vrijdag 9 februari 2018 23:12:26 UTC+1 schreef Marcin Jaczewski:
>>>
>>> More I think about this more it look as great addition to language:
>>> std::string a;
>>> int b = 0;
>>> int c = 42;
>>> db.run(F"select name as {a}, age as {b} from table where id = {c}"_sql);
>>>
>>>
>> The query could return 0, 1 or more rows. How'd that work for 0 or 2+
>> rows?
>> I find mixing expressions (or does it only work with variables) and
>> string literals to not work well most of the time.
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to std-proposals+unsubscribe@isocpp.org.
>> To post to this group, send email to std-proposals@isocpp.org.
>> To view this discussion on the web visit https://groups.google.com/a/is
>> ocpp.org/d/msgid/std-proposals/758ab0a7-8946-43d4-b2ae-5a4ac
>> ea11c20%40isocpp.org
>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/758ab0a7-8946-43d4-b2ae-5a4acea11c20%40isocpp.org?utm_medium=email&utm_source=footer>
>> .
>>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit https://groups.google.com/a/is
> ocpp.org/d/msgid/std-proposals/CAC%2B0CCOovuF%2BHGepUDQVjkSJ
> oCbGHBNcemaUU9h_gBUPD9ns%2Bw%40mail.gmail.com
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCOovuF%2BHGepUDQVjkSJoCbGHBNcemaUU9h_gBUPD9ns%2Bw%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>

--
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/
isocpp.org/d/msgid/std-proposals/CAFQaeCBywEdaj1MD0bpyxcjXRkF1j
GaCOcpk%3D4vHtSjEbYbcJw%40mail.gmail.com
<https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFQaeCBywEdaj1MD0bpyxcjXRkF1jGaCOcpk%3D4vHtSjEbYbcJw%40mail.gmail.com?utm_medium=email&utm_source=footer>
..

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCP-X-rxUpwvPGJ96SabfVX71nZEpPWCXL_%3DXpD7W87GhA%40mail.gmail.com.

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

<div dir=3D"auto"><div>That depends on the approach laid out by the user. T=
here have been many possible paths laid out in the conversation, and I must=
 admit I have gotten quite lost in the tangle. The two main ideas, if I rem=
ember correctly, are compiling an interpolated string into a tuple or a par=
ameter pack (which can mimic the former by passing that into a tuple constr=
uctor). The result may then be passed to a constexpr method to reduce it to=
 a more familiar statement.</div><div dir=3D"auto"><br></div><div dir=3D"au=
to">How that is then reduced to a single type is up to the developer, so if=
 said operation is not valid then it it will cause an error such as in your=
 example code.</div><div dir=3D"auto"><div class=3D"gmail_extra" dir=3D"aut=
o"><br><div class=3D"gmail_quote">On 15 Feb 2018 13:13, &quot;j c&quot; &lt=
;<a href=3D"mailto:james.a.cooper@gmail.com">james.a.cooper@gmail.com</a>&g=
t; wrote:<br type=3D"attribution"><blockquote class=3D"quote" style=3D"marg=
in:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"=
><div>Will the compiler be expected to be able to convert scoped enums to s=
trings by itself?</div><div>Currently, it cannot even convert them to their=
 underlying type.</div><div><br></div><div>This doesn&#39;t compile without=
 the &#39;operator&lt;&lt;&#39; function</div><div><br></div><div><br></div=
><div>#include &lt;iostream&gt;</div><div>enum class MyEnum : int<br>{<br>=
=C2=A0=C2=A0=C2=A0 A =3D 10, B =3D 15<br>};</div><div><br></div><div>/*<br>=
std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, MyEnum v)<br>{<br>=
=C2=A0=C2=A0=C2=A0 return os &lt;&lt; static_cast&lt;std::underlying_<wbr>t=
ype&lt;MyEnum&gt;::type&gt;(v);<br>}<br>*/</div><div><br></div><div>int mai=
n()<br>{<br>=C2=A0=C2=A0=C2=A0 std::cout &lt;&lt; MyEnum::A &lt;&lt; &quot;=
\n&quot;;</div><div>=C2=A0=C2=A0=C2=A0 return 0;<br>}</div></div><div class=
=3D"gmail_extra"><br><div class=3D"gmail_quote"><div class=3D"elided-text">=
On Thu, Feb 15, 2018 at 11:33 AM, Jake Arkinstall <span dir=3D"ltr">&lt;<a =
href=3D"mailto:jake.arkinstall@gmail.com" target=3D"_blank">jake.arkinstall=
@gmail.com</a>&gt;</span> wrote:<br></div><blockquote class=3D"gmail_quote"=
 style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv class=3D"elided-text"><div dir=3D"auto">If there exists a table where a =
field named &quot;ID&quot; is not unique, someone please fire the person wh=
o made it.</div><div><div class=3D"m_3694148904896856773h5"><div class=3D"g=
mail_extra"><br><div class=3D"gmail_quote">On 15 Feb 2018 09:55,  &lt;<a hr=
ef=3D"mailto:olafvdspek@gmail.com" target=3D"_blank">olafvdspek@gmail.com</=
a>&gt; wrote:<br type=3D"attribution"><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div d=
ir=3D"ltr">Op vrijdag 9 februari 2018 23:12:26 UTC+1 schreef Marcin Jaczews=
ki:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bo=
rder-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>More I thi=
nk about this more it look as great addition to language:<br><div style=3D"=
background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-styl=
e:solid;border-width:1px"><code><div><span style=3D"color:#000">std</span><=
span style=3D"color:#660">::</span><span style=3D"color:#008">string</span>=
<span style=3D"color:#000"> a</span><span style=3D"color:#660">;</span><spa=
n style=3D"color:#000"><br></span><span style=3D"color:#008">int</span><spa=
n style=3D"color:#000"> b </span><span style=3D"color:#660">=3D</span><span=
 style=3D"color:#000"> </span><span style=3D"color:#066">0</span><span styl=
e=3D"color:#660">;</span><span style=3D"color:#000"><br></span><span style=
=3D"color:#008">int</span><span style=3D"color:#000"> c </span><span style=
=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D=
"color:#066">42</span><span style=3D"color:#660">;</span><span style=3D"col=
or:#000"><br>db</span><span style=3D"color:#660">.</span><span style=3D"col=
or:#000">run</span><span style=3D"color:#660">(</span><span style=3D"color:=
#000">F</span><span style=3D"color:#080">&quot;select name as {a}, age as {=
b} from table where id =3D {c}&quot;</span><span style=3D"color:#000">_sql<=
/span><span style=3D"color:#660">);</span><span style=3D"color:#000"><br><b=
r></span></div></code></div></div></div></blockquote><div><br></div><div>Th=
e query could return 0, 1 or more rows. How&#39;d that work for 0 or 2+ row=
s?</div><div>I find mixing expressions (or does it only work with variables=
) and string literals to not work well most of the time.=C2=A0</div></div>

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&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" target=3D"_=
blank">std-proposals+unsubscribe@isoc<wbr>pp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/758ab0a7-8946-43d4-b2ae-5a4acea11c20%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/is<wbr>ocpp.org/d/msgid/std-proposals<wbr>/758a=
b0a7-8946-43d4-b2ae-5a4ac<wbr>ea11c20%40isocpp.org</a>.<br>
</blockquote></div></div>

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isoc<wbr>pp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></div></div></div>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCOovuF%2BHGepUDQVjkSJoCbGHBNc=
emaUU9h_gBUPD9ns%2Bw%40mail.gmail.com?utm_medium=3Demail&amp;utm_source=3Df=
ooter" target=3D"_blank">https://groups.google.com/a/is<wbr>ocpp.org/d/msgi=
d/std-proposals<wbr>/CAC%2B0CCOovuF%2BHGepUDQVjkSJ<wbr>oCbGHBNcemaUU9h_gBUP=
D9ns%2Bw%<wbr>40mail.gmail.com</a>.<br>
</blockquote></div><br></div><div class=3D"quoted-text">

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></div>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAFQaeCBywEdaj1MD0bpyxcjXRkF1jGaCOcpk=
%3D4vHtSjEbYbcJw%40mail.gmail.com?utm_medium=3Demail&amp;utm_source=3Dfoote=
r" target=3D"_blank">https://groups.google.com/a/<wbr>isocpp.org/d/msgid/st=
d-<wbr>proposals/<wbr>CAFQaeCBywEdaj1MD0bpyxcjXRkF1j<wbr>GaCOcpk%3D4vHtSjEb=
YbcJw%<wbr>40mail.gmail.com</a>.<br>
</blockquote></div><br></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCP-X-rxUpwvPGJ96SabfVX71nZEpP=
WCXL_%3DXpD7W87GhA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCP-X-=
rxUpwvPGJ96SabfVX71nZEpPWCXL_%3DXpD7W87GhA%40mail.gmail.com</a>.<br />

--001a113cd680f97ecb0565403d37--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 15 Feb 2018 07:51:56 -0800 (PST)
Raw View
------=_Part_1242_371729321.1518709916422
Content-Type: multipart/alternative;
 boundary="----=_Part_1243_11240387.1518709916422"

------=_Part_1243_11240387.1518709916422
Content-Type: text/plain; charset="UTF-8"

On Thursday, February 15, 2018 at 8:13:10 AM UTC-5, j c wrote:
>
> Will the compiler be expected to be able to convert scoped enums to
> strings by itself?
>

The original proposal was to have the aggregation process done by ostream.
However, the designs we've been discussing the most abandon this for a more
flexible approach. String interpolation is just the process of taking a
literal (or possibly constexpr string?) and breaking it up into string
fragments and variable references (or possibly arbitrary expressions?),
resulting in a sequence of values not unlike a pack expansion. These values
are then passed to a function, via some means (with lots of discussion
about whether this function could be a UDL or just a regular function).

Under this design, the compiler isn't generating any code for aggregating
the literal fragments and variables. The compiler isn't trying to
concatenate strings or whatever; that's the job of where those parameters
get dumped. So any value-to-string conversions are governed by the function
that gets called.

And therefore, enum-to-string conversion is an entirely orthogonal question.

But even under the stream-based idea, it's still an orthogonal question. If
enums are convertible to strings via streams, then you could use that kind
of string interpolation on them. If they're not, then you can't, just like
you can't for any other type that's not convertible to a string.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/01057924-056c-4ee5-a19c-e070d053b982%40isocpp.org.

------=_Part_1243_11240387.1518709916422
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Thursday, February 15, 2018 at 8:13:10 AM UTC-5, j c wr=
ote:<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>Will=
 the compiler be expected to be able to convert scoped enums to strings by =
itself?</div></div></blockquote><div><br>The original proposal was to have =
the aggregation process done by ostream. However, the designs we&#39;ve bee=
n discussing the most abandon this for a more flexible approach. String int=
erpolation is just the process of taking a literal (or possibly constexpr s=
tring?) and breaking it up into string fragments and variable references (o=
r possibly arbitrary expressions?), resulting in a sequence of values not u=
nlike a pack expansion. These values are then passed to a function, via som=
e means (with lots of discussion about whether this function could be a UDL=
 or just a regular function).<br><br>Under this design, the compiler isn&#3=
9;t generating any code for aggregating the literal fragments and variables=
.. The compiler isn&#39;t trying to concatenate strings or whatever; that&#3=
9;s the job of where those parameters get dumped. So any value-to-string co=
nversions are governed by the function that gets called.<br><br>And therefo=
re, enum-to-string conversion is an entirely orthogonal question.<br><br>Bu=
t even under the stream-based idea, it&#39;s still an orthogonal question. =
If enums are convertible to strings via streams, then you could use that ki=
nd of string interpolation on them. If they&#39;re not, then you can&#39;t,=
 just like you can&#39;t for any other type that&#39;s not convertible to a=
 string.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/01057924-056c-4ee5-a19c-e070d053b982%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/01057924-056c-4ee5-a19c-e070d053b982=
%40isocpp.org</a>.<br />

------=_Part_1243_11240387.1518709916422--

------=_Part_1242_371729321.1518709916422--

.


Author: Jake Arkinstall <jake.arkinstall@gmail.com>
Date: Thu, 15 Feb 2018 16:05:43 +0000
Raw View
--001a1141670ad039460565426766
Content-Type: text/plain; charset="UTF-8"

On 15 Feb 2018 15:51, "Nicol Bolas" <jmckesson@gmail.com> wrote:

Taking a literal (or possibly constexpr string?)


I was wondering whether it makes sense to even describe these things as
literals, given that they aren't literal and given that they aren't
intended to actually be stored in memory in any way. But in terms of
constexpr strings, I guess these things themselves can be built up by other
methods - I'm not sure if this makes sense in compilation, though; I'm
under the impression that the expression itself would likely need to be
processed before the constexpr methods themselves could be evaluated
(especially given that they could themselves utilise interpolation). I
could be wrong.

I think, at this point, interpolation is a bad word - it made sense in the
initial form, but now this has generalised we might want a new word for it.

(or possibly arbitrary expressions?)


This wouldn't be so much of a problem, because those expressions (other
than their declarations) don't need to be completely understood when the
[insert better name for interpolation] is performed - just the resulting
type is needed.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCM0SLuJk3GPA-zqb_X7z-kY_tNF1iLnOocLJwP9eErnLQ%40mail.gmail.com.

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

<div dir=3D"auto"><div><br><div class=3D"gmail_extra"><br><div class=3D"gma=
il_quote">On 15 Feb 2018 15:51, &quot;Nicol Bolas&quot; &lt;<a href=3D"mail=
to:jmckesson@gmail.com">jmckesson@gmail.com</a>&gt; wrote:<br type=3D"attri=
bution"><blockquote class=3D"quote" style=3D"margin:0 0 0 .8ex;border-left:=
1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"quoted-text=
">Taking a literal (or possibly constexpr string?)</div></div></blockquote>=
</div></div></div><div dir=3D"auto"><br></div><div dir=3D"auto">I was wonde=
ring whether it makes sense to even describe these things as literals, give=
n that they aren&#39;t literal and given that they aren&#39;t intended to a=
ctually be stored in memory in any way. But in terms of constexpr strings, =
I guess these things themselves can be built up by other methods - I&#39;m =
not sure if this makes sense in compilation, though; I&#39;m under the impr=
ession that the expression itself would likely need to be processed before =
the constexpr methods themselves could be evaluated (especially given that =
they could themselves utilise interpolation). I could be wrong.</div><div d=
ir=3D"auto"><br></div><div dir=3D"auto">I think, at this point, interpolati=
on is a bad word - it made sense in the initial form, but now this has gene=
ralised we might want a new word for it.</div><div dir=3D"auto"><br></div><=
div dir=3D"auto"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><blo=
ckquote class=3D"quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc sol=
id;padding-left:1ex"><div dir=3D"ltr"><div class=3D"quoted-text">(or possib=
ly arbitrary expressions?)</div></div></blockquote></div></div></div><div d=
ir=3D"auto"><br></div><div dir=3D"auto">This wouldn&#39;t be so much of a p=
roblem, because those expressions (other than their declarations) don&#39;t=
 need to be completely understood when the [insert better name for interpol=
ation] is performed - just the resulting type is needed.</div><div dir=3D"a=
uto"></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCM0SLuJk3GPA-zqb_X7z-kY_tNF1i=
LnOocLJwP9eErnLQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCM0SLuJ=
k3GPA-zqb_X7z-kY_tNF1iLnOocLJwP9eErnLQ%40mail.gmail.com</a>.<br />

--001a1141670ad039460565426766--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 15 Feb 2018 08:19:29 -0800 (PST)
Raw View
------=_Part_1366_242682078.1518711569246
Content-Type: multipart/alternative;
 boundary="----=_Part_1367_2098218891.1518711569246"

------=_Part_1367_2098218891.1518711569246
Content-Type: text/plain; charset="UTF-8"

On Thursday, February 15, 2018 at 11:06:10 AM UTC-5, Jake Arkinstall wrote:
>
> On 15 Feb 2018 15:51, "Nicol Bolas" <jmck...@gmail.com <javascript:>>
> wrote:
>
> Taking a literal (or possibly constexpr string?)
>
>
> I was wondering whether it makes sense to even describe these things as
> literals, given that they aren't literal and given that they aren't
> intended to actually be stored in memory in any way.
>

We still call literals "literals", even if you use them entirely at
compile-time via `constexpr` tricks, such that no runtime code ever needs
them. Things between quotes are literals.

But in terms of constexpr strings, I guess these things themselves can be
> built up by other methods - I'm not sure if this makes sense in
> compilation, though; I'm under the impression that the expression itself
> would likely need to be processed before the constexpr methods themselves
> could be evaluated (especially given that they could themselves utilise
> interpolation). I could be wrong.
>
> I think, at this point, interpolation is a bad word - it made sense in the
> initial form, but now this has generalised we might want a new word for it.
>

I don't agree. "String interpolation" often carries the connotation that
you're just going to concatenate strings, but it doesn't *have* to. C++
sometimes defines concepts with names that are similar to other language
features, but in a more open and freeform way. Lambdas for example don't
have lexical scoping in C++ unless you explicitly ask for them, whereas
most languages give it to you as a matter of course.

(or possibly arbitrary expressions?)
>
>
> This wouldn't be so much of a problem, because those expressions (other
> than their declarations) don't need to be completely understood when the
> [insert better name for interpolation] is performed - just the resulting
> type is needed.
>

The issue with "arbitrary expression" is that you're now requiring the
compiler to *invoke the compiler*. It's easy for the compiler to take a
compile-time string and find a variable in scope that matches it. It's much
harder (presumably) for the compiler to take a compile-time string and
invoke the compiler on it, within the current scope as if it had been
written text.

I'm not saying its impossible; I don't know much about compiler
architecture. But I can't imagine it's as easy as just finding a variable
with that name.

Not only that, once you get into wanting `constexpr` strings that can be
interpolated, you get into lots of issues. Do you really want a feature
where you're able to synthesize arbitrary expressions and have someone
insinuate them into their code at compile time?

Or... maybe you do?

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/c74fcb96-ed06-4360-bedf-e902b000b13b%40isocpp.org.

------=_Part_1367_2098218891.1518711569246
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Thursday, February 15, 2018 at 11:06:10 AM UTC-5, Jake =
Arkinstall wrote:<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"a=
uto"><div><div><div class=3D"gmail_quote">On 15 Feb 2018 15:51, &quot;Nicol=
 Bolas&quot; &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-m=
ailto=3D"gqheqMTfCgAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;jav=
ascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;re=
turn true;">jmck...@gmail.com</a>&gt; wrote:<br type=3D"attribution"><block=
quote style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1e=
x"><div dir=3D"ltr"><div>Taking a literal (or possibly constexpr string?)</=
div></div></blockquote></div></div></div><div dir=3D"auto"><br></div><div d=
ir=3D"auto">I was wondering whether it makes sense to even describe these t=
hings as literals, given that they aren&#39;t literal and given that they a=
ren&#39;t intended to actually be stored in memory in any way.</div></div><=
/blockquote><div><br>We still call literals &quot;literals&quot;, even if y=
ou use them entirely at compile-time via `constexpr` tricks, such that no r=
untime code ever needs them. Things between quotes are literals.<br><br></d=
iv><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;=
border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"auto"><div dir=
=3D"auto">But in terms of constexpr strings, I guess these things themselve=
s can be built up by other methods - I&#39;m not sure if this makes sense i=
n compilation, though; I&#39;m under the impression that the expression its=
elf would likely need to be processed before the constexpr methods themselv=
es could be evaluated (especially given that they could themselves utilise =
interpolation). I could be wrong.</div><div dir=3D"auto"><br></div><div dir=
=3D"auto">I think, at this point, interpolation is a bad word - it made sen=
se in the initial form, but now this has generalised we might want a new wo=
rd for it.</div></div></blockquote><div><br>I don&#39;t agree. &quot;String=
 interpolation&quot; often carries the connotation that you&#39;re just goi=
ng to concatenate strings, but it doesn&#39;t <i>have</i> to. C++ sometimes=
 defines concepts with names that are similar to other language features, b=
ut in a more open and freeform way. Lambdas for example don&#39;t have lexi=
cal scoping in C++ unless you explicitly ask for them, whereas most languag=
es give it to you as a matter of course.<br><br></div><blockquote class=3D"=
gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc so=
lid;padding-left: 1ex;"><div dir=3D"auto"><div dir=3D"auto"></div><div dir=
=3D"auto"><div><div class=3D"gmail_quote"><blockquote style=3D"margin:0 0 0=
 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>(o=
r possibly arbitrary expressions?)</div></div></blockquote></div></div></di=
v><div dir=3D"auto"><br></div><div dir=3D"auto">This wouldn&#39;t be so muc=
h of a problem, because those expressions (other than their declarations) d=
on&#39;t need to be completely understood when the [insert better name for =
interpolation] is performed - just the resulting type is needed.</div></div=
></blockquote><div><br>The issue with &quot;arbitrary expression&quot; is t=
hat you&#39;re now requiring the compiler to <i>invoke the compiler</i>. It=
&#39;s easy for the compiler to take a compile-time string and find a varia=
ble in scope that matches it. It&#39;s much harder (presumably) for the com=
piler to take a compile-time string and invoke the compiler on it, within t=
he current scope as if it had been written text.<br><br>I&#39;m not saying =
its impossible; I don&#39;t know much about compiler architecture. But I ca=
n&#39;t imagine it&#39;s as easy as just finding a variable with that name.=
<br><br>Not only that, once you get into wanting `constexpr` strings that c=
an be interpolated, you get into lots of issues. Do you really want a featu=
re where you&#39;re able to synthesize arbitrary expressions and have someo=
ne insinuate them into their code at compile time?<br><br>Or... maybe you d=
o?<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/c74fcb96-ed06-4360-bedf-e902b000b13b%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/c74fcb96-ed06-4360-bedf-e902b000b13b=
%40isocpp.org</a>.<br />

------=_Part_1367_2098218891.1518711569246--

------=_Part_1366_242682078.1518711569246--

.


Author: florian.csdt@gmail.com
Date: Thu, 15 Feb 2018 08:33:26 -0800 (PST)
Raw View
------=_Part_1371_343370368.1518712406607
Content-Type: multipart/alternative;
 boundary="----=_Part_1372_1055808211.1518712406608"

------=_Part_1372_1055808211.1518712406608
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



Le jeudi 15 f=C3=A9vrier 2018 17:19:29 UTC+1, Nicol Bolas a =C3=A9crit :
>
> On Thursday, February 15, 2018 at 11:06:10 AM UTC-5, Jake Arkinstall wrot=
e:
>>
>> On 15 Feb 2018 15:51, "Nicol Bolas" <jmck...@gmail.com> wrote:
>>
>> Taking a literal (or possibly constexpr string?)
>>
>>
>> I was wondering whether it makes sense to even describe these things as=
=20
>> literals, given that they aren't literal and given that they aren't=20
>> intended to actually be stored in memory in any way.
>>
>
> We still call literals "literals", even if you use them entirely at=20
> compile-time via `constexpr` tricks, such that no runtime code ever needs=
=20
> them. Things between quotes are literals.
>
> But in terms of constexpr strings, I guess these things themselves can be=
=20
>> built up by other methods - I'm not sure if this makes sense in=20
>> compilation, though; I'm under the impression that the expression itself=
=20
>> would likely need to be processed before the constexpr methods themselve=
s=20
>> could be evaluated (especially given that they could themselves utilise=
=20
>> interpolation). I could be wrong.
>>
>> I think, at this point, interpolation is a bad word - it made sense in=
=20
>> the initial form, but now this has generalised we might want a new word =
for=20
>> it.
>>
>
> I don't agree. "String interpolation" often carries the connotation that=
=20
> you're just going to concatenate strings, but it doesn't *have* to. C++=
=20
> sometimes defines concepts with names that are similar to other language=
=20
> features, but in a more open and freeform way. Lambdas for example don't=
=20
> have lexical scoping in C++ unless you explicitly ask for them, whereas=
=20
> most languages give it to you as a matter of course.
>
> (or possibly arbitrary expressions?)
>>
>>
>> This wouldn't be so much of a problem, because those expressions (other=
=20
>> than their declarations) don't need to be completely understood when the=
=20
>> [insert better name for interpolation] is performed - just the resulting=
=20
>> type is needed.
>>
>
> The issue with "arbitrary expression" is that you're now requiring the=20
> compiler to *invoke the compiler*. It's easy for the compiler to take a=
=20
> compile-time string and find a variable in scope that matches it. It's mu=
ch=20
> harder (presumably) for the compiler to take a compile-time string and=20
> invoke the compiler on it, within the current scope as if it had been=20
> written text.
>
> I'm not saying its impossible; I don't know much about compiler=20
> architecture. But I can't imagine it's as easy as just finding a variable=
=20
> with that name.
>
> Not only that, once you get into wanting `constexpr` strings that can be=
=20
> interpolated, you get into lots of issues. Do you really want a feature=
=20
> where you're able to synthesize arbitrary expressions and have someone=20
> insinuate them into their code at compile time?
>
> Or... maybe you do?
>

From what I know about compilation and formal languages in general, it=20
shouldn't be very hard for a compiler to deal with expressions within=20
`F"{}"`.
The compiler already do that kind of stuff with parentheses. Compilers are=
=20
by nature recursive.

The only thing I don't know is if the compiler deals with string literals=
=20
as a single token or not. If they do, string literal parser will have to be=
=20
modified quite a lot, even with the "identifier-only" variant.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/3a738e91-f935-4d11-ab6b-771048b556d4%40isocpp.or=
g.

------=_Part_1372_1055808211.1518712406608
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le jeudi 15 f=C3=A9vrier 2018 17:19:29 UTC+1, Nico=
l Bolas a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v dir=3D"ltr">On Thursday, February 15, 2018 at 11:06:10 AM UTC-5, Jake Ark=
install wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-le=
ft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"auto"><di=
v><div><div class=3D"gmail_quote">On 15 Feb 2018 15:51, &quot;Nicol Bolas&q=
uot; &lt;<a rel=3D"nofollow">jmck...@gmail.com</a>&gt; wrote:<br type=3D"at=
tribution"><blockquote style=3D"margin:0 0 0 .8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"ltr"><div>Taking a literal (or possibly con=
stexpr string?)</div></div></blockquote></div></div></div><div dir=3D"auto"=
><br></div><div dir=3D"auto">I was wondering whether it makes sense to even=
 describe these things as literals, given that they aren&#39;t literal and =
given that they aren&#39;t intended to actually be stored in memory in any =
way.</div></div></blockquote><div><br>We still call literals &quot;literals=
&quot;, even if you use them entirely at compile-time via `constexpr` trick=
s, such that no runtime code ever needs them. Things between quotes are lit=
erals.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;mar=
gin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"aut=
o"><div dir=3D"auto">But in terms of constexpr strings, I guess these thing=
s themselves can be built up by other methods - I&#39;m not sure if this ma=
kes sense in compilation, though; I&#39;m under the impression that the exp=
ression itself would likely need to be processed before the constexpr metho=
ds themselves could be evaluated (especially given that they could themselv=
es utilise interpolation). I could be wrong.</div><div dir=3D"auto"><br></d=
iv><div dir=3D"auto">I think, at this point, interpolation is a bad word - =
it made sense in the initial form, but now this has generalised we might wa=
nt a new word for it.</div></div></blockquote><div><br>I don&#39;t agree. &=
quot;String interpolation&quot; often carries the connotation that you&#39;=
re just going to concatenate strings, but it doesn&#39;t <i>have</i> to. C+=
+ sometimes defines concepts with names that are similar to other language =
features, but in a more open and freeform way. Lambdas for example don&#39;=
t have lexical scoping in C++ unless you explicitly ask for them, whereas m=
ost languages give it to you as a matter of course.<br><br></div><blockquot=
e class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px=
 #ccc solid;padding-left:1ex"><div dir=3D"auto"><div dir=3D"auto"></div><di=
v dir=3D"auto"><div><div class=3D"gmail_quote"><blockquote style=3D"margin:=
0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><d=
iv>(or possibly arbitrary expressions?)</div></div></blockquote></div></div=
></div><div dir=3D"auto"><br></div><div dir=3D"auto">This wouldn&#39;t be s=
o much of a problem, because those expressions (other than their declaratio=
ns) don&#39;t need to be completely understood when the [insert better name=
 for interpolation] is performed - just the resulting type is needed.</div>=
</div></blockquote><div><br>The issue with &quot;arbitrary expression&quot;=
 is that you&#39;re now requiring the compiler to <i>invoke the compiler</i=
>. It&#39;s easy for the compiler to take a compile-time string and find a =
variable in scope that matches it. It&#39;s much harder (presumably) for th=
e compiler to take a compile-time string and invoke the compiler on it, wit=
hin the current scope as if it had been written text.<br><br>I&#39;m not sa=
ying its impossible; I don&#39;t know much about compiler architecture. But=
 I can&#39;t imagine it&#39;s as easy as just finding a variable with that =
name.<br><br>Not only that, once you get into wanting `constexpr` strings t=
hat can be interpolated, you get into lots of issues. Do you really want a =
feature where you&#39;re able to synthesize arbitrary expressions and have =
someone insinuate them into their code at compile time?<br><br>Or... maybe =
you do?<br></div></div></blockquote><div><br></div><div>From what I know ab=
out compilation and formal languages in general, it shouldn&#39;t be very h=
ard for a compiler to deal with expressions within `F&quot;{}&quot;`.</div>=
<div>The compiler already do that kind of stuff with parentheses. Compilers=
 are by nature recursive.</div><div><br></div><div>The only thing I don&#39=
;t know is if the compiler deals with string literals as a single token or =
not. If they do, string literal parser will have to be modified quite a lot=
, even with the &quot;identifier-only&quot; variant.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/3a738e91-f935-4d11-ab6b-771048b556d4%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/3a738e91-f935-4d11-ab6b-771048b556d4=
%40isocpp.org</a>.<br />

------=_Part_1372_1055808211.1518712406608--

------=_Part_1371_343370368.1518712406607--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 15 Feb 2018 11:39:29 -0800 (PST)
Raw View
------=_Part_1874_349172720.1518723569403
Content-Type: multipart/alternative;
 boundary="----=_Part_1875_913364200.1518723569403"

------=_Part_1875_913364200.1518723569403
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Thursday, February 15, 2018 at 11:33:26 AM UTC-5, floria...@gmail.com=20
wrote:
>
> Le jeudi 15 f=C3=A9vrier 2018 17:19:29 UTC+1, Nicol Bolas a =C3=A9crit :
>>
>> On Thursday, February 15, 2018 at 11:06:10 AM UTC-5, Jake Arkinstall=20
>> wrote:
>>>
>>> On 15 Feb 2018 15:51, "Nicol Bolas" <jmck...@gmail.com> wrote:
>>>
>>> Taking a literal (or possibly constexpr string?)
>>>
>>>
>>> I was wondering whether it makes sense to even describe these things as=
=20
>>> literals, given that they aren't literal and given that they aren't=20
>>> intended to actually be stored in memory in any way.
>>>
>>
>> We still call literals "literals", even if you use them entirely at=20
>> compile-time via `constexpr` tricks, such that no runtime code ever need=
s=20
>> them. Things between quotes are literals.
>>
>> But in terms of constexpr strings, I guess these things themselves can b=
e=20
>>> built up by other methods - I'm not sure if this makes sense in=20
>>> compilation, though; I'm under the impression that the expression itsel=
f=20
>>> would likely need to be processed before the constexpr methods themselv=
es=20
>>> could be evaluated (especially given that they could themselves utilise=
=20
>>> interpolation). I could be wrong.
>>>
>>> I think, at this point, interpolation is a bad word - it made sense in=
=20
>>> the initial form, but now this has generalised we might want a new word=
 for=20
>>> it.
>>>
>>
>> I don't agree. "String interpolation" often carries the connotation that=
=20
>> you're just going to concatenate strings, but it doesn't *have* to. C++=
=20
>> sometimes defines concepts with names that are similar to other language=
=20
>> features, but in a more open and freeform way. Lambdas for example don't=
=20
>> have lexical scoping in C++ unless you explicitly ask for them, whereas=
=20
>> most languages give it to you as a matter of course.
>>
>> (or possibly arbitrary expressions?)
>>>
>>>
>>> This wouldn't be so much of a problem, because those expressions (other=
=20
>>> than their declarations) don't need to be completely understood when th=
e=20
>>> [insert better name for interpolation] is performed - just the resultin=
g=20
>>> type is needed.
>>>
>>
>> The issue with "arbitrary expression" is that you're now requiring the=
=20
>> compiler to *invoke the compiler*. It's easy for the compiler to take a=
=20
>> compile-time string and find a variable in scope that matches it. It's m=
uch=20
>> harder (presumably) for the compiler to take a compile-time string and=
=20
>> invoke the compiler on it, within the current scope as if it had been=20
>> written text.
>>
>> I'm not saying its impossible; I don't know much about compiler=20
>> architecture. But I can't imagine it's as easy as just finding a variabl=
e=20
>> with that name.
>>
>> Not only that, once you get into wanting `constexpr` strings that can be=
=20
>> interpolated, you get into lots of issues. Do you really want a feature=
=20
>> where you're able to synthesize arbitrary expressions and have someone=
=20
>> insinuate them into their code at compile time?
>>
>> Or... maybe you do?
>>
>
> From what I know about compilation and formal languages in general, it=20
> shouldn't be very hard for a compiler to deal with expressions within=20
> `F"{}"`.
> The compiler already do that kind of stuff with parentheses. Compilers ar=
e=20
> by nature recursive.
>

You don't seem to be fully understanding what we're talking about. This=20
isn't standard recursive-descent recursion. This is "execute some constexpr=
=20
code and then run the compiler on part of its string results." Those=20
"results" might include things like *macros*, and macro expansion is=20
supposed to have happened long before executing constexpr functions.

And you can't just say they're expressions minus macros. Many C-standard=20
library facilities are, or might be, macros after all. Is it legal to do=20
`F"{sin(foo)}"`? If string interpolation is supposed to allow arbitrary=20
expressions, it would be odd indeed if it were not. What about invoking=20
`offsetof` or similar C-isms?

If we're only going to allow string interpolation with genuine literals,=20
then this isn't much of a problem. Even the macro issue can be sorted out,=
=20
since the string is right there in the text of the source code.

But if we want string interpolation to ever be applied to the results of=20
compile-time execution, that's going to be *much* more complex if string=20
interpolation can handle arbitrary expressions. Whereas if we define it to=
=20
just be variable identifiers, extending such interpolation to constexpr=20
strings would be much more reasonable.

I would say that any proposal should be focused on the minimum featureset.=
=20
It should naturally include expanding into arbitrary expressions and=20
constexpr strings as future directions things could take, but I wouldn't=20
push for them in the short term. Sort of like how `constexpr` functions in=
=20
C++11 were really limited, which C++14 greatly expanded.

The only thing I don't know is if the compiler deals with string literals=
=20
> as a single token or not. If they do, string literal parser will have to =
be=20
> modified quite a lot, even with the "identifier-only" variant.
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/96860b9e-95ea-466a-825c-c371844a45e2%40isocpp.or=
g.

------=_Part_1875_913364200.1518723569403
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Thursday, February 15, 2018 at 11:33:26 AM UTC-5, flori=
a...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr">Le jeudi 15 f=C3=A9vrier 2018 17:19:29 UTC+1, Nicol Bolas a =C3=A9=
crit=C2=A0:<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 Thur=
sday, February 15, 2018 at 11:06:10 AM UTC-5, Jake Arkinstall wrote:<blockq=
uote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:=
1px #ccc solid;padding-left:1ex"><div dir=3D"auto"><div><div><div class=3D"=
gmail_quote">On 15 Feb 2018 15:51, &quot;Nicol Bolas&quot; &lt;<a rel=3D"no=
follow">jmck...@gmail.com</a>&gt; wrote:<br type=3D"attribution"><blockquot=
e style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><=
div dir=3D"ltr"><div>Taking a literal (or possibly constexpr string?)</div>=
</div></blockquote></div></div></div><div dir=3D"auto"><br></div><div dir=
=3D"auto">I was wondering whether it makes sense to even describe these thi=
ngs as literals, given that they aren&#39;t literal and given that they are=
n&#39;t intended to actually be stored in memory in any way.</div></div></b=
lockquote><div><br>We still call literals &quot;literals&quot;, even if you=
 use them entirely at compile-time via `constexpr` tricks, such that no run=
time code ever needs them. Things between quotes are literals.<br><br></div=
><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div dir=3D"auto"><div dir=3D"auto=
">But in terms of constexpr strings, I guess these things themselves can be=
 built up by other methods - I&#39;m not sure if this makes sense in compil=
ation, though; I&#39;m under the impression that the expression itself woul=
d likely need to be processed before the constexpr methods themselves could=
 be evaluated (especially given that they could themselves utilise interpol=
ation). I could be wrong.</div><div dir=3D"auto"><br></div><div dir=3D"auto=
">I think, at this point, interpolation is a bad word - it made sense in th=
e initial form, but now this has generalised we might want a new word for i=
t.</div></div></blockquote><div><br>I don&#39;t agree. &quot;String interpo=
lation&quot; often carries the connotation that you&#39;re just going to co=
ncatenate strings, but it doesn&#39;t <i>have</i> to. C++ sometimes defines=
 concepts with names that are similar to other language features, but in a =
more open and freeform way. Lambdas for example don&#39;t have lexical scop=
ing in C++ unless you explicitly ask for them, whereas most languages give =
it to you as a matter of course.<br><br></div><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding=
-left:1ex"><div dir=3D"auto"><div dir=3D"auto"></div><div dir=3D"auto"><div=
><div class=3D"gmail_quote"><blockquote style=3D"margin:0 0 0 .8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>(or possibly arb=
itrary expressions?)</div></div></blockquote></div></div></div><div dir=3D"=
auto"><br></div><div dir=3D"auto">This wouldn&#39;t be so much of a problem=
, because those expressions (other than their declarations) don&#39;t need =
to be completely understood when the [insert better name for interpolation]=
 is performed - just the resulting type is needed.</div></div></blockquote>=
<div><br>The issue with &quot;arbitrary expression&quot; is that you&#39;re=
 now requiring the compiler to <i>invoke the compiler</i>. It&#39;s easy fo=
r the compiler to take a compile-time string and find a variable in scope t=
hat matches it. It&#39;s much harder (presumably) for the compiler to take =
a compile-time string and invoke the compiler on it, within the current sco=
pe as if it had been written text.<br><br>I&#39;m not saying its impossible=
; I don&#39;t know much about compiler architecture. But I can&#39;t imagin=
e it&#39;s as easy as just finding a variable with that name.<br><br>Not on=
ly that, once you get into wanting `constexpr` strings that can be interpol=
ated, you get into lots of issues. Do you really want a feature where you&#=
39;re able to synthesize arbitrary expressions and have someone insinuate t=
hem into their code at compile time?<br><br>Or... maybe you do?<br></div></=
div></blockquote><div><br></div><div>From what I know about compilation and=
 formal languages in general, it shouldn&#39;t be very hard for a compiler =
to deal with expressions within `F&quot;{}&quot;`.</div><div>The compiler a=
lready do that kind of stuff with parentheses. Compilers are by nature recu=
rsive.</div></div></blockquote><div><br>You don&#39;t seem to be fully unde=
rstanding what we&#39;re talking about. This isn&#39;t standard recursive-d=
escent recursion. This is &quot;execute some constexpr code and then run th=
e compiler on part of its string results.&quot; Those &quot;results&quot; m=
ight include things like <i>macros</i>, and macro expansion is supposed to =
have happened long before executing constexpr functions.<br><br>And you can=
&#39;t just say they&#39;re expressions minus macros. Many C-standard libra=
ry facilities are, or might be, macros after all. Is it legal to do `F&quot=
;{sin(foo)}&quot;`? If string interpolation is supposed to allow arbitrary =
expressions, it would be odd indeed if it were not. What about invoking `of=
fsetof` or similar C-isms?<br><br>If we&#39;re only going to allow string i=
nterpolation with genuine literals, then this isn&#39;t much of a problem. =
Even the macro issue can be sorted out, since the string is right there in =
the text of the source code.<br><br>But if we want string interpolation to =
ever be applied to the results of compile-time execution, that&#39;s going =
to be <i>much</i> more complex if string interpolation can handle arbitrary=
 expressions. Whereas if we define it to just be variable identifiers, exte=
nding such interpolation to constexpr strings would be much more reasonable=
..<br><br>I would say that any proposal should be focused on the minimum fea=
tureset. It should naturally include expanding into arbitrary expressions a=
nd constexpr strings as future directions things could take, but I wouldn&#=
39;t push for them in the short term. Sort of like how `constexpr` function=
s in C++11 were really limited, which C++14 greatly expanded.<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><d=
iv>The only thing I don&#39;t know is if the compiler deals with string lit=
erals as a single token or not. If they do, string literal parser will have=
 to be modified quite a lot, even with the &quot;identifier-only&quot; vari=
ant.<br></div></div></blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/96860b9e-95ea-466a-825c-c371844a45e2%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/96860b9e-95ea-466a-825c-c371844a45e2=
%40isocpp.org</a>.<br />

------=_Part_1875_913364200.1518723569403--

------=_Part_1874_349172720.1518723569403--

.


Author: Florian Lemaitre <florian.csdt@gmail.com>
Date: Thu, 15 Feb 2018 23:54:09 +0100
Raw View
This is a multi-part message in MIME format.
--------------4A1C972F24C2F7300041622D
Content-Type: text/plain; charset="UTF-8"; format=flowed
Content-Transfer-Encoding: quoted-printable

On 15/02/2018 20:39, Nicol Bolas wrote:
> On Thursday, February 15, 2018 at 11:33:26 AM UTC-5,=20
> floria...@gmail.com wrote:
>
>     Le jeudi 15 f=C3=A9vrier 2018 17:19:29 UTC+1, Nicol Bolas a =C3=A9cri=
t=C2=A0:
>
>         On Thursday, February 15, 2018 at 11:06:10 AM UTC-5, Jake
>         Arkinstall wrote:
>
>             On 15 Feb 2018 15:51, "Nicol Bolas" <jmck...@gmail.com> wrote=
:
>
>                 Taking a literal (or possibly constexpr string?)
>
>
>             I was wondering whether it makes sense to even describe
>             these things as literals, given that they aren't literal
>             and given that they aren't intended to actually be stored
>             in memory in any way.
>
>
>         We still call literals "literals", even if you use them
>         entirely at compile-time via `constexpr` tricks, such that no
>         runtime code ever needs them. Things between quotes are literals.
>
>             But in terms of constexpr strings, I guess these things
>             themselves can be built up by other methods - I'm not sure
>             if this makes sense in compilation, though; I'm under the
>             impression that the expression itself would likely need to
>             be processed before the constexpr methods themselves could
>             be evaluated (especially given that they could themselves
>             utilise interpolation). I could be wrong.
>
>             I think, at this point, interpolation is a bad word - it
>             made sense in the initial form, but now this has
>             generalised we might want a new word for it.
>
>
>         I don't agree. "String interpolation" often carries the
>         connotation that you're just going to concatenate strings, but
>         it doesn't /have/ to. C++ sometimes defines concepts with
>         names that are similar to other language features, but in a
>         more open and freeform way. Lambdas for example don't have
>         lexical scoping in C++ unless you explicitly ask for them,
>         whereas most languages give it to you as a matter of course.
>
>                 (or possibly arbitrary expressions?)
>
>
>             This wouldn't be so much of a problem, because those
>             expressions (other than their declarations) don't need to
>             be completely understood when the [insert better name for
>             interpolation] is performed - just the resulting type is
>             needed.
>
>
>         The issue with "arbitrary expression" is that you're now
>         requiring the compiler to /invoke the compiler/. It's easy for
>         the compiler to take a compile-time string and find a variable
>         in scope that matches it. It's much harder (presumably) for
>         the compiler to take a compile-time string and invoke the
>         compiler on it, within the current scope as if it had been
>         written text.
>
>         I'm not saying its impossible; I don't know much about
>         compiler architecture. But I can't imagine it's as easy as
>         just finding a variable with that name.
>
>         Not only that, once you get into wanting `constexpr` strings
>         that can be interpolated, you get into lots of issues. Do you
>         really want a feature where you're able to synthesize
>         arbitrary expressions and have someone insinuate them into
>         their code at compile time?
>
>         Or... maybe you do?
>
>
>     From what I know about compilation and formal languages in
>     general, it shouldn't be very hard for a compiler to deal with
>     expressions within `F"{}"`.
>     The compiler already do that kind of stuff with parentheses.
>     Compilers are by nature recursive.
>
>
> You don't seem to be fully understanding what we're talking about.=20
> This isn't standard recursive-descent recursion. This is "execute some=20
> constexpr code and then run the compiler on part of its string=20
> results." Those "results" might include things like /macros/, and=20
> macro expansion is supposed to have happened long before executing=20
> constexpr functions.
>
> And you can't just say they're expressions minus macros. Many=20
> C-standard library facilities are, or might be, macros after all. Is=20
> it legal to do `F"{sin(foo)}"`? If string interpolation is supposed to=20
> allow arbitrary expressions, it would be odd indeed if it were not.=20
> What about invoking `offsetof` or similar C-isms?
>
> If we're only going to allow string interpolation with genuine=20
> literals, then this isn't much of a problem. Even the macro issue can=20
> be sorted out, since the string is right there in the text of the=20
> source code.
>
> But if we want string interpolation to ever be applied to the results=20
> of compile-time execution, that's going to be /much/ more complex if=20
> string interpolation can handle arbitrary expressions. Whereas if we=20
> define it to just be variable identifiers, extending such=20
> interpolation to constexpr strings would be much more reasonable.
>
> I would say that any proposal should be focused on the minimum=20
> featureset. It should naturally include expanding into arbitrary=20
> expressions and constexpr strings as future directions things could=20
> take, but I wouldn't push for them in the short term. Sort of like how=20
> `constexpr` functions in C++11 were really limited, which C++14=20
> greatly expanded.
>
>     The only thing I don't know is if the compiler deals with string
>     literals as a single token or not. If they do, string literal
>     parser will have to be modified quite a lot, even with the
>     "identifier-only" variant.
>

First thing first, currently the C++ is oblivious to the preprocessor,=20
and this will probably not change in the forseeable future (note that=20
the preprocessor is somehow aware of C++: __cplusplus macro, #include,=20
__has_cpp_attribute...).
But as far as the compiler is concerned, these are two distinct steps=20
that are processed one after the other, without going back.

Maybe you want to change that, but I think you were mentionning macros=20
taking effect within F"{}".
For instance:
|
#defineFoo5
F"{Foo}";
|
would expand to:
|
F"{5}";
|

This has basicaly nothing to do with C++, just the preprocessor should=20
be aware that F"{ and }" are somehow similar to parentheses and it=20
should process the inner part as usual.
I am simplifying here, but the idea is there. No coming back from C++ to=20
the preprocessor here.

If this is not what you have in mind, please correct me.

Now that macros are dealt with, we can actually consider the C++ side.

 =C2=A0As far as I understand this topic, I see mainly 3 possibilities:|
|
|
constexprautos =3D"bar";

// first:
foo(F"s: {s}");
// equivalent to:
foo("s: bar");

// second:
|foo(F"s: {s}");
// equivalent to:
foo("s: ",s);

// third:|
|||foo(F"s: {s}");
// equivalent to:
foo(std::string_processing("s: ",s));
|||
|

If you were thinking about a fourth option, please tell me.

For our current concern, the second and third are basically identical.=20
So let's focus on the first and the second.
And please note that everything that foolows also work if you replace s=20
by an actual C++ expression.

The second is no different than regular parsing (besides delimiters).=20
Indeed, it is just convert the string interpolation literal into a=20
sequence of literals and expressions. Nothing fancy here: it is standard=20
recursive-descent. (If you really want, you could even do that with a=20
text processor before the C++ pass, but this is probably not a very good=20
idea)

The first one is more interesting though (but limited to constexpr=20
only). This would require the compiler to create an object, behaving=20
like a string literal (const char[]) resulting from constexpr results.
But the last part is already possible in C++.
|
// Simple example
template <char... Str>
struct Foo {
 =C2=A0 static const char str[sizeof...(Str)];
};
template <char... Str>
const char Foo<Str...>::str =3D {Str...};
|

In this example, I can create an object behaving exactly like a string=20
literal, that is dependant of some constexpr computation.
Basically, the compiler is already able to do create "string literals"=20
on the fly. So it shouldn't be hard to actually implement the first variant=
..

I already hear you: my Foo<...>::str is *not* a string literal. And I=20
agree with you, but the fact is: it is possible to do exactly the same=20
thing as with a string literal transparently.
UDLs are also possible (but not transparently though). Even the template=20
<class Char, Char...> operator"" that is not part of C++.
If the hard part is already possible in plain C++, the whole idea would=20
be feasable by the compiler that has much more power.

So yes, I understand exactly what we're talking about.

PS: if you want only literal concatenation, it is already possible with=20
plain basic preprocessor. "foo" "bar" is a single valid string literal.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/0caab177-cf57-cab1-a5d5-0fc65f651491%40gmail.com=
..

--------------4A1C972F24C2F7300041622D
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<html>
  <head>
    <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-8=
">
  </head>
  <body text=3D"#000000" bgcolor=3D"#FFFFFF">
    On 15/02/2018 20:39, Nicol Bolas wrote:<br>
    <blockquote type=3D"cite"
      cite=3D"mid:96860b9e-95ea-466a-825c-c371844a45e2@isocpp.org">
      <div dir=3D"ltr">On Thursday, February 15, 2018 at 11:33:26 AM
        UTC-5, <a class=3D"moz-txt-link-abbreviated" href=3D"mailto:floria.=
...@gmail.com">floria...@gmail.com</a> 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">Le jeudi 15 f=C3=A9vrier 2018 17:19:29 UTC+1, Ni=
col
            Bolas a =C3=A9crit=C2=A0:
            <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 Thursday, February 15, 2018 at 11:06:10
                AM UTC-5, Jake Arkinstall 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"auto">
                    <div>
                      <div>
                        <div class=3D"gmail_quote">On 15 Feb 2018 15:51,
                          "Nicol Bolas" &lt;<a rel=3D"nofollow"
                            moz-do-not-send=3D"true">jmck...@gmail.com</a>&=
gt;
                          wrote:<br type=3D"attribution">
                          <blockquote style=3D"margin:0 0 0
                            .8ex;border-left:1px #ccc
                            solid;padding-left:1ex">
                            <div dir=3D"ltr">
                              <div>Taking a literal (or possibly
                                constexpr string?)</div>
                            </div>
                          </blockquote>
                        </div>
                      </div>
                    </div>
                    <div dir=3D"auto"><br>
                    </div>
                    <div dir=3D"auto">I was wondering whether it makes
                      sense to even describe these things as literals,
                      given that they aren't literal and given that they
                      aren't intended to actually be stored in memory in
                      any way.</div>
                  </div>
                </blockquote>
                <div><br>
                  We still call literals "literals", even if you use
                  them entirely at compile-time via `constexpr` tricks,
                  such that no runtime code ever needs them. Things
                  between quotes are literals.<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"auto">
                    <div dir=3D"auto">But in terms of constexpr strings, I
                      guess these things themselves can be built up by
                      other methods - I'm not sure if this makes sense
                      in compilation, though; I'm under the impression
                      that the expression itself would likely need to be
                      processed before the constexpr methods themselves
                      could be evaluated (especially given that they
                      could themselves utilise interpolation). I could
                      be wrong.</div>
                    <div dir=3D"auto"><br>
                    </div>
                    <div dir=3D"auto">I think, at this point,
                      interpolation is a bad word - it made sense in the
                      initial form, but now this has generalised we
                      might want a new word for it.</div>
                  </div>
                </blockquote>
                <div><br>
                  I don't agree. "String interpolation" often carries
                  the connotation that you're just going to concatenate
                  strings, but it doesn't <i>have</i> to. C++ sometimes
                  defines concepts with names that are similar to other
                  language features, but in a more open and freeform
                  way. Lambdas for example don't have lexical scoping in
                  C++ unless you explicitly ask for them, whereas most
                  languages give it to you as a matter of course.<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"auto">
                    <div dir=3D"auto">
                      <div>
                        <div class=3D"gmail_quote">
                          <blockquote style=3D"margin:0 0 0
                            .8ex;border-left:1px #ccc
                            solid;padding-left:1ex">
                            <div dir=3D"ltr">
                              <div>(or possibly arbitrary expressions?)</di=
v>
                            </div>
                          </blockquote>
                        </div>
                      </div>
                    </div>
                    <div dir=3D"auto"><br>
                    </div>
                    <div dir=3D"auto">This wouldn't be so much of a
                      problem, because those expressions (other than
                      their declarations) don't need to be completely
                      understood when the [insert better name for
                      interpolation] is performed - just the resulting
                      type is needed.</div>
                  </div>
                </blockquote>
                <div><br>
                  The issue with "arbitrary expression" is that you're
                  now requiring the compiler to <i>invoke the compiler</i>.
                  It's easy for the compiler to take a compile-time
                  string and find a variable in scope that matches it.
                  It's much harder (presumably) for the compiler to take
                  a compile-time string and invoke the compiler on it,
                  within the current scope as if it had been written
                  text.<br>
                  <br>
                  I'm not saying its impossible; I don't know much about
                  compiler architecture. But I can't imagine it's as
                  easy as just finding a variable with that name.<br>
                  <br>
                  Not only that, once you get into wanting `constexpr`
                  strings that can be interpolated, you get into lots of
                  issues. Do you really want a feature where you're able
                  to synthesize arbitrary expressions and have someone
                  insinuate them into their code at compile time?<br>
                  <br>
                  Or... maybe you do?<br>
                </div>
              </div>
            </blockquote>
            <div><br>
            </div>
            <div>From what I know about compilation and formal languages
              in general, it shouldn't be very hard for a compiler to
              deal with expressions within `F"{}"`.</div>
            <div>The compiler already do that kind of stuff with
              parentheses. Compilers are by nature recursive.</div>
          </div>
        </blockquote>
        <div><br>
          You don't seem to be fully understanding what we're talking
          about. This isn't standard recursive-descent recursion. This
          is "execute some constexpr code and then run the compiler on
          part of its string results." Those "results" might include
          things like <i>macros</i>, and macro expansion is supposed to
          have happened long before executing constexpr functions.<br>
          <br>
          And you can't just say they're expressions minus macros. Many
          C-standard library facilities are, or might be, macros after
          all. Is it legal to do `F"{sin(foo)}"`? If string
          interpolation is supposed to allow arbitrary expressions, it
          would be odd indeed if it were not. What about invoking
          `offsetof` or similar C-isms?<br>
          <br>
          If we're only going to allow string interpolation with genuine
          literals, then this isn't much of a problem. Even the macro
          issue can be sorted out, since the string is right there in
          the text of the source code.<br>
          <br>
          But if we want string interpolation to ever be applied to the
          results of compile-time execution, that's going to be <i>much</i>
          more complex if string interpolation can handle arbitrary
          expressions. Whereas if we define it to just be variable
          identifiers, extending such interpolation to constexpr strings
          would be much more reasonable.<br>
          <br>
          I would say that any proposal should be focused on the minimum
          featureset. It should naturally include expanding into
          arbitrary expressions and constexpr strings as future
          directions things could take, but I wouldn't push for them in
          the short term. Sort of like how `constexpr` functions in
          C++11 were really limited, which C++14 greatly expanded.<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>The only thing I don't know is if the compiler deals
              with string literals as a single token or not. If they do,
              string literal parser will have to be modified quite a
              lot, even with the "identifier-only" variant.<br>
            </div>
          </div>
        </blockquote>
      </div>
    </blockquote>
    <br>
    <div>First thing first, currently the C++ is oblivious to the
      preprocessor, and this will probably not change in the forseeable
      future (note that the preprocessor is somehow aware of C++:
      __cplusplus macro, #include, __has_cpp_attribute...).</div>
    <div>But as far as the compiler is concerned, these are two distinct
      steps that are processed one after the other, without going back.</di=
v>
    <div><br>
    </div>
    <div>Maybe you want to change that, but I think you were mentionning
      macros taking effect within F"{}".</div>
    <div>For instance:</div>
    <div>
      <div style=3D"background-color: rgb(250, 250, 250); border-color:
        rgb(187, 187, 187); border-style: solid; border-width: 1px;
        overflow-wrap: break-word;" class=3D"prettyprint"><code
          class=3D"prettyprint">
          <div class=3D"subprettyprint"><span style=3D"color: #800;"
              class=3D"styled-by-prettify">#define</span><span
              style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span
              style=3D"color: #606;" class=3D"styled-by-prettify">Foo</span=
><span
              style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span
              style=3D"color: #066;" class=3D"styled-by-prettify">5</span><=
span
              style=3D"color: #000;" class=3D"styled-by-prettify"><br>
              F</span><span style=3D"color: #080;"
              class=3D"styled-by-prettify">"{Foo}"</span><span
              style=3D"color: #660;" class=3D"styled-by-prettify">;</span><=
span
              style=3D"color: #000;" class=3D"styled-by-prettify"><br>
            </span></div>
        </code></div>
      would expand to:</div>
    <div>
      <div style=3D"background-color: rgb(250, 250, 250); border-color:
        rgb(187, 187, 187); border-style: solid; border-width: 1px;
        overflow-wrap: break-word;" class=3D"prettyprint"><code
          class=3D"prettyprint">
          <div class=3D"subprettyprint"><span style=3D"color: #000;"
              class=3D"styled-by-prettify">F</span><span style=3D"color:
              #080;" class=3D"styled-by-prettify">"{5}"</span><span
              style=3D"color: #660;" class=3D"styled-by-prettify">;</span><=
/div>
        </code></div>
    </div>
    <div><br>
    </div>
    <div>This has basicaly nothing to do with C++, just the preprocessor
      should be aware that F"{ and }" are somehow similar to parentheses
      and it should process the inner part as usual.</div>
    <div>I am simplifying here, but the idea is there. No coming back
      from C++ to the preprocessor here.</div>
    <div><br>
    </div>
    <div>If this is not what you have in mind, please correct me.<br>
    </div>
    <div><br>
    </div>
    <div>Now that macros are dealt with, we can actually consider the
      C++ side.<br>
    </div>
    <div><br>
    </div>
    <div>=C2=A0As far as I understand this topic, I see mainly 3
      possibilities:<code><br>
      </code></div>
    <div>
      <div style=3D"background-color: rgb(250, 250, 250); border-color:
        rgb(187, 187, 187); border-style: solid; border-width: 1px;
        overflow-wrap: break-word;" class=3D"prettyprint"><code
          class=3D"prettyprint">
          <div class=3D"subprettyprint"><span style=3D"color: #008;"
              class=3D"styled-by-prettify">constexpr</span><span
              style=3D"color: #000;" class=3D"styled-by-prettify"> auto</sp=
an><span
              style=3D"color: #000;" class=3D"styled-by-prettify"> s </span=
><span
              style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span=
><span
              style=3D"color: #000;" class=3D"styled-by-prettify"> "bar"</s=
pan><span
              style=3D"color: #066;" class=3D"styled-by-prettify"></span><s=
pan
              style=3D"color: #660;" class=3D"styled-by-prettify">;</span><=
span
              style=3D"color: #000;" class=3D"styled-by-prettify"><br>
              <br>
            </span><span style=3D"color: #800;" class=3D"styled-by-prettify=
">//
              first:</span><span style=3D"color: #000;"
              class=3D"styled-by-prettify"><br>
              foo</span><span style=3D"color: #660;"
              class=3D"styled-by-prettify">(</span><span style=3D"color:
              #000;" class=3D"styled-by-prettify">F</span><span
              style=3D"color: #080;" class=3D"styled-by-prettify">"s: {s}"<=
/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: #800;" class=3D"styled-by-prettify=
">//
              equivalent to:</span><span style=3D"color: #000;"
              class=3D"styled-by-prettify"><br>
              foo</span><span style=3D"color: #660;"
              class=3D"styled-by-prettify">(</span><span style=3D"color:
              #080;" class=3D"styled-by-prettify">"s: bar"</span><span
              style=3D"color: #660;" class=3D"styled-by-prettify">);</span>=
<span
              style=3D"color: #000;" class=3D"styled-by-prettify"><br>
              <br>
            </span><span style=3D"color: #800;" class=3D"styled-by-prettify=
">//
              second:</span><span style=3D"color: #000;"
              class=3D"styled-by-prettify"></span><br>
            <span style=3D"color: #000;" class=3D"styled-by-prettify"><code
                class=3D"prettyprint"><span style=3D"color: #000;"
                  class=3D"styled-by-prettify">foo</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">F</sp=
an><span
                  style=3D"color: #080;" class=3D"styled-by-prettify">"s:
                  {s}"</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: #800;"
                  class=3D"styled-by-prettify">// equivalent to:</span><spa=
n
                  style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                  foo</span><span style=3D"color: #660;"
                  class=3D"styled-by-prettify">(</span><span style=3D"color=
:
                  #080;" class=3D"styled-by-prettify">"s: "</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">,</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> s</s=
pan><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">);</s=
pan><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                  <br>
                  // third:</span></code></span><br>
            <span style=3D"color: #000;" class=3D"styled-by-prettify"><code
                class=3D"prettyprint"><span style=3D"color: #000;"
                  class=3D"styled-by-prettify"><code class=3D"prettyprint">=
<span
                      style=3D"color: #000;" class=3D"styled-by-prettify"><=
code
                        class=3D"prettyprint"><span style=3D"color: #000;"
                          class=3D"styled-by-prettify">foo</span><span
                          style=3D"color: #660;"
                          class=3D"styled-by-prettify">(</span><span
                          style=3D"color: #000;"
                          class=3D"styled-by-prettify">F</span><span
                          style=3D"color: #080;"
                          class=3D"styled-by-prettify">"s: {s}"</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: #800;"
                          class=3D"styled-by-prettify">// equivalent to:</s=
pan><span
                          style=3D"color: #000;"
                          class=3D"styled-by-prettify"><br>
                          foo</span><span style=3D"color: #660;"
                          class=3D"styled-by-prettify">(</span><span
                          style=3D"color: #080;"
                          class=3D"styled-by-prettify">std::string_processi=
ng("s:
                          "</span><span style=3D"color: #660;"
                          class=3D"styled-by-prettify">,</span><span
                          style=3D"color: #000;"
                          class=3D"styled-by-prettify"> s)</span><span
                          style=3D"color: #660;"
                          class=3D"styled-by-prettify">);</span><span
                          style=3D"color: #000;"
                          class=3D"styled-by-prettify"><br>
                        </span></code></span></code></span></code></span></=
div>
        </code></div>
    </div>
    <div><br>
    </div>
    <div>If you were thinking about a fourth option, please tell me.<br>
    </div>
    <div><br>
    </div>
    <div>For our current concern, the second and third are basically
      identical. So let's focus on the first and the second.</div>
    <div>And please note that everything that foolows also work if you
      replace s by an actual C++ expression.<br>
    </div>
    <div><br>
    </div>
    <div>The second is no different than regular parsing (besides
      delimiters). Indeed, it is just convert the string interpolation
      literal into a sequence of literals and expressions. Nothing fancy
      here: it is standard recursive-descent. (If you really want, you
      could even do that with a text processor before the C++ pass, but
      this is probably not a very good idea)</div>
    <div><br>
    </div>
    <div>The first one is more interesting though (but limited to
      constexpr only). This would require the compiler to create an
      object, behaving like a string literal (const char[]) resulting
      from constexpr results.</div>
    <div>But the last part is already possible in C++.</div>
    <div>
      <div style=3D"background-color: rgb(250, 250, 250); border-color:
        rgb(187, 187, 187); border-style: solid; border-width: 1px;
        overflow-wrap: break-word;" class=3D"prettyprint"><code
          class=3D"prettyprint">
          <div class=3D"subprettyprint"><span style=3D"color: #606;"
              class=3D"styled-by-prettify">// Simple example<br>
              template &lt;char... Str&gt;<br>
              struct Foo {<br>
              =C2=A0 static const char str[sizeof...(Str)];<br>
              };<br>
              template &lt;char... Str&gt;<br>
              const char Foo&lt;Str...&gt;::str =3D {Str...};<br>
            </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
"></span></div>
        </code></div>
    </div>
    <div><br>
    </div>
    <div>In this example, I can create an object behaving exactly like a
      string literal, that is dependant of some constexpr computation.</div=
>
    <div>Basically, the compiler is already able to do create "string
      literals" on the fly. So it shouldn't be hard to actually
      implement the first variant.</div>
    <div><br>
    </div>
    <div>I already hear you: my Foo&lt;...&gt;::str is <b>not</b> a
      string literal. And I agree with you, but the fact is: it is
      possible to do exactly the same thing as with a string literal
      transparently.</div>
    <div>UDLs are also possible (but not transparently though). Even the
      template &lt;class Char, Char...&gt; operator"" that is not part
      of C++.</div>
    <div>If the hard part is already possible in plain C++, the whole
      idea would be feasable by the compiler that has much more power.</div=
>
    <div><br>
    </div>
    <div>So yes, I understand exactly what we're talking about.</div>
    <div><br>
    </div>
    PS: if you want only literal concatenation, it is already possible
    with plain basic preprocessor. "foo" "bar" is a single valid string
    literal.
  </body>
</html>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/0caab177-cf57-cab1-a5d5-0fc65f651491%=
40gmail.com?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/0caab177-cf57-cab1-a5d5-0fc65f651491%=
40gmail.com</a>.<br />

--------------4A1C972F24C2F7300041622D--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 15 Feb 2018 17:32:10 -0800 (PST)
Raw View
------=_Part_2595_1959301049.1518744731036
Content-Type: multipart/alternative;
 boundary="----=_Part_2596_1879303657.1518744731036"

------=_Part_2596_1879303657.1518744731036
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



On Thursday, February 15, 2018 at 5:54:14 PM UTC-5, Florian Lemaitre wrote:
>
> On 15/02/2018 20:39, Nicol Bolas wrote:
>
> On Thursday, February 15, 2018 at 11:33:26 AM UTC-5, floria...@gmail.com=
=20
> wrote:=20
>>
>> Le jeudi 15 f=C3=A9vrier 2018 17:19:29 UTC+1, Nicol Bolas a =C3=A9crit :=
=20
>>>
>>> On Thursday, February 15, 2018 at 11:06:10 AM UTC-5, Jake Arkinstall=20
>>> wrote:=20
>>>>
>>>> On 15 Feb 2018 15:51, "Nicol Bolas" <jmck...@gmail.com> wrote:
>>>>
>>>> Taking a literal (or possibly constexpr string?)
>>>>
>>>>
>>>> I was wondering whether it makes sense to even describe these things a=
s=20
>>>> literals, given that they aren't literal and given that they aren't=20
>>>> intended to actually be stored in memory in any way.
>>>>
>>>
>>> We still call literals "literals", even if you use them entirely at=20
>>> compile-time via `constexpr` tricks, such that no runtime code ever nee=
ds=20
>>> them. Things between quotes are literals.
>>>
>>> But in terms of constexpr strings, I guess these things themselves can=
=20
>>>> be built up by other methods - I'm not sure if this makes sense in=20
>>>> compilation, though; I'm under the impression that the expression itse=
lf=20
>>>> would likely need to be processed before the constexpr methods themsel=
ves=20
>>>> could be evaluated (especially given that they could themselves utilis=
e=20
>>>> interpolation). I could be wrong.
>>>>
>>>> I think, at this point, interpolation is a bad word - it made sense in=
=20
>>>> the initial form, but now this has generalised we might want a new wor=
d for=20
>>>> it.
>>>>
>>>
>>> I don't agree. "String interpolation" often carries the connotation tha=
t=20
>>> you're just going to concatenate strings, but it doesn't *have* to. C++=
=20
>>> sometimes defines concepts with names that are similar to other languag=
e=20
>>> features, but in a more open and freeform way. Lambdas for example don'=
t=20
>>> have lexical scoping in C++ unless you explicitly ask for them, whereas=
=20
>>> most languages give it to you as a matter of course.
>>>
>>> (or possibly arbitrary expressions?)
>>>>
>>>>
>>>> This wouldn't be so much of a problem, because those expressions (othe=
r=20
>>>> than their declarations) don't need to be completely understood when t=
he=20
>>>> [insert better name for interpolation] is performed - just the resulti=
ng=20
>>>> type is needed.
>>>>
>>>
>>> The issue with "arbitrary expression" is that you're now requiring the=
=20
>>> compiler to *invoke the compiler*. It's easy for the compiler to take a=
=20
>>> compile-time string and find a variable in scope that matches it. It's =
much=20
>>> harder (presumably) for the compiler to take a compile-time string and=
=20
>>> invoke the compiler on it, within the current scope as if it had been=
=20
>>> written text.
>>>
>>> I'm not saying its impossible; I don't know much about compiler=20
>>> architecture. But I can't imagine it's as easy as just finding a variab=
le=20
>>> with that name.
>>>
>>> Not only that, once you get into wanting `constexpr` strings that can b=
e=20
>>> interpolated, you get into lots of issues. Do you really want a feature=
=20
>>> where you're able to synthesize arbitrary expressions and have someone=
=20
>>> insinuate them into their code at compile time?
>>>
>>> Or... maybe you do?
>>>
>>
>> From what I know about compilation and formal languages in general, it=
=20
>> shouldn't be very hard for a compiler to deal with expressions within=20
>> `F"{}"`.
>> The compiler already do that kind of stuff with parentheses. Compilers=
=20
>> are by nature recursive.
>>
>
> You don't seem to be fully understanding what we're talking about. This=
=20
> isn't standard recursive-descent recursion. This is "execute some constex=
pr=20
> code and then run the compiler on part of its string results." Those=20
> "results" might include things like *macros*, and macro expansion is=20
> supposed to have happened long before executing constexpr functions.
>
> And you can't just say they're expressions minus macros. Many C-standard=
=20
> library facilities are, or might be, macros after all. Is it legal to do=
=20
> `F"{sin(foo)}"`? If string interpolation is supposed to allow arbitrary=
=20
> expressions, it would be odd indeed if it were not. What about invoking=
=20
> `offsetof` or similar C-isms?
>
> If we're only going to allow string interpolation with genuine literals,=
=20
> then this isn't much of a problem. Even the macro issue can be sorted out=
,=20
> since the string is right there in the text of the source code.
>
> But if we want string interpolation to ever be applied to the results of=
=20
> compile-time execution, that's going to be *much* more complex if string=
=20
> interpolation can handle arbitrary expressions. Whereas if we define it t=
o=20
> just be variable identifiers, extending such interpolation to constexpr=
=20
> strings would be much more reasonable.
>
> I would say that any proposal should be focused on the minimum featureset=
..=20
> It should naturally include expanding into arbitrary expressions and=20
> constexpr strings as future directions things could take, but I wouldn't=
=20
> push for them in the short term. Sort of like how `constexpr` functions i=
n=20
> C++11 were really limited, which C++14 greatly expanded.
>
> The only thing I don't know is if the compiler deals with string literals=
=20
>> as a single token or not. If they do, string literal parser will have to=
 be=20
>> modified quite a lot, even with the "identifier-only" variant.
>>
>
> First thing first, currently the C++ is oblivious to the preprocessor, an=
d=20
> this will probably not change in the forseeable future (note that the=20
> preprocessor is somehow aware of C++: __cplusplus macro, #include,=20
> __has_cpp_attribute...).
> But as far as the compiler is concerned, these are two distinct steps tha=
t=20
> are processed one after the other, without going back.
>
> Maybe you want to change that, but I think you were mentionning macros=20
> taking effect within F"{}".
>

No, I'm mentioning macros taking effect within *string interpolation*.

We're talking about the intersection of two things, both of which are still=
=20
in question:

1) Arbitrary expressions in interpolation operations.
2) The use of constexpr strings as the *source* for interpolation=20
operations; as the string to be interpolated. That is:

constexpr constexpr_string<char> my_func()
{
  constexpr_string<char> a =3D "here's a string {sin(5)}"; //Note: not doin=
g=20
interpolation.
  constexpr_string<char> b =3D " more {foo} string"; //Still not=20
interpolating.
  return a + b;
}

auto str =3D std::concat(<interpolation syntax> my_func());

//The above is equivalent to:

auto str =3D std::concat("here's a string", sin(5), " more ", foo, " string=
");

It's the *combination* of these two things that doesn't work. By the time=
=20
the compiler gets around to actually processing the `my_func` call, macro=
=20
expansion has come and gone. So how does `sin(5)` get expanded properly?

And I know you're thinking that constexpr strings don't exist, that they're=
=20
not even really possible. Yet; the committee is working on expansions to=20
constexpr that allow memory allocation. Once that happens, we will have=20
constexpr strings. And once we do, there's no reason you should prevent=20
constexpr strings from being the source of interpolation operations.

Well, no reason unless you sandbag interpolation by requiring it to allow=
=20
arbitrary expressions. My feeling is that you have to pick one or the=20
other: you either allow arbitrary expressions or you allow constexpr string=
=20
interpolation. And if we can only have one, I'd much rather have the latter=
..

I want constexpr strings to be equivalent to literals as much as possible.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/7b1c3d63-d534-44d2-b4e9-fc0df135fff5%40isocpp.or=
g.

------=_Part_2596_1879303657.1518744731036
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Thursday, February 15, 2018 at 5:54:14 PM UTC-5=
, Florian Lemaitre wrote:<blockquote class=3D"gmail_quote" style=3D"margin:=
 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
 =20
   =20
 =20
  <div text=3D"#000000" bgcolor=3D"#FFFFFF">
    On 15/02/2018 20:39, Nicol Bolas wrote:<br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">On Thursday, February 15, 2018 at 11:33:26 AM
        UTC-5, <a>floria...@gmail.com</a> wrote:
        <blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex">
          <div dir=3D"ltr">Le jeudi 15 f=C3=A9vrier 2018 17:19:29 UTC+1, Ni=
col
            Bolas a =C3=A9crit=C2=A0:
            <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 Thursday, February 15, 2018 at 11:06:10
                AM UTC-5, Jake Arkinstall 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"auto">
                    <div>
                      <div>
                        <div class=3D"gmail_quote">On 15 Feb 2018 15:51,
                          &quot;Nicol Bolas&quot; &lt;<a rel=3D"nofollow">j=
mck...@gmail.com</a>&gt;
                          wrote:<br type=3D"attribution">
                          <blockquote style=3D"margin:0 0 0 .8ex;border-lef=
t:1px #ccc solid;padding-left:1ex">
                            <div dir=3D"ltr">
                              <div>Taking a literal (or possibly
                                constexpr string?)</div>
                            </div>
                          </blockquote>
                        </div>
                      </div>
                    </div>
                    <div dir=3D"auto"><br>
                    </div>
                    <div dir=3D"auto">I was wondering whether it makes
                      sense to even describe these things as literals,
                      given that they aren&#39;t literal and given that the=
y
                      aren&#39;t intended to actually be stored in memory i=
n
                      any way.</div>
                  </div>
                </blockquote>
                <div><br>
                  We still call literals &quot;literals&quot;, even if you =
use
                  them entirely at compile-time via `constexpr` tricks,
                  such that no runtime code ever needs them. Things
                  between quotes are literals.<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"auto">
                    <div dir=3D"auto">But in terms of constexpr strings, I
                      guess these things themselves can be built up by
                      other methods - I&#39;m not sure if this makes sense
                      in compilation, though; I&#39;m under the impression
                      that the expression itself would likely need to be
                      processed before the constexpr methods themselves
                      could be evaluated (especially given that they
                      could themselves utilise interpolation). I could
                      be wrong.</div>
                    <div dir=3D"auto"><br>
                    </div>
                    <div dir=3D"auto">I think, at this point,
                      interpolation is a bad word - it made sense in the
                      initial form, but now this has generalised we
                      might want a new word for it.</div>
                  </div>
                </blockquote>
                <div><br>
                  I don&#39;t agree. &quot;String interpolation&quot; often=
 carries
                  the connotation that you&#39;re just going to concatenate
                  strings, but it doesn&#39;t <i>have</i> to. C++ sometimes
                  defines concepts with names that are similar to other
                  language features, but in a more open and freeform
                  way. Lambdas for example don&#39;t have lexical scoping i=
n
                  C++ unless you explicitly ask for them, whereas most
                  languages give it to you as a matter of course.<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"auto">
                    <div dir=3D"auto">
                      <div>
                        <div class=3D"gmail_quote">
                          <blockquote style=3D"margin:0 0 0 .8ex;border-lef=
t:1px #ccc solid;padding-left:1ex">
                            <div dir=3D"ltr">
                              <div>(or possibly arbitrary expressions?)</di=
v>
                            </div>
                          </blockquote>
                        </div>
                      </div>
                    </div>
                    <div dir=3D"auto"><br>
                    </div>
                    <div dir=3D"auto">This wouldn&#39;t be so much of a
                      problem, because those expressions (other than
                      their declarations) don&#39;t need to be completely
                      understood when the [insert better name for
                      interpolation] is performed - just the resulting
                      type is needed.</div>
                  </div>
                </blockquote>
                <div><br>
                  The issue with &quot;arbitrary expression&quot; is that y=
ou&#39;re
                  now requiring the compiler to <i>invoke the compiler</i>.
                  It&#39;s easy for the compiler to take a compile-time
                  string and find a variable in scope that matches it.
                  It&#39;s much harder (presumably) for the compiler to tak=
e
                  a compile-time string and invoke the compiler on it,
                  within the current scope as if it had been written
                  text.<br>
                  <br>
                  I&#39;m not saying its impossible; I don&#39;t know much =
about
                  compiler architecture. But I can&#39;t imagine it&#39;s a=
s
                  easy as just finding a variable with that name.<br>
                  <br>
                  Not only that, once you get into wanting `constexpr`
                  strings that can be interpolated, you get into lots of
                  issues. Do you really want a feature where you&#39;re abl=
e
                  to synthesize arbitrary expressions and have someone
                  insinuate them into their code at compile time?<br>
                  <br>
                  Or... maybe you do?<br>
                </div>
              </div>
            </blockquote>
            <div><br>
            </div>
            <div>From what I know about compilation and formal languages
              in general, it shouldn&#39;t be very hard for a compiler to
              deal with expressions within `F&quot;{}&quot;`.</div>
            <div>The compiler already do that kind of stuff with
              parentheses. Compilers are by nature recursive.</div>
          </div>
        </blockquote>
        <div><br>
          You don&#39;t seem to be fully understanding what we&#39;re talki=
ng
          about. This isn&#39;t standard recursive-descent recursion. This
          is &quot;execute some constexpr code and then run the compiler on
          part of its string results.&quot; Those &quot;results&quot; might=
 include
          things like <i>macros</i>, and macro expansion is supposed to
          have happened long before executing constexpr functions.<br>
          <br>
          And you can&#39;t just say they&#39;re expressions minus macros. =
Many
          C-standard library facilities are, or might be, macros after
          all. Is it legal to do `F&quot;{sin(foo)}&quot;`? If string
          interpolation is supposed to allow arbitrary expressions, it
          would be odd indeed if it were not. What about invoking
          `offsetof` or similar C-isms?<br>
          <br>
          If we&#39;re only going to allow string interpolation with genuin=
e
          literals, then this isn&#39;t much of a problem. Even the macro
          issue can be sorted out, since the string is right there in
          the text of the source code.<br>
          <br>
          But if we want string interpolation to ever be applied to the
          results of compile-time execution, that&#39;s going to be <i>much=
</i>
          more complex if string interpolation can handle arbitrary
          expressions. Whereas if we define it to just be variable
          identifiers, extending such interpolation to constexpr strings
          would be much more reasonable.<br>
          <br>
          I would say that any proposal should be focused on the minimum
          featureset. It should naturally include expanding into
          arbitrary expressions and constexpr strings as future
          directions things could take, but I wouldn&#39;t push for them in
          the short term. Sort of like how `constexpr` functions in
          C++11 were really limited, which C++14 greatly expanded.<br>
          <br>
        </div>
        <blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex">
          <div dir=3D"ltr">
            <div>The only thing I don&#39;t know is if the compiler deals
              with string literals as a single token or not. If they do,
              string literal parser will have to be modified quite a
              lot, even with the &quot;identifier-only&quot; variant.<br>
            </div>
          </div>
        </blockquote>
      </div>
    </blockquote>
    <br>
    <div>First thing first, currently the C++ is oblivious to the
      preprocessor, and this will probably not change in the forseeable
      future (note that the preprocessor is somehow aware of C++:
      __cplusplus macro, #include, __has_cpp_attribute...).</div>
    <div>But as far as the compiler is concerned, these are two distinct
      steps that are processed one after the other, without going back.</di=
v>
    <div><br>
    </div>
    <div>Maybe you want to change that, but I think you were mentionning
      macros taking effect within F&quot;{}&quot;.</div></div></blockquote>=
<div><br>No, I&#39;m mentioning macros taking effect within <i>string inter=
polation</i>.<br><br>We&#39;re talking about the intersection of two things=
, both of which are still in question:<br><br>1) Arbitrary expressions in i=
nterpolation operations.<br>2) The use of constexpr strings as the <i>sourc=
e</i> for interpolation operations; as the string to be interpolated. That =
is:<br><br><div style=3D"background-color: rgb(250, 250, 250); border-color=
: rgb(187, 187, 187); border-style: solid; border-width: 1px; overflow-wrap=
: break-word;" class=3D"prettyprint"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">constexpr</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> constexpr_string</span><span style=3D"color: #080;" class=3D"styled-by-p=
rettify">&lt;char&gt;</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> my_func</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">()</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 con=
stexpr_string</span><span style=3D"color: #080;" class=3D"styled-by-prettif=
y">&lt;char&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> a </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: #080;" class=3D"styled-by-prettify">&quot;here&#39;s=
 a string {sin(5)}&quot;</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">//No=
te: not doing interpolation.</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br>=C2=A0 constexpr_string</span><span style=3D"color: #=
080;" class=3D"styled-by-prettify">&lt;char&gt;</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> b </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: #080;" class=3D"style=
d-by-prettify">&quot; more {foo} string&quot;</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #800;" class=3D"sty=
led-by-prettify">//Still not interpolating.</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">return</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> a </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">+</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> b</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r></span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> str </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">concat</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(&lt;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">interpolation syntax</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> my_func</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">());</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br><br></span><span style=3D"color: #800;" class=3D"styl=
ed-by-prettify">//The above is equivalent to:</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> str </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> std</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">concat</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(=
</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;here=
&#39;s a string&quot;</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> sin</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</s=
pan><span style=3D"color: #066;" class=3D"styled-by-prettify">5</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=
: #080;" class=3D"styled-by-prettify">&quot; more &quot;</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> foo</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: #080;" class=3D"style=
d-by-prettify">&quot; string&quot;</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br></span></div></code></div><br>It&#39;s the <i>combinati=
on</i> of these two things that doesn&#39;t work. By the time the compiler =
gets around to actually processing the `my_func` call, macro expansion has =
come and gone. So how does `sin(5)` get expanded properly?<br><br>And I kno=
w you&#39;re thinking that constexpr strings don&#39;t exist, that they&#39=
;re not even really possible. Yet; the committee is working on expansions t=
o constexpr that allow memory allocation. Once that happens, we will have c=
onstexpr strings. And once we do, there&#39;s no reason you should prevent =
constexpr strings from being the source of interpolation operations.<br><br=
>Well, no reason unless you sandbag interpolation by requiring it to allow =
arbitrary expressions. My feeling is that you have to pick one or the other=
: you either allow=20
arbitrary expressions or you allow constexpr string interpolation. And=20
if we can only have one, I&#39;d much rather have the latter.<br><br>I want=
 constexpr strings to be equivalent to literals as much as possible.<br></d=
iv><br></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/7b1c3d63-d534-44d2-b4e9-fc0df135fff5%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/7b1c3d63-d534-44d2-b4e9-fc0df135fff5=
%40isocpp.org</a>.<br />

------=_Part_2596_1879303657.1518744731036--

------=_Part_2595_1959301049.1518744731036--

.


Author: Jake Arkinstall <jake.arkinstall@gmail.com>
Date: Fri, 16 Feb 2018 02:52:48 +0000
Raw View
--001a113e500c8ac3c305654b70d2
Content-Type: text/plain; charset="UTF-8"

On 16 Feb 2018 01:32, "Nicol Bolas" <jmckesson@gmail.com> wrote:

My feeling is that you have to pick one or the other: you either allow
arbitrary expressions or you allow constexpr string interpolation. And if
we can only have one, I'd much rather have the latter.

I want constexpr strings to be equivalent to literals as much as possible.


I agree here. We can get something along the lines of an addition operator
that acts in the same way as concatenation - so we could have your example
by performing the interpolation and concatenating the results, but in terms
of e.g. allowing some constexpr string replacement, or other more advanced
string processing, I think it just adds more implementation complexity and
it could lead to some pretty dodgy practices (though it would be a code
obfuscator's goldmine).

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCMFDUop3ceSBh%2B39%2BGYq%2BeVRDLC4iSfCdauNc%3DO8A%3DwWQ%40mail.gmail.com.

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

<div dir=3D"auto"><div class=3D"gmail_extra" dir=3D"auto"><div class=3D"gma=
il_quote">On 16 Feb 2018 01:32, &quot;Nicol Bolas&quot; &lt;<a href=3D"mail=
to:jmckesson@gmail.com">jmckesson@gmail.com</a>&gt; wrote:<br type=3D"attri=
bution"><blockquote class=3D"quote" style=3D"margin:0 0 0 .8ex;border-left:=
1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"elided-text=
">My feeling is that you have to pick one or the other: you either allow=20
arbitrary expressions or you allow constexpr string interpolation. And=20
if we can only have one, I&#39;d much rather have the latter.</div><div><br=
>I want constexpr strings to be equivalent to literals as much as possible.=
</div></div></blockquote></div></div><div dir=3D"auto"><br></div><div dir=
=3D"auto">I agree here. We can get something along the lines of an addition=
 operator that acts in the same way as concatenation - so we could have you=
r example by performing the interpolation and concatenating the results, bu=
t in terms of e.g. allowing some constexpr string replacement, or other mor=
e advanced string processing, I think it just adds more implementation comp=
lexity and it could lead to some pretty dodgy practices (though it would be=
 a code obfuscator&#39;s goldmine).</div><div class=3D"gmail_extra" dir=3D"=
auto"></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCMFDUop3ceSBh%2B39%2BGYq%2BeV=
RDLC4iSfCdauNc%3DO8A%3DwWQ%40mail.gmail.com?utm_medium=3Demail&utm_source=
=3Dfooter">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC=
%2B0CCMFDUop3ceSBh%2B39%2BGYq%2BeVRDLC4iSfCdauNc%3DO8A%3DwWQ%40mail.gmail.c=
om</a>.<br />

--001a113e500c8ac3c305654b70d2--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 15 Feb 2018 19:17:51 -0800 (PST)
Raw View
------=_Part_2626_1966508890.1518751071826
Content-Type: multipart/alternative;
 boundary="----=_Part_2627_175020389.1518751071827"

------=_Part_2627_175020389.1518751071827
Content-Type: text/plain; charset="UTF-8"

On Thursday, February 15, 2018 at 9:52:50 PM UTC-5, Jake Arkinstall wrote:
>
> On 16 Feb 2018 01:32, "Nicol Bolas" <jmck...@gmail.com <javascript:>>
> wrote:
>
> My feeling is that you have to pick one or the other: you either allow
> arbitrary expressions or you allow constexpr string interpolation. And if
> we can only have one, I'd much rather have the latter.
>
> I want constexpr strings to be equivalent to literals as much as possible.
>
>
> I agree here. We can get something along the lines of an addition operator
> that acts in the same way as concatenation - so we could have your example
> by performing the interpolation and concatenating the results,
>

.... I don't understand what you mean by that. Remember: string
interpolation (in this design) doesn't "concatenate" anything. Only the
function call performs that operation. And in my example, `my_func` returns
a single string, not multiple strings.

It's not clear how what you're talking about solves the problem of using
arbitrary expressions. You cannot tell at the time macro expansion happens
whether a particular string literal will undergo string interpolation. For
example:

constexpr constexpr_string my_func() {return "bar";}

constexpr auto foo = "text {"cs + my_func() + "} moar text"cs;

std::concat(<insert interpolation syntax> foo);

Here, none of the individual literals constitute a whole string to be
interpolated. Only after concatenating the literals into a constexpr string
can you get interpolation working.

but in terms of e.g. allowing some constexpr string replacement, or other
> more advanced string processing, I think it just adds more implementation
> complexity and it could lead to some pretty dodgy practices (though it
> would be a code obfuscator's goldmine).
>

Whether it happens or not isn't really my concern at present. I'd like it
to happen, but that's contingent on how constexpr strings work out.

What I'm concerned about is design decisions that make it *impossible* to
ever go this route. And it's hard to see how allowing arbitrary expressions
would not make it impossible. If you limit it to just variable names, then
it comes back into the realm of the possible.

It also minimizes the "pretty dodgy practices" you could pull off with it.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/138fc3e9-8538-4ae0-8912-1a1e3d003c5f%40isocpp.org.

------=_Part_2627_175020389.1518751071827
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Thursday, February 15, 2018 at 9:52:50 PM UTC-5, Jake A=
rkinstall 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"au=
to"><div dir=3D"auto"><div class=3D"gmail_quote">On 16 Feb 2018 01:32, &quo=
t;Nicol Bolas&quot; &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfus=
cated-mailto=3D"0eHufQ4DCwAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&=
#39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&=
#39;;return true;">jmck...@gmail.com</a>&gt; wrote:<br type=3D"attribution"=
><blockquote style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-=
left:1ex"><div dir=3D"ltr"><div>My feeling is that you have to pick one or =
the other: you either allow=20
arbitrary expressions or you allow constexpr string interpolation. And=20
if we can only have one, I&#39;d much rather have the latter.</div><div><br=
>I want constexpr strings to be equivalent to literals as much as possible.=
</div></div></blockquote></div></div><div dir=3D"auto"><br></div><div dir=
=3D"auto">I agree here. We can get something along the lines of an addition=
 operator that acts in the same way as concatenation - so we could have you=
r example by performing the interpolation and concatenating the results,</d=
iv></div></blockquote><div><br>... I don&#39;t understand what you mean by =
that. Remember: string interpolation (in this design) doesn&#39;t &quot;con=
catenate&quot; anything. Only the function call performs that operation. An=
d in my example, `my_func` returns a single string, not multiple strings.<b=
r><br>It&#39;s not clear how what you&#39;re talking about solves the probl=
em of using arbitrary expressions. You cannot tell at the time macro expans=
ion happens whether a particular string literal will undergo string interpo=
lation. For example:<br><br><div style=3D"background-color: rgb(250, 250, 2=
50); border-color: rgb(187, 187, 187); border-style: solid; border-width: 1=
px; overflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"pretty=
print"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"=
styled-by-prettify">constexpr</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> constexpr_string my_func</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">()</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">{</span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">return</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #080;" class=3D"styled-by-prettify">&quot=
;bar&quot;</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
;}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">constexpr<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> foo </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: #080;" c=
lass=3D"styled-by-prettify">&quot;text {&quot;</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify">cs </span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">+</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> my_func</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"> </span>=
<span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;} moar text=
&quot;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">cs</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>std</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">concat</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(&lt;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">insert interpolation syntax</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> foo</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">);</span></div></code></div><br>=
Here, none of the individual literals constitute a whole string to be inter=
polated. Only after concatenating the literals into a constexpr string can =
you get interpolation working.<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;"><div dir=3D"auto"><div dir=3D"auto">but in terms of e.g. allo=
wing some constexpr string replacement, or other more advanced string proce=
ssing, I think it just adds more implementation complexity and it could lea=
d to some pretty dodgy practices (though it would be a code obfuscator&#39;=
s goldmine).</div></div></blockquote><div><br>Whether it happens or not isn=
&#39;t really my concern at present. I&#39;d like it to happen, but that&#3=
9;s contingent on how constexpr strings work out.<br><br>What I&#39;m conce=
rned about is design decisions that make it <i>impossible</i> to ever go th=
is route. And it&#39;s hard to see how allowing arbitrary expressions would=
 not make it impossible. If you limit it to just variable names, then it co=
mes back into the realm of the possible.<br><br>It also minimizes the &quot=
;pretty dodgy practices&quot; you could pull off with it.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/138fc3e9-8538-4ae0-8912-1a1e3d003c5f%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/138fc3e9-8538-4ae0-8912-1a1e3d003c5f=
%40isocpp.org</a>.<br />

------=_Part_2627_175020389.1518751071827--

------=_Part_2626_1966508890.1518751071826--

.


Author: Jake Arkinstall <jake.arkinstall@gmail.com>
Date: Fri, 16 Feb 2018 04:22:28 +0000
Raw View
--001a113d43e63aef5405654cb185
Content-Type: text/plain; charset="UTF-8"

I misread your example, but the comment holds if referring to getting the
same *outcome* and still using concatenation - not having the result being
a string, by instead allowing concatenation of interpolated results:

F"this is my var: {var}" + F", and this is my other var: {othervar}";

Equivalent to

F"this is my var: {var}, and this is my other var: {othervar}";

.... or maybe with an extra element if we opt *not* to go for the "the
first, last, and every other element, are always literals" approach.

So purely in the scope of concatenation of *self-contained* interpolated
expressions, we do have something to play with. I certainly didn't mean
arbitrary expressions, or handling of *incomplete* interpolated strings
concatenated into complete interpolated strings. That stuff would be nice,
but will need some very careful obstacle avoidance. If the order these
things get done is implementation-defined (that, I do not know, but will
aim to find out), then the more flexibility we aim for, the higher the
chances that there exists a compiler for which the proposal is incompatible
and their devs will push for a rejection.

*If it isn't* going to go down well, losing constexpr manipulation of the
input to the interpolation-handler is a shame but not the end of the world.
We may find a solution and add it as a secondary proposal at a later date -
the community having familiarity with the main proposal of just being able
to handle the simplest form might be enough persuasion to extend it.

On 16 Feb 2018 03:17, "Nicol Bolas" <jmckesson@gmail.com> wrote:

On Thursday, February 15, 2018 at 9:52:50 PM UTC-5, Jake Arkinstall wrote:

> On 16 Feb 2018 01:32, "Nicol Bolas" <jmck...@gmail.com> wrote:
>
> My feeling is that you have to pick one or the other: you either allow
> arbitrary expressions or you allow constexpr string interpolation. And if
> we can only have one, I'd much rather have the latter.
>
> I want constexpr strings to be equivalent to literals as much as possible.
>
>
> I agree here. We can get something along the lines of an addition operator
> that acts in the same way as concatenation - so we could have your example
> by performing the interpolation and concatenating the results,
>

.... I don't understand what you mean by that. Remember: string
interpolation (in this design) doesn't "concatenate" anything. Only the
function call performs that operation. And in my example, `my_func` returns
a single string, not multiple strings.

It's not clear how what you're talking about solves the problem of using
arbitrary expressions. You cannot tell at the time macro expansion happens
whether a particular string literal will undergo string interpolation. For
example:

constexpr constexpr_string my_func() {return "bar";}

constexpr auto foo = "text {"cs + my_func() + "} moar text"cs;

std::concat(<insert interpolation syntax> foo);

Here, none of the individual literals constitute a whole string to be
interpolated. Only after concatenating the literals into a constexpr string
can you get interpolation working.

but in terms of e.g. allowing some constexpr string replacement, or other
> more advanced string processing, I think it just adds more implementation
> complexity and it could lead to some pretty dodgy practices (though it
> would be a code obfuscator's goldmine).
>

Whether it happens or not isn't really my concern at present. I'd like it
to happen, but that's contingent on how constexpr strings work out.

What I'm concerned about is design decisions that make it *impossible* to
ever go this route. And it's hard to see how allowing arbitrary expressions
would not make it impossible. If you limit it to just variable names, then
it comes back into the realm of the possible.

It also minimizes the "pretty dodgy practices" you could pull off with it.

--
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/
isocpp.org/d/msgid/std-proposals/138fc3e9-8538-4ae0-
8912-1a1e3d003c5f%40isocpp.org
<https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/138fc3e9-8538-4ae0-8912-1a1e3d003c5f%40isocpp.org?utm_medium=email&utm_source=footer>
..

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCNGuh4ihhh9c%2BwO9M_RCRovOOeMasUqfdYb0sCPVJx10Q%40mail.gmail.com.

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

<div dir=3D"auto"><div>I misread your example, but the comment holds if ref=
erring to getting the same <i>outcome</i>=C2=A0and still using concatenatio=
n - not having the result being a string, by instead allowing concatenation=
 of interpolated results:</div><div dir=3D"auto"><br></div><div dir=3D"auto=
">F&quot;this is my var: {var}&quot; + F&quot;, and this is my other var: {=
othervar}&quot;;</div><div dir=3D"auto"><br></div><div dir=3D"auto">Equival=
ent to</div><div dir=3D"auto"><br></div><div dir=3D"auto">F&quot;this is my=
 var: {var}, and this is my other var: {othervar}&quot;;</div><div dir=3D"a=
uto"><br></div><div dir=3D"auto">... or maybe with an extra element if we o=
pt <i>not</i> to go for the &quot;the first, last, and every other element,=
 are always literals&quot; approach.</div><div dir=3D"auto"><br></div><div =
dir=3D"auto">So purely in the scope of concatenation of <u>self-contained</=
u> interpolated expressions, we do have something to play with. I certainly=
 didn&#39;t mean arbitrary expressions, or handling of <i>incomplete</i> in=
terpolated strings concatenated into complete interpolated strings. That st=
uff would be nice, but will need some very careful obstacle avoidance. If t=
he order these things get done is implementation-defined (that, I do not kn=
ow, but will aim to find out), then the more flexibility we aim for, the hi=
gher the chances that there exists a compiler for which the proposal is inc=
ompatible and their devs will push for a rejection.</div><div dir=3D"auto">=
<br></div><div dir=3D"auto"><i>If it isn&#39;t</i> going to go down well, l=
osing constexpr manipulation of the input to the interpolation-handler is a=
 shame but not the end of the world. We may find a solution and add it as a=
 secondary proposal at a later date - the community having familiarity with=
 the main proposal of just being able to handle the simplest form might be =
enough persuasion to extend it.</div><div dir=3D"auto"><div class=3D"gmail_=
extra" dir=3D"auto"><br><div class=3D"gmail_quote">On 16 Feb 2018 03:17, &q=
uot;Nicol Bolas&quot; &lt;<a href=3D"mailto:jmckesson@gmail.com">jmckesson@=
gmail.com</a>&gt; wrote:<br type=3D"attribution"><blockquote class=3D"quote=
" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><=
div dir=3D"ltr">On Thursday, February 15, 2018 at 9:52:50 PM UTC-5, Jake Ar=
kinstall wrote:<div class=3D"quoted-text"><blockquote class=3D"gmail_quote"=
 style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-lef=
t:1ex"><div dir=3D"auto"><div dir=3D"auto"><div class=3D"gmail_quote">On 16=
 Feb 2018 01:32, &quot;Nicol Bolas&quot; &lt;<a rel=3D"nofollow">jmck...@gm=
ail.com</a>&gt; wrote:<br type=3D"attribution"><blockquote style=3D"margin:=
0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><d=
iv>My feeling is that you have to pick one or the other: you either allow=
=20
arbitrary expressions or you allow constexpr string interpolation. And=20
if we can only have one, I&#39;d much rather have the latter.</div><div><br=
>I want constexpr strings to be equivalent to literals as much as possible.=
</div></div></blockquote></div></div><div dir=3D"auto"><br></div><div dir=
=3D"auto">I agree here. We can get something along the lines of an addition=
 operator that acts in the same way as concatenation - so we could have you=
r example by performing the interpolation and concatenating the results,</d=
iv></div></blockquote></div><div><br>... I don&#39;t understand what you me=
an by that. Remember: string interpolation (in this design) doesn&#39;t &qu=
ot;concatenate&quot; anything. Only the function call performs that operati=
on. And in my example, `my_func` returns a single string, not multiple stri=
ngs.<br><br>It&#39;s not clear how what you&#39;re talking about solves the=
 problem of using arbitrary expressions. You cannot tell at the time macro =
expansion happens whether a particular string literal will undergo string i=
nterpolation. For example:<br><br><div style=3D"background-color:rgb(250,25=
0,250);border-color:rgb(187,187,187);border-style:solid;border-width:1px" c=
lass=3D"m_1374652734628771457prettyprint"><code class=3D"m_1374652734628771=
457prettyprint"><div class=3D"m_1374652734628771457subprettyprint"><span st=
yle=3D"color:#008" class=3D"m_1374652734628771457styled-by-prettify">conste=
xpr</span><span style=3D"color:#000" class=3D"m_1374652734628771457styled-b=
y-prettify"> constexpr_string my_func</span><span style=3D"color:#660" clas=
s=3D"m_1374652734628771457styled-by-prettify">()</span><span style=3D"color=
:#000" class=3D"m_1374652734628771457styled-by-prettify"> </span><span styl=
e=3D"color:#660" class=3D"m_1374652734628771457styled-by-prettify">{</span>=
<span style=3D"color:#008" class=3D"m_1374652734628771457styled-by-prettify=
">return</span><span style=3D"color:#000" class=3D"m_1374652734628771457sty=
led-by-prettify"> </span><span style=3D"color:#080" class=3D"m_137465273462=
8771457styled-by-prettify">&quot;bar&quot;</span><span style=3D"color:#660"=
 class=3D"m_1374652734628771457styled-by-prettify">;}</span><span style=3D"=
color:#000" class=3D"m_1374652734628771457styled-by-prettify"><br><br></spa=
n><span style=3D"color:#008" class=3D"m_1374652734628771457styled-by-pretti=
fy">constexpr</span><span style=3D"color:#000" class=3D"m_13746527346287714=
57styled-by-prettify"> </span><span style=3D"color:#008" class=3D"m_1374652=
734628771457styled-by-prettify">auto</span><span style=3D"color:#000" class=
=3D"m_1374652734628771457styled-by-prettify"> foo </span><span style=3D"col=
or:#660" class=3D"m_1374652734628771457styled-by-prettify">=3D</span><span =
style=3D"color:#000" class=3D"m_1374652734628771457styled-by-prettify"> </s=
pan><span style=3D"color:#080" class=3D"m_1374652734628771457styled-by-pret=
tify">&quot;text {&quot;</span><span style=3D"color:#000" class=3D"m_137465=
2734628771457styled-by-prettify">cs </span><span style=3D"color:#660" class=
=3D"m_1374652734628771457styled-by-prettify">+</span><span style=3D"color:#=
000" class=3D"m_1374652734628771457styled-by-prettify"> my_func</span><span=
 style=3D"color:#660" class=3D"m_1374652734628771457styled-by-prettify">()<=
/span><span style=3D"color:#000" class=3D"m_1374652734628771457styled-by-pr=
ettify"> </span><span style=3D"color:#660" class=3D"m_1374652734628771457st=
yled-by-prettify">+</span><span style=3D"color:#000" class=3D"m_13746527346=
28771457styled-by-prettify"> </span><span style=3D"color:#080" class=3D"m_1=
374652734628771457styled-by-prettify">&quot;} moar text&quot;</span><span s=
tyle=3D"color:#000" class=3D"m_1374652734628771457styled-by-prettify">cs</s=
pan><span style=3D"color:#660" class=3D"m_1374652734628771457styled-by-pret=
tify">;</span><span style=3D"color:#000" class=3D"m_1374652734628771457styl=
ed-by-prettify"><br><br>std</span><span style=3D"color:#660" class=3D"m_137=
4652734628771457styled-by-prettify">::</span><span style=3D"color:#000" cla=
ss=3D"m_1374652734628771457styled-by-prettify">concat</span><span style=3D"=
color:#660" class=3D"m_1374652734628771457styled-by-prettify">(&lt;</span><=
span style=3D"color:#000" class=3D"m_1374652734628771457styled-by-prettify"=
>insert interpolation syntax</span><span style=3D"color:#660" class=3D"m_13=
74652734628771457styled-by-prettify">&gt;</span><span style=3D"color:#000" =
class=3D"m_1374652734628771457styled-by-prettify"> foo</span><span style=3D=
"color:#660" class=3D"m_1374652734628771457styled-by-prettify">);</span></d=
iv></code></div><br>Here, none of the individual literals constitute a whol=
e string to be interpolated. Only after concatenating the literals into a c=
onstexpr string can you get interpolation working.<br><br></div><div class=
=3D"quoted-text"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin=
-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"auto">=
<div dir=3D"auto">but in terms of e.g. allowing some constexpr string repla=
cement, or other more advanced string processing, I think it just adds more=
 implementation complexity and it could lead to some pretty dodgy practices=
 (though it would be a code obfuscator&#39;s goldmine).</div></div></blockq=
uote></div><div><br>Whether it happens or not isn&#39;t really my concern a=
t present. I&#39;d like it to happen, but that&#39;s contingent on how cons=
texpr strings work out.<br><br>What I&#39;m concerned about is design decis=
ions that make it <i>impossible</i> to ever go this route. And it&#39;s har=
d to see how allowing arbitrary expressions would not make it impossible. I=
f you limit it to just variable names, then it comes back into the realm of=
 the possible.<br><br>It also minimizes the &quot;pretty dodgy practices&qu=
ot; you could pull off with it.<br></div></div><div class=3D"quoted-text">

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></div>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/138fc3e9-8538-4ae0-8912-1a1e3d003c5f%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/138f=
c3e9-8538-4ae0-<wbr>8912-1a1e3d003c5f%40isocpp.org</a><wbr>.<br>
</blockquote></div><br></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCNGuh4ihhh9c%2BwO9M_RCRovOOeM=
asUqfdYb0sCPVJx10Q%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCNGuh=
4ihhh9c%2BwO9M_RCRovOOeMasUqfdYb0sCPVJx10Q%40mail.gmail.com</a>.<br />

--001a113d43e63aef5405654cb185--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 15 Feb 2018 22:02:35 -0800 (PST)
Raw View
------=_Part_2968_1348391206.1518760955956
Content-Type: multipart/alternative;
 boundary="----=_Part_2969_465134462.1518760955956"

------=_Part_2969_465134462.1518760955956
Content-Type: text/plain; charset="UTF-8"

On Thursday, February 15, 2018 at 11:22:31 PM UTC-5, Jake Arkinstall wrote:
>
> I misread your example, but the comment holds if referring to getting the
> same *outcome* and still using concatenation - not having the result
> being a string, by instead allowing concatenation of interpolated results:
>

> F"this is my var: {var}" + F", and this is my other var: {othervar}";
>
> Equivalent to
>
> F"this is my var: {var}, and this is my other var: {othervar}";
>

But that won't be equivalent to `F"{" + F"other" + F"}"`; string
interpolation is not associative. Nor does it address more complex
constexpr string manipulation, like removing characters, splicing different
fragments of strings together, and so forth.

And none of that changes the fact that macro expansion *already happened*,
and those strings were not included. How do you make macro expansion happen
after it has already happened?

That's the question.

.... or maybe with an extra element if we opt *not* to go for the "the
> first, last, and every other element, are always literals" approach.
>
> So purely in the scope of concatenation of *self-contained* interpolated
> expressions, we do have something to play with. I certainly didn't mean
> arbitrary expressions, or handling of *incomplete* interpolated strings
> concatenated into complete interpolated strings. That stuff would be nice,
> but will need some very careful obstacle avoidance. If the order these
> things get done is implementation-defined (that, I do not know, but will
> aim to find out), then the more flexibility we aim for, the higher the
> chances that there exists a compiler for which the proposal is incompatible
> and their devs will push for a rejection.
>
> *If it isn't* going to go down well, losing constexpr manipulation of the
> input to the interpolation-handler is a shame but not the end of the world.
> We may find a solution and add it as a secondary proposal at a later date -
> the community having familiarity with the main proposal of just being able
> to handle the simplest form might be enough persuasion to extend it.
>

We don't want to get locked into a design decision (using arbitrary
expressions in interpolation) that prevents us from adding new features
(constexpr string interpolation). That's why it's important to think about
what might be *before* deciding on what has to happen now.

Imagine if `constexpr` functions had been declared in C++11 such that it
would be difficult or impossible to later for C++14 to come along and
expand on them. Maybe they used non-standard syntax or something. Even if
it were a workable design, it wouldn't be a good one because it wouldn't be
easily extensible to features that we would reasonably find useful.

If we decide later on that arbitrary expressions are more important than
constexpr string interpolation, or if it's found that the two don't
interfere as much as I think, then we can expand on that. But once
arbitrary expressions are there, they're *there*, and there's no way to
restrict them back to something more constexpr-able.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/2a035024-304f-45d6-ac03-ad13e7848b9e%40isocpp.org.

------=_Part_2969_465134462.1518760955956
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Thursday, February 15, 2018 at 11:22:31 PM UTC-5, Jake =
Arkinstall wrote:<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"a=
uto"><div>I misread your example, but the comment holds if referring to get=
ting the same <i>outcome</i>=C2=A0and still using concatenation - not havin=
g the result being a string, by instead allowing concatenation of interpola=
ted results:</div></div></blockquote><blockquote class=3D"gmail_quote" styl=
e=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left:=
 1ex;"><div dir=3D"auto"><div dir=3D"auto"><br></div><div dir=3D"auto">F&qu=
ot;this is my var: {var}&quot; + F&quot;, and this is my other var: {otherv=
ar}&quot;;</div><div dir=3D"auto"><br></div><div dir=3D"auto">Equivalent to=
</div><div dir=3D"auto"><br></div><div dir=3D"auto">F&quot;this is my var: =
{var}, and this is my other var: {othervar}&quot;;</div></div></blockquote>=
<div><br>But that won&#39;t be equivalent to `F&quot;{&quot; + F&quot;other=
&quot; + F&quot;}&quot;`; string interpolation is not associative. Nor does=
 it address more complex constexpr string manipulation, like removing chara=
cters, splicing different fragments of strings together, and so forth.<br><=
br>And none of that changes the fact that macro expansion <i>already happen=
ed</i>, and those strings were not included. How do you make macro expansio=
n happen after it has already happened?<br><br>That&#39;s the question.<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"auto"><d=
iv dir=3D"auto"></div><div dir=3D"auto">... or maybe with an extra element =
if we opt <i>not</i> to go for the &quot;the first, last, and every other e=
lement, are always literals&quot; approach.</div><div dir=3D"auto"><br></di=
v><div dir=3D"auto">So purely in the scope of concatenation of <u>self-cont=
ained</u> interpolated expressions, we do have something to play with. I ce=
rtainly didn&#39;t mean arbitrary expressions, or handling of <i>incomplete=
</i> interpolated strings concatenated into complete interpolated strings. =
That stuff would be nice, but will need some very careful obstacle avoidanc=
e. If the order these things get done is implementation-defined (that, I do=
 not know, but will aim to find out), then the more flexibility we aim for,=
 the higher the chances that there exists a compiler for which the proposal=
 is incompatible and their devs will push for a rejection.</div><div dir=3D=
"auto"><br></div><div dir=3D"auto"><i>If it isn&#39;t</i> going to go down =
well, losing constexpr manipulation of the input to the interpolation-handl=
er is a shame but not the end of the world. We may find a solution and add =
it as a secondary proposal at a later date - the community having familiari=
ty with the main proposal of just being able to handle the simplest form mi=
ght be enough persuasion to extend it.</div></div></blockquote><div><br>We =
don&#39;t want to get locked into a design decision (using arbitrary expres=
sions in interpolation) that prevents us from adding new features (constexp=
r string interpolation). That&#39;s why it&#39;s important to think about w=
hat might be <i>before</i> deciding on what has to happen now.<br><br>Imagi=
ne if `constexpr` functions had been declared in C++11 such that it would b=
e difficult or impossible to later for C++14 to come along and expand on th=
em. Maybe they used non-standard syntax or something. Even if it were a wor=
kable design, it wouldn&#39;t be a good one because it wouldn&#39;t be easi=
ly extensible to features that we would reasonably find useful.</div><br>If=
 we decide later on that arbitrary expressions are more important than cons=
texpr string interpolation, or if it&#39;s found that the two don&#39;t int=
erfere as much as I think, then we can expand on that. But once arbitrary e=
xpressions are there, they&#39;re <i>there</i>, and there&#39;s no way to r=
estrict them back to something more constexpr-able.<br></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/2a035024-304f-45d6-ac03-ad13e7848b9e%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/2a035024-304f-45d6-ac03-ad13e7848b9e=
%40isocpp.org</a>.<br />

------=_Part_2969_465134462.1518760955956--

------=_Part_2968_1348391206.1518760955956--

.


Author: Florian Lemaitre <florian.csdt@gmail.com>
Date: Fri, 16 Feb 2018 10:18:37 +0100
Raw View
--001a114bb2645977e5056550d40c
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

2018-02-16 2:32 GMT+01:00 Nicol Bolas <jmckesson@gmail.com>:

>
>
> On Thursday, February 15, 2018 at 5:54:14 PM UTC-5, Florian Lemaitre wrot=
e:
>>
>> On 15/02/2018 20:39, Nicol Bolas wrote:
>>
>> On Thursday, February 15, 2018 at 11:33:26 AM UTC-5, floria...@gmail.com
>> wrote:
>>>
>>> Le jeudi 15 f=C3=A9vrier 2018 17:19:29 UTC+1, Nicol Bolas a =C3=A9crit =
:
>>>>
>>>> On Thursday, February 15, 2018 at 11:06:10 AM UTC-5, Jake Arkinstall
>>>> wrote:
>>>>>
>>>>> On 15 Feb 2018 15:51, "Nicol Bolas" <jmck...@gmail.com> wrote:
>>>>>
>>>>> Taking a literal (or possibly constexpr string?)
>>>>>
>>>>>
>>>>> I was wondering whether it makes sense to even describe these things
>>>>> as literals, given that they aren't literal and given that they aren'=
t
>>>>> intended to actually be stored in memory in any way.
>>>>>
>>>>
>>>> We still call literals "literals", even if you use them entirely at
>>>> compile-time via `constexpr` tricks, such that no runtime code ever ne=
eds
>>>> them. Things between quotes are literals.
>>>>
>>>> But in terms of constexpr strings, I guess these things themselves can
>>>>> be built up by other methods - I'm not sure if this makes sense in
>>>>> compilation, though; I'm under the impression that the expression its=
elf
>>>>> would likely need to be processed before the constexpr methods themse=
lves
>>>>> could be evaluated (especially given that they could themselves utili=
se
>>>>> interpolation). I could be wrong.
>>>>>
>>>>> I think, at this point, interpolation is a bad word - it made sense i=
n
>>>>> the initial form, but now this has generalised we might want a new wo=
rd for
>>>>> it.
>>>>>
>>>>
>>>> I don't agree. "String interpolation" often carries the connotation
>>>> that you're just going to concatenate strings, but it doesn't *have*
>>>> to. C++ sometimes defines concepts with names that are similar to othe=
r
>>>> language features, but in a more open and freeform way. Lambdas for ex=
ample
>>>> don't have lexical scoping in C++ unless you explicitly ask for them,
>>>> whereas most languages give it to you as a matter of course.
>>>>
>>>> (or possibly arbitrary expressions?)
>>>>>
>>>>>
>>>>> This wouldn't be so much of a problem, because those expressions
>>>>> (other than their declarations) don't need to be completely understoo=
d when
>>>>> the [insert better name for interpolation] is performed - just the
>>>>> resulting type is needed.
>>>>>
>>>>
>>>> The issue with "arbitrary expression" is that you're now requiring the
>>>> compiler to *invoke the compiler*. It's easy for the compiler to take
>>>> a compile-time string and find a variable in scope that matches it. It=
's
>>>> much harder (presumably) for the compiler to take a compile-time strin=
g and
>>>> invoke the compiler on it, within the current scope as if it had been
>>>> written text.
>>>>
>>>> I'm not saying its impossible; I don't know much about compiler
>>>> architecture. But I can't imagine it's as easy as just finding a varia=
ble
>>>> with that name.
>>>>
>>>> Not only that, once you get into wanting `constexpr` strings that can
>>>> be interpolated, you get into lots of issues. Do you really want a fea=
ture
>>>> where you're able to synthesize arbitrary expressions and have someone
>>>> insinuate them into their code at compile time?
>>>>
>>>> Or... maybe you do?
>>>>
>>>
>>> From what I know about compilation and formal languages in general, it
>>> shouldn't be very hard for a compiler to deal with expressions within
>>> `F"{}"`.
>>> The compiler already do that kind of stuff with parentheses. Compilers
>>> are by nature recursive.
>>>
>>
>> You don't seem to be fully understanding what we're talking about. This
>> isn't standard recursive-descent recursion. This is "execute some conste=
xpr
>> code and then run the compiler on part of its string results." Those
>> "results" might include things like *macros*, and macro expansion is
>> supposed to have happened long before executing constexpr functions.
>>
>> And you can't just say they're expressions minus macros. Many C-standard
>> library facilities are, or might be, macros after all. Is it legal to do
>> `F"{sin(foo)}"`? If string interpolation is supposed to allow arbitrary
>> expressions, it would be odd indeed if it were not. What about invoking
>> `offsetof` or similar C-isms?
>>
>> If we're only going to allow string interpolation with genuine literals,
>> then this isn't much of a problem. Even the macro issue can be sorted ou=
t,
>> since the string is right there in the text of the source code.
>>
>> But if we want string interpolation to ever be applied to the results of
>> compile-time execution, that's going to be *much* more complex if string
>> interpolation can handle arbitrary expressions. Whereas if we define it =
to
>> just be variable identifiers, extending such interpolation to constexpr
>> strings would be much more reasonable.
>>
>> I would say that any proposal should be focused on the minimum
>> featureset. It should naturally include expanding into arbitrary
>> expressions and constexpr strings as future directions things could take=
,
>> but I wouldn't push for them in the short term. Sort of like how
>> `constexpr` functions in C++11 were really limited, which C++14 greatly
>> expanded.
>>
>> The only thing I don't know is if the compiler deals with string literal=
s
>>> as a single token or not. If they do, string literal parser will have t=
o be
>>> modified quite a lot, even with the "identifier-only" variant.
>>>
>>
>> First thing first, currently the C++ is oblivious to the preprocessor,
>> and this will probably not change in the forseeable future (note that th=
e
>> preprocessor is somehow aware of C++: __cplusplus macro, #include,
>> __has_cpp_attribute...).
>> But as far as the compiler is concerned, these are two distinct steps
>> that are processed one after the other, without going back.
>>
>> Maybe you want to change that, but I think you were mentionning macros
>> taking effect within F"{}".
>>
>
> No, I'm mentioning macros taking effect within *string interpolation*.
>
> We're talking about the intersection of two things, both of which are
> still in question:
>
> 1) Arbitrary expressions in interpolation operations.
> 2) The use of constexpr strings as the *source* for interpolation
> operations; as the string to be interpolated. That is:
>
> constexpr constexpr_string<char> my_func()
> {
>   constexpr_string<char> a =3D "here's a string {sin(5)}"; //Note: not
> doing interpolation.
>   constexpr_string<char> b =3D " more {foo} string"; //Still not
> interpolating.
>   return a + b;
> }
>
> auto str =3D std::concat(<interpolation syntax> my_func());
>
> //The above is equivalent to:
>
> auto str =3D std::concat("here's a string", sin(5), " more ", foo, " stri=
ng"
> );
>
> It's the *combination* of these two things that doesn't work. By the time
> the compiler gets around to actually processing the `my_func` call, macro
> expansion has come and gone. So how does `sin(5)` get expanded properly?
>
> And I know you're thinking that constexpr strings don't exist, that
> they're not even really possible. Yet; the committee is working on
> expansions to constexpr that allow memory allocation. Once that happens, =
we
> will have constexpr strings. And once we do, there's no reason you should
> prevent constexpr strings from being the source of interpolation operatio=
ns.
>
> Well, no reason unless you sandbag interpolation by requiring it to allow
> arbitrary expressions. My feeling is that you have to pick one or the
> other: you either allow arbitrary expressions or you allow constexpr stri=
ng
> interpolation. And if we can only have one, I'd much rather have the latt=
er.
>
> I want constexpr strings to be equivalent to literals as much as possible=
..
>
> I get your problem now.
Just to simplify my explanations, let's assume that string interpolation is
done via a prefix operator called $.

You want to be able to call $ on any constexpr string, and also it would be
nice to also have expressions in the interpolation pattern. But as you
said, having both would trigger the compiler on compiler output, and this
would be difficult to handle.
I now agree with you on the complexity of having both.

What you're describing here looks like some compile-time "eval".
constexpr auto call_foo =3D "{foo()}";

// eval:
$ call_foo;
// translated to:
foo();

This looks nasty.
It would be possible to leak local variables:
int super_private_copy;

auto foo(/*whatever equivalent to string literal*/ s) {
  int super_private =3D 5;
  return std::concat($ s);
}

void bar() {
  foo("{super_private_copy =3D super_private}");
  std::cout << "super_private: " << super_private_copy << std::endl;
}

This little fictive example shows how this would be possible with those
assumptions. And this intrinsically bad, independently to the
implementation complexity.
The outer world should not affect a private scope without its consent. (so
this does not apply if some global is used within the private scope: in
that case, the access to the global is consented by the private scope)


So definitely, having both string interpolation pattern from constexpr
strings *and* expressions can be interpolated is conceptually bad.

So let's consider only string interpolation pattern from constexpr strings.
This also breaks private scope (more tricky though).
// intended to use access1, access2, access3 or access4 as pattern
auto foo(/*whatever equivalent to string literal*/ s) {
  int super_secret =3D 5;
  int access1 =3D 1;
  int access2 =3D 2;
  int access3 =3D 3;
  int access4 =3D 4;
  return std::make_tuple($ s);
}

void bar() {
  auto super_secret =3D std::get<0>(foo("{super_secret}"));
  std::cout << "super_secret: " << super_secret << std::endl;
}

Yes, this example is more convoluted, but it still shows what is possible
to do.

Another thing that could be a problem: what happens if a variable is not
declared? It probably should not compile.
But then we could have pretty complex and hard to debug code:
constexpr auto foo(int i); // returns a "string literal"-like that has the
form "{foo###}" where ### is the i-th prime number

void bar() {
  int foo3 =3D 0;
  do_whatever($ foo(2));
} // This compiles

void baz() {
  int foo4 =3D 0;
  do_whatever($ foo(2));
} // This doesn't compile (obviously)

Why is it different than just access a global variable with the right name?
There is no way to know what variables are needed in order to compile other
than trying to compile the program.
The identifier foo3 is never defined, and never appears in the code (except
within your function).
Moreover, your local scope now is entangled with the value returned by
foo(). (this kind of breaks encapsulation of the local scope)

Maybe your fine with this one, but I'm not. That's why I think string
interpolation should not apply to constexpr strings (at least, not the
interpolation pattern).

Don't get me wrong: I am perfectly fine to standardize only string
interpolation on actual string literal with only identifiers in patterns,
and see later how to improve it.
But as far as I'm concerned, I think interpolating constexpr patterns is a
bad idea and I would much prefer arbitrary expressions to be interpolated.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CANaF6iikVH-jjGFxx2whvec%3DwcRPeXDwTZSevxD9anWhY=
9zh0g%40mail.gmail.com.

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">=
2018-02-16 2:32 GMT+01:00 Nicol Bolas <span dir=3D"ltr">&lt;<a href=3D"mail=
to:jmckesson@gmail.com" target=3D"_blank">jmckesson@gmail.com</a>&gt;</span=
>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div class=3D"h5=
"><br><br>On Thursday, February 15, 2018 at 5:54:14 PM UTC-5, Florian Lemai=
tre wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0=
..8ex;border-left:1px #ccc solid;padding-left:1ex">
 =20
   =20
 =20
  <div text=3D"#000000" bgcolor=3D"#FFFFFF">
    On 15/02/2018 20:39, Nicol Bolas wrote:<br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">On Thursday, February 15, 2018 at 11:33:26 AM
        UTC-5, <a>floria...@gmail.com</a> wrote:
        <blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex">
          <div dir=3D"ltr">Le jeudi 15 f=C3=A9vrier 2018 17:19:29 UTC+1, Ni=
col
            Bolas a =C3=A9crit=C2=A0:
            <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 Thursday, February 15, 2018 at 11:06:10
                AM UTC-5, Jake Arkinstall 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"auto">
                    <div>
                      <div>
                        <div class=3D"gmail_quote">On 15 Feb 2018 15:51,
                          &quot;Nicol Bolas&quot; &lt;<a rel=3D"nofollow">j=
mck...@gmail.com</a>&gt;
                          wrote:<br type=3D"attribution">
                          <blockquote style=3D"margin:0 0 0 .8ex;border-lef=
t:1px #ccc solid;padding-left:1ex">
                            <div dir=3D"ltr">
                              <div>Taking a literal (or possibly
                                constexpr string?)</div>
                            </div>
                          </blockquote>
                        </div>
                      </div>
                    </div>
                    <div dir=3D"auto"><br>
                    </div>
                    <div dir=3D"auto">I was wondering whether it makes
                      sense to even describe these things as literals,
                      given that they aren&#39;t literal and given that the=
y
                      aren&#39;t intended to actually be stored in memory i=
n
                      any way.</div>
                  </div>
                </blockquote>
                <div><br>
                  We still call literals &quot;literals&quot;, even if you =
use
                  them entirely at compile-time via `constexpr` tricks,
                  such that no runtime code ever needs them. Things
                  between quotes are literals.<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"auto">
                    <div dir=3D"auto">But in terms of constexpr strings, I
                      guess these things themselves can be built up by
                      other methods - I&#39;m not sure if this makes sense
                      in compilation, though; I&#39;m under the impression
                      that the expression itself would likely need to be
                      processed before the constexpr methods themselves
                      could be evaluated (especially given that they
                      could themselves utilise interpolation). I could
                      be wrong.</div>
                    <div dir=3D"auto"><br>
                    </div>
                    <div dir=3D"auto">I think, at this point,
                      interpolation is a bad word - it made sense in the
                      initial form, but now this has generalised we
                      might want a new word for it.</div>
                  </div>
                </blockquote>
                <div><br>
                  I don&#39;t agree. &quot;String interpolation&quot; often=
 carries
                  the connotation that you&#39;re just going to concatenate
                  strings, but it doesn&#39;t <i>have</i> to. C++ sometimes
                  defines concepts with names that are similar to other
                  language features, but in a more open and freeform
                  way. Lambdas for example don&#39;t have lexical scoping i=
n
                  C++ unless you explicitly ask for them, whereas most
                  languages give it to you as a matter of course.<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"auto">
                    <div dir=3D"auto">
                      <div>
                        <div class=3D"gmail_quote">
                          <blockquote style=3D"margin:0 0 0 .8ex;border-lef=
t:1px #ccc solid;padding-left:1ex">
                            <div dir=3D"ltr">
                              <div>(or possibly arbitrary expressions?)</di=
v>
                            </div>
                          </blockquote>
                        </div>
                      </div>
                    </div>
                    <div dir=3D"auto"><br>
                    </div>
                    <div dir=3D"auto">This wouldn&#39;t be so much of a
                      problem, because those expressions (other than
                      their declarations) don&#39;t need to be completely
                      understood when the [insert better name for
                      interpolation] is performed - just the resulting
                      type is needed.</div>
                  </div>
                </blockquote>
                <div><br>
                  The issue with &quot;arbitrary expression&quot; is that y=
ou&#39;re
                  now requiring the compiler to <i>invoke the compiler</i>.
                  It&#39;s easy for the compiler to take a compile-time
                  string and find a variable in scope that matches it.
                  It&#39;s much harder (presumably) for the compiler to tak=
e
                  a compile-time string and invoke the compiler on it,
                  within the current scope as if it had been written
                  text.<br>
                  <br>
                  I&#39;m not saying its impossible; I don&#39;t know much =
about
                  compiler architecture. But I can&#39;t imagine it&#39;s a=
s
                  easy as just finding a variable with that name.<br>
                  <br>
                  Not only that, once you get into wanting `constexpr`
                  strings that can be interpolated, you get into lots of
                  issues. Do you really want a feature where you&#39;re abl=
e
                  to synthesize arbitrary expressions and have someone
                  insinuate them into their code at compile time?<br>
                  <br>
                  Or... maybe you do?<br>
                </div>
              </div>
            </blockquote>
            <div><br>
            </div>
            <div>From what I know about compilation and formal languages
              in general, it shouldn&#39;t be very hard for a compiler to
              deal with expressions within `F&quot;{}&quot;`.</div>
            <div>The compiler already do that kind of stuff with
              parentheses. Compilers are by nature recursive.</div>
          </div>
        </blockquote>
        <div><br>
          You don&#39;t seem to be fully understanding what we&#39;re talki=
ng
          about. This isn&#39;t standard recursive-descent recursion. This
          is &quot;execute some constexpr code and then run the compiler on
          part of its string results.&quot; Those &quot;results&quot; might=
 include
          things like <i>macros</i>, and macro expansion is supposed to
          have happened long before executing constexpr functions.<br>
          <br>
          And you can&#39;t just say they&#39;re expressions minus macros. =
Many
          C-standard library facilities are, or might be, macros after
          all. Is it legal to do `F&quot;{sin(foo)}&quot;`? If string
          interpolation is supposed to allow arbitrary expressions, it
          would be odd indeed if it were not. What about invoking
          `offsetof` or similar C-isms?<br>
          <br>
          If we&#39;re only going to allow string interpolation with genuin=
e
          literals, then this isn&#39;t much of a problem. Even the macro
          issue can be sorted out, since the string is right there in
          the text of the source code.<br>
          <br>
          But if we want string interpolation to ever be applied to the
          results of compile-time execution, that&#39;s going to be <i>much=
</i>
          more complex if string interpolation can handle arbitrary
          expressions. Whereas if we define it to just be variable
          identifiers, extending such interpolation to constexpr strings
          would be much more reasonable.<br>
          <br>
          I would say that any proposal should be focused on the minimum
          featureset. It should naturally include expanding into
          arbitrary expressions and constexpr strings as future
          directions things could take, but I wouldn&#39;t push for them in
          the short term. Sort of like how `constexpr` functions in
          C++11 were really limited, which C++14 greatly expanded.<br>
          <br>
        </div>
        <blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex">
          <div dir=3D"ltr">
            <div>The only thing I don&#39;t know is if the compiler deals
              with string literals as a single token or not. If they do,
              string literal parser will have to be modified quite a
              lot, even with the &quot;identifier-only&quot; variant.<br>
            </div>
          </div>
        </blockquote>
      </div>
    </blockquote>
    <br>
    <div>First thing first, currently the C++ is oblivious to the
      preprocessor, and this will probably not change in the forseeable
      future (note that the preprocessor is somehow aware of C++:
      __cplusplus macro, #include, __has_cpp_attribute...).</div>
    <div>But as far as the compiler is concerned, these are two distinct
      steps that are processed one after the other, without going back.</di=
v>
    <div><br>
    </div>
    <div>Maybe you want to change that, but I think you were mentionning
      macros taking effect within F&quot;{}&quot;.</div></div></blockquote>=
</div></div><div><br>No, I&#39;m mentioning macros taking effect within <i>=
string interpolation</i>.<br><br>We&#39;re talking about the intersection o=
f two things, both of which are still in question:<br><br>1) Arbitrary expr=
essions in interpolation operations.<br>2) The use of constexpr strings as =
the <i>source</i> for interpolation operations; as the string to be interpo=
lated. That is:<br><br><div style=3D"background-color:rgb(250,250,250);bord=
er-color:rgb(187,187,187);border-style:solid;border-width:1px" class=3D"m_-=
2383486546040809004prettyprint"><code class=3D"m_-2383486546040809004pretty=
print"><div class=3D"m_-2383486546040809004subprettyprint"><span style=3D"c=
olor:#008" class=3D"m_-2383486546040809004styled-by-prettify">constexpr</sp=
an><span style=3D"color:#000" class=3D"m_-2383486546040809004styled-by-pret=
tify"> constexpr_string</span><span style=3D"color:#080" class=3D"m_-238348=
6546040809004styled-by-prettify">&lt;char&gt;</span><span style=3D"color:#0=
00" class=3D"m_-2383486546040809004styled-by-prettify"> my_func</span><span=
 style=3D"color:#660" class=3D"m_-2383486546040809004styled-by-prettify">()=
</span><span style=3D"color:#000" class=3D"m_-2383486546040809004styled-by-=
prettify"><br></span><span style=3D"color:#660" class=3D"m_-238348654604080=
9004styled-by-prettify">{</span><span style=3D"color:#000" class=3D"m_-2383=
486546040809004styled-by-prettify"><br>=C2=A0 constexpr_string</span><span =
style=3D"color:#080" class=3D"m_-2383486546040809004styled-by-prettify">&lt=
;char&gt;</span><span style=3D"color:#000" class=3D"m_-2383486546040809004s=
tyled-by-prettify"> a </span><span style=3D"color:#660" class=3D"m_-2383486=
546040809004styled-by-prettify">=3D</span><span style=3D"color:#000" class=
=3D"m_-2383486546040809004styled-by-prettify"> </span><span style=3D"color:=
#080" class=3D"m_-2383486546040809004styled-by-prettify">&quot;here&#39;s a=
 string {sin(5)}&quot;</span><span style=3D"color:#660" class=3D"m_-2383486=
546040809004styled-by-prettify">;</span><span style=3D"color:#000" class=3D=
"m_-2383486546040809004styled-by-prettify"> </span><span style=3D"color:#80=
0" class=3D"m_-2383486546040809004styled-by-prettify">//Note: not doing int=
erpolation.</span><span style=3D"color:#000" class=3D"m_-238348654604080900=
4styled-by-prettify"><br>=C2=A0 constexpr_string</span><span style=3D"color=
:#080" class=3D"m_-2383486546040809004styled-by-prettify">&lt;char&gt;</spa=
n><span style=3D"color:#000" class=3D"m_-2383486546040809004styled-by-prett=
ify"> b </span><span style=3D"color:#660" class=3D"m_-2383486546040809004st=
yled-by-prettify">=3D</span><span style=3D"color:#000" class=3D"m_-23834865=
46040809004styled-by-prettify"> </span><span style=3D"color:#080" class=3D"=
m_-2383486546040809004styled-by-prettify">&quot; more {foo} string&quot;</s=
pan><span style=3D"color:#660" class=3D"m_-2383486546040809004styled-by-pre=
ttify">;</span><span style=3D"color:#000" class=3D"m_-2383486546040809004st=
yled-by-prettify"> </span><span style=3D"color:#800" class=3D"m_-2383486546=
040809004styled-by-prettify">//Still not interpolating.</span><span style=
=3D"color:#000" class=3D"m_-2383486546040809004styled-by-prettify"><br>=C2=
=A0 </span><span style=3D"color:#008" class=3D"m_-2383486546040809004styled=
-by-prettify">return</span><span style=3D"color:#000" class=3D"m_-238348654=
6040809004styled-by-prettify"> a </span><span style=3D"color:#660" class=3D=
"m_-2383486546040809004styled-by-prettify">+</span><span style=3D"color:#00=
0" class=3D"m_-2383486546040809004styled-by-prettify"> b</span><span style=
=3D"color:#660" class=3D"m_-2383486546040809004styled-by-prettify">;</span>=
<span style=3D"color:#000" class=3D"m_-2383486546040809004styled-by-prettif=
y"><br></span><span style=3D"color:#660" class=3D"m_-2383486546040809004sty=
led-by-prettify">}</span><span style=3D"color:#000" class=3D"m_-23834865460=
40809004styled-by-prettify"><br><br></span><span style=3D"color:#008" class=
=3D"m_-2383486546040809004styled-by-prettify">auto</span><span style=3D"col=
or:#000" class=3D"m_-2383486546040809004styled-by-prettify"> str </span><sp=
an style=3D"color:#660" class=3D"m_-2383486546040809004styled-by-prettify">=
=3D</span><span style=3D"color:#000" class=3D"m_-2383486546040809004styled-=
by-prettify"> std</span><span style=3D"color:#660" class=3D"m_-238348654604=
0809004styled-by-prettify">::</span><span style=3D"color:#000" class=3D"m_-=
2383486546040809004styled-by-prettify">concat</span><span style=3D"color:#6=
60" class=3D"m_-2383486546040809004styled-by-prettify">(&lt;</span><span st=
yle=3D"color:#000" class=3D"m_-2383486546040809004styled-by-prettify">inter=
polation syntax</span><span style=3D"color:#660" class=3D"m_-23834865460408=
09004styled-by-prettify">&gt;</span><span style=3D"color:#000" class=3D"m_-=
2383486546040809004styled-by-prettify"> my_func</span><span style=3D"color:=
#660" class=3D"m_-2383486546040809004styled-by-prettify">());</span><span s=
tyle=3D"color:#000" class=3D"m_-2383486546040809004styled-by-prettify"><br>=
<br></span><span style=3D"color:#800" class=3D"m_-2383486546040809004styled=
-by-prettify">//The above is equivalent to:</span><span style=3D"color:#000=
" class=3D"m_-2383486546040809004styled-by-prettify"><br><br></span><span s=
tyle=3D"color:#008" class=3D"m_-2383486546040809004styled-by-prettify">auto=
</span><span style=3D"color:#000" class=3D"m_-2383486546040809004styled-by-=
prettify"> str </span><span style=3D"color:#660" class=3D"m_-23834865460408=
09004styled-by-prettify">=3D</span><span style=3D"color:#000" class=3D"m_-2=
383486546040809004styled-by-prettify"> std</span><span style=3D"color:#660"=
 class=3D"m_-2383486546040809004styled-by-prettify">::</span><span style=3D=
"color:#000" class=3D"m_-2383486546040809004styled-by-prettify">concat</spa=
n><span style=3D"color:#660" class=3D"m_-2383486546040809004styled-by-prett=
ify">(</span><span style=3D"color:#080" class=3D"m_-2383486546040809004styl=
ed-by-prettify">&quot;here&#39;s a string&quot;</span><span style=3D"color:=
#660" class=3D"m_-2383486546040809004styled-by-prettify">,</span><span styl=
e=3D"color:#000" class=3D"m_-2383486546040809004styled-by-prettify"> sin</s=
pan><span style=3D"color:#660" class=3D"m_-2383486546040809004styled-by-pre=
ttify">(</span><span style=3D"color:#066" class=3D"m_-2383486546040809004st=
yled-by-prettify">5</span><span style=3D"color:#660" class=3D"m_-2383486546=
040809004styled-by-prettify">),</span><span style=3D"color:#000" class=3D"m=
_-2383486546040809004styled-by-prettify"> </span><span style=3D"color:#080"=
 class=3D"m_-2383486546040809004styled-by-prettify">&quot; more &quot;</spa=
n><span style=3D"color:#660" class=3D"m_-2383486546040809004styled-by-prett=
ify">,</span><span style=3D"color:#000" class=3D"m_-2383486546040809004styl=
ed-by-prettify"> foo</span><span style=3D"color:#660" class=3D"m_-238348654=
6040809004styled-by-prettify">,</span><span style=3D"color:#000" class=3D"m=
_-2383486546040809004styled-by-prettify"> </span><span style=3D"color:#080"=
 class=3D"m_-2383486546040809004styled-by-prettify">&quot; string&quot;</sp=
an><span style=3D"color:#660" class=3D"m_-2383486546040809004styled-by-pret=
tify">);</span><span style=3D"color:#000" class=3D"m_-2383486546040809004st=
yled-by-prettify"><br></span></div></code></div><br>It&#39;s the <i>combina=
tion</i> of these two things that doesn&#39;t work. By the time the compile=
r gets around to actually processing the `my_func` call, macro expansion ha=
s come and gone. So how does `sin(5)` get expanded properly?<br><br>And I k=
now you&#39;re thinking that constexpr strings don&#39;t exist, that they&#=
39;re not even really possible. Yet; the committee is working on expansions=
 to constexpr that allow memory allocation. Once that happens, we will have=
 constexpr strings. And once we do, there&#39;s no reason you should preven=
t constexpr strings from being the source of interpolation operations.<br><=
br>Well, no reason unless you sandbag interpolation by requiring it to allo=
w arbitrary expressions. My feeling is that you have to pick one or the oth=
er: you either allow=20
arbitrary expressions or you allow constexpr string interpolation. And=20
if we can only have one, I&#39;d much rather have the latter.<br><br>I want=
 constexpr strings to be equivalent to literals as much as possible.<br></d=
iv><br></div></blockquote></div><div>I get your problem now.<br></div><div>=
Just to simplify my explanations, let&#39;s assume that string interpolatio=
n is done via a prefix operator called $.</div><div><br></div><div>You
 want to be able to call $ on any constexpr string, and also it would be
 nice to also have expressions in the interpolation pattern. But as you=20
said, having both would trigger the compiler on compiler output, and=20
this would be difficult to handle.</div><div>I now agree with you on the co=
mplexity of having both.</div><div><br></div><div>What you&#39;re describin=
g here looks like some compile-time &quot;eval&quot;.</div><div><div style=
=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-=
style:solid;border-width:1px" class=3D"gmail-prettyprint"><code class=3D"gm=
ail-prettyprint"><div class=3D"gmail-subprettyprint"><span style=3D"color:r=
gb(0,0,136)" class=3D"gmail-styled-by-prettify">constexpr</span><span style=
=3D"color:rgb(0,0,0)" class=3D"gmail-styled-by-prettify"> </span><span styl=
e=3D"color:rgb(0,0,136)" class=3D"gmail-styled-by-prettify">auto</span><spa=
n style=3D"color:rgb(0,0,0)" class=3D"gmail-styled-by-prettify"> call_foo <=
/span><span style=3D"color:rgb(102,102,0)" class=3D"gmail-styled-by-prettif=
y">=3D</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-styled-by-pret=
tify"> </span><span style=3D"color:rgb(0,136,0)" class=3D"gmail-styled-by-p=
rettify">&quot;{foo()}&quot;</span><span style=3D"color:rgb(102,102,0)" cla=
ss=3D"gmail-styled-by-prettify">;</span><span style=3D"color:rgb(0,0,0)" cl=
ass=3D"gmail-styled-by-prettify"><br><br></span><span style=3D"color:rgb(13=
6,0,0)" class=3D"gmail-styled-by-prettify">// eval:</span><span style=3D"co=
lor:rgb(0,0,0)" class=3D"gmail-styled-by-prettify"><br>$ call_foo</span><sp=
an style=3D"color:rgb(102,102,0)" class=3D"gmail-styled-by-prettify">;</spa=
n><span style=3D"color:rgb(0,0,0)" class=3D"gmail-styled-by-prettify"><br><=
/span><span style=3D"color:rgb(136,0,0)" class=3D"gmail-styled-by-prettify"=
>// translated to:</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-st=
yled-by-prettify"><br>foo</span><span style=3D"color:rgb(102,102,0)" class=
=3D"gmail-styled-by-prettify">();</span><span style=3D"color:rgb(0,0,0)" cl=
ass=3D"gmail-styled-by-prettify"><br></span></div></code></div><br>This loo=
ks nasty.<br></div><div>It would be possible to leak local variables:</div>=
<div><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,1=
87,187);border-style:solid;border-width:1px" class=3D"gmail-prettyprint"><c=
ode class=3D"gmail-prettyprint"><div class=3D"gmail-subprettyprint"><span s=
tyle=3D"color:rgb(0,0,136)" class=3D"gmail-styled-by-prettify">int</span><s=
pan style=3D"color:rgb(0,0,0)" class=3D"gmail-styled-by-prettify"> super_pr=
ivate_copy</span><span style=3D"color:rgb(102,102,0)" class=3D"gmail-styled=
-by-prettify">;</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-style=
d-by-prettify"><br><br></span><span style=3D"color:rgb(0,0,136)" class=3D"g=
mail-styled-by-prettify">auto</span><span style=3D"color:rgb(0,0,0)" class=
=3D"gmail-styled-by-prettify"> foo</span><span style=3D"color:rgb(102,102,0=
)" class=3D"gmail-styled-by-prettify">(</span><span style=3D"color:rgb(136,=
0,0)" class=3D"gmail-styled-by-prettify">/*whatever equivalent to string li=
teral*/</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-styled-by-pre=
ttify"> s</span><span style=3D"color:rgb(102,102,0)" class=3D"gmail-styled-=
by-prettify">)</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-styled=
-by-prettify"> </span><span style=3D"color:rgb(102,102,0)" class=3D"gmail-s=
tyled-by-prettify">{</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-=
styled-by-prettify"><br>=C2=A0 </span><span style=3D"color:rgb(0,0,136)" cl=
ass=3D"gmail-styled-by-prettify">int</span><span style=3D"color:rgb(0,0,0)"=
 class=3D"gmail-styled-by-prettify"> super_private </span><span style=3D"co=
lor:rgb(102,102,0)" class=3D"gmail-styled-by-prettify">=3D</span><span styl=
e=3D"color:rgb(0,0,0)" class=3D"gmail-styled-by-prettify"> </span><span sty=
le=3D"color:rgb(0,102,102)" class=3D"gmail-styled-by-prettify">5</span><spa=
n style=3D"color:rgb(102,102,0)" class=3D"gmail-styled-by-prettify">;</span=
><span style=3D"color:rgb(0,0,0)" class=3D"gmail-styled-by-prettify"><br>=
=C2=A0 </span><span style=3D"color:rgb(0,0,136)" class=3D"gmail-styled-by-p=
rettify">return</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-style=
d-by-prettify"> std</span><span style=3D"color:rgb(102,102,0)" class=3D"gma=
il-styled-by-prettify">::</span><span style=3D"color:rgb(0,0,0)" class=3D"g=
mail-styled-by-prettify">concat</span><span style=3D"color:rgb(102,102,0)" =
class=3D"gmail-styled-by-prettify">(</span><span style=3D"color:rgb(0,0,0)"=
 class=3D"gmail-styled-by-prettify">$ s</span><span style=3D"color:rgb(102,=
102,0)" class=3D"gmail-styled-by-prettify">);</span><span style=3D"color:rg=
b(0,0,0)" class=3D"gmail-styled-by-prettify"><br></span><span style=3D"colo=
r:rgb(102,102,0)" class=3D"gmail-styled-by-prettify">}</span><span style=3D=
"color:rgb(0,0,0)" class=3D"gmail-styled-by-prettify"><br><br></span><span =
style=3D"color:rgb(0,0,136)" class=3D"gmail-styled-by-prettify">void</span>=
<span style=3D"color:rgb(0,0,0)" class=3D"gmail-styled-by-prettify"> bar</s=
pan><span style=3D"color:rgb(102,102,0)" class=3D"gmail-styled-by-prettify"=
>()</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-styled-by-prettif=
y"> </span><span style=3D"color:rgb(102,102,0)" class=3D"gmail-styled-by-pr=
ettify">{</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-styled-by-p=
rettify"><br>=C2=A0 foo</span><span style=3D"color:rgb(102,102,0)" class=3D=
"gmail-styled-by-prettify">(</span><span style=3D"color:rgb(0,136,0)" class=
=3D"gmail-styled-by-prettify">&quot;{super_private_copy =3D super_private}&=
quot;</span><span style=3D"color:rgb(102,102,0)" class=3D"gmail-styled-by-p=
rettify">);</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-styled-by=
-prettify"><br>=C2=A0 std</span><span style=3D"color:rgb(102,102,0)" class=
=3D"gmail-styled-by-prettify">::</span><span style=3D"color:rgb(0,0,0)" cla=
ss=3D"gmail-styled-by-prettify">cout </span><span style=3D"color:rgb(102,10=
2,0)" class=3D"gmail-styled-by-prettify">&lt;&lt;</span><span style=3D"colo=
r:rgb(0,0,0)" class=3D"gmail-styled-by-prettify"> </span><span style=3D"col=
or:rgb(0,136,0)" class=3D"gmail-styled-by-prettify">&quot;super_private: &q=
uot;</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-styled-by-pretti=
fy"> </span><span style=3D"color:rgb(102,102,0)" class=3D"gmail-styled-by-p=
rettify">&lt;&lt;</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-sty=
led-by-prettify"> super_private_copy </span><span style=3D"color:rgb(102,10=
2,0)" class=3D"gmail-styled-by-prettify">&lt;&lt;</span><span style=3D"colo=
r:rgb(0,0,0)" class=3D"gmail-styled-by-prettify"> std</span><span style=3D"=
color:rgb(102,102,0)" class=3D"gmail-styled-by-prettify">::</span><span sty=
le=3D"color:rgb(0,0,0)" class=3D"gmail-styled-by-prettify">endl</span><span=
 style=3D"color:rgb(102,102,0)" class=3D"gmail-styled-by-prettify">;</span>=
<span style=3D"color:rgb(0,0,0)" class=3D"gmail-styled-by-prettify"><br></s=
pan><span style=3D"color:rgb(102,102,0)" class=3D"gmail-styled-by-prettify"=
>}</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-styled-by-prettify=
"><br></span></div></code></div></div><div><br>This
 little fictive example shows how this would be possible with those=20
assumptions. And this intrinsically bad, independently to the=20
implementation complexity.</div><div>The outer world should not affect a
 private scope without its consent. (so this does not apply if some=20
global is used within the private scope: in that case, the access to the
 global is consented by the private scope)</div><div><br></div><div><br></d=
iv><div>So definitely, having both string interpolation pattern from conste=
xpr strings <b>and</b> expressions can be interpolated is conceptually bad.=
</div><div><br></div><div>So let&#39;s consider only string interpolation p=
attern from constexpr strings.</div><div>This also breaks private scope (mo=
re tricky though).</div><div><div style=3D"background-color:rgb(250,250,250=
);border-color:rgb(187,187,187);border-style:solid;border-width:1px" class=
=3D"gmail-prettyprint"><code class=3D"gmail-prettyprint"><div class=3D"gmai=
l-subprettyprint"><span style=3D"color:rgb(0,0,136)" class=3D"gmail-styled-=
by-prettify">// intended to use access1, access2, access3 or access4 as pat=
tern<br>auto</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-styled-b=
y-prettify"> foo</span><span style=3D"color:rgb(102,102,0)" class=3D"gmail-=
styled-by-prettify">(</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail=
-styled-by-prettify"><code class=3D"gmail-prettyprint"><span style=3D"color=
:rgb(136,0,0)" class=3D"gmail-styled-by-prettify">/*whatever equivalent to =
string literal*/</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-styl=
ed-by-prettify"> s) {<br>=C2=A0 int super_secret =3D 5;<br>=C2=A0 int acces=
s1 =3D 1;<br>=C2=A0 int access2 =3D 2;<br>=C2=A0 int access3 =3D 3;<br>=C2=
=A0 int access4 =3D 4;<br>=C2=A0 return std::make_tuple($ s);<br>}<br><br>v=
oid bar() {<br>=C2=A0 auto super_secret =3D std::get&lt;0&gt;(foo(&quot;{su=
per_secret}&quot;));<br>=C2=A0 std::cout &lt;&lt; &quot;super_secret: &quot=
; &lt;&lt; super_secret &lt;&lt; std::endl;<br>}<br></span><span style=3D"c=
olor:rgb(102,102,0)" class=3D"gmail-styled-by-prettify"></span></code></spa=
n></div></code></div></div><div><br>Yes, this example is more convoluted, b=
ut it still shows what is possible to do.</div><div><br></div><div>Another =
thing that could be a problem: what happens if a variable is not declared? =
It probably should not compile.</div><div>But then we could have pretty com=
plex and hard to debug code:</div><div><div style=3D"background-color:rgb(2=
50,250,250);border-color:rgb(187,187,187);border-style:solid;border-width:1=
px" class=3D"gmail-prettyprint"><code class=3D"gmail-prettyprint"><div clas=
s=3D"gmail-subprettyprint"><span style=3D"color:rgb(102,0,102)" class=3D"gm=
ail-styled-by-prettify">constexpr auto foo</span><span style=3D"color:rgb(1=
02,102,0)" class=3D"gmail-styled-by-prettify"></span>(int i); // returns a =
&quot;string literal&quot;-like that has the form &quot;{foo###}&quot; wher=
e ### is the i-th prime number<br><br>void bar() {<br>=C2=A0 int foo3 =3D 0=
;<br>=C2=A0 do_whatever($ foo(2));<br>} // This compiles<br><br>void baz() =
{<br>=C2=A0 int foo4 =3D 0;<br>=C2=A0 do_whatever($ foo(2));<br>} // This d=
oesn&#39;t compile (obviously)<br></div></code></div><br>Why
 is it different than just access a global variable with the right name?
 There is no way to know what variables are needed in order to compile=20
other than trying to compile the program.</div><div>The identifier foo3 is =
never defined, and never appears in the code (except within your function).=
</div><div>Moreover,
 your local scope now is entangled with the value returned by foo().=20
(this kind of breaks encapsulation of the local scope)</div><div><br></div>=
<div>Maybe
 your fine with this one, but I&#39;m not. That&#39;s why I think string=20
interpolation should not apply to constexpr strings (at least, not the=20
interpolation pattern).</div><div><br></div><div>Don&#39;t get me wrong: I=
=20
am perfectly fine to standardize only string interpolation on actual=20
string literal with only identifiers in patterns, and see later how to=20
improve it.</div><div>But as far as I&#39;m concerned, I think interpolatin=
g
 constexpr patterns is a bad idea and I would much prefer arbitrary=20
expressions to be interpolated.<br></div><div><br></div><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CANaF6iikVH-jjGFxx2whvec%3DwcRPeXDwTZ=
SevxD9anWhY9zh0g%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANaF6iikVH-jjG=
Fxx2whvec%3DwcRPeXDwTZSevxD9anWhY9zh0g%40mail.gmail.com</a>.<br />

--001a114bb2645977e5056550d40c--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 16 Feb 2018 07:53:43 -0800 (PST)
Raw View
------=_Part_2304_1587938850.1518796423469
Content-Type: multipart/alternative;
 boundary="----=_Part_2305_2040834516.1518796423470"

------=_Part_2305_2040834516.1518796423470
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Friday, February 16, 2018 at 4:18:40 AM UTC-5, Florian Lemaitre wrote:
>
>
> 2018-02-16 2:32 GMT+01:00 Nicol Bolas <jmck...@gmail.com <javascript:>>:
>
>>
>>
>> On Thursday, February 15, 2018 at 5:54:14 PM UTC-5, Florian Lemaitre=20
>> wrote:
>>>
>>> On 15/02/2018 20:39, Nicol Bolas wrote:
>>>
>>> On Thursday, February 15, 2018 at 11:33:26 AM UTC-5, floria...@gmail.co=
m=20
>>> wrote:=20
>>>>
>>>> Le jeudi 15 f=C3=A9vrier 2018 17:19:29 UTC+1, Nicol Bolas a =C3=A9crit=
 :=20
>>>>>
>>>>> On Thursday, February 15, 2018 at 11:06:10 AM UTC-5, Jake Arkinstall=
=20
>>>>> wrote:=20
>>>>>>
>>>>>> On 15 Feb 2018 15:51, "Nicol Bolas" <jmck...@gmail.com> wrote:
>>>>>>
>>>>>> Taking a literal (or possibly constexpr string?)
>>>>>>
>>>>>>
>>>>>> I was wondering whether it makes sense to even describe these things=
=20
>>>>>> as literals, given that they aren't literal and given that they aren=
't=20
>>>>>> intended to actually be stored in memory in any way.
>>>>>>
>>>>>
>>>>> We still call literals "literals", even if you use them entirely at=
=20
>>>>> compile-time via `constexpr` tricks, such that no runtime code ever n=
eeds=20
>>>>> them. Things between quotes are literals.
>>>>>
>>>>> But in terms of constexpr strings, I guess these things themselves ca=
n=20
>>>>>> be built up by other methods - I'm not sure if this makes sense in=
=20
>>>>>> compilation, though; I'm under the impression that the expression it=
self=20
>>>>>> would likely need to be processed before the constexpr methods thems=
elves=20
>>>>>> could be evaluated (especially given that they could themselves util=
ise=20
>>>>>> interpolation). I could be wrong.
>>>>>>
>>>>>> I think, at this point, interpolation is a bad word - it made sense=
=20
>>>>>> in the initial form, but now this has generalised we might want a ne=
w word=20
>>>>>> for it.
>>>>>>
>>>>>
>>>>> I don't agree. "String interpolation" often carries the connotation=
=20
>>>>> that you're just going to concatenate strings, but it doesn't *have*=
=20
>>>>> to. C++ sometimes defines concepts with names that are similar to oth=
er=20
>>>>> language features, but in a more open and freeform way. Lambdas for e=
xample=20
>>>>> don't have lexical scoping in C++ unless you explicitly ask for them,=
=20
>>>>> whereas most languages give it to you as a matter of course.
>>>>>
>>>>> (or possibly arbitrary expressions?)
>>>>>>
>>>>>>
>>>>>> This wouldn't be so much of a problem, because those expressions=20
>>>>>> (other than their declarations) don't need to be completely understo=
od when=20
>>>>>> the [insert better name for interpolation] is performed - just the=
=20
>>>>>> resulting type is needed.
>>>>>>
>>>>>
>>>>> The issue with "arbitrary expression" is that you're now requiring th=
e=20
>>>>> compiler to *invoke the compiler*. It's easy for the compiler to take=
=20
>>>>> a compile-time string and find a variable in scope that matches it. I=
t's=20
>>>>> much harder (presumably) for the compiler to take a compile-time stri=
ng and=20
>>>>> invoke the compiler on it, within the current scope as if it had been=
=20
>>>>> written text.
>>>>>
>>>>> I'm not saying its impossible; I don't know much about compiler=20
>>>>> architecture. But I can't imagine it's as easy as just finding a vari=
able=20
>>>>> with that name.
>>>>>
>>>>> Not only that, once you get into wanting `constexpr` strings that can=
=20
>>>>> be interpolated, you get into lots of issues. Do you really want a fe=
ature=20
>>>>> where you're able to synthesize arbitrary expressions and have someon=
e=20
>>>>> insinuate them into their code at compile time?
>>>>>
>>>>> Or... maybe you do?
>>>>>
>>>>
>>>> From what I know about compilation and formal languages in general, it=
=20
>>>> shouldn't be very hard for a compiler to deal with expressions within=
=20
>>>> `F"{}"`.
>>>> The compiler already do that kind of stuff with parentheses. Compilers=
=20
>>>> are by nature recursive.
>>>>
>>>
>>> You don't seem to be fully understanding what we're talking about. This=
=20
>>> isn't standard recursive-descent recursion. This is "execute some const=
expr=20
>>> code and then run the compiler on part of its string results." Those=20
>>> "results" might include things like *macros*, and macro expansion is=20
>>> supposed to have happened long before executing constexpr functions.
>>>
>>> And you can't just say they're expressions minus macros. Many C-standar=
d=20
>>> library facilities are, or might be, macros after all. Is it legal to d=
o=20
>>> `F"{sin(foo)}"`? If string interpolation is supposed to allow arbitrary=
=20
>>> expressions, it would be odd indeed if it were not. What about invoking=
=20
>>> `offsetof` or similar C-isms?
>>>
>>> If we're only going to allow string interpolation with genuine literals=
,=20
>>> then this isn't much of a problem. Even the macro issue can be sorted o=
ut,=20
>>> since the string is right there in the text of the source code.
>>>
>>> But if we want string interpolation to ever be applied to the results o=
f=20
>>> compile-time execution, that's going to be *much* more complex if=20
>>> string interpolation can handle arbitrary expressions. Whereas if we de=
fine=20
>>> it to just be variable identifiers, extending such interpolation to=20
>>> constexpr strings would be much more reasonable.
>>>
>>> I would say that any proposal should be focused on the minimum=20
>>> featureset. It should naturally include expanding into arbitrary=20
>>> expressions and constexpr strings as future directions things could tak=
e,=20
>>> but I wouldn't push for them in the short term. Sort of like how=20
>>> `constexpr` functions in C++11 were really limited, which C++14 greatly=
=20
>>> expanded.
>>>
>>> The only thing I don't know is if the compiler deals with string=20
>>>> literals as a single token or not. If they do, string literal parser w=
ill=20
>>>> have to be modified quite a lot, even with the "identifier-only" varia=
nt.
>>>>
>>>
>>> First thing first, currently the C++ is oblivious to the preprocessor,=
=20
>>> and this will probably not change in the forseeable future (note that t=
he=20
>>> preprocessor is somehow aware of C++: __cplusplus macro, #include,=20
>>> __has_cpp_attribute...).
>>> But as far as the compiler is concerned, these are two distinct steps=
=20
>>> that are processed one after the other, without going back.
>>>
>>> Maybe you want to change that, but I think you were mentionning macros=
=20
>>> taking effect within F"{}".
>>>
>>
>> No, I'm mentioning macros taking effect within *string interpolation*.
>>
>> We're talking about the intersection of two things, both of which are=20
>> still in question:
>>
>> 1) Arbitrary expressions in interpolation operations.
>> 2) The use of constexpr strings as the *source* for interpolation=20
>> operations; as the string to be interpolated. That is:
>>
>> constexpr constexpr_string<char> my_func()
>> {
>>   constexpr_string<char> a =3D "here's a string {sin(5)}"; //Note: not=
=20
>> doing interpolation.
>>   constexpr_string<char> b =3D " more {foo} string"; //Still not=20
>> interpolating.
>>   return a + b;
>> }
>>
>> auto str =3D std::concat(<interpolation syntax> my_func());
>>
>> //The above is equivalent to:
>>
>> auto str =3D std::concat("here's a string", sin(5), " more ", foo, "=20
>> string");
>>
>> It's the *combination* of these two things that doesn't work. By the=20
>> time the compiler gets around to actually processing the `my_func` call,=
=20
>> macro expansion has come and gone. So how does `sin(5)` get expanded=20
>> properly?
>>
>> And I know you're thinking that constexpr strings don't exist, that=20
>> they're not even really possible. Yet; the committee is working on=20
>> expansions to constexpr that allow memory allocation. Once that happens,=
 we=20
>> will have constexpr strings. And once we do, there's no reason you shoul=
d=20
>> prevent constexpr strings from being the source of interpolation operati=
ons.
>>
>> Well, no reason unless you sandbag interpolation by requiring it to allo=
w=20
>> arbitrary expressions. My feeling is that you have to pick one or the=20
>> other: you either allow arbitrary expressions or you allow constexpr str=
ing=20
>> interpolation. And if we can only have one, I'd much rather have the lat=
ter.
>>
>> I want constexpr strings to be equivalent to literals as much as possibl=
e.
>>
>> I get your problem now.
> Just to simplify my explanations, let's assume that string interpolation=
=20
> is done via a prefix operator called $.
>
> You want to be able to call $ on any constexpr string, and also it would=
=20
> be nice to also have expressions in the interpolation pattern. But as you=
=20
> said, having both would trigger the compiler on compiler output, and this=
=20
> would be difficult to handle.
> I now agree with you on the complexity of having both.
>
> What you're describing here looks like some compile-time "eval".
> constexpr auto call_foo =3D "{foo()}";
>
> // eval:
> $ call_foo;
> // translated to:
> foo();
>
> This looks nasty.
> It would be possible to leak local variables:
> int super_private_copy;
>
> auto foo(/*whatever equivalent to string literal*/ s) {
>   int super_private =3D 5;
>   return std::concat($ s);
> }
>
> void bar() {
>   foo("{super_private_copy =3D super_private}");
>   std::cout << "super_private: " << super_private_copy << std::endl;
> }
>
> This little fictive example shows how this would be possible with those=
=20
> assumptions. And this intrinsically bad, independently to the=20
> implementation complexity.
> The outer world should not affect a private scope without its consent. (s=
o=20
> this does not apply if some global is used within the private scope: in=
=20
> that case, the access to the global is consented by the private scope)
>

> So definitely, having both string interpolation pattern from constexpr=20
> strings *and* expressions can be interpolated is conceptually bad.
>
> So let's consider only string interpolation pattern from constexpr string=
s.
> This also breaks private scope (more tricky though).
> // intended to use access1, access2, access3 or access4 as pattern
> auto foo(/*whatever equivalent to string literal*/ s) {
>   int super_secret =3D 5;
>   int access1 =3D 1;
>   int access2 =3D 2;
>   int access3 =3D 3;
>   int access4 =3D 4;
>   return std::make_tuple($ s);
> }
>
> void bar() {
>   auto super_secret =3D std::get<0>(foo("{super_secret}"));
>   std::cout << "super_secret: " << super_secret << std::endl;
> }
>
> Yes, this example is more convoluted, but it still shows what is possible=
=20
> to do.
>

It's not like the outer scope can force the inner scope to return a=20
`tuple($ s)`. That's the inner scope's choice. Why is it wrong to honor=20
that choice?

You're simply talking about an interface issue. The outer scope can pass=20
the wrong thing to the inner scope, which can cause a compile error or just=
=20
misbehavior. But that's no different from passing the wrong function=20
pointer to a function. If you pass a comparison operator to `std::sort`=20
that doesn't create a strict-weak order, you get broken results. And=20
there's no way to verify that without executing it and seeing the results.

Since this is all done at compile-time, there isn't much of a problem for=
=20
general perfidy in this case (that is, someone hacking your app).

Another thing that could be a problem: what happens if a variable is not=20
> declared? It probably should not compile.
> But then we could have pretty complex and hard to debug code:
>

That's true of any serious `constexpr` coding issue. As we get more and=20
more `constexpr` stuff, we're going to encounter more and more `constexpr`=
=20
debugging problems. At least in this case, the compiler can show us the=20
string that's failing to compile; it's generally easy to track down where=
=20
that came from.

But C++ compilers will need to get into the debugging business if constexpr=
=20
coding is going to be significant. That's regardless of whether we allow=20
string interpolation on constexpr strings.

constexpr auto foo(int i); // returns a "string literal"-like that has the=
=20
> form "{foo###}" where ### is the i-th prime number
>
> void bar() {
>   int foo3 =3D 0;
>   do_whatever($ foo(2));
> } // This compiles
>
> void baz() {
>   int foo4 =3D 0;
>   do_whatever($ foo(2));
> } // This doesn't compile (obviously)
>
> Why is it different than just access a global variable with the right=20
> name? There is no way to know what variables are needed in order to compi=
le=20
> other than trying to compile the program.
> The identifier foo3 is never defined, and never appears in the code=20
> (except within your function).
> Moreover, your local scope now is entangled with the value returned by=20
> foo(). (this kind of breaks encapsulation of the local scope)
>
> Maybe your fine with this one, but I'm not. That's why I think string=20
> interpolation should not apply to constexpr strings (at least, not the=20
> interpolation pattern).
>
> Don't get me wrong: I am perfectly fine to standardize only string=20
> interpolation on actual string literal with only identifiers in patterns,=
=20
> and see later how to improve it.
> But as far as I'm concerned, I think interpolating constexpr patterns is =
a=20
> bad idea and I would much prefer arbitrary expressions to be interpolated=
..
>
>
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/b376bd12-c955-4ed7-a17b-80b552389476%40isocpp.or=
g.

------=_Part_2305_2040834516.1518796423470
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Friday, February 16, 2018 at 4:18:40 AM UTC-5, Florian =
Lemaitre 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=
"><div><br><div class=3D"gmail_quote">2018-02-16 2:32 GMT+01:00 Nicol Bolas=
 <span dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfusc=
ated-mailto=3D"qaWhZxwYCwAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#=
39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#=
39;;return true;">jmck...@gmail.com</a>&gt;</span>:<br><blockquote class=3D=
"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding=
-left:1ex"><div dir=3D"ltr"><div><div><br><br>On Thursday, February 15, 201=
8 at 5:54:14 PM UTC-5, Florian Lemaitre wrote:<blockquote class=3D"gmail_qu=
ote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding=
-left:1ex">
 =20
   =20
 =20
  <div text=3D"#000000" bgcolor=3D"#FFFFFF">
    On 15/02/2018 20:39, Nicol Bolas wrote:<br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">On Thursday, February 15, 2018 at 11:33:26 AM
        UTC-5, <a>floria...@gmail.com</a> wrote:
        <blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex">
          <div dir=3D"ltr">Le jeudi 15 f=C3=A9vrier 2018 17:19:29 UTC+1, Ni=
col
            Bolas a =C3=A9crit=C2=A0:
            <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 Thursday, February 15, 2018 at 11:06:10
                AM UTC-5, Jake Arkinstall 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"auto">
                    <div>
                      <div>
                        <div class=3D"gmail_quote">On 15 Feb 2018 15:51,
                          &quot;Nicol Bolas&quot; &lt;<a rel=3D"nofollow">j=
mck...@gmail.com</a>&gt;
                          wrote:<br type=3D"attribution">
                          <blockquote style=3D"margin:0 0 0 .8ex;border-lef=
t:1px #ccc solid;padding-left:1ex">
                            <div dir=3D"ltr">
                              <div>Taking a literal (or possibly
                                constexpr string?)</div>
                            </div>
                          </blockquote>
                        </div>
                      </div>
                    </div>
                    <div dir=3D"auto"><br>
                    </div>
                    <div dir=3D"auto">I was wondering whether it makes
                      sense to even describe these things as literals,
                      given that they aren&#39;t literal and given that the=
y
                      aren&#39;t intended to actually be stored in memory i=
n
                      any way.</div>
                  </div>
                </blockquote>
                <div><br>
                  We still call literals &quot;literals&quot;, even if you =
use
                  them entirely at compile-time via `constexpr` tricks,
                  such that no runtime code ever needs them. Things
                  between quotes are literals.<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"auto">
                    <div dir=3D"auto">But in terms of constexpr strings, I
                      guess these things themselves can be built up by
                      other methods - I&#39;m not sure if this makes sense
                      in compilation, though; I&#39;m under the impression
                      that the expression itself would likely need to be
                      processed before the constexpr methods themselves
                      could be evaluated (especially given that they
                      could themselves utilise interpolation). I could
                      be wrong.</div>
                    <div dir=3D"auto"><br>
                    </div>
                    <div dir=3D"auto">I think, at this point,
                      interpolation is a bad word - it made sense in the
                      initial form, but now this has generalised we
                      might want a new word for it.</div>
                  </div>
                </blockquote>
                <div><br>
                  I don&#39;t agree. &quot;String interpolation&quot; often=
 carries
                  the connotation that you&#39;re just going to concatenate
                  strings, but it doesn&#39;t <i>have</i> to. C++ sometimes
                  defines concepts with names that are similar to other
                  language features, but in a more open and freeform
                  way. Lambdas for example don&#39;t have lexical scoping i=
n
                  C++ unless you explicitly ask for them, whereas most
                  languages give it to you as a matter of course.<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"auto">
                    <div dir=3D"auto">
                      <div>
                        <div class=3D"gmail_quote">
                          <blockquote style=3D"margin:0 0 0 .8ex;border-lef=
t:1px #ccc solid;padding-left:1ex">
                            <div dir=3D"ltr">
                              <div>(or possibly arbitrary expressions?)</di=
v>
                            </div>
                          </blockquote>
                        </div>
                      </div>
                    </div>
                    <div dir=3D"auto"><br>
                    </div>
                    <div dir=3D"auto">This wouldn&#39;t be so much of a
                      problem, because those expressions (other than
                      their declarations) don&#39;t need to be completely
                      understood when the [insert better name for
                      interpolation] is performed - just the resulting
                      type is needed.</div>
                  </div>
                </blockquote>
                <div><br>
                  The issue with &quot;arbitrary expression&quot; is that y=
ou&#39;re
                  now requiring the compiler to <i>invoke the compiler</i>.
                  It&#39;s easy for the compiler to take a compile-time
                  string and find a variable in scope that matches it.
                  It&#39;s much harder (presumably) for the compiler to tak=
e
                  a compile-time string and invoke the compiler on it,
                  within the current scope as if it had been written
                  text.<br>
                  <br>
                  I&#39;m not saying its impossible; I don&#39;t know much =
about
                  compiler architecture. But I can&#39;t imagine it&#39;s a=
s
                  easy as just finding a variable with that name.<br>
                  <br>
                  Not only that, once you get into wanting `constexpr`
                  strings that can be interpolated, you get into lots of
                  issues. Do you really want a feature where you&#39;re abl=
e
                  to synthesize arbitrary expressions and have someone
                  insinuate them into their code at compile time?<br>
                  <br>
                  Or... maybe you do?<br>
                </div>
              </div>
            </blockquote>
            <div><br>
            </div>
            <div>From what I know about compilation and formal languages
              in general, it shouldn&#39;t be very hard for a compiler to
              deal with expressions within `F&quot;{}&quot;`.</div>
            <div>The compiler already do that kind of stuff with
              parentheses. Compilers are by nature recursive.</div>
          </div>
        </blockquote>
        <div><br>
          You don&#39;t seem to be fully understanding what we&#39;re talki=
ng
          about. This isn&#39;t standard recursive-descent recursion. This
          is &quot;execute some constexpr code and then run the compiler on
          part of its string results.&quot; Those &quot;results&quot; might=
 include
          things like <i>macros</i>, and macro expansion is supposed to
          have happened long before executing constexpr functions.<br>
          <br>
          And you can&#39;t just say they&#39;re expressions minus macros. =
Many
          C-standard library facilities are, or might be, macros after
          all. Is it legal to do `F&quot;{sin(foo)}&quot;`? If string
          interpolation is supposed to allow arbitrary expressions, it
          would be odd indeed if it were not. What about invoking
          `offsetof` or similar C-isms?<br>
          <br>
          If we&#39;re only going to allow string interpolation with genuin=
e
          literals, then this isn&#39;t much of a problem. Even the macro
          issue can be sorted out, since the string is right there in
          the text of the source code.<br>
          <br>
          But if we want string interpolation to ever be applied to the
          results of compile-time execution, that&#39;s going to be <i>much=
</i>
          more complex if string interpolation can handle arbitrary
          expressions. Whereas if we define it to just be variable
          identifiers, extending such interpolation to constexpr strings
          would be much more reasonable.<br>
          <br>
          I would say that any proposal should be focused on the minimum
          featureset. It should naturally include expanding into
          arbitrary expressions and constexpr strings as future
          directions things could take, but I wouldn&#39;t push for them in
          the short term. Sort of like how `constexpr` functions in
          C++11 were really limited, which C++14 greatly expanded.<br>
          <br>
        </div>
        <blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex">
          <div dir=3D"ltr">
            <div>The only thing I don&#39;t know is if the compiler deals
              with string literals as a single token or not. If they do,
              string literal parser will have to be modified quite a
              lot, even with the &quot;identifier-only&quot; variant.<br>
            </div>
          </div>
        </blockquote>
      </div>
    </blockquote>
    <br>
    <div>First thing first, currently the C++ is oblivious to the
      preprocessor, and this will probably not change in the forseeable
      future (note that the preprocessor is somehow aware of C++:
      __cplusplus macro, #include, __has_cpp_attribute...).</div>
    <div>But as far as the compiler is concerned, these are two distinct
      steps that are processed one after the other, without going back.</di=
v>
    <div><br>
    </div>
    <div>Maybe you want to change that, but I think you were mentionning
      macros taking effect within F&quot;{}&quot;.</div></div></blockquote>=
</div></div><div><br>No, I&#39;m mentioning macros taking effect within <i>=
string interpolation</i>.<br><br>We&#39;re talking about the intersection o=
f two things, both of which are still in question:<br><br>1) Arbitrary expr=
essions in interpolation operations.<br>2) The use of constexpr strings as =
the <i>source</i> for interpolation operations; as the string to be interpo=
lated. That is:<br><br><div style=3D"background-color:rgb(250,250,250);bord=
er-color:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><=
span style=3D"color:#008">constexpr</span><span style=3D"color:#000"> const=
expr_string</span><span style=3D"color:#080">&lt;char&gt;</span><span style=
=3D"color:#000"> my_func</span><span style=3D"color:#660">()</span><span st=
yle=3D"color:#000"><br></span><span style=3D"color:#660">{</span><span styl=
e=3D"color:#000"><br>=C2=A0 constexpr_string</span><span style=3D"color:#08=
0">&lt;char&gt;</span><span style=3D"color:#000"> a </span><span style=3D"c=
olor:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D"colo=
r:#080">&quot;here&#39;s a string {sin(5)}&quot;</span><span style=3D"color=
:#660">;</span><span style=3D"color:#000"> </span><span style=3D"color:#800=
">//Note: not doing interpolation.</span><span style=3D"color:#000"><br>=C2=
=A0 constexpr_string</span><span style=3D"color:#080">&lt;char&gt;</span><s=
pan style=3D"color:#000"> b </span><span style=3D"color:#660">=3D</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#080">&quot; more {foo=
} string&quot;</span><span style=3D"color:#660">;</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#800">//Still not interpolating.</span=
><span style=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#008">re=
turn</span><span style=3D"color:#000"> a </span><span style=3D"color:#660">=
+</span><span style=3D"color:#000"> b</span><span style=3D"color:#660">;</s=
pan><span style=3D"color:#000"><br></span><span style=3D"color:#660">}</spa=
n><span style=3D"color:#000"><br><br></span><span style=3D"color:#008">auto=
</span><span style=3D"color:#000"> str </span><span style=3D"color:#660">=
=3D</span><span style=3D"color:#000"> std</span><span style=3D"color:#660">=
::</span><span style=3D"color:#000">concat</span><span style=3D"color:#660"=
>(&lt;</span><span style=3D"color:#000">interpolation syntax</span><span st=
yle=3D"color:#660">&gt;</span><span style=3D"color:#000"> my_func</span><sp=
an style=3D"color:#660">());</span><span style=3D"color:#000"><br><br></spa=
n><span style=3D"color:#800">//The above is equivalent to:</span><span styl=
e=3D"color:#000"><br><br></span><span style=3D"color:#008">auto</span><span=
 style=3D"color:#000"> str </span><span style=3D"color:#660">=3D</span><spa=
n style=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span=
 style=3D"color:#000">concat</span><span style=3D"color:#660">(</span><span=
 style=3D"color:#080">&quot;here&#39;s a string&quot;</span><span style=3D"=
color:#660">,</span><span style=3D"color:#000"> sin</span><span style=3D"co=
lor:#660">(</span><span style=3D"color:#066">5</span><span style=3D"color:#=
660">),</span><span style=3D"color:#000"> </span><span style=3D"color:#080"=
>&quot; more &quot;</span><span style=3D"color:#660">,</span><span style=3D=
"color:#000"> foo</span><span style=3D"color:#660">,</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#080">&quot; string&quot;</span><sp=
an style=3D"color:#660">);</span><span style=3D"color:#000"><br></span></di=
v></code></div><br>It&#39;s the <i>combination</i> of these two things that=
 doesn&#39;t work. By the time the compiler gets around to actually process=
ing the `my_func` call, macro expansion has come and gone. So how does `sin=
(5)` get expanded properly?<br><br>And I know you&#39;re thinking that cons=
texpr strings don&#39;t exist, that they&#39;re not even really possible. Y=
et; the committee is working on expansions to constexpr that allow memory a=
llocation. Once that happens, we will have constexpr strings. And once we d=
o, there&#39;s no reason you should prevent constexpr strings from being th=
e source of interpolation operations.<br><br>Well, no reason unless you san=
dbag interpolation by requiring it to allow arbitrary expressions. My feeli=
ng is that you have to pick one or the other: you either allow=20
arbitrary expressions or you allow constexpr string interpolation. And=20
if we can only have one, I&#39;d much rather have the latter.<br><br>I want=
 constexpr strings to be equivalent to literals as much as possible.<br></d=
iv><br></div></blockquote></div><div>I get your problem now.<br></div><div>=
Just to simplify my explanations, let&#39;s assume that string interpolatio=
n is done via a prefix operator called $.</div><div><br></div><div>You
 want to be able to call $ on any constexpr string, and also it would be
 nice to also have expressions in the interpolation pattern. But as you=20
said, having both would trigger the compiler on compiler output, and=20
this would be difficult to handle.</div><div>I now agree with you on the co=
mplexity of having both.</div><div><br></div><div>What you&#39;re describin=
g here looks like some compile-time &quot;eval&quot;.</div><div><div style=
=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-=
style:solid;border-width:1px"><code><div><span style=3D"color:rgb(0,0,136)"=
>constexpr</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"co=
lor:rgb(0,0,136)">auto</span><span style=3D"color:rgb(0,0,0)"> call_foo </s=
pan><span style=3D"color:rgb(102,102,0)">=3D</span><span style=3D"color:rgb=
(0,0,0)"> </span><span style=3D"color:rgb(0,136,0)">&quot;{foo()}&quot;</sp=
an><span style=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,=
0,0)"><br><br></span><span style=3D"color:rgb(136,0,0)">// eval:</span><spa=
n style=3D"color:rgb(0,0,0)"><br>$ call_foo</span><span style=3D"color:rgb(=
102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br></span><span style=
=3D"color:rgb(136,0,0)">// translated to:</span><span style=3D"color:rgb(0,=
0,0)"><br>foo</span><span style=3D"color:rgb(102,102,0)">();</span><span st=
yle=3D"color:rgb(0,0,0)"><br></span></div></code></div><br>This looks nasty=
..<br></div><div>It would be possible to leak local variables:</div><div><di=
v style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);=
border-style:solid;border-width:1px"><code><div><span style=3D"color:rgb(0,=
0,136)">int</span><span style=3D"color:rgb(0,0,0)"> super_private_copy</spa=
n><span style=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0=
,0)"><br><br></span><span style=3D"color:rgb(0,0,136)">auto</span><span sty=
le=3D"color:rgb(0,0,0)"> foo</span><span style=3D"color:rgb(102,102,0)">(</=
span><span style=3D"color:rgb(136,0,0)">/*whatever equivalent to string lit=
eral*/</span><span style=3D"color:rgb(0,0,0)"> s</span><span style=3D"color=
:rgb(102,102,0)">)</span><span style=3D"color:rgb(0,0,0)"> </span><span sty=
le=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"><br>=
=C2=A0 </span><span style=3D"color:rgb(0,0,136)">int</span><span style=3D"c=
olor:rgb(0,0,0)"> super_private </span><span style=3D"color:rgb(102,102,0)"=
>=3D</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rg=
b(0,102,102)">5</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)"> std</span><span style=3D"=
color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,0)">concat</spa=
n><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0=
,0)">$ s</span><span style=3D"color:rgb(102,102,0)">);</span><span style=3D=
"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(102,102,0)">}</span>=
<span style=3D"color:rgb(0,0,0)"><br><br></span><span style=3D"color:rgb(0,=
0,136)">void</span><span style=3D"color:rgb(0,0,0)"> bar</span><span style=
=3D"color:rgb(102,102,0)">()</span><span style=3D"color:rgb(0,0,0)"> </span=
><span style=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,=
0)"><br>=C2=A0 foo</span><span style=3D"color:rgb(102,102,0)">(</span><span=
 style=3D"color:rgb(0,136,0)">&quot;{super_private_copy =3D super_private}&=
quot;</span><span style=3D"color:rgb(102,102,0)">);</span><span style=3D"co=
lor:rgb(0,0,0)"><br>=C2=A0 std</span><span style=3D"color:rgb(102,102,0)">:=
:</span><span style=3D"color:rgb(0,0,0)">cout </span><span style=3D"color:r=
gb(102,102,0)">&lt;&lt;</span><span style=3D"color:rgb(0,0,0)"> </span><spa=
n style=3D"color:rgb(0,136,0)">&quot;super_private: &quot;</span><span styl=
e=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">&lt;&lt=
;</span><span style=3D"color:rgb(0,0,0)"> super_private_copy </span><span s=
tyle=3D"color:rgb(102,102,0)">&lt;&lt;</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)">endl</span><span style=3D"color:rgb(102,102,0)">;</span><=
span style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(102,102=
,0)">}</span><span style=3D"color:rgb(0,0,0)"><br></span></div></code></div=
></div><div><br>This
 little fictive example shows how this would be possible with those=20
assumptions. And this intrinsically bad, independently to the=20
implementation complexity.</div><div>The outer world should not affect a
 private scope without its consent. (so this does not apply if some=20
global is used within the private scope: in that case, the access to the
 global is consented by the private scope)</div></div></div></blockquote><b=
lockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; border-=
left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div><br></div></bl=
ockquote><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></div><div>So definitely, having both string interpolation pattern fr=
om constexpr strings <b>and</b> expressions can be interpolated is conceptu=
ally bad.</div><div><br></div><div>So let&#39;s consider only string interp=
olation pattern from constexpr strings.</div><div>This also breaks private =
scope (more tricky though).</div><div><div style=3D"background-color:rgb(25=
0,250,250);border-color:rgb(187,187,187);border-style:solid;border-width:1p=
x"><code><div><span style=3D"color:rgb(0,0,136)">// intended to use access1=
, access2, access3 or access4 as pattern<br>auto</span><span style=3D"color=
:rgb(0,0,0)"> foo</span><span style=3D"color:rgb(102,102,0)">(</span><span =
style=3D"color:rgb(0,0,0)"><code><span style=3D"color:rgb(136,0,0)">/*whate=
ver equivalent to string literal*/</span><span style=3D"color:rgb(0,0,0)"> =
s) {<br>=C2=A0 int super_secret =3D 5;<br>=C2=A0 int access1 =3D 1;<br>=C2=
=A0 int access2 =3D 2;<br>=C2=A0 int access3 =3D 3;<br>=C2=A0 int access4 =
=3D 4;<br>=C2=A0 return std::make_tuple($ s);<br>}<br><br>void bar() {<br>=
=C2=A0 auto super_secret =3D std::get&lt;0&gt;(foo(&quot;{super_<wbr>secret=
}&quot;));<br>=C2=A0 std::cout &lt;&lt; &quot;super_secret: &quot; &lt;&lt;=
 super_secret &lt;&lt; std::endl;<br>}<br></span><span style=3D"color:rgb(1=
02,102,0)"></span></code></span></div></code></div></div><div><br>Yes, this=
 example is more convoluted, but it still shows what is possible to do.</di=
v></div></div></blockquote><div><br>It&#39;s not like the outer scope can f=
orce the inner scope to return a `tuple($ s)`. That&#39;s the inner scope&#=
39;s choice. Why is it wrong to honor that choice?<br><br>You&#39;re simply=
 talking about an interface issue. The outer scope can pass the wrong thing=
 to the inner scope, which can cause a compile error or just misbehavior. B=
ut that&#39;s no different from passing the wrong function pointer to a fun=
ction. If you pass a comparison operator to `std::sort` that doesn&#39;t cr=
eate a strict-weak order, you get broken results. And there&#39;s no way to=
 verify that without executing it and seeing the results.<br><br>Since this=
 is all done at compile-time, there isn&#39;t much of a problem for general=
 perfidy in this case (that is, someone hacking your app).<br><br></div><bl=
ockquote 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></div>=
<div>Another thing that could be a problem: what happens if a variable is n=
ot declared? It probably should not compile.</div><div>But then we could ha=
ve pretty complex and hard to debug code:</div></div></div></blockquote><di=
v><br>That&#39;s true of any serious `constexpr` coding issue. As we get mo=
re and more `constexpr` stuff, we&#39;re going to encounter more and more `=
constexpr` debugging problems. At least in this case, the compiler can show=
 us the string that&#39;s failing to compile; it&#39;s generally easy to tr=
ack down where that came from.<br><br>But C++ compilers will need to get in=
to the debugging business if constexpr coding is going to be significant. T=
hat&#39;s regardless of whether we allow string interpolation on constexpr =
strings.<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><div style=3D"background-color:rgb(250,250,250);border-c=
olor:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><span=
 style=3D"color:rgb(102,0,102)">constexpr auto foo</span><span style=3D"col=
or:rgb(102,102,0)"></span>(int i); // returns a &quot;string literal&quot;-=
like that has the form &quot;{foo###}&quot; where ### is the i-th prime num=
ber<br><br>void bar() {<br>=C2=A0 int foo3 =3D 0;<br>=C2=A0 do_whatever($ f=
oo(2));<br>} // This compiles<br><br>void baz() {<br>=C2=A0 int foo4 =3D 0;=
<br>=C2=A0 do_whatever($ foo(2));<br>} // This doesn&#39;t compile (obvious=
ly)<br></div></code></div><br>Why
 is it different than just access a global variable with the right name?
 There is no way to know what variables are needed in order to compile=20
other than trying to compile the program.</div><div>The identifier foo3 is =
never defined, and never appears in the code (except within your function).=
</div><div>Moreover,
 your local scope now is entangled with the value returned by foo().=20
(this kind of breaks encapsulation of the local scope)</div><div><br></div>=
<div>Maybe
 your fine with this one, but I&#39;m not. That&#39;s why I think string=20
interpolation should not apply to constexpr strings (at least, not the=20
interpolation pattern).</div><div><br></div><div>Don&#39;t get me wrong: I=
=20
am perfectly fine to standardize only string interpolation on actual=20
string literal with only identifiers in patterns, and see later how to=20
improve it.</div><div>But as far as I&#39;m concerned, I think interpolatin=
g
 constexpr patterns is a bad idea and I would much prefer arbitrary=20
expressions to be interpolated.<br></div><div><br></div><br></div></div>
</blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/b376bd12-c955-4ed7-a17b-80b552389476%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/b376bd12-c955-4ed7-a17b-80b552389476=
%40isocpp.org</a>.<br />

------=_Part_2305_2040834516.1518796423470--

------=_Part_2304_1587938850.1518796423469--

.


Author: inkwizytoryankes@gmail.com
Date: Fri, 16 Feb 2018 13:39:41 -0800 (PST)
Raw View
------=_Part_4974_86121140.1518817181891
Content-Type: multipart/alternative;
 boundary="----=_Part_4975_1051887967.1518817181892"

------=_Part_4975_1051887967.1518817181892
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



On Thursday, February 15, 2018 at 11:54:14 PM UTC+1, Florian Lemaitre wrote=
:
>
> On 15/02/2018 20:39, Nicol Bolas wrote:
>
> On Thursday, February 15, 2018 at 11:33:26 AM UTC-5, floria...@gmail.com=
=20
> wrote:=20
>>
>> Le jeudi 15 f=C3=A9vrier 2018 17:19:29 UTC+1, Nicol Bolas a =C3=A9crit :=
=20
>>>
>>> On Thursday, February 15, 2018 at 11:06:10 AM UTC-5, Jake Arkinstall=20
>>> wrote:=20
>>>>
>>>> On 15 Feb 2018 15:51, "Nicol Bolas" <jmck...@gmail.com> wrote:
>>>>
>>>> Taking a literal (or possibly constexpr string?)
>>>>
>>>>
>>>> I was wondering whether it makes sense to even describe these things a=
s=20
>>>> literals, given that they aren't literal and given that they aren't=20
>>>> intended to actually be stored in memory in any way.
>>>>
>>>
>>> We still call literals "literals", even if you use them entirely at=20
>>> compile-time via `constexpr` tricks, such that no runtime code ever nee=
ds=20
>>> them. Things between quotes are literals.
>>>
>>> But in terms of constexpr strings, I guess these things themselves can=
=20
>>>> be built up by other methods - I'm not sure if this makes sense in=20
>>>> compilation, though; I'm under the impression that the expression itse=
lf=20
>>>> would likely need to be processed before the constexpr methods themsel=
ves=20
>>>> could be evaluated (especially given that they could themselves utilis=
e=20
>>>> interpolation). I could be wrong.
>>>>
>>>> I think, at this point, interpolation is a bad word - it made sense in=
=20
>>>> the initial form, but now this has generalised we might want a new wor=
d for=20
>>>> it.
>>>>
>>>
>>> I don't agree. "String interpolation" often carries the connotation tha=
t=20
>>> you're just going to concatenate strings, but it doesn't *have* to. C++=
=20
>>> sometimes defines concepts with names that are similar to other languag=
e=20
>>> features, but in a more open and freeform way. Lambdas for example don'=
t=20
>>> have lexical scoping in C++ unless you explicitly ask for them, whereas=
=20
>>> most languages give it to you as a matter of course.
>>>
>>> (or possibly arbitrary expressions?)
>>>>
>>>>
>>>> This wouldn't be so much of a problem, because those expressions (othe=
r=20
>>>> than their declarations) don't need to be completely understood when t=
he=20
>>>> [insert better name for interpolation] is performed - just the resulti=
ng=20
>>>> type is needed.
>>>>
>>>
>>> The issue with "arbitrary expression" is that you're now requiring the=
=20
>>> compiler to *invoke the compiler*. It's easy for the compiler to take a=
=20
>>> compile-time string and find a variable in scope that matches it. It's =
much=20
>>> harder (presumably) for the compiler to take a compile-time string and=
=20
>>> invoke the compiler on it, within the current scope as if it had been=
=20
>>> written text.
>>>
>>> I'm not saying its impossible; I don't know much about compiler=20
>>> architecture. But I can't imagine it's as easy as just finding a variab=
le=20
>>> with that name.
>>>
>>> Not only that, once you get into wanting `constexpr` strings that can b=
e=20
>>> interpolated, you get into lots of issues. Do you really want a feature=
=20
>>> where you're able to synthesize arbitrary expressions and have someone=
=20
>>> insinuate them into their code at compile time?
>>>
>>> Or... maybe you do?
>>>
>>
>> From what I know about compilation and formal languages in general, it=
=20
>> shouldn't be very hard for a compiler to deal with expressions within=20
>> `F"{}"`.
>> The compiler already do that kind of stuff with parentheses. Compilers=
=20
>> are by nature recursive.
>>
>
> You don't seem to be fully understanding what we're talking about. This=
=20
> isn't standard recursive-descent recursion. This is "execute some constex=
pr=20
> code and then run the compiler on part of its string results." Those=20
> "results" might include things like *macros*, and macro expansion is=20
> supposed to have happened long before executing constexpr functions.
>
> And you can't just say they're expressions minus macros. Many C-standard=
=20
> library facilities are, or might be, macros after all. Is it legal to do=
=20
> `F"{sin(foo)}"`? If string interpolation is supposed to allow arbitrary=
=20
> expressions, it would be odd indeed if it were not. What about invoking=
=20
> `offsetof` or similar C-isms?
>
> If we're only going to allow string interpolation with genuine literals,=
=20
> then this isn't much of a problem. Even the macro issue can be sorted out=
,=20
> since the string is right there in the text of the source code.
>
> But if we want string interpolation to ever be applied to the results of=
=20
> compile-time execution, that's going to be *much* more complex if string=
=20
> interpolation can handle arbitrary expressions. Whereas if we define it t=
o=20
> just be variable identifiers, extending such interpolation to constexpr=
=20
> strings would be much more reasonable.
>
> I would say that any proposal should be focused on the minimum featureset=
..=20
> It should naturally include expanding into arbitrary expressions and=20
> constexpr strings as future directions things could take, but I wouldn't=
=20
> push for them in the short term. Sort of like how `constexpr` functions i=
n=20
> C++11 were really limited, which C++14 greatly expanded.
>
> The only thing I don't know is if the compiler deals with string literals=
=20
>> as a single token or not. If they do, string literal parser will have to=
 be=20
>> modified quite a lot, even with the "identifier-only" variant.
>>
>
> First thing first, currently the C++ is oblivious to the preprocessor, an=
d=20
> this will probably not change in the forseeable future (note that the=20
> preprocessor is somehow aware of C++: __cplusplus macro, #include,=20
> __has_cpp_attribute...).
> But as far as the compiler is concerned, these are two distinct steps tha=
t=20
> are processed one after the other, without going back.
>
> Maybe you want to change that, but I think you were mentionning macros=20
> taking effect within F"{}".
> For instance:
> #define Foo 5
> F"{Foo}";
> would expand to:
> F"{5}";
>
> This has basicaly nothing to do with C++, just the preprocessor should be=
=20
> aware that F"{ and }" are somehow similar to parentheses and it should=20
> process the inner part as usual.
> I am simplifying here, but the idea is there. No coming back from C++ to=
=20
> the preprocessor here.
>
> If this is not what you have in mind, please correct me.
>
>
This is impossible, macros can't work with interpolation (at least not in=
=20
broken way).
Consider this code:

#define X C}E
F"A{X}B"; // `"A", C , " E}B"`

#define Y(X) F"A{X}B";
Y(a}Y{c); // `"A", a, "Y", c, "B"`


#define Z {B
F"A{Z}C"; // `"A{B}C"` normal string!

#define W(A, B) F"{A B}"
W({{, b) // `"{", b`
W(a}, b) // `a, " B}"` or `a, " b}"`?
W({, b) // `"{ b}"` or `"{ B}"`?

#define LL(P, A) P##"{A}"
LL(F, a) // `F"{A}"` or `F"{a}"`?

#define RR(_HERE_) FR"{AA}( A ){_HERE_}" FR"{AA}( B ){AA}" //second `FR`=20
should be part of raw string, true end is last `){AA}"`
RR(AA) // `FR"{AA}( A ){AA}" FR"{AA}( B ){AA}"` =3D> `F" A " F" B "` =3D> `=
F" A=20
 B "` or `F" A ){AA}\" FR\"{AA}( B "`?



This will be pain in a** to implement, probably lot of easier will be by=20
replacing `{` by `"`, at least all tools and processor will be easier to=20
adjust to support this.
Then why not this work this way:
F"A "b" B "c" D"_postfix
But this could have confusing part that last symbol is postfix or variable=
=20
named `_postfix`?








--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/ddf515c9-70f6-401b-93eb-b412128779a0%40isocpp.or=
g.

------=_Part_4975_1051887967.1518817181892
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Thursday, February 15, 2018 at 11:54:14 PM UTC+=
1, Florian Lemaitre wrote:<blockquote class=3D"gmail_quote" style=3D"margin=
: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
 =20
   =20
 =20
  <div text=3D"#000000" bgcolor=3D"#FFFFFF">
    On 15/02/2018 20:39, Nicol Bolas wrote:<br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">On Thursday, February 15, 2018 at 11:33:26 AM
        UTC-5, <a>floria...@gmail.com</a> wrote:
        <blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex">
          <div dir=3D"ltr">Le jeudi 15 f=C3=A9vrier 2018 17:19:29 UTC+1, Ni=
col
            Bolas a =C3=A9crit=C2=A0:
            <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 Thursday, February 15, 2018 at 11:06:10
                AM UTC-5, Jake Arkinstall 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"auto">
                    <div>
                      <div>
                        <div class=3D"gmail_quote">On 15 Feb 2018 15:51,
                          &quot;Nicol Bolas&quot; &lt;<a rel=3D"nofollow">j=
mck...@gmail.com</a>&gt;
                          wrote:<br type=3D"attribution">
                          <blockquote style=3D"margin:0 0 0 .8ex;border-lef=
t:1px #ccc solid;padding-left:1ex">
                            <div dir=3D"ltr">
                              <div>Taking a literal (or possibly
                                constexpr string?)</div>
                            </div>
                          </blockquote>
                        </div>
                      </div>
                    </div>
                    <div dir=3D"auto"><br>
                    </div>
                    <div dir=3D"auto">I was wondering whether it makes
                      sense to even describe these things as literals,
                      given that they aren&#39;t literal and given that the=
y
                      aren&#39;t intended to actually be stored in memory i=
n
                      any way.</div>
                  </div>
                </blockquote>
                <div><br>
                  We still call literals &quot;literals&quot;, even if you =
use
                  them entirely at compile-time via `constexpr` tricks,
                  such that no runtime code ever needs them. Things
                  between quotes are literals.<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"auto">
                    <div dir=3D"auto">But in terms of constexpr strings, I
                      guess these things themselves can be built up by
                      other methods - I&#39;m not sure if this makes sense
                      in compilation, though; I&#39;m under the impression
                      that the expression itself would likely need to be
                      processed before the constexpr methods themselves
                      could be evaluated (especially given that they
                      could themselves utilise interpolation). I could
                      be wrong.</div>
                    <div dir=3D"auto"><br>
                    </div>
                    <div dir=3D"auto">I think, at this point,
                      interpolation is a bad word - it made sense in the
                      initial form, but now this has generalised we
                      might want a new word for it.</div>
                  </div>
                </blockquote>
                <div><br>
                  I don&#39;t agree. &quot;String interpolation&quot; often=
 carries
                  the connotation that you&#39;re just going to concatenate
                  strings, but it doesn&#39;t <i>have</i> to. C++ sometimes
                  defines concepts with names that are similar to other
                  language features, but in a more open and freeform
                  way. Lambdas for example don&#39;t have lexical scoping i=
n
                  C++ unless you explicitly ask for them, whereas most
                  languages give it to you as a matter of course.<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"auto">
                    <div dir=3D"auto">
                      <div>
                        <div class=3D"gmail_quote">
                          <blockquote style=3D"margin:0 0 0 .8ex;border-lef=
t:1px #ccc solid;padding-left:1ex">
                            <div dir=3D"ltr">
                              <div>(or possibly arbitrary expressions?)</di=
v>
                            </div>
                          </blockquote>
                        </div>
                      </div>
                    </div>
                    <div dir=3D"auto"><br>
                    </div>
                    <div dir=3D"auto">This wouldn&#39;t be so much of a
                      problem, because those expressions (other than
                      their declarations) don&#39;t need to be completely
                      understood when the [insert better name for
                      interpolation] is performed - just the resulting
                      type is needed.</div>
                  </div>
                </blockquote>
                <div><br>
                  The issue with &quot;arbitrary expression&quot; is that y=
ou&#39;re
                  now requiring the compiler to <i>invoke the compiler</i>.
                  It&#39;s easy for the compiler to take a compile-time
                  string and find a variable in scope that matches it.
                  It&#39;s much harder (presumably) for the compiler to tak=
e
                  a compile-time string and invoke the compiler on it,
                  within the current scope as if it had been written
                  text.<br>
                  <br>
                  I&#39;m not saying its impossible; I don&#39;t know much =
about
                  compiler architecture. But I can&#39;t imagine it&#39;s a=
s
                  easy as just finding a variable with that name.<br>
                  <br>
                  Not only that, once you get into wanting `constexpr`
                  strings that can be interpolated, you get into lots of
                  issues. Do you really want a feature where you&#39;re abl=
e
                  to synthesize arbitrary expressions and have someone
                  insinuate them into their code at compile time?<br>
                  <br>
                  Or... maybe you do?<br>
                </div>
              </div>
            </blockquote>
            <div><br>
            </div>
            <div>From what I know about compilation and formal languages
              in general, it shouldn&#39;t be very hard for a compiler to
              deal with expressions within `F&quot;{}&quot;`.</div>
            <div>The compiler already do that kind of stuff with
              parentheses. Compilers are by nature recursive.</div>
          </div>
        </blockquote>
        <div><br>
          You don&#39;t seem to be fully understanding what we&#39;re talki=
ng
          about. This isn&#39;t standard recursive-descent recursion. This
          is &quot;execute some constexpr code and then run the compiler on
          part of its string results.&quot; Those &quot;results&quot; might=
 include
          things like <i>macros</i>, and macro expansion is supposed to
          have happened long before executing constexpr functions.<br>
          <br>
          And you can&#39;t just say they&#39;re expressions minus macros. =
Many
          C-standard library facilities are, or might be, macros after
          all. Is it legal to do `F&quot;{sin(foo)}&quot;`? If string
          interpolation is supposed to allow arbitrary expressions, it
          would be odd indeed if it were not. What about invoking
          `offsetof` or similar C-isms?<br>
          <br>
          If we&#39;re only going to allow string interpolation with genuin=
e
          literals, then this isn&#39;t much of a problem. Even the macro
          issue can be sorted out, since the string is right there in
          the text of the source code.<br>
          <br>
          But if we want string interpolation to ever be applied to the
          results of compile-time execution, that&#39;s going to be <i>much=
</i>
          more complex if string interpolation can handle arbitrary
          expressions. Whereas if we define it to just be variable
          identifiers, extending such interpolation to constexpr strings
          would be much more reasonable.<br>
          <br>
          I would say that any proposal should be focused on the minimum
          featureset. It should naturally include expanding into
          arbitrary expressions and constexpr strings as future
          directions things could take, but I wouldn&#39;t push for them in
          the short term. Sort of like how `constexpr` functions in
          C++11 were really limited, which C++14 greatly expanded.<br>
          <br>
        </div>
        <blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex">
          <div dir=3D"ltr">
            <div>The only thing I don&#39;t know is if the compiler deals
              with string literals as a single token or not. If they do,
              string literal parser will have to be modified quite a
              lot, even with the &quot;identifier-only&quot; variant.<br>
            </div>
          </div>
        </blockquote>
      </div>
    </blockquote>
    <br>
    <div>First thing first, currently the C++ is oblivious to the
      preprocessor, and this will probably not change in the forseeable
      future (note that the preprocessor is somehow aware of C++:
      __cplusplus macro, #include, __has_cpp_attribute...).</div>
    <div>But as far as the compiler is concerned, these are two distinct
      steps that are processed one after the other, without going back.</di=
v>
    <div><br>
    </div>
    <div>Maybe you want to change that, but I think you were mentionning
      macros taking effect within F&quot;{}&quot;.</div>
    <div>For instance:</div>
    <div>
      <div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,=
187,187);border-style:solid;border-width:1px"><code>
          <div><span style=3D"color:#800">#define</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#606">Foo</span><span style=3D"color:#=
000"> </span><span style=3D"color:#066">5</span><span style=3D"color:#000">=
<br>
              F</span><span style=3D"color:#080">&quot;{Foo}&quot;</span><s=
pan style=3D"color:#660">;</span><span style=3D"color:#000"><br>
            </span></div>
        </code></div>
      would expand to:</div>
    <div>
      <div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,=
187,187);border-style:solid;border-width:1px"><code>
          <div><span style=3D"color:#000">F</span><span style=3D"color:#080=
">&quot;{5}&quot;</span><span style=3D"color:#660">;</span></div>
        </code></div>
    </div>
    <div><br>
    </div>
    <div>This has basicaly nothing to do with C++, just the preprocessor
      should be aware that F&quot;{ and }&quot; are somehow similar to pare=
ntheses
      and it should process the inner part as usual.</div>
    <div>I am simplifying here, but the idea is there. No coming back
      from C++ to the preprocessor here.</div>
    <div><br>
    </div>
    <div>If this is not what you have in mind, please correct me.<br>
    </div><br></div></blockquote><div><br>This is impossible, macros can&#3=
9;t work with interpolation (at least not in broken way).<br>Consider this =
code:<br><span style=3D"color: #a31515;"><div style=3D"background-color: rg=
b(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; bo=
rder-width: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code cl=
ass=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #800;" cl=
ass=3D"styled-by-prettify">#define</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> X C</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">E<br>F</span><span style=3D"color: #080;" class=3D"styled-by-prett=
ify">&quot;A{X}B&quot;</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">// `&q=
uot;A&quot;, C , &quot; E}B&quot;`</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br><br></span><span style=3D"color: #800;" class=
=3D"styled-by-prettify">#define</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-pretti=
fy">X</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> F</span><span=
 style=3D"color: #080;" class=3D"styled-by-prettify">&quot;A{X}B&quot;</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br>Y</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">a</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">}</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=
">c</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #800;" class=3D"styled-by-prettify">// `&quot;A&quot;, a, &q=
uot;Y&quot;, c, &quot;B&quot;`</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br><br><br></span><span style=3D"color: #800;" class=
=3D"styled-by-prettify">#define</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-prett=
ify">B<br>F</span><span style=3D"color: #080;" class=3D"styled-by-prettify"=
>&quot;A{Z}C&quot;</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #800;" class=3D"styled-by-prettify">// `&quot;=
A{B}C&quot;` normal string!</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br><br></span><span style=3D"color: #800;" class=3D"style=
d-by-prettify">#define</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> W</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">A</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> B</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> F</span><span style=3D"color: #080;" cl=
ass=3D"styled-by-prettify">&quot;{A B}&quot;</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br>W</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">({{,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> b</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">//=
 `&quot;{&quot;, b`</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br>W</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">a</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">},</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> b</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #800;" =
class=3D"styled-by-prettify">// `a, &quot; B}&quot;` or `a, &quot; b}&quot;=
`?</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>W</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">({,</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> b</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #800;" =
class=3D"styled-by-prettify">// `&quot;{ b}&quot;` or `&quot;{ B}&quot;`?</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></sp=
an><span style=3D"color: #800;" class=3D"styled-by-prettify">#define</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> LL</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">P</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> A</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> P</span><span style=3D"color: #800;" class=3D"styled-by-prettify">#=
#&quot;{A}&quot;</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br>LL</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">F</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> a</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">// `F&quot;{A}&quot;` or `F&quot;{a}&quot;`?</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><s=
pan style=3D"color: #800;" class=3D"styled-by-prettify">#define</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> RR</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">_HERE_</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> FR</span><span style=3D"color: #080;" class=3D"st=
yled-by-prettify">&quot;{AA}( A ){_HERE_}&quot;</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> FR</span><span style=3D"color: #080;"=
 class=3D"styled-by-prettify">&quot;{AA}( B ){AA}&quot;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #800;" class=3D"styled-by-prettify">//second `FR` should be part of raw s=
tring, true end is last `){AA}&quot;`</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br>RR</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">AA</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #800;" class=3D"styled-by-prettify">// `FR&quot=
;{AA}( A ){AA}&quot; FR&quot;{AA}( B ){AA}&quot;` =3D&gt; `F&quot; A &quot;=
 F&quot; B &quot;` =3D&gt; `F&quot; A =C2=A0B &quot;` or `F&quot; A ){AA}\&=
quot; FR\&quot;{AA}( B &quot;`?</span></div></code></div><br><br></span><br=
>This will be pain in a** to implement, probably lot of easier will be by r=
eplacing `{` by `&quot;`, at least all tools and processor will be easier t=
o adjust to support this.<br>Then why not this work this way:<br><div style=
=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187);=
 border-style: solid; border-width: 1px; overflow-wrap: break-word;" class=
=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subprettyprint">=
<span style=3D"color: #000;" class=3D"styled-by-prettify">F</span><span sty=
le=3D"color: #080;" class=3D"styled-by-prettify">&quot;A &quot;</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify">b</span><span style=3D=
"color: #080;" class=3D"styled-by-prettify">&quot; B &quot;</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify">c</span><span style=3D"col=
or: #080;" class=3D"styled-by-prettify">&quot; D&quot;</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">_postfix</span></div></code></d=
iv>But this could have confusing part that last symbol is postfix or variab=
le named `_postfix`?<br><br><br><br><br><br><br><br><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/ddf515c9-70f6-401b-93eb-b412128779a0%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/ddf515c9-70f6-401b-93eb-b412128779a0=
%40isocpp.org</a>.<br />

------=_Part_4975_1051887967.1518817181892--

------=_Part_4974_86121140.1518817181891--

.