220 36814 <356d5835-f1bf-4699-94f5-0b2d3d0b9c0e@isocpp.org> article
Path: news.gmane.org!.POSTED!not-for-mail
From: Jake Arkinstall <jake.arkinstall@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: String interpolation
Date: Thu, 8 Feb 2018 17:41:16 -0800 (PST)
Lines: 356
Approved: news@gmane.org
Message-ID: <356d5835-f1bf-4699-94f5-0b2d3d0b9c0e@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_3859_1149588477.1518140476992"
X-Trace: blaine.gmane.org 1518140372 5709 195.159.176.226 (9 Feb 2018 01:39:32 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Fri, 9 Feb 2018 01:39:32 +0000 (UTC)
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBDCZX3WUUQFRBPXY6PJQKGQESLZIIRI@isocpp.org Fri Feb 09 02:39:28 2018
Return-path: <std-proposals+bncBDCZX3WUUQFRBPXY6PJQKGQESLZIIRI@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-ua0-f198.google.com ([209.85.217.198])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBDCZX3WUUQFRBPXY6PJQKGQESLZIIRI@isocpp.org>)
	id 1ejxek-0000Ib-Co
	for gclcip-std-proposals@m.gmane.org; Fri, 09 Feb 2018 02:39:14 +0100
Original-Received: by mail-ua0-f198.google.com with SMTP id b45sf3827649uad.10
        for <gclcip-std-proposals@m.gmane.org>; Thu, 08 Feb 2018 17:41:20 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to:message-id:subject:mime-version:x-original-sender
         :reply-to:precedence:mailing-list:list-id:list-post:list-help
         :list-archive:list-subscribe:list-unsubscribe;
        bh=nMad8sL/sTyFe9O/lhf3c0036FTAL/6MoBCU34bJmmY=;
        b=ZDNKTYA2Mts23vhXPyk29nwnfCsvbiPky4A6yiRjqU0ubEmwJkBEupYw9HbJ6AvF1r
         f1hu/FtBtybDTIP6miS+thnp6Q3bQgUa2rSqgvnP1XAjvPUAqfLhvNN5VzqymO61bHyE
         WFZdJFOo3nOh05HF/Z4JCJ+8ZwObrSRmBurdPDzeKZvtguTPOMeghoQos+TOHBsW2bCk
         77QQFpunHtPihkpcvLwNqUFqJBluvAFo7EnlnBb9SuoMCa1A7fzJMo5dqHoVm6/cPW2g
         BAmFL9yZE5LjDXS3U3hDsryzZrF7fbX8fBysWCl6Bf0q2DAajtNS8ujtjUQmw91HsASh
         rkpQ==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20161025;
        h=date:from:to:message-id:subject:mime-version:x-original-sender
         :reply-to:precedence:mailing-list:list-id:list-post:list-help
         :list-archive:list-subscribe:list-unsubscribe;
        bh=nMad8sL/sTyFe9O/lhf3c0036FTAL/6MoBCU34bJmmY=;
        b=rk4wRXvwAef4s7P/2pElzrZEU6Q3BhfE/xgipRSmhBEUZMYASs2anrMpTXXYlR9nGX
         JOPMzWvX7nPxyb53uwD2dnrIfIijj9b+fsITOGCDorm2Xz+hQvm006oRe3twFycvkVDg
         /J+xG5S74M9uz8pizYGwAfCo7VevjqNvHghDatOZ1neTVqvmhrFIvy/wEmGXdAc5los4
         NaR8fsbgQ1CStZA2sbvIWrb1SBP2J1nsrUI3IXLIyz8ImszKHlPzuA+msEK0L6NXImMZ
         5tDNWaFHv13BdJ/nyGy2ymfj+G2aaDWwNfLcNHZMZnM79TRqMstArHtcJn90D/8I7nDA
         yIVA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        h=x-gm-message-state:date:from:to:message-id: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=nMad8sL/sTyFe9O/lhf3c0036FTAL/6MoBCU34bJmmY=;
        b=o7pwFO8oq4/I5qpMI7/F0nWbgxSNR2zJGiJU+e9WqYhn1AY6RRwSwPnI+YYS+/9zGv
         FmOmZKESzkHD7FXtp91/ANK+5P9tYT1QNBmrIUc0+PxE0uEfko8938JfxdQSS51nbbAk
         aUjhN/4zy04k0aKPgSAEurPs7qn/mWLQDVQcqmMROl69X8crD8D/bkGezaECrsAW+oGZ
         8sEL7YqJepYwJLufvomP9JWHxQQOSR7GMJhtOtUiyXpfqhHKiDWIFgv0IDkppH7QXCBh
         JVQLxlnSx/QQEkd9HReeKklFwVG2QET0cPsUES1G8d0HwovzIPv7vzLnQEdl+dVDH0KZ
         fqCQ==
X-Gm-Message-State: APf1xPDAG76Gj5/veK6tcRhsLlm3vw97tGUyCMEWyur4mKEdzNBpbsIt
	TVUCUT31CLKSanYUmjERkvX8sw==
X-Google-Smtp-Source: AH8x226o35Rkl9xl/fPEtdlj7vT3685FMZ27kTCuia+gyfntMFHt7qBkYJqwS3AgoaFCMVfrB4ZfaA==
X-Received: by 10.31.155.87 with SMTP id d84mr635881vke.121.1518140479566;
        Thu, 08 Feb 2018 17:41:19 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.31.95.142 with SMTP id t136ls3212453vkb.20.gmail; Thu, 08 Feb
 2018 17:41:17 -0800 (PST)
X-Received: by 10.31.180.205 with SMTP id d196mr117813vkf.10.1518140477667;
        Thu, 08 Feb 2018 17:41:17 -0800 (PST)
X-Original-Sender: jake.arkinstall@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:36814
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/36814>

------=_Part_3859_1149588477.1518140476992
Content-Type: multipart/alternative; 
	boundary="----=_Part_3860_917082784.1518140476993"

------=_Part_3860_917082784.1518140476993
Content-Type: text/plain; charset="UTF-8"

Hello everyone,

This one is light-hearted, but will be controversial. It is not related to 
the language itself, and is an effort to add syntactic sugar to C++ 
concatenation/streaming.

Before I start, let me set the scene with an axiom: *Not all of the code 
you write during early development is designed to end up in the final 
product.* One logical conclusion to this is that *some of the code you 
write during development doesn't need to be streamlined*, which leads to *having 
to write more code, simply because user-friendly approaches would be less 
efficient, is sometimes a waste of time.* During the initial development 
phase of a project, or at least in my case, some throwaway code is put into 
place just to get *something* happening - some output in certain events you 
want to monitor, some variables you want to keep track of. Apart from the 
big decisions such as application flow, efficiency of the code that just 
exists to show that the cogs are moving is (effectively) irrelevant. This 
is the basis of this post; the solution isn't going to end up (I hope) 
being used in a production-level stock market tick feed, or in the logging 
code for a time-sensitive process. It's aiming for the more casual 
occasion, where baseball caps are acceptable and cumberbands and pocket 
watches are a social faux pas - but everyone has brought their cumberbands 
and pocket watches along to the party, stored in their bag, ready to wear 
when the time is right.

The crude reason that this is the basis for the post is that I cannot 
forsee a efficient implementation and, in this specific circumstance, that 
doesn't concern me.

Now the scene is set, on we go.

Some programming languages allow direct string interpolation, i.e. the 
injection of variables into what otherwise appears to be a string literal. 
For example, in bash:
recipient="World"
echo "Hello, ${recipient}!"

Similar syntaxes are used in a wide variety of languages - see 
https://en.wikipedia.org/wiki/String_interpolation . These languages are 
higher level, and do not compete directly with C++, so there are good 
reasons for them have some user-friendly features that aren't really 
accessible to us. But this is something that isn't too hard to implement if 
we allow some concessions.

I fully understand that we *do* have the ability to inject values into 
strings using Boost's format library, the fmt library, printf, and friends. 
With these we get a lot of flexibility, great performance in some cases - 
but the code on the user's side is slightly more cryptic because variables 
are placed after the format string, and it is up to the code reader to do 
*find* which variable coincides with which *token*, rather than it being 
effortless. Effortless is nice. Of course, we also have streams, but 
writing these up explicitly gets tedious.

So here's what I'm suggesting: a syntax similar to - but obviously not the 
same as - that of a string literal, which enables interpolation through the 
use of stream operations, performed during translation phase 4.

We can use something similar to the C# syntax, using the dollar symbol 
preceding the opening quotation mark to differentiate between string 
literals and interpolation-enabled strings, but using the bash/perl/php 
approach to inserting variables, using the dollar symbol and curly braces 
(minimising confusion when we actually *want* braces).

T recipient;
// operator<<(std::ostream&, T) defined, or we naturally get an undefined 
operator<< error later on

string message = $"Hello, ${recipient}!"

// becomes, internally, equivalent to:
// string message;
// {
//     std::stringstream TMP_;
//     TMP_ << "Hello " << recipient << "!";
//     message = TMP_.str()
// }

std::cout << $"The message is ${message}\n";

// becomes, internally, equivalent to:
// {
//     std::cout << "The message is " << message << "\n";
// }
// // braces not really necessary, but it makes generalisation easier:
// // Trade a dollar for a pair of braces every time.
//
// // If we REALLY don't care about performance, this could use the
// // string approach and send the resulting string to std::cout. *shudder*

This is designed to be a gentler, quick-and-easy way of using streams, not 
the most flexible nor the fastest approach; obviously, if you want speed 
and flexibility, you're often going to have to do things the long way 
around. But if you don't want that, and just want to get that code down as 
quickly as possible before future optimisations, I think this approach has 
merit. There is potential to add some extra decoration, which is seen in 
bash when a quick and easy operation is needed:
recipient="Worm";
echo "Hello, ${recipient/m/ld}!"

I'm definitely not suggesting that we have a string replacement feature 
(that would be pointless), but it demonstrates that operations upon the 
variables output is possible, and these can be implemented in a 
backwards-compatible manner. For example, if we use the above syntax as the 
default, erring out if there exists invalid syntax inside the curly braces, 
we could in future allow shortcuts to <iomanip> functionality (such that 
type doesn't even come into it - [set precision, send a string, unset 
precision] is not an error, it's just pointless):
double pi = std::acos(-1);
std::cout << $"Pi to 3 s.f. is ${pi:3}, but it is ${pi} by default\n";
// becomes, internally, equivalent to:
// {
//     std::streamsize TMP_ = std::cout.precision();
//     std::cout << "Pi to 3 s.f. is "
//               << std::setprecision(3) << pi << std::setprecision(TMP_)
//               << ", but in full is " << pi << "by default\n";
// }

The idea is that this will be an optional inclusion, through a flag, so 
there is negligible compilation overhead for those who don't want, or are 
maybe even offended by, this functionality.

This is not much of a proposal as yet, mainly because I am aware that this 
idea might not be incredibly popular; most proposals tend to aim for more 
efficient, more flexible code at the optional expense of adding *more* 
code, and this is doing the exact opposite of that. As such, going further 
with this without probing for opinions is a waste of time.

Regards,
Jake Arkinstall

-- 
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 email 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/356d5835-f1bf-4699-94f5-0b2d3d0b9c0e%40isocpp.org.

------=_Part_3860_917082784.1518140476993
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hello everyone,<br><br>This one is light-hearted, but will=
 be controversial. It is not related to the language itself, and is an effo=
rt to add syntactic sugar to C++ concatenation/streaming.<br><br>Before I s=
tart, let me set the scene with an axiom: <i>Not all of the code you write =
during early development is designed to end up in the final product.</i> On=
e logical conclusion to this is that <i>some of the code you write during d=
evelopment doesn&#39;t need to be streamlined</i>, which leads to <i>having=
 to write more code, simply because user-friendly approaches would be less =
efficient, is sometimes a waste of time.</i><i> </i>During the initial deve=
lopment phase of a project, or at least in my case, some throwaway code is =
put into place just to get *something* happening - some output in certain e=
vents you want to monitor, some variables you want to keep track of. Apart =
from the big decisions such as application flow, efficiency of the code tha=
t just exists to show that the cogs are moving is (effectively) irrelevant.=
 This is the basis of this post; the solution isn&#39;t going to end up (I =
hope) being used in a production-level stock market tick feed, or in the lo=
gging code for a time-sensitive process. It&#39;s aiming for the more casua=
l occasion, where baseball caps are acceptable and cumberbands and pocket w=
atches are a social faux pas - but everyone has brought their cumberbands a=
nd pocket watches along to the party, stored in their bag, ready to wear wh=
en the time is right.<br><br>The crude reason that this is the basis for th=
e post is that I cannot forsee a efficient implementation and, in this spec=
ific circumstance, that doesn&#39;t concern me.<br><br>Now the scene is set=
, on we go.<br><br>Some programming languages allow direct string interpola=
tion, i.e. the injection of variables into what otherwise appears to be a s=
tring literal. For example, in bash:<br><div style=3D"background-color: rgb=
(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; bor=
der-width: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code cla=
ss=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #000=
;" class=3D"styled-by-prettify">recipient</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #080;" class=
=3D"styled-by-prettify">&quot;World&quot;</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br>echo </span><span style=3D"color: #080;"=
 class=3D"styled-by-prettify">&quot;Hello, ${recipient}!&quot;</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div></code=
></div><br>Similar syntaxes are used in a wide variety of languages - see h=
ttps://en.wikipedia.org/wiki/String_interpolation . These languages are hig=
her level, and do not compete directly with C++, so there are good reasons =
for them have some user-friendly features that aren&#39;t really accessible=
 to us. But this is something that isn&#39;t too hard to implement if we al=
low some concessions.<br><br>I fully understand that we <b>do</b> have the =
ability to inject values into strings using Boost&#39;s format library, the=
 fmt library, printf, and friends. With these we get a lot of flexibility, =
great performance in some cases - but the code on the user&#39;s side is sl=
ightly more cryptic because variables are placed after the format string, a=
nd it is up to the code reader to do <i>find</i> which variable coincides w=
ith which <i>token</i>, rather than it being effortless. Effortless is nice=
.. Of course, we also have streams, but writing these up explicitly gets ted=
ious.<br><br>So here&#39;s what I&#39;m suggesting: a syntax similar to - b=
ut obviously not the same as - that of a string literal, which enables inte=
rpolation through the use of stream operations, performed during translatio=
n phase 4.<br><br>We can use something similar to the C# syntax, using the =
dollar symbol preceding the opening quotation mark to differentiate between=
 string literals and interpolation-enabled strings, but using the bash/perl=
/php approach to inserting variables, using the dollar symbol and curly bra=
ces (minimising confusion when we actually <b>want</b> braces).<br><br><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"subprettypr=
int"><span style=3D"color: #000;" class=3D"styled-by-prettify">T recipient<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span sty=
le=3D"color: #800;" class=3D"styled-by-prettify">// operator&lt;&lt;(std::o=
stream&amp;, T) defined, or we naturally get an undefined operator&lt;&lt; =
error later on</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">string</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> m=
essage </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> $</span><=
span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;Hello, ${rec=
ipient}!&quot;</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br><br></span><span style=3D"color: #800;" class=3D"styled-by-prettify=
">// becomes, internally, equivalent to:</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br></span><span style=3D"color: #800;" class=
=3D"styled-by-prettify">// string message;</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #800;" cla=
ss=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">// =C2=A0 =C2=A0 std::stringstream TMP_;</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color=
: #800;" class=3D"styled-by-prettify">// =C2=A0 =C2=A0 TMP_ &lt;&lt; &quot;=
Hello &quot; &lt;&lt; recipient &lt;&lt; &quot;!&quot;;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #800;" class=3D"styled-by-prettify">// =C2=A0 =C2=A0 message =3D TMP_.=
str()</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><=
/span><span style=3D"color: #800;" class=3D"styled-by-prettify">// }</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>std</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">cout </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&lt;&lt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> $</span><span style=3D"colo=
r: #080;" class=3D"styled-by-prettify">&quot;The message is ${message}\n&qu=
ot;</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">// becomes, intern=
ally, equivalent to:</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br></span><span style=3D"color: #800;" class=3D"styled-by-pretti=
fy">// {</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r></span><span style=3D"color: #800;" class=3D"styled-by-prettify">// =C2=
=A0 =C2=A0 std::cout &lt;&lt; &quot;The message is &quot; &lt;&lt; message =
&lt;&lt; &quot;\n&quot;;</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"><br></span><span style=3D"color: #800;" class=3D"styled-by-pr=
ettify">// }</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br></span><span style=3D"color: #800;" class=3D"styled-by-prettify">// /=
/ braces not really necessary, but it makes generalisation easier:</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span st=
yle=3D"color: #800;" class=3D"styled-by-prettify">// // Trade a dollar for =
a pair of braces every time.</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br></span><span style=3D"color: #800;" class=3D"styled-b=
y-prettify">//</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br></span><span style=3D"color: #800;" class=3D"styled-by-prettify">//=
 // If we REALLY don&#39;t care about performance, this could use the</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span=
 style=3D"color: #800;" class=3D"styled-by-prettify">// // string approach =
and send the resulting string to std::cout. *shudder*</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br></span></div></code></div><b=
r>This is designed to be a gentler, quick-and-easy way of using streams, no=
t the most flexible nor the fastest approach; obviously, if you want speed =
and flexibility, you&#39;re often going to have to do things the long way a=
round. But if you don&#39;t want that, and just want to get that code down =
as quickly as possible before future optimisations, I think this approach h=
as merit. There is potential to add some extra decoration, which is seen in=
 bash when a quick and easy operation is needed:<code></code><br><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">recipient</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span st=
yle=3D"color: #080;" class=3D"styled-by-prettify">&quot;Worm&quot;</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>echo </span><span style=
=3D"color: #080;" class=3D"styled-by-prettify">&quot;Hello, ${recipient/m/l=
d}!&quot;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br></span></div></code></div><br>I&#39;m definitely not suggesting that we =
have a string replacement feature (that would be pointless), but it demonst=
rates that operations upon the variables output is possible, and these can =
be implemented in a backwards-compatible manner. For example, if we use the=
 above syntax as the default, erring out if there exists invalid syntax ins=
ide the curly braces, we could in future allow shortcuts to &lt;iomanip&gt;=
 functionality (such that type doesn&#39;t even come into it - [set precisi=
on, send a string, unset precision] is not an error, it&#39;s just pointles=
s):<br><div style=3D"background-color: rgb(250, 250, 250); border-color: rg=
b(187, 187, 187); border-style: solid; border-width: 1px; overflow-wrap: br=
eak-word;" class=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"=
subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">d=
ouble</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> pi <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">acos</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">(-</span><span style=3D"color: #066;" =
class=3D"styled-by-prettify">1</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br>std</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>cout </span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;=
&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> $</sp=
an><span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;Pi to 3 =
s.f. is ${pi:3}, but it is ${pi} by default\n&quot;</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #800;" cla=
ss=3D"styled-by-prettify">// becomes, internally, equivalent to:</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span styl=
e=3D"color: #800;" class=3D"styled-by-prettify">// {</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: =
#800;" class=3D"styled-by-prettify">// =C2=A0 =C2=A0 std::streamsize TMP_ =
=3D std::cout.precision();</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br></span><span style=3D"color: #800;" class=3D"styled-by-=
prettify">// =C2=A0 =C2=A0 std::cout &lt;&lt; &quot;Pi to 3 s.f. is &quot;<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span>=
<span style=3D"color: #800;" class=3D"styled-by-prettify">// =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 &lt;&lt; std::setprecision(3) &lt;&lt; p=
i &lt;&lt; std::setprecision(TMP_)</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #800;" class=3D"st=
yled-by-prettify">// =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 &lt;&=
lt; &quot;, but in full is &quot; &lt;&lt; pi &lt;&lt; &quot;by default\n&q=
uot;;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><=
/span><span style=3D"color: #800;" class=3D"styled-by-prettify">// }</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div>=
</code></div><br>The idea is that this will be an optional inclusion, throu=
gh a flag, so there is negligible compilation overhead for those who don&#3=
9;t want, or are maybe even offended by, this functionality.<br><br>This is=
 not much of a proposal as yet, mainly because I am aware that this idea mi=
ght not be incredibly popular; most proposals tend to aim for more efficien=
t, more flexible code at the optional expense of adding <i>more</i> code, a=
nd this is doing the exact opposite of that. As such, going further with th=
is without probing for opinions is a waste of time.<br><br>Regards,<br>Jake=
 Arkinstall<br></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/356d5835-f1bf-4699-94f5-0b2d3d0b9c0e%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/356d5835-f1bf-4699-94f5-0b2d3d0b9c0e=
%40isocpp.org</a>.<br />

------=_Part_3860_917082784.1518140476993--

------=_Part_3859_1149588477.1518140476992--

.
