220 36933 <0caab177-cf57-cab1-a5d5-0fc65f651491@gmail.com> article
Path: news.gmane.org!.POSTED!not-for-mail
From: Florian Lemaitre <florian.csdt@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: String interpolation
Date: Thu, 15 Feb 2018 23:54:09 +0100
Lines: 717
Approved: news@gmane.org
Message-ID: <0caab177-cf57-cab1-a5d5-0fc65f651491@gmail.com>
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>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative;
 boundary="------------4A1C972F24C2F7300041622D"
X-Trace: blaine.gmane.org 1518735149 5622 195.159.176.226 (15 Feb 2018 22:52:29 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Thu, 15 Feb 2018 22:52:29 +0000 (UTC)
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101
 Thunderbird/52.6.0
To: Nicol Bolas <jmckesson@gmail.com>,
 ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBC26HM4V3MIRBFE7TDKAKGQEG2WQZ6A@isocpp.org Thu Feb 15 23:52:25 2018
Return-path: <std-proposals+bncBC26HM4V3MIRBFE7TDKAKGQEG2WQZ6A@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-wr0-f200.google.com ([209.85.128.200])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBC26HM4V3MIRBFE7TDKAKGQEG2WQZ6A@isocpp.org>)
	id 1emSNs-0000Ct-1h
	for gclcip-std-proposals@m.gmane.org; Thu, 15 Feb 2018 23:52:08 +0100
Original-Received: by mail-wr0-f200.google.com with SMTP id w10sf625478wrg.2
        for <gclcip-std-proposals@m.gmane.org>; Thu, 15 Feb 2018 14:54:14 -0800 (PST)
ARC-Seal: i=2; a=rsa-sha256; t=1518735253; cv=pass;
        d=google.com; s=arc-20160816;
        b=InT5m3779nvva3zsGHpaDSCNlyCCn044tCClY11lBB9myCJMnP/p3YWovzR+We6LnF
         LXcWP/diUJ5Lw4rb1AnqJG28kvKp4qE31zZXEgIYF0t07/CeURCEh5ZuI0WzL6sCehip
         Oh1w/a5xaHjaSgZgosRGRws0Vddy9H/vaHkPsLC599Sv6M4Ug4ZwtAQOMZaRF3/a5UGf
         2ponEoG+puA0NmD5oEArTbmBKk8vtcGORBJkOw6QseeF8yt2o9x/XD5FYzmp/FWp8ZVV
         DTigjpS8cGJaFdFZZRxadP8NNU+ecTtGzvIQ3F29JZMwlXf6IAjImdro+lbBEfFjOXSP
         Fd7A==
ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816;
        h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post
         :list-id:mailing-list:precedence:reply-to:content-language
         :in-reply-to:mime-version:user-agent:date:message-id:from:references
         :to:subject:arc-authentication-results:arc-message-signature
         :dkim-signature:arc-authentication-results;
        bh=xsOxd3iOQkekA6z88HAOYPtAjFqBs59T6+s+WKohHso=;
        b=IDP8F3qw0f6eHTbg3fgG2XfTNnI6vQYFGl3yEuu4HbbJOzXcwU8alLrcO+ZmT+q8Q7
         7Odbqr9hUMA3XJrlWLit5KrF1HXa+HJSPOCBoPA78alty+F5G0N3cEhb+R3DGnlbT0lQ
         3nH1l1AtXNCn9XpI7WDXbl6bDphEYtYhKu6/9uIaDk/hzFUVs5Yuih+AS8ZaAVf5TTpM
         E0wjxyKHY9pJKcqRS8xwnye1qeq9tN4tWP6i7EpQCvRbW94CoibrcJX3eFQiJ7jkv45p
         vrwlP5T/g0GDzsGMaWzTBoWoYK2FHF33TGHLUPobd+umtW0qpf8UjlGLhuny7t9HUIZZ
         k3Ng==
ARC-Authentication-Results: i=2; mx.google.com;
       dkim=pass header.i=@gmail.com header.s=20161025 header.b=aBRW8CUa;
       spf=pass (google.com: domain of florian.csdt@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=florian.csdt@gmail.com;
       dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=subject:to:references:from:message-id:date:user-agent:mime-version
         :in-reply-to:content-language:x-original-sender
         :x-original-authentication-results:reply-to:precedence:mailing-list
         :list-id:list-post:list-help:list-archive:list-subscribe
         :list-unsubscribe;
        bh=xsOxd3iOQkekA6z88HAOYPtAjFqBs59T6+s+WKohHso=;
        b=bVp4+Q+pgwxSGJ7m9wH3kufr5iT+5VkuZFoZqahqvsClEjzg5B+B83UPdotDHXB6BA
         QBryjz+TyHVoE23p9zdVRQsvA/BwPkmjgKZeJS1Wyttju9Qhm+LzDHBA5yD4m7EAgzih
         0bQ50GNf68GJAurAcTN0dAwOvwVCyU0u5y8QR/Y7ADdhoiz7P7KayTSwUyOmudi562xg
         BBr2mx9mVEUvZH7PYWOv3ZiQXu2ZGfpyN7z7WgQuHs/AnZqjR9aVegqxWCGzYzkiVcNn
         f1RTg9Ss/afvslLofV5IbrXqR2Dh9lgDwiAAd6SmBXDa4pIOyuvX1mlUYrzusOoZoIos
         1EfQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        h=x-gm-message-state:subject:to:references:from:message-id:date
         :user-agent:mime-version:in-reply-to:content-language
         :x-original-sender:x-original-authentication-results:reply-to
         :precedence:mailing-list:list-id:x-spam-checked-in-group:list-post
         :list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=xsOxd3iOQkekA6z88HAOYPtAjFqBs59T6+s+WKohHso=;
        b=aM5I1EnLxDIPHhsL5VJfDdXVYiJdQOuIVBYw+Vi1m4mGQVW1bCjCWMmoqbIFswFUBC
         NSgRVFj+u9hMhRsmAcZYjOO+uO119fNLDpqwj8j6KGnTW4Y9HwMiCrIvl6l33xsat9L1
         ELX/1rrG9PdR2ZC6eR5GjhVq7tE/beGUDXrbeQG1pW73FWNns9OzTdXq7PPWq889RRgq
         MatQ1afsL0jqLnFXb26CDPcer7ldxp8JUDjxJmSUvJFQqEUY4FFaArcIGfjjjYz0qQ2r
         NBqrGOpZFGcDKXOuly3DR00zFHI7xdsXvfergI4x/3y+KmM3SUp4FhxePCLUWtzsYrJ7
         1 
X-Gm-Message-State: APf1xPAx2eLpi44Wa4yJzDGZdGZyu1+WEw2L0Igo450vj4T9HSeq115p
	F0I0qYyIdTZVcGftb6EfNybabQ==
X-Google-Smtp-Source: AH8x227+Z903Frnydgzq5qfApn9H8Y+aVxAFcxXIRyAtQQ7hOmk6pgzh/d4Bvtqk5iasdackg/M5FA==
X-Received: by 10.28.145.139 with SMTP id t133mr1124276wmd.21.1518735253786;
        Thu, 15 Feb 2018 14:54:13 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.28.31.200 with SMTP id f191ls10716wmf.5.canary-gmail; Thu, 15
 Feb 2018 14:54:12 -0800 (PST)
X-Received: by 10.28.103.9 with SMTP id b9mr813478wmc.32.1518735251966;
        Thu, 15 Feb 2018 14:54:11 -0800 (PST)
ARC-Seal: i=1; a=rsa-sha256; t=1518735251; cv=none;
        d=google.com; s=arc-20160816;
        b=IHClgPXdYtqMs8fMJ3Ki0dThOCMsqmbIv3ShnXhKYZ96SBsSDnk7Dv+QyGuMv9mHSP
         WXPHNydaxL8BNdNktd2pXtI/wlT54nv5dsb0ZTtC1u55ku61tXwxiscZ/VBKZbuG0JVi
         y2CUM5IAutIvnfg5WDVQWZgpQnaH2BQccsCUcJf3LihgvMDl0a2Qb3tpBEeIzb+8Oawz
         E17Oz+9JPb16twiS2YqXkK9mpi5KB4pzOBpXy/jfaKNfAW3n13rvJ0HMtZWejqLaM+qS
         0erDbwwot/wZVskIYEYdjSpCfyecoCXNwSNgwHNYcWrBq8UI24I5DdVkdgeBhJRbuX0E
         UopA==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816;
        h=content-language:in-reply-to:mime-version:user-agent:date
         :message-id:from:references:to:subject:dkim-signature
         :arc-authentication-results;
        bh=FefABpeG1X3WxNGncpL5JpgZc9pKfVLqG9iRufC/AYU=;
        b=1EB+A58m87Xm9dxNqqFugwG0xNTrVcqsao/lkKVSXTX0TFAUBHK1b3pJMw51tx/OlC
         bUaWKl/s+q2nDpXh7HwdyRNzpG0/4xy2C06DjOXPp5Vd5ITIMFqOtKeLK+X2o6oGIeQf
         hZ3Bt9MRkiIgNWkjTYh5C4Fq1EK1PAnr3mRPzjbWcanP+zMy4a8mRQgiYpcWzHdCPh0y
         3NN2Y8MHIa8GCj8rm2ko0tmisYSybgfGLaAabVT6rwFgnkDjxpVewvgWcH5Nv3BXQbbX
         /FBDhl7xRzUjaS5jK4KeonJM8YlDSNSl+9/LjBJfoC27Y8ll/x5VghFVryWfF0ldP4Sn
         BSng==
ARC-Authentication-Results: i=1; mx.google.com;
       dkim=pass header.i=@gmail.com header.s=20161025 header.b=aBRW8CUa;
       spf=pass (google.com: domain of florian.csdt@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=florian.csdt@gmail.com;
       dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com
Original-Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41])
        by mx.google.com with SMTPS id w79sor7659620wrb.12.2018.02.15.14.54.11
        for <std-proposals@isocpp.org>
        (Google Transport Security);
        Thu, 15 Feb 2018 14:54:11 -0800 (PST)
Received-SPF: pass (google.com: domain of florian.csdt@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41;
X-Received: by 10.223.136.188 with SMTP id f57mr3751738wrf.7.1518735251175;
        Thu, 15 Feb 2018 14:54:11 -0800 (PST)
Original-Received: from [192.168.1.90] (176-153-8-250.abo.bbox.fr. [176.153.8.250])
        by smtp.gmail.com with ESMTPSA id z78sm19241482wrc.53.2018.02.15.14.54.10
        (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
        Thu, 15 Feb 2018 14:54:10 -0800 (PST)
In-Reply-To: <96860b9e-95ea-466a-825c-c371844a45e2@isocpp.org>
Content-Language: en-US
X-Original-Sender: florian.csdt@gmail.com
X-Original-Authentication-Results: mx.google.com;       dkim=pass
 header.i=@gmail.com header.s=20161025 header.b=aBRW8CUa;       spf=pass
 (google.com: domain of florian.csdt@gmail.com designates 209.85.220.41 as
 permitted sender) smtp.mailfrom=florian.csdt@gmail.com;       dmarc=pass
 (p=NONE sp=QUARANTINE dis=NONE) header.from=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:36933
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/36933>

This is a multi-part message in MIME format.
--------------4A1C972F24C2F7300041622D
Content-Type: text/plain; charset="UTF-8"; format=flowed
Content-Transfer-Encoding: quoted-printable

On 15/02/2018 20:39, Nicol Bolas wrote:
> On Thursday, February 15, 2018 at 11:33:26 AM UTC-5,=20
> floria...@gmail.com wrote:
>
>     Le jeudi 15 f=C3=A9vrier 2018 17:19:29 UTC+1, Nicol Bolas a =C3=A9cri=
t=C2=A0:
>
>         On Thursday, February 15, 2018 at 11:06:10 AM UTC-5, Jake
>         Arkinstall wrote:
>
>             On 15 Feb 2018 15:51, "Nicol Bolas" <jmck...@gmail.com> wrote=
:
>
>                 Taking a literal (or possibly constexpr string?)
>
>
>             I was wondering whether it makes sense to even describe
>             these things as literals, given that they aren't literal
>             and given that they aren't intended to actually be stored
>             in memory in any way.
>
>
>         We still call literals "literals", even if you use them
>         entirely at compile-time via `constexpr` tricks, such that no
>         runtime code ever needs them. Things between quotes are literals.
>
>             But in terms of constexpr strings, I guess these things
>             themselves can be built up by other methods - I'm not sure
>             if this makes sense in compilation, though; I'm under the
>             impression that the expression itself would likely need to
>             be processed before the constexpr methods themselves could
>             be evaluated (especially given that they could themselves
>             utilise interpolation). I could be wrong.
>
>             I think, at this point, interpolation is a bad word - it
>             made sense in the initial form, but now this has
>             generalised we might want a new word for it.
>
>
>         I don't agree. "String interpolation" often carries the
>         connotation that you're just going to concatenate strings, but
>         it doesn't /have/ to. C++ sometimes defines concepts with
>         names that are similar to other language features, but in a
>         more open and freeform way. Lambdas for example don't have
>         lexical scoping in C++ unless you explicitly ask for them,
>         whereas most languages give it to you as a matter of course.
>
>                 (or possibly arbitrary expressions?)
>
>
>             This wouldn't be so much of a problem, because those
>             expressions (other than their declarations) don't need to
>             be completely understood when the [insert better name for
>             interpolation] is performed - just the resulting type is
>             needed.
>
>
>         The issue with "arbitrary expression" is that you're now
>         requiring the compiler to /invoke the compiler/. It's easy for
>         the compiler to take a compile-time string and find a variable
>         in scope that matches it. It's much harder (presumably) for
>         the compiler to take a compile-time string and invoke the
>         compiler on it, within the current scope as if it had been
>         written text.
>
>         I'm not saying its impossible; I don't know much about
>         compiler architecture. But I can't imagine it's as easy as
>         just finding a variable with that name.
>
>         Not only that, once you get into wanting `constexpr` strings
>         that can be interpolated, you get into lots of issues. Do you
>         really want a feature where you're able to synthesize
>         arbitrary expressions and have someone insinuate them into
>         their code at compile time?
>
>         Or... maybe you do?
>
>
>     From what I know about compilation and formal languages in
>     general, it shouldn't be very hard for a compiler to deal with
>     expressions within `F"{}"`.
>     The compiler already do that kind of stuff with parentheses.
>     Compilers are by nature recursive.
>
>
> You don't seem to be fully understanding what we're talking about.=20
> This isn't standard recursive-descent recursion. This is "execute some=20
> constexpr code and then run the compiler on part of its string=20
> results." Those "results" might include things like /macros/, and=20
> macro expansion is supposed to have happened long before executing=20
> constexpr functions.
>
> And you can't just say they're expressions minus macros. Many=20
> C-standard library facilities are, or might be, macros after all. Is=20
> it legal to do `F"{sin(foo)}"`? If string interpolation is supposed to=20
> allow arbitrary expressions, it would be odd indeed if it were not.=20
> What about invoking `offsetof` or similar C-isms?
>
> If we're only going to allow string interpolation with genuine=20
> literals, then this isn't much of a problem. Even the macro issue can=20
> be sorted out, since the string is right there in the text of the=20
> source code.
>
> But if we want string interpolation to ever be applied to the results=20
> of compile-time execution, that's going to be /much/ more complex if=20
> string interpolation can handle arbitrary expressions. Whereas if we=20
> define it to just be variable identifiers, extending such=20
> interpolation to constexpr strings would be much more reasonable.
>
> I would say that any proposal should be focused on the minimum=20
> featureset. It should naturally include expanding into arbitrary=20
> expressions and constexpr strings as future directions things could=20
> take, but I wouldn't push for them in the short term. Sort of like how=20
> `constexpr` functions in C++11 were really limited, which C++14=20
> greatly expanded.
>
>     The only thing I don't know is if the compiler deals with string
>     literals as a single token or not. If they do, string literal
>     parser will have to be modified quite a lot, even with the
>     "identifier-only" variant.
>

First thing first, currently the C++ is oblivious to the preprocessor,=20
and this will probably not change in the forseeable future (note that=20
the preprocessor is somehow aware of C++: __cplusplus macro, #include,=20
__has_cpp_attribute...).
But as far as the compiler is concerned, these are two distinct steps=20
that are processed one after the other, without going back.

Maybe you want to change that, but I think you were mentionning macros=20
taking effect within F"{}".
For instance:
|
#defineFoo5
F"{Foo}";
|
would expand to:
|
F"{5}";
|

This has basicaly nothing to do with C++, just the preprocessor should=20
be aware that F"{ and }" are somehow similar to parentheses and it=20
should process the inner part as usual.
I am simplifying here, but the idea is there. No coming back from C++ to=20
the preprocessor here.

If this is not what you have in mind, please correct me.

Now that macros are dealt with, we can actually consider the C++ side.

 =C2=A0As far as I understand this topic, I see mainly 3 possibilities:|
|
|
constexprautos =3D"bar";

// first:
foo(F"s: {s}");
// equivalent to:
foo("s: bar");

// second:
|foo(F"s: {s}");
// equivalent to:
foo("s: ",s);

// third:|
|||foo(F"s: {s}");
// equivalent to:
foo(std::string_processing("s: ",s));
|||
|

If you were thinking about a fourth option, please tell me.

For our current concern, the second and third are basically identical.=20
So let's focus on the first and the second.
And please note that everything that foolows also work if you replace s=20
by an actual C++ expression.

The second is no different than regular parsing (besides delimiters).=20
Indeed, it is just convert the string interpolation literal into a=20
sequence of literals and expressions. Nothing fancy here: it is standard=20
recursive-descent. (If you really want, you could even do that with a=20
text processor before the C++ pass, but this is probably not a very good=20
idea)

The first one is more interesting though (but limited to constexpr=20
only). This would require the compiler to create an object, behaving=20
like a string literal (const char[]) resulting from constexpr results.
But the last part is already possible in C++.
|
// Simple example
template <char... Str>
struct Foo {
 =C2=A0 static const char str[sizeof...(Str)];
};
template <char... Str>
const char Foo<Str...>::str =3D {Str...};
|

In this example, I can create an object behaving exactly like a string=20
literal, that is dependant of some constexpr computation.
Basically, the compiler is already able to do create "string literals"=20
on the fly. So it shouldn't be hard to actually implement the first variant=
..

I already hear you: my Foo<...>::str is *not* a string literal. And I=20
agree with you, but the fact is: it is possible to do exactly the same=20
thing as with a string literal transparently.
UDLs are also possible (but not transparently though). Even the template=20
<class Char, Char...> operator"" that is not part of C++.
If the hard part is already possible in plain C++, the whole idea would=20
be feasable by the compiler that has much more power.

So yes, I understand exactly what we're talking about.

PS: if you want only literal concatenation, it is already possible with=20
plain basic preprocessor. "foo" "bar" is a single valid string literal.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/0caab177-cf57-cab1-a5d5-0fc65f651491%40gmail.com=
..

--------------4A1C972F24C2F7300041622D
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<html>
  <head>
    <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-8=
">
  </head>
  <body text=3D"#000000" bgcolor=3D"#FFFFFF">
    On 15/02/2018 20:39, Nicol Bolas wrote:<br>
    <blockquote type=3D"cite"
      cite=3D"mid:96860b9e-95ea-466a-825c-c371844a45e2@isocpp.org">
      <div dir=3D"ltr">On Thursday, February 15, 2018 at 11:33:26 AM
        UTC-5, <a class=3D"moz-txt-link-abbreviated" href=3D"mailto:floria.=
...@gmail.com">floria...@gmail.com</a> wrote:
        <blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
          0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
          <div dir=3D"ltr">Le jeudi 15 f=C3=A9vrier 2018 17:19:29 UTC+1, Ni=
col
            Bolas a =C3=A9crit=C2=A0:
            <blockquote class=3D"gmail_quote"
              style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc
              solid;padding-left:1ex">
              <div dir=3D"ltr">On Thursday, February 15, 2018 at 11:06:10
                AM UTC-5, Jake Arkinstall wrote:
                <blockquote class=3D"gmail_quote"
                  style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc
                  solid;padding-left:1ex">
                  <div dir=3D"auto">
                    <div>
                      <div>
                        <div class=3D"gmail_quote">On 15 Feb 2018 15:51,
                          "Nicol Bolas" &lt;<a rel=3D"nofollow"
                            moz-do-not-send=3D"true">jmck...@gmail.com</a>&=
gt;
                          wrote:<br type=3D"attribution">
                          <blockquote style=3D"margin:0 0 0
                            .8ex;border-left:1px #ccc
                            solid;padding-left:1ex">
                            <div dir=3D"ltr">
                              <div>Taking a literal (or possibly
                                constexpr string?)</div>
                            </div>
                          </blockquote>
                        </div>
                      </div>
                    </div>
                    <div dir=3D"auto"><br>
                    </div>
                    <div dir=3D"auto">I was wondering whether it makes
                      sense to even describe these things as literals,
                      given that they aren't literal and given that they
                      aren't intended to actually be stored in memory in
                      any way.</div>
                  </div>
                </blockquote>
                <div><br>
                  We still call literals "literals", even if you use
                  them entirely at compile-time via `constexpr` tricks,
                  such that no runtime code ever needs them. Things
                  between quotes are literals.<br>
                  <br>
                </div>
                <blockquote class=3D"gmail_quote"
                  style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc
                  solid;padding-left:1ex">
                  <div dir=3D"auto">
                    <div dir=3D"auto">But in terms of constexpr strings, I
                      guess these things themselves can be built up by
                      other methods - I'm not sure if this makes sense
                      in compilation, though; I'm under the impression
                      that the expression itself would likely need to be
                      processed before the constexpr methods themselves
                      could be evaluated (especially given that they
                      could themselves utilise interpolation). I could
                      be wrong.</div>
                    <div dir=3D"auto"><br>
                    </div>
                    <div dir=3D"auto">I think, at this point,
                      interpolation is a bad word - it made sense in the
                      initial form, but now this has generalised we
                      might want a new word for it.</div>
                  </div>
                </blockquote>
                <div><br>
                  I don't agree. "String interpolation" often carries
                  the connotation that you're just going to concatenate
                  strings, but it doesn't <i>have</i> to. C++ sometimes
                  defines concepts with names that are similar to other
                  language features, but in a more open and freeform
                  way. Lambdas for example don't have lexical scoping in
                  C++ unless you explicitly ask for them, whereas most
                  languages give it to you as a matter of course.<br>
                  <br>
                </div>
                <blockquote class=3D"gmail_quote"
                  style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc
                  solid;padding-left:1ex">
                  <div dir=3D"auto">
                    <div dir=3D"auto">
                      <div>
                        <div class=3D"gmail_quote">
                          <blockquote style=3D"margin:0 0 0
                            .8ex;border-left:1px #ccc
                            solid;padding-left:1ex">
                            <div dir=3D"ltr">
                              <div>(or possibly arbitrary expressions?)</di=
v>
                            </div>
                          </blockquote>
                        </div>
                      </div>
                    </div>
                    <div dir=3D"auto"><br>
                    </div>
                    <div dir=3D"auto">This wouldn't be so much of a
                      problem, because those expressions (other than
                      their declarations) don't need to be completely
                      understood when the [insert better name for
                      interpolation] is performed - just the resulting
                      type is needed.</div>
                  </div>
                </blockquote>
                <div><br>
                  The issue with "arbitrary expression" is that you're
                  now requiring the compiler to <i>invoke the compiler</i>.
                  It's easy for the compiler to take a compile-time
                  string and find a variable in scope that matches it.
                  It's much harder (presumably) for the compiler to take
                  a compile-time string and invoke the compiler on it,
                  within the current scope as if it had been written
                  text.<br>
                  <br>
                  I'm not saying its impossible; I don't know much about
                  compiler architecture. But I can't imagine it's as
                  easy as just finding a variable with that name.<br>
                  <br>
                  Not only that, once you get into wanting `constexpr`
                  strings that can be interpolated, you get into lots of
                  issues. Do you really want a feature where you're able
                  to synthesize arbitrary expressions and have someone
                  insinuate them into their code at compile time?<br>
                  <br>
                  Or... maybe you do?<br>
                </div>
              </div>
            </blockquote>
            <div><br>
            </div>
            <div>From what I know about compilation and formal languages
              in general, it shouldn't be very hard for a compiler to
              deal with expressions within `F"{}"`.</div>
            <div>The compiler already do that kind of stuff with
              parentheses. Compilers are by nature recursive.</div>
          </div>
        </blockquote>
        <div><br>
          You don't seem to be fully understanding what we're talking
          about. This isn't standard recursive-descent recursion. This
          is "execute some constexpr code and then run the compiler on
          part of its string results." Those "results" might include
          things like <i>macros</i>, and macro expansion is supposed to
          have happened long before executing constexpr functions.<br>
          <br>
          And you can't just say they're expressions minus macros. Many
          C-standard library facilities are, or might be, macros after
          all. Is it legal to do `F"{sin(foo)}"`? If string
          interpolation is supposed to allow arbitrary expressions, it
          would be odd indeed if it were not. What about invoking
          `offsetof` or similar C-isms?<br>
          <br>
          If we're only going to allow string interpolation with genuine
          literals, then this isn't much of a problem. Even the macro
          issue can be sorted out, since the string is right there in
          the text of the source code.<br>
          <br>
          But if we want string interpolation to ever be applied to the
          results of compile-time execution, that's going to be <i>much</i>
          more complex if string interpolation can handle arbitrary
          expressions. Whereas if we define it to just be variable
          identifiers, extending such interpolation to constexpr strings
          would be much more reasonable.<br>
          <br>
          I would say that any proposal should be focused on the minimum
          featureset. It should naturally include expanding into
          arbitrary expressions and constexpr strings as future
          directions things could take, but I wouldn't push for them in
          the short term. Sort of like how `constexpr` functions in
          C++11 were really limited, which C++14 greatly expanded.<br>
          <br>
        </div>
        <blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
          0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
          <div dir=3D"ltr">
            <div>The only thing I don't know is if the compiler deals
              with string literals as a single token or not. If they do,
              string literal parser will have to be modified quite a
              lot, even with the "identifier-only" variant.<br>
            </div>
          </div>
        </blockquote>
      </div>
    </blockquote>
    <br>
    <div>First thing first, currently the C++ is oblivious to the
      preprocessor, and this will probably not change in the forseeable
      future (note that the preprocessor is somehow aware of C++:
      __cplusplus macro, #include, __has_cpp_attribute...).</div>
    <div>But as far as the compiler is concerned, these are two distinct
      steps that are processed one after the other, without going back.</di=
v>
    <div><br>
    </div>
    <div>Maybe you want to change that, but I think you were mentionning
      macros taking effect within F"{}".</div>
    <div>For instance:</div>
    <div>
      <div style=3D"background-color: rgb(250, 250, 250); border-color:
        rgb(187, 187, 187); border-style: solid; border-width: 1px;
        overflow-wrap: break-word;" class=3D"prettyprint"><code
          class=3D"prettyprint">
          <div class=3D"subprettyprint"><span style=3D"color: #800;"
              class=3D"styled-by-prettify">#define</span><span
              style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span
              style=3D"color: #606;" class=3D"styled-by-prettify">Foo</span=
><span
              style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span
              style=3D"color: #066;" class=3D"styled-by-prettify">5</span><=
span
              style=3D"color: #000;" class=3D"styled-by-prettify"><br>
              F</span><span style=3D"color: #080;"
              class=3D"styled-by-prettify">"{Foo}"</span><span
              style=3D"color: #660;" class=3D"styled-by-prettify">;</span><=
span
              style=3D"color: #000;" class=3D"styled-by-prettify"><br>
            </span></div>
        </code></div>
      would expand to:</div>
    <div>
      <div style=3D"background-color: rgb(250, 250, 250); border-color:
        rgb(187, 187, 187); border-style: solid; border-width: 1px;
        overflow-wrap: break-word;" class=3D"prettyprint"><code
          class=3D"prettyprint">
          <div class=3D"subprettyprint"><span style=3D"color: #000;"
              class=3D"styled-by-prettify">F</span><span style=3D"color:
              #080;" class=3D"styled-by-prettify">"{5}"</span><span
              style=3D"color: #660;" class=3D"styled-by-prettify">;</span><=
/div>
        </code></div>
    </div>
    <div><br>
    </div>
    <div>This has basicaly nothing to do with C++, just the preprocessor
      should be aware that F"{ and }" are somehow similar to parentheses
      and it should process the inner part as usual.</div>
    <div>I am simplifying here, but the idea is there. No coming back
      from C++ to the preprocessor here.</div>
    <div><br>
    </div>
    <div>If this is not what you have in mind, please correct me.<br>
    </div>
    <div><br>
    </div>
    <div>Now that macros are dealt with, we can actually consider the
      C++ side.<br>
    </div>
    <div><br>
    </div>
    <div>=C2=A0As far as I understand this topic, I see mainly 3
      possibilities:<code><br>
      </code></div>
    <div>
      <div style=3D"background-color: rgb(250, 250, 250); border-color:
        rgb(187, 187, 187); border-style: solid; border-width: 1px;
        overflow-wrap: break-word;" class=3D"prettyprint"><code
          class=3D"prettyprint">
          <div class=3D"subprettyprint"><span style=3D"color: #008;"
              class=3D"styled-by-prettify">constexpr</span><span
              style=3D"color: #000;" class=3D"styled-by-prettify"> auto</sp=
an><span
              style=3D"color: #000;" class=3D"styled-by-prettify"> s </span=
><span
              style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span=
><span
              style=3D"color: #000;" class=3D"styled-by-prettify"> "bar"</s=
pan><span
              style=3D"color: #066;" class=3D"styled-by-prettify"></span><s=
pan
              style=3D"color: #660;" class=3D"styled-by-prettify">;</span><=
span
              style=3D"color: #000;" class=3D"styled-by-prettify"><br>
              <br>
            </span><span style=3D"color: #800;" class=3D"styled-by-prettify=
">//
              first:</span><span style=3D"color: #000;"
              class=3D"styled-by-prettify"><br>
              foo</span><span style=3D"color: #660;"
              class=3D"styled-by-prettify">(</span><span style=3D"color:
              #000;" class=3D"styled-by-prettify">F</span><span
              style=3D"color: #080;" class=3D"styled-by-prettify">"s: {s}"<=
/span><span
              style=3D"color: #660;" class=3D"styled-by-prettify">);</span>=
<span
              style=3D"color: #000;" class=3D"styled-by-prettify"><br>
            </span><span style=3D"color: #800;" class=3D"styled-by-prettify=
">//
              equivalent to:</span><span style=3D"color: #000;"
              class=3D"styled-by-prettify"><br>
              foo</span><span style=3D"color: #660;"
              class=3D"styled-by-prettify">(</span><span style=3D"color:
              #080;" class=3D"styled-by-prettify">"s: bar"</span><span
              style=3D"color: #660;" class=3D"styled-by-prettify">);</span>=
<span
              style=3D"color: #000;" class=3D"styled-by-prettify"><br>
              <br>
            </span><span style=3D"color: #800;" class=3D"styled-by-prettify=
">//
              second:</span><span style=3D"color: #000;"
              class=3D"styled-by-prettify"></span><br>
            <span style=3D"color: #000;" class=3D"styled-by-prettify"><code
                class=3D"prettyprint"><span style=3D"color: #000;"
                  class=3D"styled-by-prettify">foo</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">F</sp=
an><span
                  style=3D"color: #080;" class=3D"styled-by-prettify">"s:
                  {s}"</span><span style=3D"color: #660;"
                  class=3D"styled-by-prettify">);</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                </span><span style=3D"color: #800;"
                  class=3D"styled-by-prettify">// equivalent to:</span><spa=
n
                  style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                  foo</span><span style=3D"color: #660;"
                  class=3D"styled-by-prettify">(</span><span style=3D"color=
:
                  #080;" class=3D"styled-by-prettify">"s: "</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">,</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> s</s=
pan><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">);</s=
pan><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                  <br>
                  // third:</span></code></span><br>
            <span style=3D"color: #000;" class=3D"styled-by-prettify"><code
                class=3D"prettyprint"><span style=3D"color: #000;"
                  class=3D"styled-by-prettify"><code class=3D"prettyprint">=
<span
                      style=3D"color: #000;" class=3D"styled-by-prettify"><=
code
                        class=3D"prettyprint"><span style=3D"color: #000;"
                          class=3D"styled-by-prettify">foo</span><span
                          style=3D"color: #660;"
                          class=3D"styled-by-prettify">(</span><span
                          style=3D"color: #000;"
                          class=3D"styled-by-prettify">F</span><span
                          style=3D"color: #080;"
                          class=3D"styled-by-prettify">"s: {s}"</span><span
                          style=3D"color: #660;"
                          class=3D"styled-by-prettify">);</span><span
                          style=3D"color: #000;"
                          class=3D"styled-by-prettify"><br>
                        </span><span style=3D"color: #800;"
                          class=3D"styled-by-prettify">// equivalent to:</s=
pan><span
                          style=3D"color: #000;"
                          class=3D"styled-by-prettify"><br>
                          foo</span><span style=3D"color: #660;"
                          class=3D"styled-by-prettify">(</span><span
                          style=3D"color: #080;"
                          class=3D"styled-by-prettify">std::string_processi=
ng("s:
                          "</span><span style=3D"color: #660;"
                          class=3D"styled-by-prettify">,</span><span
                          style=3D"color: #000;"
                          class=3D"styled-by-prettify"> s)</span><span
                          style=3D"color: #660;"
                          class=3D"styled-by-prettify">);</span><span
                          style=3D"color: #000;"
                          class=3D"styled-by-prettify"><br>
                        </span></code></span></code></span></code></span></=
div>
        </code></div>
    </div>
    <div><br>
    </div>
    <div>If you were thinking about a fourth option, please tell me.<br>
    </div>
    <div><br>
    </div>
    <div>For our current concern, the second and third are basically
      identical. So let's focus on the first and the second.</div>
    <div>And please note that everything that foolows also work if you
      replace s by an actual C++ expression.<br>
    </div>
    <div><br>
    </div>
    <div>The second is no different than regular parsing (besides
      delimiters). Indeed, it is just convert the string interpolation
      literal into a sequence of literals and expressions. Nothing fancy
      here: it is standard recursive-descent. (If you really want, you
      could even do that with a text processor before the C++ pass, but
      this is probably not a very good idea)</div>
    <div><br>
    </div>
    <div>The first one is more interesting though (but limited to
      constexpr only). This would require the compiler to create an
      object, behaving like a string literal (const char[]) resulting
      from constexpr results.</div>
    <div>But the last part is already possible in C++.</div>
    <div>
      <div style=3D"background-color: rgb(250, 250, 250); border-color:
        rgb(187, 187, 187); border-style: solid; border-width: 1px;
        overflow-wrap: break-word;" class=3D"prettyprint"><code
          class=3D"prettyprint">
          <div class=3D"subprettyprint"><span style=3D"color: #606;"
              class=3D"styled-by-prettify">// Simple example<br>
              template &lt;char... Str&gt;<br>
              struct Foo {<br>
              =C2=A0 static const char str[sizeof...(Str)];<br>
              };<br>
              template &lt;char... Str&gt;<br>
              const char Foo&lt;Str...&gt;::str =3D {Str...};<br>
            </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
"></span></div>
        </code></div>
    </div>
    <div><br>
    </div>
    <div>In this example, I can create an object behaving exactly like a
      string literal, that is dependant of some constexpr computation.</div=
>
    <div>Basically, the compiler is already able to do create "string
      literals" on the fly. So it shouldn't be hard to actually
      implement the first variant.</div>
    <div><br>
    </div>
    <div>I already hear you: my Foo&lt;...&gt;::str is <b>not</b> a
      string literal. And I agree with you, but the fact is: it is
      possible to do exactly the same thing as with a string literal
      transparently.</div>
    <div>UDLs are also possible (but not transparently though). Even the
      template &lt;class Char, Char...&gt; operator"" that is not part
      of C++.</div>
    <div>If the hard part is already possible in plain C++, the whole
      idea would be feasable by the compiler that has much more power.</div=
>
    <div><br>
    </div>
    <div>So yes, I understand exactly what we're talking about.</div>
    <div><br>
    </div>
    PS: if you want only literal concatenation, it is already possible
    with plain basic preprocessor. "foo" "bar" is a single valid string
    literal.
  </body>
</html>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/0caab177-cf57-cab1-a5d5-0fc65f651491%=
40gmail.com?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/0caab177-cf57-cab1-a5d5-0fc65f651491%=
40gmail.com</a>.<br />

--------------4A1C972F24C2F7300041622D--

.
