<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
  <head>
    <meta content="text/html;charset=UTF-8" http-equiv="Content-Type">
    <title>Allow lambda capture [=, this]</title>
    <style type="text/css">
      html { margin: 0; padding: 0; color: black; background-color: white; }
      body { padding: 2em; font-size: medium; font-family: "DejaVu Serif", serif; line-height: 150%; }
      code { font-family: "DejaVu Sans Mono", monospace; color: #006; }

      h1, h2, h3 { margin: 1.5em 0 .75em 0; line-height: 125%; }

      div.code { white-space: pre-line; font-family: "DejaVu Sans Mono", monospace;
                 border: thin solid #E0E0E0; background-color: #F8F8F8; padding: 1em;
                 border-radius: 4px; }

      div.strictpre { white-space: pre; }

      sup, sub { line-height: 0; }

      .docinfo { float: right; }
      .docinfo p { margin: 0; text-align:right; }
      .docinfo address { font-style: normal; }

      .quote { display: inline-block; clear: both; margin-left: 1ex;
                 border: thin solid #E0E0E0; background-color: #F8F8F8; padding: 1ex; }

      .modify { border-left: thick solid #999; border-right: thick solid #999; padding: 0 1em; }
      .insert { border-left: thick solid #0A0; border-right: thick solid #0A0; padding: 0 1em; }
      .comment { color: #456; }

      table { border-collapse: collapse; margin: 0; padding: 0; }
      th, td { vertical-align: top; text-align: left; margin: 0; padding: 0 1em 1ex 0; }
      table ul { margin: 0; padding: 0; list-style-position: outside; }
      table li { margin: 0 0 0 1em; padding: 0; }

      p.skip { margin-top: 1em; }

           .prn { color: #666; }
      ins, .pro { color: #090; }
      del, .con { color: #A00; }
      ins code, del code { color: inherit; }
    </style>
  </head>
  <body>
    <div class="docinfo">
      <p>Date: 2016-10-11</p>
      <address>Thomas K&ouml;ppe &lt;<a href="mailto:tkoeppe@google.com">tkoeppe@google.com</a>&gt;</address>
      <p class="skip">ISO/IEC JTC1 SC22 WG21 P0409R1</p>
      <p>To: EWG</p>
    </div>

    <h1>Allow lambda capture <code>[=, this]</code></h1>

    <!-- fgrep -e "<h2 id=" allow_this_v2.html | sed -e 's/.*id="\(.*\)">\(.*\)<\/h2>/<li><a href="#\1">\2<\/a><\/li>/g' -->
    <h2>Contents</h2>
    <ol>
      <li><a href="#history">Revision history</a></li>
      <li><a href="#proposal">Proposal</a></li>
      <li><a href="#impact">Impact on the Standard</a></li>
      <li><a href="#wording">Formal wording</a></li>
      <li><a href="#alternatives">Alternatives and discussion</a></li>
    </ol>

    <h2 id="history">Revision history</h2>
    <ul>
      <li>P0409R0: Initial proposal.</li>
      <li>P0409R1: Added discussion of alternatives; no change in the proposal proper.</li>
    </ul>

    <h2 id="proposal">Proposal</h2>

    <p>We propose to allow <code>[=, this]</code> as a lambda capture.</p>

    <p>With the introduction of capture-<code>this</code>-by-value in C++17, it may be
      desirable to increase code readability by being explicit about the kind of capture
      in the presence of a <code>[=]</code>-default:</p>

    <div class="code">std::function&lt;void()&gt; X::f(int n) {
      &nbsp; return coin() ? [=,&nbsp; this]() { g(n, x_, y_, z_); }
      &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : [=, *this]() { h(n, x_, y_, z_); };
      }</div>

    <p>By contrast, when both <code>[=]</code> and <code>[=, *this]</code> are present
      in a code base in large numbers, it may be easy to forget that the former is different
      from the latter: It is hard to notice the absence of something. In such situations, authors
      may wish to be explicit and to spare the reader from having remember the correct default.</p>

    <h2 id="impact">Impact on the Standard</h2>

    <p>The proposal is a pure core language extension. The newly allowed syntax was
      previously ill-formed.</p>

    <h2 id="wording">Formal wording</h2>

    <p>In section 5.1.5 [expr.prim.lambda], change paragraph 9 as follows.</p>

    <div class="modify">
      <p>If a <em>lambda-capture</em> includes a <em>capture-default</em> that is <code>&amp;</code>,
        no identifier in a <em>simple-capture</em> of that <em>lambda-capture</em> shall be preceded
        by <code>&amp;</code>. If a <em>lambda-capture</em> includes a <em>capture-default</em> that
        is <code>=</code>, each <em>simple-capture</em> of that <em>lambda-capture</em> shall be of
        the form &ldquo;<code>&amp;</code> <em>identifier</em>&rdquo;<ins>, &ldquo;<code>this</code>&rdquo;</ins>
        or &ldquo;<code>* this</code>&rdquo;. [<em>Note</em>: The form <code>[&amp;, this]</code> is
        redundant but accepted for compatibility with ISO C++ 2014. &ndash; <em>end note</em>]
        Ignoring appearances in initializers of <em>init-captures</em>, an identifier or <code>this</code>
        shall not appear more than once in a <em>lambda-capture</em>. [<em>Example</em>:</p>
      <div class="code">struct S2 { void f(int i); };
        void S2::f(int i) {
        &nbsp; [&amp;, i]{ }; &nbsp; &nbsp; &nbsp; &nbsp; // OK
        &nbsp; <ins>[&amp;, this, i]{ }; &nbsp; // OK, equivalent to [&amp;, i]</ins>
        &nbsp; [&amp;, &amp;i]{ }; &nbsp; &nbsp; &nbsp; &nbsp;// error: i preceded by &amp; when &amp; is the default
        &nbsp; [=, *this]{ }; &nbsp; &nbsp; // OK
        &nbsp; [=, this]{ }; &nbsp; &nbsp; &nbsp;// <del>error: this when = is the default</del><ins>OK, equivalent to [=]</ins>
        &nbsp; [i, i]{ }; &nbsp; &nbsp; &nbsp; &nbsp; // error: i repeated
        &nbsp; [this, *this]{ }; &nbsp;// error: this appears twice
        }</div>
      <p>&ndash; <em>end example</em>]</p>
    </div>

    <h2 id="alternatives">Alternatives and discussion</h2>

    <p>This proposal falls into a very crowded design space where we are left with relatively
      little room to move. Several alternative changes have been proposed in this space, but
      by and large they are all mutually exclusive. We present a few plausible alternatives,
      along with their advantages and disadvantages.</p>

    <p>We will not consider deprecation in the following survey, since we are only interested
      in exploring the long-term direction, and deprecation without direction is not all that
      interesting. Everything that follows is to be understood in the context of lambdas with
      default captures.</p>

    <table>
      <tr><th colspan="2"><h3>0. This proposal: Allow <code>[=, this]</code></h3></th></tr>
      <tr>
        <th>Description:</th>
        <td>
          <code>[&amp;]</code>, <code>[&amp;, this]</code>, <code>[=]</code>, <code>[=,
          this]</code> capture <code>*this</code> by reference; <code>[&amp;,
            *this]</code>, <code>[=, *this]</code> capture <code>*this</code> by value.</td>
      </tr>
      <tr>
        <th class="pro">Pros:</th>
        <td>
          <ul>
            <li>Non-breaking change; this is a pure extension.</li>
            <li>Allows for self-documenting code. Each kind of <code>this</code>-capture
              can be spelled out explicitly, no need to remember defaults.</li>
          </ul>
        </td>
      </tr>
      <tr>
        <th class="con">Cons:</th>
        <td>
          <ul>
            <li>Adds a redundant syntactical form.</li>
          </ul>
        </td>
      </tr>

      <tr><th colspan="2"><h3>1. Disallow <code>[&amp;, this]</code></h3></th></tr>
      <tr>
        <th>Description:</th>
        <td>Remove the currently allowed redundant form <code>[&amp;, this]</code>.
          <code>[&amp;]</code> captures <code>*this</code> by reference;
          <code>[&amp;, *this]</code> captures <code>*this</code> by value.</td>
      </tr>
      <tr>
        <th class="pro">Pros:</th>
        <td><ul><li>Removes all redundancy.</li></ul></td>
      </tr>
      <tr>
        <th class="con">Cons:</th>
        <td>
          <ul>
            <li>Breaking change. However, there is a transition path; equivalent code
              exists that is valid both with and without this change.</li>
            <li>No self-documenting code. Users need to remember the default.
              (&ldquo;Does <code>[=]</code> capture by value or by reference?&rdquo;)</li>
          </ul>
        </td>
      </tr>

      <tr><th colspan="2"><h3>2. Allow <em>only</em> <code>[&amp;, this]</code> and
        <code>[=, this]</code></h3></th></tr>
      <tr>
        <th>Description:</th>
        <td>Remove both implicit forms <code>[&amp;]</code> and <code>[=]</code> entirely.
          <code>[&amp;, this]</code> and <code>[=, this]</code> capture <code>*this</code>
          by reference; <code>[&amp;, *this]</code> and <code>[=, *this]</code> capture
          <code>*this</code> by value.</td>
      </tr>
      <tr>
        <th class="pro">Pros:</th>
        <td>
          <ul>
            <li>Removes all redundancy.</li>
            <li>Leaves only self-documenting code behind.</li>
          </ul>
        </td>
      </tr>
      <tr>
        <th class="con">Cons:</th>
        <td>
          <ul>
            <li>Breaking change, and no transition path. There is no code that is valid
              both with and without this change.</li>
          </ul>
        </td>
      </tr>
      <tr>
        <th></th>
        <td><em>Note.</em> This alternative is not viable, since there is no transition
          path towards it. We mention it mainly because it presents an interesting alternative
          reality. Moreover, if the present proposal were accepted, this would be a potential
          and accessible <em>future</em> direction.</td>
      </tr>

      <tr><th colspan="2"><h3>3. Make <code>[=]</code> capture by value</h3></th></tr>
      <tr>
        <th>Description:</th>
        <td><code>[=]</code> means <code>[=, *this]</code> and captures <code>*this</code>
          by value; <code>[this, =]</code> captures <code>*this</code> by reference.
      </tr>
      <tr>
        <th class="pro">Pros:</th>
        <td><ul><li>Changes the notion of &ldquo;by value&rdquo; to something more intuitive.</li></ul></td>
      </tr>
      <tr>
        <th class="prn">Prons:</th>
        <td><ul><li>
          Code is not so much &ldquo;self-documenting&rdquo; as it is perhaps
          &ldquo;natural&rdquo; if you have the appropriate mental model of <code>this</code>.
        </li></ul></td>
      </tr>
      <tr>
        <th class="con">Cons:</th>
        <td>
          <ul>
            <li>Still allows redundant syntactical forms.</li>
            <li>Breaking change without transition path: <code>[=]</code> changes meaning
              and there is no currently valid equivalent form that preserves meaning.</li>
          </ul>
        </td>
      </tr>
      <tr>
        <th></th>
        <td><em>Note.</em> This direction is popular with several people, since it is &ldquo;what
          lambdas should always have been like&rdquo;. This change is non-atomic, and we do not
          wish to explore it in detail, but we note in passing that this change contains the
          present proposal as the non-breaking subset.</td>
      </tr>
    </table>

    <p>Only alternatives 0 and 1 are immediately viable, since there is a transition path from
      the current standard. Note that alternative 0 (this proposal) is a subset of and starting
      point for both alternatives 2 and 3. Thus the immediate decision that is required is
      between 0 and 1. We believe that allowing explicit, unambiguous code (as per 0) adds
      greater value than removing redundancy from the language (as per 1). Moreover,
      pragmatically, alternative 1 would perhaps struggle to ever achieve a complete removal
      of <code>[&, this]</code> from the language; at best the feature would end up permanently
      deprecated. Without pressure to act on the deprecation, its value seems limited. By contrast,
      alternative 0 enables actionable style rules to &ldquo;always capture <code>this</code>
      explicitly&rdquo;, which may add real value to a codebase.</p>

    <h3>Further discussion</h3>

    <p>The above alternatives were surfaced during discussion on the reflector and at the
      BSI meeting in London. We conclude with a few further discussion points that were
      raised and should be heard.</p>
    <ul>
      <li>&ldquo;It is special-case behaviour that does not match anything else. [&hellip;]
        It does not add symmetry, it <em>removes</em> it.&rdquo; (Our response: it neither
        adds nor removes symmetry; it is merely another tool.)</li>
      <li>&ldquo;I&rsquo;m afraid readers will think that <code>[=]</code> is different from
        <code>[=, this]</code>.&rdquo; (Our response: Readers may also worry whether
        <code>[=]</code> is different from <code>[=, *this]</code>. Codebases should encourage
        to always be explicit so readers do not need to worry at all.)</li>
    </ul>

  </body>
</html>
