220 36896 <5f8efcc0-f4e9-4518-abe5-5fffeab55083@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: Tue, 13 Feb 2018 01:49:59 -0800 (PST)
Lines: 513
Approved: news@gmane.org
Message-ID: <5f8efcc0-f4e9-4518-abe5-5fffeab55083@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>
 <750ecf62-9637-40f4-8585-e3be2780fb46@isocpp.org>
 <f8f4407b-ecf6-4a4a-b3f6-c65813e3f843@isocpp.org>
 <5b5435db-772e-4c38-8867-f6fbc66d7cec@isocpp.org>
 <5c51d89a-54b6-490b-87f2-09ed263d8322@isocpp.org>
 <305b7669-0744-473e-9715-807b7e8051b6@isocpp.org>
 <0ceb2063-d7b6-4cb8-8c5c-c63aceb5b549@isocpp.org>
 <d26b85c2-707b-49a5-a007-617027506dd1@isocpp.org>
 <41b87b07-1a91-4bca-ba00-5734c09dbe77@isocpp.org>
 <ef8fbc4c-08c0-409e-815b-28e161101231@isocpp.org>
 <1a7f714d-4a91-4a95-8da4-0c688d18c4c4@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_11246_456222789.1518515400041"
X-Trace: blaine.gmane.org 1518515313 28689 195.159.176.226 (13 Feb 2018 09:48:33 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Tue, 13 Feb 2018 09:48:33 +0000 (UTC)
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBC26HM4V3MIRBSPJRLKAKGQE56HP7NQ@isocpp.org Tue Feb 13 10:48:28 2018
Return-path: <std-proposals+bncBC26HM4V3MIRBSPJRLKAKGQE56HP7NQ@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-ua0-f197.google.com ([209.85.217.197])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBC26HM4V3MIRBSPJRLKAKGQE56HP7NQ@isocpp.org>)
	id 1elXBt-0005P0-Aq
	for gclcip-std-proposals@m.gmane.org; Tue, 13 Feb 2018 10:47:57 +0100
Original-Received: by mail-ua0-f197.google.com with SMTP id b31sf12071466uah.12
        for <gclcip-std-proposals@m.gmane.org>; Tue, 13 Feb 2018 01:50:03 -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=hJAjq+i5NrU6IUWfo1+zc7s6zGgQw6YVK9CApQOqxTo=;
        b=cb8/nxOTssyYQoI414jRplW3O715hHMJuGiGaycH5xEmtEQ6fC+/ezVggvrQGirDsA
         /k1wJB5iS4C4drF/QBD3Fq+qjwvEv6UpZLIxqejK+Qh2ghNNxiaZcPCHIk7icJm3PpGl
         0jmvBwIqccP9qV6ZqCKdbzqpm0yxbqT5oLmYOLLbeIJP7yhu6cyPhUwkT6MECX+HD2hx
         dO+jlPPiVHK7bhWQGo6PeFFwimrzwaQNOiNOUDAGQ2+eXAHwkQVi3a/qjzHjMeWXDL3E
         iYO05EivTSg3PhdsKFPtAKw9UL1ZsDUSQVCZYLtDlC/Mu0ZWB3qLTIMEPkrvkS/1utAk
         3zig==
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=hJAjq+i5NrU6IUWfo1+zc7s6zGgQw6YVK9CApQOqxTo=;
        b=ncYyUVPEc3YoKe3dE3JlOpMLvDolAqHt4sNEa1u2qkbVcazGaumkdUoXCcLDAUZq2W
         aLNtVeHalQp1q3y5t+fKb6/YZw8SCz/Oh1pKxtt9yAQ03lfDq8YPWgClOXX6smPmoH4O
         wGNdQtZy7EVmYYN99T5xpqhbyoXFfD/yKTthE6j31zabK7yRMMbH6RWb3X1JiZEjYuZW
         ZY+6s7f1P0glvMbFAiA9wPsIze7jVDDWAPTQGas3n87zu3C9vYaVVkBoU3KDy5AjK740
         lAmT+4SMrhW++JGT223Xd9m3DhWs//gb4DpsFdK5ig+aVKubbBPfNFWDqMo2G6cbwyBk
         SKaQ==
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=hJAjq+i5NrU6IUWfo1+zc7s6zGgQw6YVK9CApQOqxTo=;
        b=r3MLC1+2qta2VsluqBa00cXAKPmAv92ywCmEah2OXfbgOaqtYLGuWe7qTyCylOrkeK
         o5ESL8D/B80fSXYww3xNFDekhuz/qfnBYynq4n6SZS+Ze0Ls6SHYg6HrEVzis1W6NVW7
         5gbh8VS9XYnWvfUzrvsPCB15viTZIhwqxze1lRDw61zbDxSq4bd8xGM4pfyt7fXBRH7r
         jl7Z9coMlJ4dG/D5ouvz9SVNyVbovIwILR06XoJm0ZSBdFz57LxczoUB0Z5Fb61dK/jV
         nvaa5XnNSFOOmcH9u+fyyseULWHr2wc6PxTbBEnt6PfSSc1suosqIIITfZ4Q+E+ueAd2
         TTcA==
X-Gm-Message-State: APf1xPDgXuLYZi7HRb16krZyOKyEdMrJXNJMwZy4qWWfqmerjbISJ87i
	eLN88grXzMN3iMW9bJAxlLO81g==
X-Google-Smtp-Source: AH8x227k5F1bI1jKwQHqImM6akCPUm+3P77QDdAcPuPsyKFujCPLObVbO8tY/wQfiXTHDsI03bTZMg==
X-Received: by 10.176.19.237 with SMTP id n42mr106626uae.121.1518515402772;
        Tue, 13 Feb 2018 01:50:02 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.31.252.70 with SMTP id a67ls158440vki.16.gmail; Tue, 13 Feb
 2018 01:50:01 -0800 (PST)
X-Received: by 10.31.160.5 with SMTP id j5mr57353vke.6.1518515400713;
        Tue, 13 Feb 2018 01:50:00 -0800 (PST)
In-Reply-To: <1a7f714d-4a91-4a95-8da4-0c688d18c4c4@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:36896
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/36896>

------=_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--

.
