Topic: Allow optional trailing commas in comma separated lists


Author: Justin Bassett <jbassett271@gmail.com>
Date: Tue, 19 Jun 2018 23:17:03 -0700
Raw View
--0000000000005692cc056f0cbf06
Content-Type: text/plain; charset="UTF-8"

Prior discussion here but no proposal seems to have come from it:
https://groups.google.com/a/isocpp.org/forum/#!searchin/std-proposals/trailing$20comma%7Csort:date/std-proposals/I8N_75J9ZB8/discussion

Currently, when we make a function call, it's not allowed to end the list
of arguments with a trailing comma:

auto foo1 = bar(some, arguments);
// Not allowed:
// auto foo2 = bar(some, arguments,);

This *is *allowed when using brace initialization and enums, however:

auto foo3 = bar{some, arguments,};

enum class baz {
    a,
    b,
    c,
};

I claim the optional trailing comma should be extended to all comma
separated lists.

Motivating reasons:

   - Code generation. It's easier to write a tool to generate C++ code if
   it doesn't have to special case the last item in a list to not output a
   comma
   - Consistency. Being able to end each entry with a comma makes each
   entry consistent with each other. Allowing trailing commas everywhere is
   consistent.
   - git diff . Given a list with one element per line, adding a new item
   will affect two lines rather than just one.
   - Code formatting. The benefit here isn't as obvious. Clang Format will
   format brace initialization with one argument per line if the list has a
   trailing comma, and it will format the whole thing on one possibly-wrapped
   line if there is no trailing comma. The trailing comma is a hint to the
   formatter to format the code differently. This could be especially useful
   for complicated lists of template arguments.

Where this should apply:

Here's a list of the cases I could think of, although there are probably
more:

   - auto foo = bar(some, arguments,);
   - void bar(int arg1,);
   - template <typename T, auto V,>
   - std::vector<int, double,> vec;
   - class Baz : public A, public B, public C, {};

While I strongly prefer consistently allowing the trailing comma
everywhere, there are some cases that might be considered for special
exceptions:

   - If the list is terminated by a ;

int a,

    b,
;

using std::foo,

      std::bar,;


   - operator[], as we are only allowed to call it with a single argument
   (I'm specifically talking about the natural syntax).
   - Empty lists

bar(,);


   - Preprocessor macros shouldn't be directly affected by this. Trailing
   commas already "have meaning," in that an extra "empty" argument is passed
   in to the macro. Macro calls could still work, though:

// fine if

SOME_MACRO(some, args,);

// expanded to

some_function(some, args,);


Note that the comma operator doesn't need to count as a location with a
comma separated list, so this can be invalid:

(... , args,);

--
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/CAPuuy5eT%2BR7%3DWqF%3DQXs%2BK2W%2B3TCdOeYw17WXWQmuR7ORV6eX7Q%40mail.gmail.com.

--0000000000005692cc056f0cbf06
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Prior discussion here but no proposal seems to have c=
ome from it:=C2=A0<a href=3D"https://groups.google.com/a/isocpp.org/forum/#=
!searchin/std-proposals/trailing$20comma%7Csort:date/std-proposals/I8N_75J9=
ZB8/discussion">https://groups.google.com/a/isocpp.org/forum/#!searchin/std=
-proposals/trailing$20comma%7Csort:date/std-proposals/I8N_75J9ZB8/discussio=
n</a></div><div><br></div><div>Currently, when we make a function call, it&=
#39;s not allowed to end the list of arguments with a trailing comma:<br></=
div><div><br></div><div><font face=3D"monospace, monospace"><font color=3D"=
#0000ff">auto </font>foo1 =3D bar(some, arguments);</font></div><div><font =
face=3D"monospace, monospace" color=3D"#e06666">// Not allowed:</font></div=
><div><font face=3D"monospace, monospace" color=3D"#e06666">// auto foo2 =
=3D bar(some, arguments,);</font></div><div><br></div><div>This <i>is </i>a=
llowed when using brace initialization and enums, however:</div><div><br></=
div><div><font face=3D"monospace, monospace"><font color=3D"#0000ff">auto <=
/font>foo3 =3D bar{some, arguments,};</font></div><div><font face=3D"monosp=
ace, monospace"><br></font></div><div><font face=3D"monospace, monospace"><=
font color=3D"#0000ff">enum class</font> baz {</font></div><div><font face=
=3D"monospace, monospace">=C2=A0 =C2=A0 a,</font></div><div><font face=3D"m=
onospace, monospace">=C2=A0 =C2=A0 b,</font></div><div><font face=3D"monosp=
ace, monospace">=C2=A0 =C2=A0 c,</font></div><div><font face=3D"monospace, =
monospace">};</font></div><div><br></div><div>I claim the optional trailing=
 comma should be extended to all comma separated lists.</div><div><br></div=
><div>Motivating reasons:</div><div><ul><li>Code generation. It&#39;s easie=
r to write a tool to generate C++ code if it doesn&#39;t have to special ca=
se the last item in a list to not output a comma</li><li>Consistency. Being=
 able to end each entry with a comma makes each entry consistent with each =
other. Allowing trailing commas everywhere is consistent.</li><li><font fac=
e=3D"monospace, monospace">git diff</font> . Given a list with one element =
per line, adding a new item will affect two lines rather than just one.</li=
><li>Code formatting. The benefit here isn&#39;t as obvious. Clang Format w=
ill format brace initialization with one argument per line if the list has =
a trailing comma, and it will format the whole thing on one possibly-wrappe=
d line if there is no trailing comma. The trailing comma is a hint to the f=
ormatter to format the code differently. This could be especially useful fo=
r complicated lists of template arguments.</li></ul></div><div>Where this s=
hould apply:</div><div><br></div><div>Here&#39;s a list of the cases I coul=
d think of, although there are probably more:</div><div><ul><li><font color=
=3D"#0000ff" style=3D"font-family:monospace,monospace">auto </font><font co=
lor=3D"#000000" style=3D"font-family:monospace,monospace">foo =3D bar(some,=
 arguments,);</font></li><li><font color=3D"#0000ff" style=3D"font-family:m=
onospace,monospace">void</font><span style=3D"font-family:monospace,monospa=
ce"> bar(</span><font color=3D"#0000ff" style=3D"font-family:monospace,mono=
space">int </font><span style=3D"font-family:monospace,monospace">arg1,</sp=
an><span style=3D"font-family:monospace,monospace">);</span></li><li><font =
color=3D"#0000ff" style=3D"font-family:monospace,monospace">template </font=
><span style=3D"font-family:monospace,monospace">&lt;</span><font color=3D"=
#0000ff" style=3D"font-family:monospace,monospace">typename </font><span st=
yle=3D"font-family:monospace,monospace">T, <font color=3D"#0000ff">auto</fo=
nt> V</span><span style=3D"font-family:monospace,monospace">,&gt;</span></l=
i><li><font face=3D"monospace, monospace">std::vector&lt;<font color=3D"#00=
00ff">int</font>, <font color=3D"#0000ff">double</font>,&gt; vec</font><spa=
n style=3D"font-family:monospace,monospace">;</span></li><li><span style=3D=
"font-family:monospace,monospace"><font color=3D"#0000ff">class</font> Baz =
: <font color=3D"#0000ff">public </font>A, <font color=3D"#0000ff">public <=
/font>B, <font color=3D"#0000ff">public </font>C, {};</span></li></ul></div=
><div>While I strongly prefer consistently allowing the trailing comma ever=
ywhere, there are some cases that might be considered for special exception=
s:</div><div><ul><li>If the list is terminated by a <font face=3D"monospace=
, monospace">;</font></li></ul></div><blockquote style=3D"margin:0px 0px 0p=
x 40px;border:none;padding:0px"><div><div><font face=3D"monospace, monospac=
e"><font color=3D"#0000ff">int</font> a,</font></div></div></blockquote><bl=
ockquote style=3D"margin:0px 0px 0px 40px;border:none;padding:0px"><div><fo=
nt face=3D"monospace, monospace">=C2=A0 =C2=A0 b,</font></div><div><font fa=
ce=3D"monospace, monospace">;</font></div><div><font face=3D"monospace, mon=
ospace"><br></font></div></blockquote><blockquote style=3D"margin:0px 0px 0=
px 40px;border:none;padding:0px"><div><font face=3D"monospace, monospace"><=
font color=3D"#0000ff">using </font>std::foo,</font></div></blockquote><blo=
ckquote style=3D"margin:0px 0px 0px 40px;border:none;padding:0px"><div><fon=
t face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 std::bar,</font><span =
style=3D"font-family:monospace,monospace">;</span></div></blockquote><div><=
ul><li><font face=3D"monospace, monospace"><font color=3D"#0000ff">operator=
</font>[]</font>, as we are only allowed to call it with a single argument =
(I&#39;m specifically talking about the natural syntax).</li><li>Empty list=
s</li></ul><div><blockquote style=3D"font-size:small;text-decoration-style:=
initial;text-decoration-color:initial;margin:0px 0px 0px 40px;border:none;p=
adding:0px"><div><div><font face=3D"monospace, monospace">bar(,);</font></d=
iv></div></blockquote></div><ul><li>Preprocessor macros shouldn&#39;t be di=
rectly affected by this. Trailing commas already &quot;have meaning,&quot; =
in that an extra &quot;empty&quot; argument is passed in to the macro. Macr=
o calls could still work, though:</li></ul></div><blockquote style=3D"margi=
n:0px 0px 0px 40px;border:none;padding:0px"><font face=3D"monospace, monosp=
ace" color=3D"#e06666">// fine if</font></blockquote><blockquote style=3D"m=
argin:0px 0px 0px 40px;border:none;padding:0px"><div><div><font face=3D"mon=
ospace, monospace">SOME_MACRO(some, args,);</font></div></div></blockquote>=
<blockquote style=3D"margin:0px 0px 0px 40px;border:none;padding:0px"><div>=
<font face=3D"monospace, monospace" color=3D"#e06666">// expanded to</font>=
</div></blockquote><blockquote style=3D"margin:0px 0px 0px 40px;border:none=
;padding:0px"><div><font face=3D"monospace, monospace">some_function(some, =
args,);</font></div></blockquote><div><br></div><div>Note that the comma op=
erator doesn&#39;t need to count as a location with a comma separated list,=
 so this can be invalid:</div><div><br></div><div><font face=3D"monospace, =
monospace">(... , args,);</font></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAPuuy5eT%2BR7%3DWqF%3DQXs%2BK2W%2B3T=
CdOeYw17WXWQmuR7ORV6eX7Q%40mail.gmail.com?utm_medium=3Demail&utm_source=3Df=
ooter">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAPuuy5=
eT%2BR7%3DWqF%3DQXs%2BK2W%2B3TCdOeYw17WXWQmuR7ORV6eX7Q%40mail.gmail.com</a>=
..<br />

--0000000000005692cc056f0cbf06--

.