220 36942 <b376bd12-c955-4ed7-a17b-80b552389476@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: Fri, 16 Feb 2018 07:53:43 -0800 (PST)
Lines: 858
Approved: news@gmane.org
Message-ID: <b376bd12-c955-4ed7-a17b-80b552389476@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> <758ab0a7-8946-43d4-b2ae-5a4acea11c20@isocpp.org>
 <CAC+0CCOovuF+HGepUDQVjkSJoCbGHBNcemaUU9h_gBUPD9ns+w@mail.gmail.com>
 <CAFQaeCBywEdaj1MD0bpyxcjXRkF1jGaCOcpk=4vHtSjEbYbcJw@mail.gmail.com>
 <01057924-056c-4ee5-a19c-e070d053b982@isocpp.org> <CAC+0CCM0SLuJk3GPA-zqb_X7z-kY_tNF1iLnOocLJwP9eErnLQ@mail.gmail.com>
 <c74fcb96-ed06-4360-bedf-e902b000b13b@isocpp.org> <3a738e91-f935-4d11-ab6b-771048b556d4@isocpp.org>
 <96860b9e-95ea-466a-825c-c371844a45e2@isocpp.org> <0caab177-cf57-cab1-a5d5-0fc65f651491@gmail.com>
 <7b1c3d63-d534-44d2-b4e9-fc0df135fff5@isocpp.org>
 <CANaF6iikVH-jjGFxx2whvec=wcRPeXDwTZSevxD9anWhY9zh0g@mail.gmail.com>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_2304_1587938850.1518796423469"
X-Trace: blaine.gmane.org 1518796326 29040 195.159.176.226 (16 Feb 2018 15:52:06 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Fri, 16 Feb 2018 15:52:06 +0000 (UTC)
Cc: jmckesson@gmail.com, florian.csdt@gmail.com
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBCEKFTV6ZUMBBCH5TPKAKGQEFNZS5JA@isocpp.org Fri Feb 16 16:52:02 2018
Return-path: <std-proposals+bncBCEKFTV6ZUMBBCH5TPKAKGQEFNZS5JA@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-vk0-f69.google.com ([209.85.213.69])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBCEKFTV6ZUMBBCH5TPKAKGQEFNZS5JA@isocpp.org>)
	id 1emiIW-0005zz-G2
	for gclcip-std-proposals@m.gmane.org; Fri, 16 Feb 2018 16:51:40 +0100
Original-Received: by mail-vk0-f69.google.com with SMTP id o202sf1839464vkd.23
        for <gclcip-std-proposals@m.gmane.org>; Fri, 16 Feb 2018 07:53:46 -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=2N8cSksq3WVdzK1YAbD6NrG1wSqoF6E68t1rkL9chbA=;
        b=O8s5ZGNBibNKau3ea7+BgKIPE7jL82psAq9e1i9WU7DotlKPJVU2xXU96jHg0c9mJK
         McFMzNqzZLHDoKxfnrt9A3WvdAYBpNsg7+o6V0bgcijHfOJ/aLMbh0x8+CCVHQtpOvYT
         0teE++zXm/4/XVSFEaaM6YekoYLMN5QQo4WMWFODR8LNw+/ufBdfxddve1CFZCqHRTnR
         lY0Z+ydDHPk/PASgmY5Prspm2z5Sk3BMaexwtR/Jf5jF7PY0J/RuQ4qM5AxP3zu5SBRD
         anrnYpYLsBA8zN84AeJdRLpjljUhxoawM4014j6l87SnVdb6ySseJwX+XZJa4B+TrL7I
         okfg==
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=2N8cSksq3WVdzK1YAbD6NrG1wSqoF6E68t1rkL9chbA=;
        b=TBRetHOf080OzduAcEi3CimXPbatzcxdKS+GIrWqmyjaxaGSbtGRzBnHmlYgl2UZpl
         Ir9dQAxGzOCSed5H7gJVUNtbMsa11fyvkOk8tyh3PwPAjgJwrEBkNxJmwbAXMhQ4WRtf
         QJL7/a/PuosWewPfga6I0UnCiUPFQ969DGHM3zF8iNW/Zf2Q7v4G63dhAOsSFDxURuDL
         8mZPTE1/CJBOk73+456yO+udb6AIeKKtzww/ASmJKcQae3lm/w37YeE9kAdgYx6Fe2Xq
         jRZpHle6bhycpSguvKcCppN/s94X8u+GsorFroI9vMpjNTLd+BPIcQmGCV7n3how1fxZ
         HsuA==
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=2N8cSksq3WVdzK1YAbD6NrG1wSqoF6E68t1rkL9chbA=;
        b=GqAQlBTJbSlUzaOMKdAV3tmmv/2fODD8zg/UJpfxBkRHtijv8MuPhYlGajZNKDvuox
         5DNh7TlPp+VMTITCb/AEGvqZyG6xmQmVSVDGA/T6gvn20EZyTSZPL3bMbm0DjjhBKvvQ
         6G3HtLriPZvkr3VXNJ36Smy9r5iO+zSiDhFIzhwycXZSzTw5qzzZNQZ29ok6RVYk3+Hj
         2ab2M5w5PeVpc4QX0d6J1SboPbEHa+6ohoJXZJuJEDddlMNb4JeB2CSBMMMXZCr+kWOx
         x5vD4BtDtUqmkQODaNUi4l+zTeW65dm7zGyq6Ub9ut7lfIornGKstbOKfMi3D0SZ2XIL
         iXrQ==
X-Gm-Message-State: APf1xPCodZz5XzZQAOtt1J+knBpJPbfJVRqQdULz43lKjfdPmzQDXdho
	CQFuHfn91U0aL82uH2CUOztpBg==
X-Google-Smtp-Source: AH8x2257F5zVFWc7HqKOopmiE2HaQfzyQ0cRgW+vS4fxapUXGXnxtl8FPXTpHrL4utI/9NySkDfPCg==
X-Received: by 10.31.237.7 with SMTP id l7mr1698775vkh.101.1518796426195;
        Fri, 16 Feb 2018 07:53:46 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.31.147.150 with SMTP id v144ls1354484vkd.2.gmail; Fri, 16 Feb
 2018 07:53:44 -0800 (PST)
X-Received: by 10.31.157.18 with SMTP id g18mr1062290vke.2.1518796424130;
        Fri, 16 Feb 2018 07:53:44 -0800 (PST)
In-Reply-To: <CANaF6iikVH-jjGFxx2whvec=wcRPeXDwTZSevxD9anWhY9zh0g@mail.gmail.com>
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:36942
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/36942>

------=_Part_2304_1587938850.1518796423469
Content-Type: multipart/alternative; 
	boundary="----=_Part_2305_2040834516.1518796423470"

------=_Part_2305_2040834516.1518796423470
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Friday, February 16, 2018 at 4:18:40 AM UTC-5, Florian Lemaitre wrote:
>
>
> 2018-02-16 2:32 GMT+01:00 Nicol Bolas <jmck...@gmail.com <javascript:>>:
>
>>
>>
>> On Thursday, February 15, 2018 at 5:54:14 PM UTC-5, Florian Lemaitre=20
>> wrote:
>>>
>>> On 15/02/2018 20:39, Nicol Bolas wrote:
>>>
>>> On Thursday, February 15, 2018 at 11:33:26 AM UTC-5, floria...@gmail.co=
m=20
>>> wrote:=20
>>>>
>>>> Le jeudi 15 f=C3=A9vrier 2018 17:19:29 UTC+1, Nicol Bolas a =C3=A9crit=
 :=20
>>>>>
>>>>> On Thursday, February 15, 2018 at 11:06:10 AM UTC-5, Jake Arkinstall=
=20
>>>>> wrote:=20
>>>>>>
>>>>>> On 15 Feb 2018 15:51, "Nicol Bolas" <jmck...@gmail.com> wrote:
>>>>>>
>>>>>> Taking a literal (or possibly constexpr string?)
>>>>>>
>>>>>>
>>>>>> I was wondering whether it makes sense to even describe these things=
=20
>>>>>> as literals, given that they aren't literal and given that they aren=
't=20
>>>>>> intended to actually be stored in memory in any way.
>>>>>>
>>>>>
>>>>> We still call literals "literals", even if you use them entirely at=
=20
>>>>> compile-time via `constexpr` tricks, such that no runtime code ever n=
eeds=20
>>>>> them. Things between quotes are literals.
>>>>>
>>>>> But in terms of constexpr strings, I guess these things themselves ca=
n=20
>>>>>> be built up by other methods - I'm not sure if this makes sense in=
=20
>>>>>> compilation, though; I'm under the impression that the expression it=
self=20
>>>>>> would likely need to be processed before the constexpr methods thems=
elves=20
>>>>>> could be evaluated (especially given that they could themselves util=
ise=20
>>>>>> interpolation). I could be wrong.
>>>>>>
>>>>>> I think, at this point, interpolation is a bad word - it made sense=
=20
>>>>>> in the initial form, but now this has generalised we might want a ne=
w word=20
>>>>>> for it.
>>>>>>
>>>>>
>>>>> I don't agree. "String interpolation" often carries the connotation=
=20
>>>>> that you're just going to concatenate strings, but it doesn't *have*=
=20
>>>>> to. C++ sometimes defines concepts with names that are similar to oth=
er=20
>>>>> language features, but in a more open and freeform way. Lambdas for e=
xample=20
>>>>> don't have lexical scoping in C++ unless you explicitly ask for them,=
=20
>>>>> whereas most languages give it to you as a matter of course.
>>>>>
>>>>> (or possibly arbitrary expressions?)
>>>>>>
>>>>>>
>>>>>> This wouldn't be so much of a problem, because those expressions=20
>>>>>> (other than their declarations) don't need to be completely understo=
od when=20
>>>>>> the [insert better name for interpolation] is performed - just the=
=20
>>>>>> resulting type is needed.
>>>>>>
>>>>>
>>>>> The issue with "arbitrary expression" is that you're now requiring th=
e=20
>>>>> compiler to *invoke the compiler*. It's easy for the compiler to take=
=20
>>>>> a compile-time string and find a variable in scope that matches it. I=
t's=20
>>>>> much harder (presumably) for the compiler to take a compile-time stri=
ng and=20
>>>>> invoke the compiler on it, within the current scope as if it had been=
=20
>>>>> written text.
>>>>>
>>>>> I'm not saying its impossible; I don't know much about compiler=20
>>>>> architecture. But I can't imagine it's as easy as just finding a vari=
able=20
>>>>> with that name.
>>>>>
>>>>> Not only that, once you get into wanting `constexpr` strings that can=
=20
>>>>> be interpolated, you get into lots of issues. Do you really want a fe=
ature=20
>>>>> where you're able to synthesize arbitrary expressions and have someon=
e=20
>>>>> insinuate them into their code at compile time?
>>>>>
>>>>> Or... maybe you do?
>>>>>
>>>>
>>>> From what I know about compilation and formal languages in general, it=
=20
>>>> shouldn't be very hard for a compiler to deal with expressions within=
=20
>>>> `F"{}"`.
>>>> The compiler already do that kind of stuff with parentheses. Compilers=
=20
>>>> are by nature recursive.
>>>>
>>>
>>> You don't seem to be fully understanding what we're talking about. This=
=20
>>> isn't standard recursive-descent recursion. This is "execute some const=
expr=20
>>> code and then run the compiler on part of its string results." Those=20
>>> "results" might include things like *macros*, and macro expansion is=20
>>> supposed to have happened long before executing constexpr functions.
>>>
>>> And you can't just say they're expressions minus macros. Many C-standar=
d=20
>>> library facilities are, or might be, macros after all. Is it legal to d=
o=20
>>> `F"{sin(foo)}"`? If string interpolation is supposed to allow arbitrary=
=20
>>> expressions, it would be odd indeed if it were not. What about invoking=
=20
>>> `offsetof` or similar C-isms?
>>>
>>> If we're only going to allow string interpolation with genuine literals=
,=20
>>> then this isn't much of a problem. Even the macro issue can be sorted o=
ut,=20
>>> since the string is right there in the text of the source code.
>>>
>>> But if we want string interpolation to ever be applied to the results o=
f=20
>>> compile-time execution, that's going to be *much* more complex if=20
>>> string interpolation can handle arbitrary expressions. Whereas if we de=
fine=20
>>> it to just be variable identifiers, extending such interpolation to=20
>>> constexpr strings would be much more reasonable.
>>>
>>> I would say that any proposal should be focused on the minimum=20
>>> featureset. It should naturally include expanding into arbitrary=20
>>> expressions and constexpr strings as future directions things could tak=
e,=20
>>> but I wouldn't push for them in the short term. Sort of like how=20
>>> `constexpr` functions in C++11 were really limited, which C++14 greatly=
=20
>>> expanded.
>>>
>>> The only thing I don't know is if the compiler deals with string=20
>>>> literals as a single token or not. If they do, string literal parser w=
ill=20
>>>> have to be modified quite a lot, even with the "identifier-only" varia=
nt.
>>>>
>>>
>>> First thing first, currently the C++ is oblivious to the preprocessor,=
=20
>>> and this will probably not change in the forseeable future (note that t=
he=20
>>> preprocessor is somehow aware of C++: __cplusplus macro, #include,=20
>>> __has_cpp_attribute...).
>>> But as far as the compiler is concerned, these are two distinct steps=
=20
>>> that are processed one after the other, without going back.
>>>
>>> Maybe you want to change that, but I think you were mentionning macros=
=20
>>> taking effect within F"{}".
>>>
>>
>> No, I'm mentioning macros taking effect within *string interpolation*.
>>
>> We're talking about the intersection of two things, both of which are=20
>> still in question:
>>
>> 1) Arbitrary expressions in interpolation operations.
>> 2) The use of constexpr strings as the *source* for interpolation=20
>> operations; as the string to be interpolated. That is:
>>
>> constexpr constexpr_string<char> my_func()
>> {
>>   constexpr_string<char> a =3D "here's a string {sin(5)}"; //Note: not=
=20
>> doing interpolation.
>>   constexpr_string<char> b =3D " more {foo} string"; //Still not=20
>> interpolating.
>>   return a + b;
>> }
>>
>> auto str =3D std::concat(<interpolation syntax> my_func());
>>
>> //The above is equivalent to:
>>
>> auto str =3D std::concat("here's a string", sin(5), " more ", foo, "=20
>> string");
>>
>> It's the *combination* of these two things that doesn't work. By the=20
>> time the compiler gets around to actually processing the `my_func` call,=
=20
>> macro expansion has come and gone. So how does `sin(5)` get expanded=20
>> properly?
>>
>> And I know you're thinking that constexpr strings don't exist, that=20
>> they're not even really possible. Yet; the committee is working on=20
>> expansions to constexpr that allow memory allocation. Once that happens,=
 we=20
>> will have constexpr strings. And once we do, there's no reason you shoul=
d=20
>> prevent constexpr strings from being the source of interpolation operati=
ons.
>>
>> Well, no reason unless you sandbag interpolation by requiring it to allo=
w=20
>> arbitrary expressions. My feeling is that you have to pick one or the=20
>> other: you either allow arbitrary expressions or you allow constexpr str=
ing=20
>> interpolation. And if we can only have one, I'd much rather have the lat=
ter.
>>
>> I want constexpr strings to be equivalent to literals as much as possibl=
e.
>>
>> I get your problem now.
> Just to simplify my explanations, let's assume that string interpolation=
=20
> is done via a prefix operator called $.
>
> You want to be able to call $ on any constexpr string, and also it would=
=20
> be nice to also have expressions in the interpolation pattern. But as you=
=20
> said, having both would trigger the compiler on compiler output, and this=
=20
> would be difficult to handle.
> I now agree with you on the complexity of having both.
>
> What you're describing here looks like some compile-time "eval".
> constexpr auto call_foo =3D "{foo()}";
>
> // eval:
> $ call_foo;
> // translated to:
> foo();
>
> This looks nasty.
> It would be possible to leak local variables:
> int super_private_copy;
>
> auto foo(/*whatever equivalent to string literal*/ s) {
>   int super_private =3D 5;
>   return std::concat($ s);
> }
>
> void bar() {
>   foo("{super_private_copy =3D super_private}");
>   std::cout << "super_private: " << super_private_copy << std::endl;
> }
>
> This little fictive example shows how this would be possible with those=
=20
> assumptions. And this intrinsically bad, independently to the=20
> implementation complexity.
> The outer world should not affect a private scope without its consent. (s=
o=20
> this does not apply if some global is used within the private scope: in=
=20
> that case, the access to the global is consented by the private scope)
>

> So definitely, having both string interpolation pattern from constexpr=20
> strings *and* expressions can be interpolated is conceptually bad.
>
> So let's consider only string interpolation pattern from constexpr string=
s.
> This also breaks private scope (more tricky though).
> // intended to use access1, access2, access3 or access4 as pattern
> auto foo(/*whatever equivalent to string literal*/ s) {
>   int super_secret =3D 5;
>   int access1 =3D 1;
>   int access2 =3D 2;
>   int access3 =3D 3;
>   int access4 =3D 4;
>   return std::make_tuple($ s);
> }
>
> void bar() {
>   auto super_secret =3D std::get<0>(foo("{super_secret}"));
>   std::cout << "super_secret: " << super_secret << std::endl;
> }
>
> Yes, this example is more convoluted, but it still shows what is possible=
=20
> to do.
>

It's not like the outer scope can force the inner scope to return a=20
`tuple($ s)`. That's the inner scope's choice. Why is it wrong to honor=20
that choice?

You're simply talking about an interface issue. The outer scope can pass=20
the wrong thing to the inner scope, which can cause a compile error or just=
=20
misbehavior. But that's no different from passing the wrong function=20
pointer to a function. If you pass a comparison operator to `std::sort`=20
that doesn't create a strict-weak order, you get broken results. And=20
there's no way to verify that without executing it and seeing the results.

Since this is all done at compile-time, there isn't much of a problem for=
=20
general perfidy in this case (that is, someone hacking your app).

Another thing that could be a problem: what happens if a variable is not=20
> declared? It probably should not compile.
> But then we could have pretty complex and hard to debug code:
>

That's true of any serious `constexpr` coding issue. As we get more and=20
more `constexpr` stuff, we're going to encounter more and more `constexpr`=
=20
debugging problems. At least in this case, the compiler can show us the=20
string that's failing to compile; it's generally easy to track down where=
=20
that came from.

But C++ compilers will need to get into the debugging business if constexpr=
=20
coding is going to be significant. That's regardless of whether we allow=20
string interpolation on constexpr strings.

constexpr auto foo(int i); // returns a "string literal"-like that has the=
=20
> form "{foo###}" where ### is the i-th prime number
>
> void bar() {
>   int foo3 =3D 0;
>   do_whatever($ foo(2));
> } // This compiles
>
> void baz() {
>   int foo4 =3D 0;
>   do_whatever($ foo(2));
> } // This doesn't compile (obviously)
>
> Why is it different than just access a global variable with the right=20
> name? There is no way to know what variables are needed in order to compi=
le=20
> other than trying to compile the program.
> The identifier foo3 is never defined, and never appears in the code=20
> (except within your function).
> Moreover, your local scope now is entangled with the value returned by=20
> foo(). (this kind of breaks encapsulation of the local scope)
>
> Maybe your fine with this one, but I'm not. That's why I think string=20
> interpolation should not apply to constexpr strings (at least, not the=20
> interpolation pattern).
>
> Don't get me wrong: I am perfectly fine to standardize only string=20
> interpolation on actual string literal with only identifiers in patterns,=
=20
> and see later how to improve it.
> But as far as I'm concerned, I think interpolating constexpr patterns is =
a=20
> bad idea and I would much prefer arbitrary expressions to be interpolated=
..
>
>
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/b376bd12-c955-4ed7-a17b-80b552389476%40isocpp.or=
g.

------=_Part_2305_2040834516.1518796423470
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Friday, February 16, 2018 at 4:18:40 AM UTC-5, Florian =
Lemaitre wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr=
"><div><br><div class=3D"gmail_quote">2018-02-16 2:32 GMT+01:00 Nicol Bolas=
 <span dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfusc=
ated-mailto=3D"qaWhZxwYCwAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#=
39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#=
39;;return true;">jmck...@gmail.com</a>&gt;</span>:<br><blockquote class=3D=
"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding=
-left:1ex"><div dir=3D"ltr"><div><div><br><br>On Thursday, February 15, 201=
8 at 5:54:14 PM UTC-5, Florian Lemaitre wrote:<blockquote class=3D"gmail_qu=
ote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding=
-left:1ex">
 =20
   =20
 =20
  <div text=3D"#000000" bgcolor=3D"#FFFFFF">
    On 15/02/2018 20:39, Nicol Bolas wrote:<br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">On Thursday, February 15, 2018 at 11:33:26 AM
        UTC-5, <a>floria...@gmail.com</a> wrote:
        <blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex">
          <div dir=3D"ltr">Le jeudi 15 f=C3=A9vrier 2018 17:19:29 UTC+1, Ni=
col
            Bolas a =C3=A9crit=C2=A0:
            <blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left=
:0.8ex;border-left:1px #ccc solid;padding-left:1ex">
              <div dir=3D"ltr">On Thursday, February 15, 2018 at 11:06:10
                AM UTC-5, Jake Arkinstall wrote:
                <blockquote class=3D"gmail_quote" style=3D"margin:0;margin-=
left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">
                  <div dir=3D"auto">
                    <div>
                      <div>
                        <div class=3D"gmail_quote">On 15 Feb 2018 15:51,
                          &quot;Nicol Bolas&quot; &lt;<a rel=3D"nofollow">j=
mck...@gmail.com</a>&gt;
                          wrote:<br type=3D"attribution">
                          <blockquote style=3D"margin:0 0 0 .8ex;border-lef=
t:1px #ccc solid;padding-left:1ex">
                            <div dir=3D"ltr">
                              <div>Taking a literal (or possibly
                                constexpr string?)</div>
                            </div>
                          </blockquote>
                        </div>
                      </div>
                    </div>
                    <div dir=3D"auto"><br>
                    </div>
                    <div dir=3D"auto">I was wondering whether it makes
                      sense to even describe these things as literals,
                      given that they aren&#39;t literal and given that the=
y
                      aren&#39;t intended to actually be stored in memory i=
n
                      any way.</div>
                  </div>
                </blockquote>
                <div><br>
                  We still call literals &quot;literals&quot;, even if you =
use
                  them entirely at compile-time via `constexpr` tricks,
                  such that no runtime code ever needs them. Things
                  between quotes are literals.<br>
                  <br>
                </div>
                <blockquote class=3D"gmail_quote" style=3D"margin:0;margin-=
left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">
                  <div dir=3D"auto">
                    <div dir=3D"auto">But in terms of constexpr strings, I
                      guess these things themselves can be built up by
                      other methods - I&#39;m not sure if this makes sense
                      in compilation, though; I&#39;m under the impression
                      that the expression itself would likely need to be
                      processed before the constexpr methods themselves
                      could be evaluated (especially given that they
                      could themselves utilise interpolation). I could
                      be wrong.</div>
                    <div dir=3D"auto"><br>
                    </div>
                    <div dir=3D"auto">I think, at this point,
                      interpolation is a bad word - it made sense in the
                      initial form, but now this has generalised we
                      might want a new word for it.</div>
                  </div>
                </blockquote>
                <div><br>
                  I don&#39;t agree. &quot;String interpolation&quot; often=
 carries
                  the connotation that you&#39;re just going to concatenate
                  strings, but it doesn&#39;t <i>have</i> to. C++ sometimes
                  defines concepts with names that are similar to other
                  language features, but in a more open and freeform
                  way. Lambdas for example don&#39;t have lexical scoping i=
n
                  C++ unless you explicitly ask for them, whereas most
                  languages give it to you as a matter of course.<br>
                  <br>
                </div>
                <blockquote class=3D"gmail_quote" style=3D"margin:0;margin-=
left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">
                  <div dir=3D"auto">
                    <div dir=3D"auto">
                      <div>
                        <div class=3D"gmail_quote">
                          <blockquote style=3D"margin:0 0 0 .8ex;border-lef=
t:1px #ccc solid;padding-left:1ex">
                            <div dir=3D"ltr">
                              <div>(or possibly arbitrary expressions?)</di=
v>
                            </div>
                          </blockquote>
                        </div>
                      </div>
                    </div>
                    <div dir=3D"auto"><br>
                    </div>
                    <div dir=3D"auto">This wouldn&#39;t be so much of a
                      problem, because those expressions (other than
                      their declarations) don&#39;t need to be completely
                      understood when the [insert better name for
                      interpolation] is performed - just the resulting
                      type is needed.</div>
                  </div>
                </blockquote>
                <div><br>
                  The issue with &quot;arbitrary expression&quot; is that y=
ou&#39;re
                  now requiring the compiler to <i>invoke the compiler</i>.
                  It&#39;s easy for the compiler to take a compile-time
                  string and find a variable in scope that matches it.
                  It&#39;s much harder (presumably) for the compiler to tak=
e
                  a compile-time string and invoke the compiler on it,
                  within the current scope as if it had been written
                  text.<br>
                  <br>
                  I&#39;m not saying its impossible; I don&#39;t know much =
about
                  compiler architecture. But I can&#39;t imagine it&#39;s a=
s
                  easy as just finding a variable with that name.<br>
                  <br>
                  Not only that, once you get into wanting `constexpr`
                  strings that can be interpolated, you get into lots of
                  issues. Do you really want a feature where you&#39;re abl=
e
                  to synthesize arbitrary expressions and have someone
                  insinuate them into their code at compile time?<br>
                  <br>
                  Or... maybe you do?<br>
                </div>
              </div>
            </blockquote>
            <div><br>
            </div>
            <div>From what I know about compilation and formal languages
              in general, it shouldn&#39;t be very hard for a compiler to
              deal with expressions within `F&quot;{}&quot;`.</div>
            <div>The compiler already do that kind of stuff with
              parentheses. Compilers are by nature recursive.</div>
          </div>
        </blockquote>
        <div><br>
          You don&#39;t seem to be fully understanding what we&#39;re talki=
ng
          about. This isn&#39;t standard recursive-descent recursion. This
          is &quot;execute some constexpr code and then run the compiler on
          part of its string results.&quot; Those &quot;results&quot; might=
 include
          things like <i>macros</i>, and macro expansion is supposed to
          have happened long before executing constexpr functions.<br>
          <br>
          And you can&#39;t just say they&#39;re expressions minus macros. =
Many
          C-standard library facilities are, or might be, macros after
          all. Is it legal to do `F&quot;{sin(foo)}&quot;`? If string
          interpolation is supposed to allow arbitrary expressions, it
          would be odd indeed if it were not. What about invoking
          `offsetof` or similar C-isms?<br>
          <br>
          If we&#39;re only going to allow string interpolation with genuin=
e
          literals, then this isn&#39;t much of a problem. Even the macro
          issue can be sorted out, since the string is right there in
          the text of the source code.<br>
          <br>
          But if we want string interpolation to ever be applied to the
          results of compile-time execution, that&#39;s going to be <i>much=
</i>
          more complex if string interpolation can handle arbitrary
          expressions. Whereas if we define it to just be variable
          identifiers, extending such interpolation to constexpr strings
          would be much more reasonable.<br>
          <br>
          I would say that any proposal should be focused on the minimum
          featureset. It should naturally include expanding into
          arbitrary expressions and constexpr strings as future
          directions things could take, but I wouldn&#39;t push for them in
          the short term. Sort of like how `constexpr` functions in
          C++11 were really limited, which C++14 greatly expanded.<br>
          <br>
        </div>
        <blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex">
          <div dir=3D"ltr">
            <div>The only thing I don&#39;t know is if the compiler deals
              with string literals as a single token or not. If they do,
              string literal parser will have to be modified quite a
              lot, even with the &quot;identifier-only&quot; variant.<br>
            </div>
          </div>
        </blockquote>
      </div>
    </blockquote>
    <br>
    <div>First thing first, currently the C++ is oblivious to the
      preprocessor, and this will probably not change in the forseeable
      future (note that the preprocessor is somehow aware of C++:
      __cplusplus macro, #include, __has_cpp_attribute...).</div>
    <div>But as far as the compiler is concerned, these are two distinct
      steps that are processed one after the other, without going back.</di=
v>
    <div><br>
    </div>
    <div>Maybe you want to change that, but I think you were mentionning
      macros taking effect within F&quot;{}&quot;.</div></div></blockquote>=
</div></div><div><br>No, I&#39;m mentioning macros taking effect within <i>=
string interpolation</i>.<br><br>We&#39;re talking about the intersection o=
f two things, both of which are still in question:<br><br>1) Arbitrary expr=
essions in interpolation operations.<br>2) The use of constexpr strings as =
the <i>source</i> for interpolation operations; as the string to be interpo=
lated. That is:<br><br><div style=3D"background-color:rgb(250,250,250);bord=
er-color:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><=
span style=3D"color:#008">constexpr</span><span style=3D"color:#000"> const=
expr_string</span><span style=3D"color:#080">&lt;char&gt;</span><span style=
=3D"color:#000"> my_func</span><span style=3D"color:#660">()</span><span st=
yle=3D"color:#000"><br></span><span style=3D"color:#660">{</span><span styl=
e=3D"color:#000"><br>=C2=A0 constexpr_string</span><span style=3D"color:#08=
0">&lt;char&gt;</span><span style=3D"color:#000"> a </span><span style=3D"c=
olor:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D"colo=
r:#080">&quot;here&#39;s a string {sin(5)}&quot;</span><span style=3D"color=
:#660">;</span><span style=3D"color:#000"> </span><span style=3D"color:#800=
">//Note: not doing interpolation.</span><span style=3D"color:#000"><br>=C2=
=A0 constexpr_string</span><span style=3D"color:#080">&lt;char&gt;</span><s=
pan style=3D"color:#000"> b </span><span style=3D"color:#660">=3D</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#080">&quot; more {foo=
} string&quot;</span><span style=3D"color:#660">;</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#800">//Still not interpolating.</span=
><span style=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#008">re=
turn</span><span style=3D"color:#000"> a </span><span style=3D"color:#660">=
+</span><span style=3D"color:#000"> b</span><span style=3D"color:#660">;</s=
pan><span style=3D"color:#000"><br></span><span style=3D"color:#660">}</spa=
n><span style=3D"color:#000"><br><br></span><span style=3D"color:#008">auto=
</span><span style=3D"color:#000"> str </span><span style=3D"color:#660">=
=3D</span><span style=3D"color:#000"> std</span><span style=3D"color:#660">=
::</span><span style=3D"color:#000">concat</span><span style=3D"color:#660"=
>(&lt;</span><span style=3D"color:#000">interpolation syntax</span><span st=
yle=3D"color:#660">&gt;</span><span style=3D"color:#000"> my_func</span><sp=
an style=3D"color:#660">());</span><span style=3D"color:#000"><br><br></spa=
n><span style=3D"color:#800">//The above is equivalent to:</span><span styl=
e=3D"color:#000"><br><br></span><span style=3D"color:#008">auto</span><span=
 style=3D"color:#000"> str </span><span style=3D"color:#660">=3D</span><spa=
n style=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span=
 style=3D"color:#000">concat</span><span style=3D"color:#660">(</span><span=
 style=3D"color:#080">&quot;here&#39;s a string&quot;</span><span style=3D"=
color:#660">,</span><span style=3D"color:#000"> sin</span><span style=3D"co=
lor:#660">(</span><span style=3D"color:#066">5</span><span style=3D"color:#=
660">),</span><span style=3D"color:#000"> </span><span style=3D"color:#080"=
>&quot; more &quot;</span><span style=3D"color:#660">,</span><span style=3D=
"color:#000"> foo</span><span style=3D"color:#660">,</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#080">&quot; string&quot;</span><sp=
an style=3D"color:#660">);</span><span style=3D"color:#000"><br></span></di=
v></code></div><br>It&#39;s the <i>combination</i> of these two things that=
 doesn&#39;t work. By the time the compiler gets around to actually process=
ing the `my_func` call, macro expansion has come and gone. So how does `sin=
(5)` get expanded properly?<br><br>And I know you&#39;re thinking that cons=
texpr strings don&#39;t exist, that they&#39;re not even really possible. Y=
et; the committee is working on expansions to constexpr that allow memory a=
llocation. Once that happens, we will have constexpr strings. And once we d=
o, there&#39;s no reason you should prevent constexpr strings from being th=
e source of interpolation operations.<br><br>Well, no reason unless you san=
dbag interpolation by requiring it to allow arbitrary expressions. My feeli=
ng is that you have to pick one or the other: you either allow=20
arbitrary expressions or you allow constexpr string interpolation. And=20
if we can only have one, I&#39;d much rather have the latter.<br><br>I want=
 constexpr strings to be equivalent to literals as much as possible.<br></d=
iv><br></div></blockquote></div><div>I get your problem now.<br></div><div>=
Just to simplify my explanations, let&#39;s assume that string interpolatio=
n is done via a prefix operator called $.</div><div><br></div><div>You
 want to be able to call $ on any constexpr string, and also it would be
 nice to also have expressions in the interpolation pattern. But as you=20
said, having both would trigger the compiler on compiler output, and=20
this would be difficult to handle.</div><div>I now agree with you on the co=
mplexity of having both.</div><div><br></div><div>What you&#39;re describin=
g here looks like some compile-time &quot;eval&quot;.</div><div><div style=
=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-=
style:solid;border-width:1px"><code><div><span style=3D"color:rgb(0,0,136)"=
>constexpr</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"co=
lor:rgb(0,0,136)">auto</span><span style=3D"color:rgb(0,0,0)"> call_foo </s=
pan><span style=3D"color:rgb(102,102,0)">=3D</span><span style=3D"color:rgb=
(0,0,0)"> </span><span style=3D"color:rgb(0,136,0)">&quot;{foo()}&quot;</sp=
an><span style=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,=
0,0)"><br><br></span><span style=3D"color:rgb(136,0,0)">// eval:</span><spa=
n style=3D"color:rgb(0,0,0)"><br>$ call_foo</span><span style=3D"color:rgb(=
102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br></span><span style=
=3D"color:rgb(136,0,0)">// translated to:</span><span style=3D"color:rgb(0,=
0,0)"><br>foo</span><span style=3D"color:rgb(102,102,0)">();</span><span st=
yle=3D"color:rgb(0,0,0)"><br></span></div></code></div><br>This looks nasty=
..<br></div><div>It would be possible to leak local variables:</div><div><di=
v style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);=
border-style:solid;border-width:1px"><code><div><span style=3D"color:rgb(0,=
0,136)">int</span><span style=3D"color:rgb(0,0,0)"> super_private_copy</spa=
n><span style=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0=
,0)"><br><br></span><span style=3D"color:rgb(0,0,136)">auto</span><span sty=
le=3D"color:rgb(0,0,0)"> foo</span><span style=3D"color:rgb(102,102,0)">(</=
span><span style=3D"color:rgb(136,0,0)">/*whatever equivalent to string lit=
eral*/</span><span style=3D"color:rgb(0,0,0)"> s</span><span style=3D"color=
:rgb(102,102,0)">)</span><span style=3D"color:rgb(0,0,0)"> </span><span sty=
le=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"><br>=
=C2=A0 </span><span style=3D"color:rgb(0,0,136)">int</span><span style=3D"c=
olor:rgb(0,0,0)"> super_private </span><span style=3D"color:rgb(102,102,0)"=
>=3D</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rg=
b(0,102,102)">5</span><span style=3D"color:rgb(102,102,0)">;</span><span st=
yle=3D"color:rgb(0,0,0)"><br>=C2=A0 </span><span style=3D"color:rgb(0,0,136=
)">return</span><span style=3D"color:rgb(0,0,0)"> std</span><span style=3D"=
color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,0)">concat</spa=
n><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0=
,0)">$ s</span><span style=3D"color:rgb(102,102,0)">);</span><span style=3D=
"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(102,102,0)">}</span>=
<span style=3D"color:rgb(0,0,0)"><br><br></span><span style=3D"color:rgb(0,=
0,136)">void</span><span style=3D"color:rgb(0,0,0)"> bar</span><span style=
=3D"color:rgb(102,102,0)">()</span><span style=3D"color:rgb(0,0,0)"> </span=
><span style=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,=
0)"><br>=C2=A0 foo</span><span style=3D"color:rgb(102,102,0)">(</span><span=
 style=3D"color:rgb(0,136,0)">&quot;{super_private_copy =3D super_private}&=
quot;</span><span style=3D"color:rgb(102,102,0)">);</span><span style=3D"co=
lor:rgb(0,0,0)"><br>=C2=A0 std</span><span style=3D"color:rgb(102,102,0)">:=
:</span><span style=3D"color:rgb(0,0,0)">cout </span><span style=3D"color:r=
gb(102,102,0)">&lt;&lt;</span><span style=3D"color:rgb(0,0,0)"> </span><spa=
n style=3D"color:rgb(0,136,0)">&quot;super_private: &quot;</span><span styl=
e=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">&lt;&lt=
;</span><span style=3D"color:rgb(0,0,0)"> super_private_copy </span><span s=
tyle=3D"color:rgb(102,102,0)">&lt;&lt;</span><span style=3D"color:rgb(0,0,0=
)"> std</span><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"=
color:rgb(0,0,0)">endl</span><span style=3D"color:rgb(102,102,0)">;</span><=
span style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(102,102=
,0)">}</span><span style=3D"color:rgb(0,0,0)"><br></span></div></code></div=
></div><div><br>This
 little fictive example shows how this would be possible with those=20
assumptions. And this intrinsically bad, independently to the=20
implementation complexity.</div><div>The outer world should not affect a
 private scope without its consent. (so this does not apply if some=20
global is used within the private scope: in that case, the access to the
 global is consented by the private scope)</div></div></div></blockquote><b=
lockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; border-=
left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div><br></div></bl=
ockquote><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div=
><div></div><div>So definitely, having both string interpolation pattern fr=
om constexpr strings <b>and</b> expressions can be interpolated is conceptu=
ally bad.</div><div><br></div><div>So let&#39;s consider only string interp=
olation pattern from constexpr strings.</div><div>This also breaks private =
scope (more tricky though).</div><div><div style=3D"background-color:rgb(25=
0,250,250);border-color:rgb(187,187,187);border-style:solid;border-width:1p=
x"><code><div><span style=3D"color:rgb(0,0,136)">// intended to use access1=
, access2, access3 or access4 as pattern<br>auto</span><span style=3D"color=
:rgb(0,0,0)"> foo</span><span style=3D"color:rgb(102,102,0)">(</span><span =
style=3D"color:rgb(0,0,0)"><code><span style=3D"color:rgb(136,0,0)">/*whate=
ver equivalent to string literal*/</span><span style=3D"color:rgb(0,0,0)"> =
s) {<br>=C2=A0 int super_secret =3D 5;<br>=C2=A0 int access1 =3D 1;<br>=C2=
=A0 int access2 =3D 2;<br>=C2=A0 int access3 =3D 3;<br>=C2=A0 int access4 =
=3D 4;<br>=C2=A0 return std::make_tuple($ s);<br>}<br><br>void bar() {<br>=
=C2=A0 auto super_secret =3D std::get&lt;0&gt;(foo(&quot;{super_<wbr>secret=
}&quot;));<br>=C2=A0 std::cout &lt;&lt; &quot;super_secret: &quot; &lt;&lt;=
 super_secret &lt;&lt; std::endl;<br>}<br></span><span style=3D"color:rgb(1=
02,102,0)"></span></code></span></div></code></div></div><div><br>Yes, this=
 example is more convoluted, but it still shows what is possible to do.</di=
v></div></div></blockquote><div><br>It&#39;s not like the outer scope can f=
orce the inner scope to return a `tuple($ s)`. That&#39;s the inner scope&#=
39;s choice. Why is it wrong to honor that choice?<br><br>You&#39;re simply=
 talking about an interface issue. The outer scope can pass the wrong thing=
 to the inner scope, which can cause a compile error or just misbehavior. B=
ut that&#39;s no different from passing the wrong function pointer to a fun=
ction. If you pass a comparison operator to `std::sort` that doesn&#39;t cr=
eate a strict-weak order, you get broken results. And there&#39;s no way to=
 verify that without executing it and seeing the results.<br><br>Since this=
 is all done at compile-time, there isn&#39;t much of a problem for general=
 perfidy in this case (that is, someone hacking your app).<br><br></div><bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div></div>=
<div>Another thing that could be a problem: what happens if a variable is n=
ot declared? It probably should not compile.</div><div>But then we could ha=
ve pretty complex and hard to debug code:</div></div></div></blockquote><di=
v><br>That&#39;s true of any serious `constexpr` coding issue. As we get mo=
re and more `constexpr` stuff, we&#39;re going to encounter more and more `=
constexpr` debugging problems. At least in this case, the compiler can show=
 us the string that&#39;s failing to compile; it&#39;s generally easy to tr=
ack down where that came from.<br><br>But C++ compilers will need to get in=
to the debugging business if constexpr coding is going to be significant. T=
hat&#39;s regardless of whether we allow string interpolation on constexpr =
strings.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;=
margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><div><div><div style=3D"background-color:rgb(250,250,250);border-c=
olor:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><span=
 style=3D"color:rgb(102,0,102)">constexpr auto foo</span><span style=3D"col=
or:rgb(102,102,0)"></span>(int i); // returns a &quot;string literal&quot;-=
like that has the form &quot;{foo###}&quot; where ### is the i-th prime num=
ber<br><br>void bar() {<br>=C2=A0 int foo3 =3D 0;<br>=C2=A0 do_whatever($ f=
oo(2));<br>} // This compiles<br><br>void baz() {<br>=C2=A0 int foo4 =3D 0;=
<br>=C2=A0 do_whatever($ foo(2));<br>} // This doesn&#39;t compile (obvious=
ly)<br></div></code></div><br>Why
 is it different than just access a global variable with the right name?
 There is no way to know what variables are needed in order to compile=20
other than trying to compile the program.</div><div>The identifier foo3 is =
never defined, and never appears in the code (except within your function).=
</div><div>Moreover,
 your local scope now is entangled with the value returned by foo().=20
(this kind of breaks encapsulation of the local scope)</div><div><br></div>=
<div>Maybe
 your fine with this one, but I&#39;m not. That&#39;s why I think string=20
interpolation should not apply to constexpr strings (at least, not the=20
interpolation pattern).</div><div><br></div><div>Don&#39;t get me wrong: I=
=20
am perfectly fine to standardize only string interpolation on actual=20
string literal with only identifiers in patterns, and see later how to=20
improve it.</div><div>But as far as I&#39;m concerned, I think interpolatin=
g
 constexpr patterns is a bad idea and I would much prefer arbitrary=20
expressions to be interpolated.<br></div><div><br></div><br></div></div>
</blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/b376bd12-c955-4ed7-a17b-80b552389476%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/b376bd12-c955-4ed7-a17b-80b552389476=
%40isocpp.org</a>.<br />

------=_Part_2305_2040834516.1518796423470--

------=_Part_2304_1587938850.1518796423469--

.
