220 36878 <750ecf62-9637-40f4-8585-e3be2780fb46@isocpp.org> article
Path: news.gmane.org!.POSTED!not-for-mail
From: florian.csdt@gmail.com
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: String interpolation
Date: Mon, 12 Feb 2018 02:17:45 -0800 (PST)
Lines: 617
Approved: news@gmane.org
Message-ID: <750ecf62-9637-40f4-8585-e3be2780fb46@isocpp.org>
References: <356d5835-f1bf-4699-94f5-0b2d3d0b9c0e@isocpp.org>
 <CAMD6iD9aT26x8GQHnQL+kuj3Rq8fVQSfYYFtvTnFidkf6jU_ag@mail.gmail.com>
 <25CCF885-86AD-4D51-8F5C-C46376D34DE0@gmail.com> <4890431.TR9UepuQra@tjmaciei-mobl1>
 <CALvx3hac77b6Z=EOWzKqynALi1-352OvY0dnnOer8rN6tfa01g@mail.gmail.com> <1cdb6300-7397-46d7-bce9-62e6e8dac40b@isocpp.org>
 <CAC+0CCOSZHaTA=YPSDU8Add7mE_BYcYPRCmGW8TRPtZhdqL8Hw@mail.gmail.com>
 <4bce681e-e729-4124-9322-69291fdb6678@isocpp.org>
 <f5feb9a0-99d3-433a-ae46-af34c8d00a61@isocpp.org>
 <8e456af5-09c3-461d-8562-30df127e93af@isocpp.org>
 <bd24b702-025a-4b06-976b-559c779851e1@isocpp.org>
 <f63ed807-c5f6-4997-b03f-b4bc16a70982@isocpp.org>
 <28e80709-5ebb-44d2-b26d-22cafd681330@isocpp.org>
 <52b86f0a-b3b9-455f-9d4d-0f6b15192c90@isocpp.org>
 <1e9a5468-6efa-48a2-87ce-6bdb6d5c4e83@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_6458_588853956.1518430665592"
X-Trace: blaine.gmane.org 1518430556 3594 195.159.176.226 (12 Feb 2018 10:15:56 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Mon, 12 Feb 2018 10:15:56 +0000 (UTC)
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBC26HM4V3MIRBSWTQXKAKGQE3XIYO6Y@isocpp.org Mon Feb 12 11:15:52 2018
Return-path: <std-proposals+bncBC26HM4V3MIRBSWTQXKAKGQE3XIYO6Y@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-vk0-f70.google.com ([209.85.213.70])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBC26HM4V3MIRBSWTQXKAKGQE3XIYO6Y@isocpp.org>)
	id 1elB9C-0008Qk-Kk
	for gclcip-std-proposals@m.gmane.org; Mon, 12 Feb 2018 11:15:42 +0100
Original-Received: by mail-vk0-f70.google.com with SMTP id c17sf8881938vke.1
        for <gclcip-std-proposals@m.gmane.org>; Mon, 12 Feb 2018 02:17:48 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to:message-id:in-reply-to:references:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :list-post:list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=aL9nlErqi6yFNWp1abRp5NLqtalAzeYqMa1DYJtNZDk=;
        b=htjCMpw6Kw5YlqOmJWH678M6R8KYuh1410D14scjPJHcbcQsFrMokHUXbDObLtACkg
         wAlgGBF2Q72DWSdN2jytQlm07ieGgYm5I6Q7O+Lj+SaFlL3w9H2tGmA/a1qs09N8o6Ax
         v9Lz/mJgLsjIkipKuFf+uOMRCYiXAr9m4uR1NQgzqfbsRKD+nr+E/LyWhQa8VEY1w9sQ
         F0TqJMHpMZG8GJf9+XCNPKXYTyJqq6I5ue72ZWQTI8yVK1+di49aZ4l1MsCnab7azR/A
         fdQdfAZ4qmy1xTu5KdieoAUF6Iri16KX+j6eLMab29hbsXa4RbzLqflPeXSTL+mv3sR3
         AK+A==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20161025;
        h=date:from:to:message-id:in-reply-to:references:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :list-post:list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=aL9nlErqi6yFNWp1abRp5NLqtalAzeYqMa1DYJtNZDk=;
        b=O951yGl0e5aEa0ODtUwRF81H8ImU0lJKrrugt5Y3Zxku9xy95ujuGyGi/QnN/ngB+w
         l3p1ItdcUTw3QbuXtkt7W/LkZ83k7yQQatqdT1sEvjyg2Gpl8kNb0cs3Grujy/XLI35j
         18j6pIHftn5+C0Y2MFTpjVMT5buMKD1tNph1+3A3MNKi/7jpuMmxYBBuy5y8pd8m7b5P
         RCcpZtJZX+nAUVfBQRPBM4kbDBzOT4WA29RAjjflnvRzSWupqdHdfgwQLmfzbJxiSuF9
         lD/rbZrYaZdmiI1Swcae6XN7DR5oiJuGrO47CuBDVPoDu4/DF2LfO+EmbxmWoKFXvRl9
         LVEA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        h=x-gm-message-state:date:from:to:message-id:in-reply-to:references
         :subject:mime-version:x-original-sender:reply-to:precedence
         :mailing-list:list-id:x-spam-checked-in-group:list-post:list-help
         :list-archive:list-subscribe:list-unsubscribe;
        bh=aL9nlErqi6yFNWp1abRp5NLqtalAzeYqMa1DYJtNZDk=;
        b=HwDvDygmFCetIFTFif8r1EDZ9JeP8EnPgnZsZZXvIQbHHb8qrcUzWZrJATZlLp8iTr
         4oPufUVEEBUs7IsW8hIfEi9Fqf/wtjquLKZDXTDdtGNOpC2hHd+nrIUyPuEkFI++T0on
         aCtHrsIE1Kk710f1IpzH4hkIf+ad4AyGqRgQybhqH0g+0wU+QE52zQ/IkG7wq/2ZUj0o
         L7+6x6d6romCtfRCVkkKLsEtESS2UDgOv51P35uocW+Kt7+6c76ihkvekCfKfBpY4huG
         39S+KKKKhGb9T+3o3OcVf83XtUr8RaJ0Jsm2Q23/NJo+aoi4XXcvFZoebuXmBmoyDSjw
         DP9A==
X-Gm-Message-State: APf1xPAfpEyv6S3RnsrRjEK3tNss3qv1E9Y4JRWXT4Vow7k4iYMOal+Y
	u4LsraH0KaI0uevShhJXfEFmOQ==
X-Google-Smtp-Source: AH8x227YifQ1lG39ESC7vygLPD1eprGe/PVwxe3ztw0n/fC8L4lXbZ+La1UQo9VkfKNgYf2bXoUBrQ==
X-Received: by 10.31.132.20 with SMTP id g20mr5608234vkd.58.1518430668094;
        Mon, 12 Feb 2018 02:17:48 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.31.156.206 with SMTP id f197ls7351774vke.1.gmail; Mon, 12 Feb
 2018 02:17:46 -0800 (PST)
X-Received: by 10.31.158.65 with SMTP id h62mr992759vke.4.1518430666201;
        Mon, 12 Feb 2018 02:17:46 -0800 (PST)
In-Reply-To: <1e9a5468-6efa-48a2-87ce-6bdb6d5c4e83@isocpp.org>
X-Original-Sender: florian.csdt@gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Spam-Checked-In-Group: std-proposals@isocpp.org
X-Google-Group-Id: 399137483710
List-Post: <https://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <https://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <https://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:36878
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/36878>

------=_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--

.
