220 20532 <CD250AD7-0567-4BE6-A71B-F35346FEE603@gmail.com> article
Path: news.gmane.org!not-for-mail
From: Miro Knejp <miro.knejp@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Rough Draft Proposal of Interpolated String Literals
Date: Sun, 20 Sep 2015 22:19:10 +0200
Lines: 281
Approved: news@gmane.org
Message-ID: <CD250AD7-0567-4BE6-A71B-F35346FEE603@gmail.com>
References: <CAB+4KHKxwEPXSFScU-FjeUL=yQFZWGfm6uk5fbh1+9bfScL_2Q@mail.gmail.com> <55FC8A6B.1070100@gmail.com> <650f78b0-289e-4880-9c03-8615b25360ec@isocpp.org> <CAB+4KHKU-rA6Os77FLT4Vm2CrPKzMiMpACk2LrGq5r0Khkp9Bg@mail.gmail.com>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2104\))
Content-Type: multipart/alternative; boundary="Apple-Mail=_1F1C4633-8183-46B5-8820-2DABC150F546"
X-Trace: ger.gmane.org 1442780363 4040 80.91.229.3 (20 Sep 2015 20:19:23 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Sun, 20 Sep 2015 20:19:23 +0000 (UTC)
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBC6ONSXJ54LBBQVJ7SXQKGQEIKJWUKQ@isocpp.org Sun Sep 20 22:19:18 2015
Return-path: <std-proposals+bncBC6ONSXJ54LBBQVJ7SXQKGQEIKJWUKQ@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-la0-f72.google.com ([209.85.215.72])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBC6ONSXJ54LBBQVJ7SXQKGQEIKJWUKQ@isocpp.org>)
	id 1Zdl4v-0008EF-Cy
	for gclcip-std-proposals@m.gmane.org; Sun, 20 Sep 2015 22:19:17 +0200
Original-Received: by lamp12 with SMTP id p12sf33847027lam.2
        for <gclcip-std-proposals@m.gmane.org>; Sun, 20 Sep 2015 13:19:16 -0700 (PDT)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:from:content-type:message-id:mime-version
         :subject:date:references:to:in-reply-to: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=ZllAx5TrwkWiX2zLmUoE5mzl+4UTzdEXHAmlqM8WuTs=;
        b=DCkIWd3lzSX0XnTZSX+HGNKagtHhMmF9gmM7G7yeMZQVuw4NsU30fytDCdkqcxFJMP
         IizIkq4+q5izG/YX2g/gRlCZoxO9N41RqsxOmE+OlCrFtk5HIrBs9o2NNDq7wXGelmYQ
         w7dl9gemibdMoC4YzMmMGTrKBVmsnL3p8ltn5iKT/yWYVWKReCU2I1BTG95FYidCOdBq
         KJH4BUXCwWy5A3EUMuwhhy+6nxQ5kvtYaWubPplV5PDWlwKUMzvjcq3a0yZukdfs9PUi
         7u+7z7A6yYy8XVOJXtfABNiPQtq5drjIVUYz7OBo/Vr6o0l3w0gcgDhtk6lv624EJXKh
         YK8w==
X-Gm-Message-State: ALoCoQlyxfgiZk5jOg1huP2f61Xov1bl/mijrxdIAPOPXS7GOrieTDziWWLxcxEuEZAN3v6Yxoa8
X-Received: by 10.152.22.101 with SMTP id c5mr2650819laf.0.1442780356856;
        Sun, 20 Sep 2015 13:19:16 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.180.96.134 with SMTP id ds6ls538570wib.27.canary; Sun, 20 Sep
 2015 13:19:14 -0700 (PDT)
X-Received: by 10.194.172.130 with SMTP id bc2mr22420399wjc.85.1442780354212;
        Sun, 20 Sep 2015 13:19:14 -0700 (PDT)
Original-Received: from mail-wi0-x22d.google.com (mail-wi0-x22d.google.com. [2a00:1450:400c:c05::22d])
        by mx.google.com with ESMTPS id k14si26771374wjr.21.2015.09.20.13.19.14
        for <std-proposals@isocpp.org>
        (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
        Sun, 20 Sep 2015 13:19:14 -0700 (PDT)
Received-SPF: pass (google.com: domain of miro.knejp@gmail.com designates 2a00:1450:400c:c05::22d as permitted sender) client-ip=2a00:1450:400c:c05::22d;
Original-Received: by wicfx3 with SMTP id fx3so86970979wic.0
        for <std-proposals@isocpp.org>; Sun, 20 Sep 2015 13:19:13 -0700 (PDT)
X-Received: by 10.194.52.6 with SMTP id p6mr21620492wjo.119.1442780353841;
        Sun, 20 Sep 2015 13:19:13 -0700 (PDT)
Original-Received: from [192.168.184.201] ([84.18.150.172])
        by smtp.gmail.com with ESMTPSA id c2sm9864698wiy.11.2015.09.20.13.19.12
        for <std-proposals@isocpp.org>
        (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128);
        Sun, 20 Sep 2015 13:19:13 -0700 (PDT)
In-Reply-To: <CAB+4KHKU-rA6Os77FLT4Vm2CrPKzMiMpACk2LrGq5r0Khkp9Bg@mail.gmail.com>
X-Mailer: Apple Mail (2.2104)
X-Original-Sender: miro.knejp@gmail.com
X-Original-Authentication-Results: mx.google.com;       spf=pass (google.com:
 domain of miro.knejp@gmail.com designates 2a00:1450:400c:c05::22d as
 permitted sender) smtp.mailfrom=miro.knejp@gmail.com;       dkim=pass
 header.i=@gmail.com;       dmarc=pass (p=NONE 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: <http://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <http://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <http://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <http://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>,
 <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:20532
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/20532>

--Apple-Mail=_1F1C4633-8183-46B5-8820-2DABC150F546
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8


> On 20 Sep 2015, at 15:01 , Andrew Tomazos <andrewtomazos@gmail.com> wrote=
:
>=20
> On Sat, Sep 19, 2015 at 12:33 PM, Bengt Gustafsson <bengt.gustafsson@beam=
ways.com <mailto:bengt.gustafsson@beamways.com>> wrote:
> - Do we really need to be able to specify the introducer character. Can't=
 % be fixed (with the usual %% escape possibility).
>=20
> I considered that, but no matter what introducer you pick, there are alwa=
ys cases where the introducer is prevalent in the target string.  This occu=
rs in natural language, but is especially the case of code generation, wher=
e you are generating strings for later compilation in C++ or some other pro=
gramming language.  Having the introducer be defined at the start also make=
s it easier to read, as you are reminded what the special token is (just li=
ke the compiler is).
>=20
> Compare:
>=20
>    F"The result of %x %% %y is not zero (it is %(x%y))."
>=20
> with
>=20
>    F"$ The result of $x % $y is not zero (it is $[x%y])."
>=20
> Similar problematic examples can be found with any set predefined introdu=
cer or set predefined brackets.
The brackets are not a problem as they must be preceded by the introducing =
character and contain a balanced token sequence, so the choice of brackets =
does not matter. I don=E2=80=99t really mind being able to chose the introd=
ucer, only that it is part of the string, meaning the compiler truncates my=
 string! There is a lacking visual separation of data and metadata. I also =
think there should be a predefined sensible default introducer ($ makes sen=
se as it is not a valid identifier character or operator in C++ code and it=
s occurrence in natural language is rather rare as a currency symbol) which=
 can be optionally overridden if needed.
>=20
> - Wouldn't it be more logical if this resulted in an expanded pack, i.e. =
a number of comma separated parts.
>=20
> format(std::cout, F"The number of %goods is %count");
>=20
> No, I think:
>=20
>   std::cout F"% The number of %goods is %count";
>=20
> is better.
=E2=80=9Cbetter=E2=80=9D in what way? Does the syntax please you more or do=
es it function better?
>=20
> But I am considering changing the definition of an interpolated string to=
 be a function call expression of return type std::interpolated_string.
This is a very strange limitation. By that logic all user defined literals =
should return a std::udl_string, which I think people would agree is silly.=
 So why limit interpolated strings in that way? If the interpolated string =
is supposed to be sugar for transforming a sequence of expressions into one=
, then transforming it into a call to a user-defined function is the most f=
lexible thing the proposal can provide. If F=E2=80=9D$ x + y =3D ${x + y}=
=E2=80=9D_foo (whatever the syntax may be) is translated to foo(=E2=80=9Cx =
+ y =3D =E2=80=9C, x + y) then the type of the interpolated string is the r=
esult type of foo(). This is a very powerful mechanism that may not be limi=
ted to strings only, If people want to capture arguments by reference they =
can decide to do so. Let the users decide how to process the interpolated s=
tring literal, just give them the hooks into the compiler=E2=80=99s magic.
>=20
> This would mean we would have to write:
>=20
>   std::cout << F"% The number of %goods is %count";
>=20
> (which some have requested anyway).
>=20
> But it also means we could also write:
>=20
>   std::string s =3D F"% The number of %goods is %count";
>=20
> or use it anywhere you can use a string normally.
>=20
> std::interpolated_string would contain:
> 1. a reference to the constant expression format string and positions of =
embedded expressions (which are known at compile time)
> 2. references to the values of the evaluated embedded expressions for the=
 current execution. (calculated at run-time usually, but it should be const=
expr-compatible)
You basically just described how to call a function.
>=20
> This means the operator<<(ostream&, interpolated_string) could be defined=
 to stream out the substrings and subexpressions just like (and just as eff=
iciently) as if you had written << for each.
>=20
> For the conversion from std::interpolated_string to std::string, it could=
 use std::ostringstream internally or some more efficient method.
>=20
> So consumers of std::interpolated_strings could use operator<<(ostream&, =
std::interpolated_string), or use the conversion from std::interpolated_str=
ing to std::string implicitly (by just using std::string or std::string_vie=
w), or they could overload on std::interpolated_string.
>=20
> Users could also overload on std::interpolated_string to implement a tran=
slation mechanism, as they would have access to both the original source co=
de text of the expressions as well as their evaluated values.
>=20
> std::interpolated_string would actually be a class template parametric on=
 the types of the embedded expressions, but that's an implementation detail=
..
It is not an implementation detail because it is exposed in the interface o=
f std::interpolated_string which impacts people=E2=80=99s function signatur=
es.

I still don=E2=80=99t understand the purpose of this limitation. Who benefi=
ts from std::interpolated_string? Why isn=E2=80=99t there a std::udl_string=
? If we allow the interpolated literal to be converted to a user-defined fu=
nction call it can return whatever the user needs. Add meaningful defaults =
to the standard library to cover the most common use cases, but leave the c=
ustomization point open for advanced users. I believe it=E2=80=99s easier t=
o specify the behavior of =E2=80=9Csplit up this literal and call a functio=
n with these arguments=E2=80=9D compared to =E2=80=9Csplit up this literal,=
 remember the expression result references and pack them into a magic std t=
ype, which either needs to be a template or be type-erased=E2=80=9D.

--=20

---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_1F1C4633-8183-46B5-8820-2DABC150F546
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 20 Sep 2015, at 1=
5:01 , Andrew Tomazos &lt;<a href=3D"mailto:andrewtomazos@gmail.com" class=
=3D"">andrewtomazos@gmail.com</a>&gt; wrote:</div><br class=3D"Apple-interc=
hange-newline"><div class=3D""><div dir=3D"ltr" class=3D""><div class=3D"gm=
ail_extra"><div class=3D"gmail_quote">On Sat, Sep 19, 2015 at 12:33 PM, Ben=
gt Gustafsson <span dir=3D"ltr" class=3D"">&lt;<a href=3D"mailto:bengt.gust=
afsson@beamways.com" target=3D"_blank" class=3D"">bengt.gustafsson@beamways=
..com</a>&gt;</span> wrote:<br class=3D""><blockquote class=3D"gmail_quote" =
style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:r=
gb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir=3D"ltr" =
class=3D""><div class=3D"">- Do we really need to be able to specify the in=
troducer character. Can't % be fixed (with the usual %% escape possibility)=
..</div></div></blockquote><div class=3D""><br class=3D""></div><div class=
=3D"">I considered that, but no matter what introducer you pick, there are =
always cases where the introducer is prevalent in the target string.&nbsp; =
This occurs in natural language, but is especially the case of code generat=
ion, where you are generating strings for later compilation in C++ or some =
other programming language.&nbsp; Having the introducer be defined at the s=
tart also makes it easier to read, as you are reminded what the special tok=
en is (just like the compiler is).</div><div class=3D""><br class=3D""></di=
v><div class=3D"">Compare:</div><div class=3D""><br class=3D""></div><div c=
lass=3D"">&nbsp; &nbsp;F"The result of %x %% %y is not zero (it is %(x%y)).=
"</div><div class=3D""><br class=3D""></div><div class=3D"">with</div><div =
class=3D""><br class=3D""></div><div class=3D"">&nbsp; &nbsp;F"$ The result=
 of $x % $y is not zero (it is $[x%y])."</div><div class=3D""><br class=3D"=
"></div><div class=3D"">Similar problematic examples can be found with any =
set predefined introducer or set predefined brackets.</div></div></div></di=
v></div></blockquote>The brackets are not a problem as they must be precede=
d by the introducing character and contain a balanced token sequence, so th=
e choice of brackets does not matter. I don=E2=80=99t really mind being abl=
e to chose the introducer, only that it is part of the string, meaning the =
compiler truncates my string! There is a lacking visual separation of data =
and metadata. I also think there should be a predefined sensible default in=
troducer ($ makes sense as it is not a valid identifier character or operat=
or in C++ code and its occurrence in natural language is rather rare as a c=
urrency symbol) which can be optionally overridden if needed.<br class=3D""=
><blockquote type=3D"cite" class=3D""><div class=3D""><div dir=3D"ltr" clas=
s=3D""><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div class=3D"=
"><br class=3D""></div><blockquote class=3D"gmail_quote" style=3D"margin:0p=
x 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);bo=
rder-left-style:solid;padding-left:1ex"><div dir=3D"ltr" class=3D""><div cl=
ass=3D""></div><div class=3D"">- Wouldn't it be more logical if this result=
ed in an expanded pack, i.e. a number of comma separated parts.</div></div>=
</blockquote><div class=3D""><br class=3D""></div><blockquote class=3D"gmai=
l_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-lef=
t-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir=
=3D"ltr" class=3D""><div class=3D"">format(std::cout, F"The number of %good=
s is %count");</div></div></blockquote><div class=3D""><br class=3D""></div=
><div class=3D"">No, I think:</div><div class=3D""><br class=3D""></div><di=
v class=3D"">&nbsp; std::cout F"% The number of %goods is %count";</div><di=
v class=3D""><br class=3D""></div><div class=3D"">is better.</div></div></d=
iv></div></div></blockquote>=E2=80=9Cbetter=E2=80=9D in what way? Does the =
syntax please you more or does it function better?<br class=3D""><blockquot=
e type=3D"cite" class=3D""><div class=3D""><div dir=3D"ltr" class=3D""><div=
 class=3D"gmail_extra"><div class=3D"gmail_quote"><div class=3D""><br class=
=3D""></div><div class=3D"">But I am considering changing the definition of=
 an interpolated string to be a function call expression of return type std=
::interpolated_string.<br class=3D""></div></div></div></div></div></blockq=
uote>This is a very strange limitation. By that logic all user defined lite=
rals should return a std::udl_string, which I think people would agree is s=
illy. So why limit interpolated strings in that way? If the interpolated st=
ring is supposed to be sugar for transforming a sequence of expressions int=
o one, then transforming it into a call to a user-defined function is the m=
ost flexible thing the proposal can provide. If F=E2=80=9D$ x + y =3D ${x +=
 y}=E2=80=9D_foo (whatever the syntax may be) is translated to foo(=E2=80=
=9Cx + y =3D =E2=80=9C, x + y) then the type of the interpolated string is =
the result type of foo(). This is a very powerful mechanism that may not be=
 limited to strings only, If people want to capture arguments by reference =
they can decide to do so. Let the users decide how to process the interpola=
ted string literal, just give them the hooks into the compiler=E2=80=99s ma=
gic.<br class=3D""><blockquote type=3D"cite" class=3D""><div class=3D""><di=
v dir=3D"ltr" class=3D""><div class=3D"gmail_extra"><div class=3D"gmail_quo=
te"><div class=3D""><br class=3D""></div><div class=3D"">This would mean we=
 would have to write:</div><div class=3D""><br class=3D""></div><div class=
=3D""><div class=3D"">&nbsp; std::cout &lt;&lt; F"% The number of %goods is=
 %count";</div></div><div class=3D""><br class=3D""></div><div class=3D"">(=
which some have requested anyway).</div><div class=3D""><br class=3D""></di=
v><div class=3D"">But it also means we could also write:</div><div class=3D=
""><br class=3D""></div><div class=3D"">&nbsp; std::string s =3D F"% The nu=
mber of %goods is %count";</div><div class=3D""><br class=3D""></div><div c=
lass=3D"">or use it anywhere you can use a string normally.</div><div class=
=3D""><br class=3D""></div><div class=3D"">std::interpolated_string would c=
ontain:<br class=3D""></div><div class=3D"">1. a reference to the constant =
expression format string and positions of embedded expressions (which are k=
nown at compile time)</div><div class=3D"">2. references to the values of t=
he evaluated embedded expressions for the current execution. (calculated at=
 run-time usually, but it should be constexpr-compatible)</div></div></div>=
</div></div></blockquote>You basically just described how to call a functio=
n.<br class=3D""><blockquote type=3D"cite" class=3D""><div class=3D""><div =
dir=3D"ltr" class=3D""><div class=3D"gmail_extra"><div class=3D"gmail_quote=
"><div class=3D""><br class=3D""></div><div class=3D"">This means the opera=
tor&lt;&lt;(ostream&amp;, interpolated_string) could be defined to stream o=
ut the substrings and subexpressions just like (and just as efficiently) as=
 if you had written &lt;&lt; for each.</div><div class=3D""><br class=3D"">=
</div><div class=3D"">For the conversion from std::interpolated_string to s=
td::string, it could use std::ostringstream internally or some more efficie=
nt method.</div><div class=3D""><br class=3D""></div><div class=3D"">So con=
sumers of std::interpolated_strings could use operator&lt;&lt;(ostream&amp;=
, std::interpolated_string), or use the conversion from std::interpolated_s=
tring to std::string implicitly (by just using std::string or std::string_v=
iew), or they could overload on std::interpolated_string.</div><div class=
=3D""><br class=3D""></div><div class=3D"">Users could also overload on std=
::interpolated_string to implement a translation mechanism, as they would h=
ave access to both the original source code text of the expressions as well=
 as their evaluated values.</div><div class=3D""><br class=3D""></div><div =
class=3D"">std::interpolated_string would actually be a class template para=
metric on the types of the embedded expressions, but that's an implementati=
on detail.</div></div></div></div></div></blockquote>It is not an implement=
ation detail because it is exposed in the interface of std::interpolated_st=
ring which impacts people=E2=80=99s function signatures.</div><div><br clas=
s=3D"">I still don=E2=80=99t understand the purpose of this limitation. Who=
 benefits from std::interpolated_string? Why isn=E2=80=99t there a std::udl=
_string? If we allow the interpolated literal to be converted to a user-def=
ined function call it can return whatever the user needs. Add meaningful de=
faults to the standard library to cover the most common use cases, but leav=
e the customization point open for advanced users. I believe it=E2=80=99s e=
asier to specify the behavior of =E2=80=9Csplit up this literal and call a =
function with these arguments=E2=80=9D compared to =E2=80=9Csplit up this l=
iteral, remember the expression result references and pack them into a magi=
c std type, which either needs to be a template or be type-erased=E2=80=9D.=
</div><div><br class=3D""></div></body></html>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_1F1C4633-8183-46B5-8820-2DABC150F546--

.
