<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="author" content="P0671R1, ISO/IEC JTC1 SC22 WG21">

<link rel="stylesheet" href="http://cdn.jsdelivr.net/font-hack/2.015/css/hack.min.css"/>
<style type="text/css">
pre {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  margin-left:20pt;
  line-height: 1.1em;
  font-size: small;
}
code {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-size: small;
}
pre > i {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
code > i {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
pre > em {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
code > em {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
body {
    color: #000000; background-color: #FFFFFF; 
    font-family: "Book Antiqua", "Times New Roman", "Times", serif;
    padding: 2em;
}
/*del { text-decoration: line-through; color: #8B0040; }
ins { text-decoration: underline; color: #005100; }*/
del { text-decoration: line-through; color: #8B0040; }
ins { text-decoration: none;
    border-bottom: 1px solid #005100;
    color: #005100;
    line-height: 1.4em;
}
ins.edit { text-decoration: none;
    border-bottom: 1px solid #0000c1;
    color: #0000c1;
    line-height: 1.4em;
    background-color: #eeeeff;
}
del.edit {
  text-decoration: line-through;
    border-bottom: 1px solid #0000c1;
    color: #0000c1;
    line-height: 1.4em;
    background-color: #eeeeff;
}
span.section_name {
    float: right;
    font-weight: bold;
}

p.example { margin-left: 2em; }
pre.example { margin-left: 2em; }
div.example { margin-left: 2em; }

code.extract { background-color: #F5F6A2; }
pre.extract { margin-left: 2em; background-color: #F5F6A2;
  border: 1px solid #E1E28E; }
.attribute { margin-left: 2em; }
.attribute dt { float: left; font-style: italic;
  padding-right: 1ex; }
.attribute dd { margin-left: 0em; margin-bottom: 0.5em;}

blockquote.std { color: #000000; background-color: #F1F1F1;
  border: 1px solid #D1D1D1;
  padding-left: 0.5em; padding-right: 0.5em; }
blockquote.stddel { text-decoration: line-through;
  color: #000000; background-color: #FFEBFF;
  border: 1px solid #ECD7EC;
  padding-left: 0.5em;
  padding-right: 0.5em; }

blockquote.stdins { text-decoration: underline;
  color: #000000; background-color: #C8FFC8;
  border: 1px solid #B3EBB3; padding: 0.5em; }

table { border: 1px solid black; border-spacing: 0px;
  margin-left: auto; margin-right: auto;
  margin-top: 2em; margin-bottom: 2em;}

table.withBorder {
  border-top: none;
  border-left: none;
  border-right: 1px solid black;
  border-bottom: 1px solid black;
}
.withBorder th {
  border-top: 1px solid black;
  border-bottom: 1px solid black;
  border-left: 1px solid black;
/*  border-top: 2px solid black;
  border-left: 2px solid black;
  border-bottom: 1px solid black;
  border-right: 1px solid black;*/
}
.withBorder td {
  border-top: 1px solid black;
  border-left: 1px solid black;
}

table.header {
  margin-left: 0em;
  border: none;
    margin-bottom: 2em;
}
th { text-align: left; vertical-align: top;
  padding-left: 0.4em; 
  padding-right: 0.4em; }
td { text-align: left; vertical-align: top;
  padding-left: 0.4em; 
  padding-right: 0.4em;  }
</style>

<title>Function Arguments That Speak</title>
</head>

<body>
<table class="header">
    <tr><td>Document Number:</td> <td><b>P0671R1</b>, ISO/IEC JTC1 SC22 WG21</td></tr>
  <tr><td>Audience:</td><td>EWG</td></tr>
    <tr><td>Date:</td><td>2018-02-12</td></tr>
  <tr><td>Author:</td><td>Axel Naumann (axel@cern.ch)</td></tr>
</table>
<h1>Parametric Functions</h1>

    <h2>Table of Contents</h2>
<nav id="TOC">
<ul>
<li><a href="#preamble">Don't think you had this discussion. Don't reject this without reading it.</a></li>
<li><a href="#feature">The Feature in a Nutshell</a></li>
<li><a href="#motivation">Lots of Motivation</a></li>
<li><a href="#details">Feature Details</a></li>
<li><a href="#acknowledgments">Acknowledgments</a></li>
<li><a href="#history">Revision history</a></li>
<li><a href="#references">References</a></li>
</ul>
</nav>

  <!--
    <h2>&nbsp;</h2>
<blockquote>
<p></p>
</blockquote>
-->

<h2 id="preamble"></h2>
<h2>Preamble</h2>
<p>Please don't assume that you know what this paper is about. Several people have invested time e.g. for discussions of the feature, making it reasonable, and making it new (i.e. I am aware of past discussions). This is <em>different</em> and I appreciate that you make up your mind based on what's written here. I am almost certain: you haven't seen this before.</p>

<h2 id="feature">The Feature in a Nutshell</h3>
<p>One of my colleagues' pet peeves is the lack of named parameters in C++ (a wonderful synopsis of pain is at <a href="#ref-synopsis">[1]</a>). It's seen as a usability limitation caused by a C syntax anachronism. With many current languages, passing arguments can be done using the parameter index (C-style) or its name.</p>
<p>So here is what I suggest: allow naming arguments in regular index-based, C++-style function calls, but ignoring them from the standard's point of view (but not necessarily so from the implementers'). An example:</p>
<pre>
  <code>
double Gauss(double x, double mean = 0., double width = 1., double height = 1.);
Gauss(0.1, mean := 0., width := 2.);
  </code>
</pre>
<p>The call is completely equivalent to this traditional one:</p>
<pre>
  <code>
Gauss(0.1, 0., 2.);
  </code>
</pre>
<p>But if the call looks like this:</p>
<pre>
<code>
Gauss(0.1, width := 2., age := 65.);
</code>
</pre>
<p>then implementations could warn that the parameter <code>width</code> is known from one of the declarations of <code>Gauss</code> but is passed at the wrong position, and that <code>age</code> isn't a parameter that shows up for any of the redeclarations ("maybe you've meant to call a different overload?"). Wouldn't that be an incredibly nice and helpful compiler!</p>

<h2 id="motivation">Lots of Motivation</h2>
<p>What we currently have on the call-site of functions is tuple-style: a series of types. What C++ advocates for is classes with named members. But in current C++, member names are used much less than function parameters. How come then that we still think "a parameter index is all a call could possibly hope for"?</p>
<p>There are multiple usage patterns where current actual code and humans dealing with it suffer, in reality, on a daily basis. Here they are (if you know more, let me know!)</p>

<h3>Readability is maintainability</h3>
<p>We all have functions that take three strings, or three ints, or three doubles. It's always awkward to read calls, especially when calling with literals because they don't have any semantic meaning attached. People came up with workarounds:</p>
<pre>
  <code>func(true /*goodProposal*/, false /*gotReservations*/, true /*goodFor20*/);</code>
</pre>
<p>Apparently we need C-style comments to make C++ readable and maintainable <a href="#ref-comments">[3]</a>. Or preprocessor-magic <a href="#ref-boost">[4]</a>. Or the workaround called "use a struct and direct-initialize it". Or the "just-so-it-has-a-name" pattern of declared-once, used-once variables:</p>
<pre>
  <code>
    const bool isFast = true;
    const bool IsRed = false;
    const int numCycles = 12;
    doIt(obj, isFast, isRed, numCycles);
  </code>
</pre>

<h3>Interface evolution</h3>
<p>When evolving interfaces we have to consider all possible existing invocations. Consider this function:</p>
<pre>
  <code>
Entity Transform(const Config&amp; cfg) const;
  </code>
</pre>
  <p>It is okay to evolve this to the declaration below? Where "okay" means: will all calls provoke compiler errors, such that clients can adjust to the new interface?</p>
<pre>
<code>
Entity Transform(const vector&lt;Config&gt;&amp; cfgs) const;
</code>
</pre>
<p>No it's not, due to possible calls out there that currently invoke a <code>Config</code> constructor, but might now invoke a <code>vector</code> constructor instead.</p>
<p>And we have all lost <em>hours</em> of debugging on these issues; scale that with the number of people hitting this problem and you see how relevant this becomes. Yes, we try to make the types really non-cooperative to conversions. On the other hand we <em>want</em> interfaces and their invocations to be simple; invocation through <code>{}</code> is seen as one of the benefits that C++11 brought.</p>
<p>What if we could make this much clearer? This call</p>
  <pre>
    <code>
auto F = Transform(cfg := {});
    </code>
  </pre>
  <p>is much more of a contract between caller and callee. Long-lived code can make sure that the call remains what it was when it was written. The calling code is proposing to the implementation to check whether the selected overload is the one the call expected. That by itself is just wonderful.</p>

<h3>Overload resolution</h3>
<p>Overloading works like a charm when it works, and is a curse if the unsuspected happens. (If you question that statement, read this month's thread on ADL and <code>Path</code> from the LWG reflector.) C++ would be nice to its users if it offered argument names as a crosscheck that code author and compiler agree on the selected overload.</p>

<h3>Call: what was the order again?</h3>
<p>One of the major sources of errors we see in our code base is due to function calls with wrong parameter order. Sometimes the compiler helps (different types), but very often it doesn't. Take the example from before: without looking it up, do you remember the name of the function from the introduction? You probably did: Gauss. Do you remember the name of the parameters? Likely. But do you remember their position? Compare <code>Gauss(0.1, width:=2., mean:=0)</code> to <code>Gauss(0.1, 2., 0.)</code>. Err, wait - I meant <code>Gauss(0.1, 0., 2.)</code>. With this proposal, a good implementation would tell you that you got the order wrong.</p>
<p>Names are far more significant than indices, which is why we use them so much in C++. This is not just cosmetics - this is an actual source of bugs.</p>
<p>Counter-argument: use an IDE. That helps writing code but not reading. And maintenance cost is all about reading code.</p>

<h3>But this is not the real thing!</h3>
<p>In many other languages, parameter naming allows to specify arguments in arbitrary order, skipping arbitrary defaulted parameters. This enables much more stable interfaces - but it would introduce an ABI dependence on names (see the discussion on R0 of this proposal). So yes, this is not the real thing, far from it. But it's addressing an issue that C and C++ call syntax have since their conception, without turning C++ functions inside out.</p>

<h2 id="details">Feature Details</h2>

<h3>Syntax <code>parname := value</code></h3>
<p>In function calls, arguments can be named by separating an identifier with <code>:=</code> from the argument's expression. The use of the identifier has no effect. And as a <em>Note</em> we'll add that implementations could verify whether this name is used in any of the redeclarations of the called function.</p>
<p>Again: this proposal does not introduce a new function type, changes nothing in function declarations, is a complete opt-in syntactic sugar. So is the use of names for accessing data members these days (instead of <code>get&lt;0&gt;</code>), but wow are member names useful.</p>

<h3>Possible diagnostic implementation wrt redeclarations and overridden functions</h3>
<p>It would seem reasonable to issue no diagnostic if any declaration of the called function uses the parameter name for the argument it was specified for. If the function is virtual, parameter names used in base classes' declarations could be considered, too. The implementation cost is likely a (possibly lazily built - at least until argument names rule the world) set of known parameter names for each parameter.</p>

<h3>Effect on the standard</h3>
<p>No effect on the standard is expected: this proposal doesn't change the normative behavior. It might have an effect on the future committee: if the world falls in love with this call syntax, agreeing on parameter names for std2 might be a good idea. Until then, implementations would probably not warn about parameter name mismatches for functions in system headers.</p>

<h2 id="acknowledgments">Acknowledgments</h2>
<p>Thanks to all the CERN and Fermilab folks who insisted that this matters and provided valuable feedback, criticism and suggestions. Thanks to Ville for suggesting an approach that builds on what is suggested in this paper!</p>



<h2 id="history">Revision history</h2>

<h4>Changes compared to revision 0 (<a href="http://wg21.link/P0671R0">P0671R0</a>)</h4>
<p>Get the core features with a fairly unintrusive change: new syntax that is ignored for the standard, but enables compilers to emit diagnostics.</p>


<h2 id="references" class="references unnumbered">References</h2>

<div id="ref-synopsis">
<p>1. <a href="https://marcoarena.wordpress.com/2014/12/16/bring-named-parameters-in-modern-cpp/"><em>Bring named parameters in modern C++</em></a> by Marco Arena (retrieved on 2017-06-13).</p>
</div>

<div id="ref-n4172">
<p>2. <a href="http://wg21.link/N4172"><em>Named arguments</em></a> (N4172) by Ehsan Akhgari, Botond Ballo, and its <a href="http://wiki.edg.com/bin/view/Wg21urbana-champaign/FunctionFacilities#N4172_Named_Function_Arguments">discussion notes</a> from Urbana-Champaign.</p>
</div>

<div id="ref-comments">
<p>3. <a href="https://github.com/llvm-mirror/clang/blob/f0e160dd674697ef9c569c1d1136746da70cf44e/lib/Frontend/CompilerInstance.cpp#L860">Typical example of c-style comments to provide a name to an argument</a>.</p>
</div>

<div id="ref-boost">
<p>4. <a href="http://www.boost.org/doc/libs/1_64_0/libs/parameter/doc/html/index.html"><em>Boost parameter library</em></a> (retrieved on 2017-06-13).</p>
</div>

<!--div id="ref-varnames">
<p>5. <a href="https://github.com/llvm-mirror/clang/blob/48c1c1f35b02b2726851e1fdae84f37670fbb6af/lib/Parse/ParseDecl.cpp#L4255">Typical example of variables introduced to provide a name to an argument</a>.</p>
</div-->

</body>
</html>
