<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
  <head>
    <meta content="text/html;charset=UTF-8" http-equiv="Content-Type">
    <title>Explicit concept expressions</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%; }

      sup, sub { line-height: 0; }

      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; }

      div.code em { font-family: "DejaVu Serif", serif; }

      table { border-top: 2px solid black; border-bottom: 2px solid black; border-collapse: collapse; margin: 3em auto; }
      thead th { border-bottom: 2px solid black; }
      th, td { text-align: left; padding: 1ex 1ex 1ex 5em; }
      th:first-child, td:first-child { padding-left: 1ex; }

      tr.new td { background-color: #EFE; }
      td.new:after { content: "new!"; font-family: "DejaVu Sans", sans-serif; font-weight: bold; font-size: xx-small;
                     vertical-align: top; top: -1em; right: -1em; position: relative; float: right; color: #090; }

      .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; }

      /*  Use DIV[insert] and DIV[delete] if the entire paragraph is added or removed; otherwise
       *  use DIV[modify] and use INS/DEL elements to mark up individual changes.
       */

      div.insert { border-left: thick solid #0A0; border-right: thick solid #0A0; padding: 0 1em; }
      div.modify { border-left: thick solid #999; border-right: thick solid #999; padding: 0 1em; }
      div.delete { border-left: thick solid #A00; border-right: thick solid #A00; padding: 0 1em; }

      .comment { color: #753; }

      del { color: #A00; text-decoration: line-through; }
      ins { color: #090; }
      ins code, del code { color: inherit; }

      .box { border: thin black solid; padding: 2px; }

      .nowrap { white-space: nowrap; }
    </style>
  </head>
  <body>
    <div class="docinfo">
      <p>ISO/IEC JTC 1/SC 22/WG 21 P1013R1</p>
      <p>Date: 2018-06-10</p>
      <p>Audience: none (for historical record)</p>
      <address>
        Thomas K&ouml;ppe &lt;<a href="mailto:tkoeppe@google.com">tkoeppe@google.com</a>&gt;<br />
        Hubert S.K. Tong &lt;<a href="mailto:hubert.reinterpretcast@gmail.com">hubert.reinterpretcast@gmail.com</a>&gt;
      </address>
    </div>

    <h1>Explicit concept expressions</h1>

    <h2>Abstract</h2>

    <p>We propose to remove from the working paper the fact that mere application of arguments
      to concepts cause evaluation &ldquo;everywhere&rdquo; as boolean prvalue expressions and
      instead introduce a mildly more verbose &ldquo;<em>simple-requires-expression</em>&rdquo;.
      Instead of <code class="nowrap">bool b = Sortable&lt;MyType&gt;;</code> we propose
      <code class="nowrap">bool b = <strong>requires</strong> Sortable&lt;MyType&gt;;</code>
      This change removes unfortunate corner cases and paves the way for future extensions.</p>

    <h2>Contents</h2>
    <!-- fgrep -e "<h2 id=" concept_novalue.html | sed -e 's/.*id="\(.*\)">\(.*\)<\/h2>/<li><a href="#\1">\2<\/a><\/li>/g' -->
    <ol>
      <li><a href="#history">Revision history</a></li>
      <li><a href="#beforeafter">Before/After</a></li>
      <li><a href="#motivation">Problem and motivation</a></li>
      <li><a href="#proposal">Proposal</a></li>
      <li><a href="#alt">Alternatives</a></li>
      <li><a href="#ts-relative">Context in relation to the Concepts TS Working Draft (N4674)</a></li>
      <li><a href="#impact">Impact on the past and future</a></li>
      <li><a href="#wording">Proposed wording</a></li>
      <li><a href="#ack">Acknowledgements</a></li>
      <li><a href="#discuss">Discussion outcome: no consensus</a></li>
    </ol>

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

    <ul>
      <li>P1013R1 (this revision). <em>A draft D1013R1 was <a href="#discuss">presented</a> to EWG
          in Rapperswil 2018, but the proposal did not achieve consensus. It is made available here
          for historic record. The draft is identical to this final revision except for this change
          entry and the discussion outcome below.</em>
        <ul>
          <li>More accurately describe the scope of the issue as applying to the use of concept names with template argument lists.</li>
          <li>Added description of the issue in the context of the Concepts TS and where it was going.</li>
          <li>Corrected description of the contexts where concept value evaluation remains just an <em>id-expression</em>.</li>
        </ul>
      </li>
      <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1013r0.html">P1013R0</a>: Initial proposal</li>
    </ul>

    <h2 id="beforeafter">Before/After</h2>

    <table>
      <colgroup>
        <col style="width: 37em">
        <col style="width: 42em">
      </colgroup>

      <thead>
        <tr><th>Before the proposal</th><th>With the proposal</th></tr>
      </thead>

      <tbody>
        <tr>
          <td><div class="code">template &lt;typename T&gt; concept Foo = <span class="comment">/* ... */</span>;

template &lt;typename T&gt; void f(T) {
<span style="color: #A00">&nbsp; static_assert(Foo&lt;T&gt;);</span>
<span style="color: #A00">&nbsp; if constexpr (Foo&lt;T&gt;)</span> { <span class="comment">/* ... */</span> }
}</div></td>
          <td><div class="code">template &lt;typename T&gt; concept Foo = <span class="comment">/* ... */</span>;

template &lt;typename T&gt; void f(T) {
<span style="color: #0A0">&nbsp; static_assert(requires Foo&lt;T&gt;);</span>
<span style="color: #0A0">&nbsp; if constexpr (requires Foo&lt;T&gt;)</span> { <span class="comment">/* ... */</span> }
}</div></td>
        </tr>
      </tbody>
    </table>

    <h2 id="motivation">Problem and motivation</h2>

    <p>Consider a simple type concept:</p>
    <div class="code">template &lt;typename T, typename U = T&gt; concept Foo = <span class="comment">/* ... */</span>;</div>
    <p>For a given type, say <code>int</code>, the current working paper makes <code>Foo&lt;int&gt;</code>
      a boolean prvalue. This creates a curious corner case if we consider future syntax extensions for
      abbreviated function templates. Consider the following code:</p>
    <div class="code">template &lt;typename T&gt; bool x(Foo&lt;T&gt;);</div>
    <p>There are two plausible meanings this code could have (assuming further work in the direction
      of <a href="http://wg21.link/p0745r0">P0745R0</a>):</p>
    <div class="code">template &lt;typename T&gt;<!--
--> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<!-- typename
--> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<!-- U&gt; requires
--> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;<!-- Foo&lt;T, U&gt;
--> bool x = Foo&lt;T&gt;; &nbsp; <span class="comment">// #1 (variable)</span>

template &lt;typename T, typename U&gt; requires Foo&lt;T, U&gt; bool x(U u); &nbsp; &nbsp; &nbsp; <span class="comment">// #2 (function)</span></div>
    <p>This is kind of an inverse of the &ldquo;most vexing parse&rdquo;. In the status quo of
      the working paper, the meaning is that of case #1 (a variable declaration); whereas at
      least some have expressed that the preferable meaning would be that of case #2 (a function
      declaration).  This latter case is the one that is consistent with dropping constraints:
      <code>template &lt;typename T&gt; bool x(T)</code> is already a function declaration in
      the status quo.</p>

    <p>We can avoid this problem if we make it so that applying template argument lists to plain
      concept names do not form prvalue expressions, thus spuriously occupying a &ldquo;privileged&rdquo;
      syntax. If we retain the status quo and later discover that this problem is serious, it will be a
      breaking change to remove or change the behaviour. On the other hand, if we remove the behaviour
      now and later discover that we actually do need it, we can easily add it back in without breaking
      code written to a level of C++ specified by an International Standard.</p>

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

    <p>We propose that an <em>id-expression</em> ([expr.prim.id]) that denotes the
      specialization of a concept no longer results in a prvalue except in specific contexts
      where we can expect normalization to apply the specific rule for normalization of an <em>id-expression</em>
      that names a specialization of a concept, i.e., it is not a subexpression of an atomic constraint (and
      in, for example, a <em>constraint-logical-or-expression</em>).
      To make up for the lost functionality, we introduce a new kind of expression: a
      &ldquo;<em>simple-requires-expression</em>&rdquo;, which turns a specialization of a
      concept into the boolean value indicating its constraint satisfaction.</p>

    <h2 id="alt">Alternatives</h2>

    <p>Instead of making concepts not be expressions, we could make them expressions precisely
      when they are &ldquo;named fully&rdquo; or &ldquo;fully specialized&rdquo;, but treat
      them as type placeholders when they are only &ldquo;partially bound&rdquo;.  A
      hypothetical short function template syntax might then fit in like this:</p>

    <div class="code">template &lt;typename A, typename B&gt; concept Foo = <span class="comment">/* ... */</span>;

      bool x(Foo&lt;int, char&gt;);&nbsp; <span class="comment">// variable, equiv. to bool x = Foo&lt;int, char&gt;;</span>
      bool y(Foo&lt;char&gt;); &nbsp;&nbsp;&nbsp;&nbsp;<!--
      int, --> &nbsp;<!-- two spaces
      --><span class="comment">// function, equiv. to template &lt;typename T&gt; requires Foo&lt;char, T&gt; bool y(T)</span></div>

    <p>In this approach, it is necessary to know the declaration of <code>Foo</code> in order to
      know whether <code class="nowrap">bool y(Foo&lt;char&gt;)</code> declares a variable or a
      function, with the usual concerns about maintenance, default arguments, etc.</p>

    <p>This approach presupposes a detail of a future, not-yet-made design. It is a plausible
      approach, but at the same time this direction is compatible with our main proposal: we can
      first remove the evaluation-for-satisfaction interpretation of supplying arguments to concept
      names, and later bring it back with the semantics described here.</p>

    <p>The proposed new <em>simple-requires-expression</em> is not strictly required,
      since a boolean value can also be obtained from an (ordinary) <em>requires-expression</em>
      such as &ldquo;<code>requires { requires Foo&lt;T&gt;; }</code>&rdquo;.
      We feel that such an expression would be somewhat unwieldy in contexts such as those of
      constexpr if and static assertion, and that the new <em>simple-requires-expression</em>
      will fit in more naturally.</p>

    <h2 id="ts-relative">Context in relation to the Concepts TS Working Draft (N4674)</h2>

    <p>The issue mentioned by this paper appears in the context of the Concepts TS as an ambiguity between
      <em>constrained-type-specifier</em>s whose <em>constrained-type-name</em> is a <em>partial-concept-id</em> and
      <em>simple-template-id</em>s whose <em>template-name</em> names a concept; the Concepts TS does not contain
      wording to add this ambiguity in either [stmt.ambig] or [dcl.ambig.res].</p>

    <p>The Concepts TS has a process for concept resolution (N4674 [temp.constr.resolve]), the primary purpose
      of which is to handle overloading of function concepts, that could come into play as part of ambiguity
      resolution through determining whether the potential <em>partial-concept-id</em> is or is not a <em>type-name</em>.
      As an example, concept resolution will fail when considering <code>C&lt;int&gt;</code> (below) as a placeholder type,
      because there is a mismatch between the <code>int</code> type argument and the non-type template parameter. The
      alternate interpretation of <code>C&lt;int&gt;</code> as an expression is considered viable.</p>

    <div class="code">template &lt;typename T, int N = 0&gt; concept bool C = true;
      bool f(C&lt;int&gt;);</div>

    <p>It is observed that semantic aspects in the details of the definition and of the use weigh into disambiguation with such a strategy.</p>

    <p>We move beyond the traditional type-versus-expression ambiguity if we further pursue the direction, indicated to be intended by the design
      of the TS on the core reflector <a href="https://accu.org/cgi-bin/wg21/message?wg=core&amp;msg=28404">[core-28404]</a>, of allowing concept
      placeholders with other-than-type prototype parameters. On the reflector, it was observed that the TS admits <em>constrained-type-specifier</em>s
      (N4674 [dcl.type.simple]) to be placeholders for non-type and template template arguments, but does not extend the grammar to allow
      <em>constrained-type-specifier</em>s in the corresponding contexts; the latter situation appears to be considered a wording problem.</p>

    <p>On that aspect of the design space, in addition to being short on wording to be found already in the Concepts TS, the GCC implementation
      behaves oddly when presented with such <em>constrained-type-specifier</em>s in contexts where they may have been parsed as a type
      <a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85846">[GccBug85846]</a><a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85991"
      >[GccBug85991]</a>.</p>

    <p>Additional design guidance would also be required on the value/value ambiguity between evaluation for substitution versus being a placeholder,
      and the interpretation as to whether an argument list forms part of a <em>partial-concept-id</em> or not when used with concepts having template
      prototype parameters.</p>

    <p>For example, consider the following:</p>
    <div class="code">template &lt;typename&gt; class TmplA;

      template &lt;template &lt;template &lt;typename&gt; class&gt; class, template &lt;typename&gt; class = TmplA&gt;
      concept bool Tmpl1 = true;

      template &lt;template &lt;template &lt;typename&gt; class&gt; class, typename = int&gt;
      concept bool C = true;

      bool f(C&lt;Tmpl1&lt;TmplA&gt; &gt;); <em>// is Tmpl1&lt;TmplA&gt; a type-name or a template-name?</em></div>

    <p>We may find that these aspects hint towards needing extra syntax to engage the placeholder interpretation as opposed to requiring extra syntax
      for the evaluation-for-satisfaction; however, the future is hard to predict.</p>

    <h2 id="impact">Impact on the past and future</h2>

    <p>There is no impact on the Standard, since the proposal modifies a feature that has not
      yet been standardized.</p>

    <p>Removing concept <em>id-expressions</em> now means that we do not standardize a feature
      that we may later regret and cannot change without a break. On the other hand, adding the
      removed feature back in later, if and when we do need it, is straightforward.</p>

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

    <p>[to be fleshed out]</p>
    <div class="modify"><em>requires-expression</em>:<br />
      &nbsp; &nbsp; <code>requires</code> <em>requirement-parameter-list</em><sub>opt</sub> <em>requirement-body</em><br />
      <br />
      <ins><em>simple-requires-expression</em>:</ins><br />
      &nbsp; &nbsp; <ins><code>requires</code> <em>nested-name-specifier</em><sub>opt</sub> <em>simple-template-id</em></ins>
    </div>

    <p>An <del><em>id-expression</em> that</del><ins><em>simple-requires-expression</em>
      whose <em>simple-template-id</em></ins> denotes the specialization of a concept
      [temp.concept] results in a prvalue of type <code>bool</code>. The expression
      is <code>true</code> if the concept&rsquo;s normalized <em>constraint-expression</em>
      [temp.constr.decl] is satisfied [temp.constr.constr] by the specified template arguments
      and <code>false</code> otherwise.</p>

    <div class="code">template&lt;typename T&gt; concept C = true;
      static_assert(<ins>requires </ins>C&lt;int&gt;);          // OK</div>

    <p>[<em>Note</em>: A concept&rsquo;s constraints are also considered
      when using a template name [temp.names] and during overload resolution [over],
      and they are compared during the the partial ordering of constraints [temp.constr.order].
      &ndash;&nbsp;<em>end note</em>]</p>

    <h2 id="ack">Acknowledgements</h2>

    <p>Many thanks to Andrew Sutton for valuable discussion, Botond Ballo for necessary poking, and
      Richard Smith for his pre-Rapperswil review and feedback.</p>

    <h2 id="discuss">Discussion outcome: no consensus</h2>

    <p>This proposal was presented to EWG in Rapperswil 2018 but did not achieve consensus
      (SF: 4 | F: 15 | N: 11 | A: 6 | SA: 8). The main points of opposition were:</p>
    <ul>
      <li>The proposal adds undesired verbosity.</li>
      <li>The perceived problem is &ldquo;hypothetical&rdquo;, based on future proposals.</li>
      <li>There are mitigating factors for the potential of a breaking change from C++20:<ul>
        <li>The future terse syntax extensions may be free of the ambiguities we describe here.</li>
        <li>Ambiguities, should they exist, may be addressed as part of processing the proposed terse syntax.</li>
        <li>There is no breaking change to C++20 if terse syntax lands before C++20 ships.</li>
      </ul></li>
    </ul>

  </body>
</html>
