220 36906 <d2698aec-cf41-4787-8aa5-334a34868aea@isocpp.org> article
Path: news.gmane.org!.POSTED!not-for-mail
From: Nicol Bolas <jmckesson@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: String interpolation
Date: Tue, 13 Feb 2018 13:39:35 -0800 (PST)
Lines: 552
Approved: news@gmane.org
Message-ID: <d2698aec-cf41-4787-8aa5-334a34868aea@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>
 <5f8efcc0-f4e9-4518-abe5-5fffeab55083@isocpp.org>
 <0e0876bb-7a44-45ff-ab9b-6443e78ea59c@isocpp.org>
 <3468ee0c-a44a-437a-a835-0156c623df2e@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_8004_1403166943.1518557975801"
X-Trace: blaine.gmane.org 1518557868 22016 195.159.176.226 (13 Feb 2018 21:37:48 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Tue, 13 Feb 2018 21:37:48 +0000 (UTC)
Cc: florian.csdt@gmail.com
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBCEKFTV6ZUMBBGFWRXKAKGQEV2OSO6Q@isocpp.org Tue Feb 13 22:37:44 2018
Return-path: <std-proposals+bncBCEKFTV6ZUMBBGFWRXKAKGQEV2OSO6Q@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-vk0-f71.google.com ([209.85.213.71])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBCEKFTV6ZUMBBGFWRXKAKGQEV2OSO6Q@isocpp.org>)
	id 1eliGa-0004mG-R8
	for gclcip-std-proposals@m.gmane.org; Tue, 13 Feb 2018 22:37:33 +0100
Original-Received: by mail-vk0-f71.google.com with SMTP id l205sf12073064vke.13
        for <gclcip-std-proposals@m.gmane.org>; Tue, 13 Feb 2018 13:39:38 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to:cc: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=m/myaocWZD7EHKxEcH12FdU9ocSIWXEzHjKWkQJYOzU=;
        b=dvVz7VzUTxJ1/3y3n7YYkCTbmPKM4XgMkF9ZnEZhGpKnY45XcUb2eUsmNUNiWQTLEH
         eJCrzW8+aMzdHPr0io+m3sp43Iqa42Wa2EbWZzSKsEoH7AcIxQCwYOwH/ZvOD7U64Q56
         6FKGeewDmjMMTJYgiuSy4pG/qOl0nNiiZO6lfiU8XEXiMD7e35/K6ySpxN3m3NIZELwi
         amD2V532CJTKJXz4ZBHmL4t/HaIpAY6EacXGV5xufEerw+Cnc3vkjLBr/Gf1wdz31sMt
         6HT6b159DlRY+9x5qJxYoF0WRHIt40usrjrY1rY0hwrtBJ2/iUeTUPdkipk8Hs8FSoW0
         mmbw==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20161025;
        h=date:from:to:cc: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=m/myaocWZD7EHKxEcH12FdU9ocSIWXEzHjKWkQJYOzU=;
        b=Wj5BbjF6mpyW4Z9juii0k9AxTpBjOPjBI4jq3NNSMnVuFNB8ZNuBzdiUKZqIV0m8GC
         5+7IgHlsk9JBIbkx/+2VJgeoJbEmoOTdwtB8HoANMjA7AtOaqBpoyCk5HYm+Zj8Cckpj
         HkY2bv34q6XM6Bc/uVBmtJryyClImNuVxFjxelgXaKcyW58nMGW0RLpSbcudSMgnRzga
         4Lo7nCszoXrFme65r0Z4IsZbTNTx4nRhMHt7x5Cf+77bxS/AMpBlc2ktU8Siif8Wmm0T
         ZOZlj3zTfN/3ymCT4iitn8X5R8csI5TATIo/gTIv0xi61DTSAM+GQqS9o9jCIpOt2IHm
         /gqw==
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:cc: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=m/myaocWZD7EHKxEcH12FdU9ocSIWXEzHjKWkQJYOzU=;
        b=pMoGBKKu/nnJEQbG9U8vrOWseKHdsijtzeH2KknKaus4aN2lkO25UoIAOJIMiLtEkG
         Q69NzDyNrpGyuXW5ydErWIufG+6PPuRPHPRzvTSXSn0e5ch5b4kbjGHXzphFXjZduYCK
         +9DpF51sPyVU30oaziIQCmpHreaA4t+zaJqPBhcn2mDVgP0POEQvNw+R8pXBF54OqewQ
         KUXVMapaeegTExcBJc5WkdgWOp+oNq7QCraBgfMeFX6ArFKcTJ8kDECXcPeDx6m564HC
         DG6lqyWygnV4G3kyrflZ6YqqZ2nf7rbKc5HSDSkqqlH0q/UBar7xWO+H0N3Xppcg2Usv
         COEA==
X-Gm-Message-State: APf1xPB9o5UBsTl8HqkA79fN2sIcRQlppR9JpAizUJ4ud5z3/fybo3cd
	sN3kMoxMnSVWj4ZtDi01PJYVQw==
X-Google-Smtp-Source: AH8x2268efwaoGwYsmUJ6jZeDZDu5FsreMmS86SLzWUPYgExOfKW4GY9+/FJpNWGWlVcs5TVpSuqow==
X-Received: by 10.176.91.23 with SMTP id u23mr1148548uae.57.1518557978389;
        Tue, 13 Feb 2018 13:39:38 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.31.170.74 with SMTP id t71ls2462776vke.8.gmail; Tue, 13 Feb
 2018 13:39:36 -0800 (PST)
X-Received: by 10.31.185.13 with SMTP id j13mr149475vkf.8.1518557976441;
        Tue, 13 Feb 2018 13:39:36 -0800 (PST)
In-Reply-To: <3468ee0c-a44a-437a-a835-0156c623df2e@isocpp.org>
X-Original-Sender: jmckesson@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:36906
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/36906>

------=_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--

.
