<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
  <head>
    <meta content="text/html;charset=UTF-8" http-equiv="Content-Type">
    <title>An Adjective Syntax for Concepts</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: #753; }
      .comment a:link, .comment a:visited { color: #A51; }

      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: 0; margin: 0; }
      tr:first-child td { padding-top: 1ex; }
      tr:last-child td { padding-bottom: 1ex; }

      .x th, .x td { padding: 1ex 1ex 1ex 1ex; }
      .x th:first-child, .x td:first-child { padding-left: 1ex; }
      td.y { padding: 0 1em; }

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

      ins { color: #090; }
      del { color: #A00; }
      ins code, del code { color: inherit; }

      #toggleparams:checked ~ * .params { display: none; }
    </style>
  </head>
  <body>
    <div class="docinfo">
      <p>Date: 2017-10-12</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 P0807r0</p>
      <p>To: EWG</p>
    </div>

    <h1>An Adjective Syntax for Concepts</h1>

    <!-- fgrep -e "<h2 id=" adjective.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="#summary">Summary</a></li>
      <li><a href="#motivation">Motivation</a></li>
      <li><a href="#details">Details</a></li>
      <li><a href="#auto">What about <code>auto</code>?</a></li>
      <li><a href="#lambda">And what about lambdas?</a></li>
      <li><a href="#recap">Recap</a></li>
      <li><a href="#future">Future directions</a></li>
      <li><a href="#alt">Alternatives</a></li>
      <li><a href="#questions">Questions</a></li>
      <li><a href="#ack">Acknowledgements</a></li>
    </ol>

    <h2 id="history">Revision history</h2>
    <ul>
      <li>P0807r0: Initial proposal.</li>
    </ul>

    <h2 id="summary">Summary</h2>

    <p>We propose to change the <em>constrained-parameter</em> syntax for concepts to be
      more general, more explicit and more expressive by using the grammatical structure
      of &ldquo;<em>attributive adjective, subject noun, predicate noun</em>&rdquo;:</p>
    <table>
      <tr>
        <td><code>template &lt;</code></td>
        <td><code>Sortable&nbsp;</code></td>
        <td class="y"><code>typename&nbsp;</code></td>
        <td><code>T</code></td>
        <td><code>&gt; void f(T&amp; collection);</code></td>
      </tr>
      <tr>
        <td><code>template &lt;</code></td>
        <td><code>Even&nbsp;</code></td>
        <td class="y"><code>int&nbsp;</code></td>
        <td><code>N</code></td>
        <td><code>&gt; void g(Foo (&amp;pairs)[N]);</code></td>
      </tr>
      <tr>
        <td></td>
        <td><em>attr. adjective</em></td>
        <td class="y"><em>subj. noun</em></td>
        <td><em>pred. noun</em></td>
        <td></td>
      </tr>
    </table>

    <p>This idea is not original; to my best knowledge it was first proposed by Richard Smith in
      Issaquah 2016, and I have since heard it restated as Richard&rsquo;s idea by several
      others, including members of the BSI and on the std-proposals mailing list.</p>

    <h2 id="motivation">Motivation</h2>

    <p>In the present C++ working paper
      (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4687.pdf">N4687</a>),
      the &ldquo;Concepts&rdquo; feature consists of the core mechanics of template constraints
      ([temp.constr]), as well as a &ldquo;convenience syntax&rdquo; in the form
      of <em>constrained-parameter</em>s, which offer a short-hand access to a limited subset of
      constraints. Specifically, a constrained template like <code>template &lt;Sortable T&gt;</code>
      is syntactic sugar for <code>template &lt;typename T&gt; requires Sortable&lt;T&gt;</code>
      when <code>Sortable</code> is a type concept, and more generally the kind of <code>T</code>
      is deduced from the prototype parameter of the concept.</p>

    <p>This syntax is superficially convenient, but it suffers from the problem that it creates
      an ambiguity: Does <code>template &lt;Foo X&gt;</code> have an unconstrained non-type
      parameter or a constrained (type or template) parameter? This ambiguity may not be an
      immediate concern, but it presents a kind of dead end for the design space: Additional
      syntactic shorthands, such as the terse function syntax from the Concepts TS, bring their
      own set of new ambiguities. (For example, is <code>f(Foo x, Foo y)</code> a function or a
      function template? Does it have one or two template parameters?)</p>

    <p>We propose to improve the situation by revising the <em>constrained-parameter</em>
      syntax.  (The core Concepts engine will remain unaffected.) The proposed changes establish
      a consistent set of syntactical rules and markers that resolve the present ambiguities and
      will also work well with future additional syntactic sugar for function and variable
      declarations.</p>

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

    <p>There are three <em>kinds</em> of entities in C++ that one can parametrise over:</p>

    <table class="x">
      <thead>
        <tr><th></th><th>Kind</th><th>Disambiguator</th><th>Declaration example</th><th>Template parameter example</th></tr>
      </thead>
      <tbody>
        <tr>
          <td>1.</td>
          <td>things that <em>have</em> a type</td>
          <td>nothing</td>
          <td><code>int a = x;</code> (<code>x</code> is a value)</td>
          <td><code>template &lt;int N&gt;</code></td>
        </tr>
        <tr>
          <td>2.</td>
          <td>things that <em>are</em> a type</td>
          <td><code>typename</code></td>
          <td><code>using T = typename foo::x;</code> (<code>x</code> is a type)</td>
          <td><code>template &lt;typename T&gt;</code></td>
        </tr>
        <tr>
          <td>3.</td>
          <td>templates</td>
          <td><code>template</code></td>
          <td><code> using A = typename foo::template x&lt;T&gt;</code> (<code>x</code> is a template)</td>
          <td><code>template &lt;template &lt;/* ... */&gt; typename Tmpl&gt;</code></td>
        </tr>
      </tbody>
    </table>

    <p>Templates can be specialised to form all three of these kinds (variable/function
      templates for (1), class templates for (2), and alias templates for (3)). Let us call the
      three kinds <em>values</em>, <em>types</em> and <em>templates</em> for short, just for the
      sake of brevity and for the scope of this proposal (so functions are values for now). When
      we need to be explicit about the kind of an entity, either because a name is dependent, or
      because we are specifying template parameters, we distinguish the three kinds with the
      <em>disambiguator</em> shown in the table above.</p>

    <p>If we examine the template parameter grammar in C++ from the perspective of natural language,
      an analogy suggests itself: In <code>int N</code>, <code>typename T</code>, <code>template
        ... Tmpl</code>, the name of the parameter that is being declared is naturally a predicate
      noun, and the word that precedes it is the subject: &ldquo;The integer is <code>N</code>.&rdquo;,
      &ldquo;A type called <code>T</code>.&rdquo;, etc. The disambiguator is a noun making up that
      subject, and for the <em>value</em> case, the actual type name of the parameter is the
      noun. Where does this leave concept constraints? Constraints constrain something, so they are
      a kind of qualification, an attribute. The simplest kind of attribute is the attributive adjective:
      A <em>red</em> door, an <em>even</em> number. Constraint names can often be read as adjectives
      (or perhaps as some more complex attributive).</p>

    <p>This little excursion into natural language suggests a modification to the C++ grammar that
      makes the language more expressive and that resolves the current problems. The solution is to
      retain <em>both</em> the attributive adjective <em>and</em> the subject noun in the parameter
      declaration:</p>

    <ol>
      <li><code>template &lt;Even int N&gt;</code> for <code>template &lt;int N&gt; requires Even&lt;N&gt;</code> (unary non-type constraint).</li>
      <li><code>template &lt;Sortable typename T&gt;</code> for <code>template &lt;typename T&gt; requires Sortable&lt;T&gt;</code> (unary type constraint).</li>
      <li><code>template &lt;Rebindable template &lt;typename&gt; typename Tmpl&gt;</code> for
          <code>template &lt;typename&gt; typename Tmpl&gt; requires Rebindable&lt;Tmpl&gt;</code> (unary template constraint); but see below.</li>
    </ol>

    <p>Both the adjective and the predicate are optional, of course: A parameter can be unconstrained
      and need not be named. But the general template parameter now consists of three parts, and there
      is now no ambiguity: If <code>typename</code> is present, it is a type parameter, if <code>template</code>
      is present, it is a template parameter, and if neither is present, it is a non-type parameter.</p>

    <p>A concept that can be used as an adjective in this way is required to be <em>unary</em>, i.e.
      to constrain only one template parameter, and it has to have the appropriate
      kind of prototype parameter: value concepts must have a non-type parameter of the correct type,
      type concepts must have a type parameter, and template concepts must have a template parameter
      of a compatible signature (allowing for <code>...</code> to match non-variadic templates, etc.).
      Additional template parameters are allowed, just as they are in the status quo, and are filled in
      after the first parameter: <code>template &lt;VeryEven&lt;A, B, C&gt; int N&gt;</code> becomes
      <code>template &lt;int N&gt; requires VeryEven&lt;N, A, B, C&gt</code>.</p>

    <p>For constrained template template parameters, we may wish to use the simpler form
      <code>template &lt;Rebindable template Tmpl&gt;</code> and leave the template signature
      entirely to be determined by the concept. On the other hand, using the full template
      signature allows the user to request a template of a specific signature that is <em>also</em>
      constrained by a (possibly more generic) concept. We could also allow both a short form (without
      <code>typename</code> and <code>class</code>) that deduces the template signature from the
      concept, as well as a long form (with <code>typename</code> or <code>class</code>). If the
      long form is used, the user-provided signature must be compatible with the concept&rsquo;s
      prototype parameter.</p>

    <h2 id="auto">What about <code>auto</code>?</h2>

    <p>An <code>auto</code>
      parameter is a non-type parameter whose type is deduced. As such, we may wish to constrain both
      its value and also its permissible types.</p>

    <p>The most conservative solution is to continue the same logic as above, and require
      the concept to have an exactly matching prototype parameter, namely an <code>auto</code> parameter.
      For example, <code>template &lt;EvenInteger auto N&gt;</code> becomes <code>template &lt;auto N&gt;
        requires EvenInteger&lt;N&gt;</code>, and the concept could be something like:</p>
    <div class="code">template &lt;auto N&gt;
      &nbsp; concept EvenInteger = (std::is_integer_v&lt;decltype(N)&gt;) &amp;&amp; (N % 2 == 0);</div>

    <p>However, we can imagine different directions or generalisations:</p>
    <ul>
      <li>Allow type concepts to constrain <code>auto</code> parameters: <code>template &lt;Foo auto N&gt;</code>
        becomes <code>template &lt;auto N&gt; requires Foo&lt;decltype(N)&gt;</code> when <code>Foo</code> is a
        type concept (&ldquo;automatic <code>decltype</code> unwrapping&rdquo;).</li>
      <li><code>template &lt;Even auto N&gt;</code> might be allowed but a hard error or SFINAE condition
        when <code>N</code> is deduced to anything other than <code>int</code>.</li>
    </ul>

    <p>Let us call a concept whose prototype parameter is <code>auto</code> an <em>auto</em>
      concept. Naturally, auto concepts constrain auto parameters. But we may also allow auto
      concepts to constrain typed non-type parameters: <code>template &lt;EvenInteger long
      N&gt;</code> becomes <code>template &lt;long N&gt; requires EvenInteger&lt;N&gt;</code>
      and deduces the type of <code>N</code> as <code>long</code>. The adjective syntax allows
      us to write specific templates (e.g. using <code>long</code>) constrained by generic,
      reusable concepts (e.g. <code>EvenInteger</code>).</p>

    <h2 id="lambda">And what about lambdas?</h2>

    <p>A C++14-style generic lambda contains a function template that does not use a template introducer,
      and instead declares a parameter with type specifier <code>auto</code>, where <code>(auto x)</code>
      stands for a function template of the form <code>template &lt;typename T&gt; (T x)</code>. To allow
      constrained generic lambdas, only type constraints may be applied to the (implied) template parameter.
      The natural syntax that suggests itself here is to perform &ldquo;<code>decltype</code> unwrapping&rdquo;
      and admit type-constraining concepts of the form</p>
    <div class="code">[](Sortable auto x) { /* ... */ }</div>
    <p>to stand for</p>
    <div class="code">[]&lt;Sortable typename T&gt;(T x) { /* ... */ }
      <span class="comment">// which is, behind the scenes:</span>
      template &lt;Sortable typename T&gt; auto operator()(T x) const { /* ... */ }
      <span class="comment">// or in full:</span>
      template &lt;typename T&gt; requires Sortable&lt;T&gt; auto operator()(T x) const { /* ... */ }
    </div>

    <h2 id="recap">Recap</h2>

    <input id="toggleparams" type="checkbox" checked="checked">hide <code><em>params</em>/<em>args</em></code> examples

    <table class="x">
      <thead>
        <tr><th>Constraint kind</th><th>Concept example</th><th>Example usage</th></tr>
      </thead>
      <tbody>
        <tr>
          <th>Unary non-type template constraint</th>
          <td><div class="code">template &lt;int N<span class="params">, /*<em>params</em>*/</span>&gt;
              &nbsp; concept NonTypeFoo = /* ... */;

          </div></td>
          <td><div class="code">template &lt;NonTypeFoo<span class="params">&lt;/*<em>args</em>*/&gt;</span> int V&gt;
              &nbsp; struct X;
              <span class="comment">// requires NonTypeFoo&lt;V<span class="params">, /*<em>args</em>*/</span>&gt;</span></div></td>
        </tr>
        <tr>
          <th>Unary type template constraint</th>
          <td><div class="code">template &lt;typename T<span class="params">, /*<em>params</em>*/</span>&gt;
              &nbsp; concept TypeBar = /* ... */;

          </div></td>
          <td><div class="code">template &lt;TypeBar<span class="params">&lt;/*<em>args</em>*/&gt;</span> typename T&gt;
              &nbsp; struct Y;
              <span class="comment">// requires TypeBar&lt;T<span class="params">, /*<em>args</em>*/</span>&gt;</span></div></td>
        </tr>
        <tr>
          <th>Unary template template constraint</th>
          <td><div class="code">template &lt;template &lt;typename, int, typename...&gt; typename Tmpl<span class="params">, /*<em>params</em>*/</span>&gt;
              &nbsp; concept TemplateQuz = /* ... */;







              
          </div></td>
          <td><div class="code">template &lt;TemplateQuz<span class="params">&lt;/*<em>args</em>*/&gt;</span> template &lt;
              &nbsp; &nbsp; typename, int, bool, char&gt; typename Tmpl&gt;
              &nbsp; struct Z;
              <span class="comment">// long form</span>
              <span class="comment">// requires TemplateQuz&lt;Tmpl<span class="params">, /*<em>args</em>*/</span>&gt;</span>

              template &lt;TemplateQuz<span class="params">&lt;/*<em>args</em>*/&gt;</span> template Tmpl&gt;
              &nbsp; struct Z;
              <span class="comment">// short form, Tmpl is &lt;typename, int, typename...&gt;</span>
              <span class="comment">// requires TemplateQuz&lt;Tmpl<span class="params">, /*<em>args</em>*/</span>&gt;</span>
          </div></td>
        </tr>
        <tr>
          <th>
            Unary auto template constraints
            <ul>
              <li>on <code>auto</code> non-type parameters</li>
              <li>on typed non-type parameters</li>
            </ul>
          </th>
          <td><div class="code">template &lt;auto N<span class="params">, /*<em>params</em>*/</span>&gt;
              &nbsp; concept <span class="params">Very</span>EvenInteger =
              &nbsp; &nbsp; std::is_integer_v&lt;decltype(N)&gt; &amp;&amp; (N % 2 == 0)<span class="params"> && OtherReqs&lt;/*<em>params</em>*/&gt;</span>;




          </div></td>
          <td><div class="code">template &lt;<span class="params">Very</span>EvenInteger<span class="params">&lt;/*<em>args</em>*/&gt;</span> auto N&gt;
              &nbsp; struct W1;
              <span class="comment">// requires <span class="params">Very</span>EvenInteger&lt;N<span class="params">, /*<em>args</em>*/</span>&gt;</span>

              template &lt;<span class="params">Very</span>EvenInteger<span class="params">&lt;/*<em>args</em>*/&gt;</span> std::size_t N&gt;
              &nbsp; struct W2;
              <span class="comment">// requires <span class="params">Very</span>EvenInteger&lt;N<span class="params">, /*<em>args</em>*/</span>&gt;, deducing std::size_t</span>
          </div></td>
        </tr>
        <tr>
          <th>
            Unary type and non-type constraints<br>on <code>auto</code> parameters
            <ul>
              <li><code>decltype</code>-unwrapping<br></li>
              <li>value-constraining</li>
          </ul></th>
          <td><div class="code">template &lt;typename T<span class="params">, /*<em>params</em>*/</span>&gt;
              &nbsp; concept <span class="params">Very</span>Integral = std::is_integer_v&lt;T&gt;<span class="params"> && OtherReqs&lt;/*<em>params</em>*/&gt;</span>;

              
              template &lt;int N<span class="params">, /*<em>params</em>*/</span>&gt;
              &nbsp; concept <span class="params">Very</span>Even = (N % 2 == 0)<span class="params"> && OtherReqs&lt;/*<em>params</em>*/&gt;</span>;
              
          </div></td>
          <td><div class="code">template &lt;<span class="params">Very</span>Integral<span class="params">&lt;/*<em>args</em>*/&gt;</span> auto N&gt;
              &nbsp; struct W3;
              <span class="comment">// requires <span class="params">Very</span>Integral&lt;decltype(N)<span class="params">, /*<em>args</em>*/</span>&gt;</span>

              template &lt;<span class="params">Very</span>Even<span class="params">&lt;/*<em>args</em>*/&gt;</span> auto N&gt;
              &nbsp; struct W4;
              <span class="comment">// requires <span class="params">Very</span>Even&lt;N<span class="params">, /*<em>args</em>*/</span>&gt;, and decltype(N) must be int</span>
          </div></td>
        </tr>
        <tr>
          <th>Function template constraints<br>on generic lambdas<br>(type constraints only)</th>
          <td colspan="2"><div class="code">[](TypeBar<span class="params">&lt;/*<em>args</em>*/&gt;</span> auto x) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="comment">// equivalent to:</span>
              []&lt;TypeBar<span class="params">&lt;/*<em>args</em>*/&gt;</span> typename T&gt;(T x) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="comment">// equivalent to:</span>
              []&lt;typename T&gt; requires TypeBar&lt;T<span class="params">, /*<em>args</em>*/</span>&gt; (T x) &nbsp; &nbsp;<span class="comment">// (hypothetical)</span></div></td>

        </tr>
      </tbody>
    </table>

    <p>The changes in a nutshell:</p>
    <ul>
      <li>The <em>constrained-parameter</em> syntax for templates becomes more verbose, more
        explicit and more general.</li>
      <li>Template parameters become (again) unambiguously decorated by their familiar
        disambiguator as non-type, type and template kind.</li>
      <li>In particular, constrained <code>auto</code> parameters are decorated with an
        explicit <code>auto</code> and can additionally be constrained with type concepts (via
        &ldquo;<code>decltype</code> unwrapping&rdquo;) and with value concepts (via required
        type matching).</li>
      <li>Constrained template template parameters and constrained value parameters  may be more
        specialised than their concept&rsquo;s prototype parameter.</li>
      <li>The proposed style extends naturally to generic lambdas and other kinds of syntactic
        shorthands. It provides an unambiguous syntactic marker (<code>auto</code>) that a
        template is being declared, and that each declared constrained parameter is a distinct
        template parameter.</li>
    </ul>

    <h2 id="future">Future directions</h2>

    <h3>Function templates</h3>

    <p>We <a href="#lambda">already demonstrated</a> how the adjective syntax may be reused to
      allow constrained generic lambdas.  Since lambdas share many characteristics with ordinary
      functions, it is natural to allow ordinary function templates to use the same parameter
      declaration syntax as generic lambdas. Putting the constraint in attributive position
      leaves the <code>auto</code> keyword as an unmistakable signifier that the declaration is
      a function template. (The alternative syntactic shorthand that was present in the Concepts
      TS omits the <code>auto</code> keyword when a constraint is present, which leaves it
      unclear at a glance whether a function or a function template is being declared.)</p>

    <div class="code">void f(Foo auto x, Bar auto y);

      <span class="comment">// short for:</span>

      template &lt;typename T, typename U&gt; requires Foo&lt;T&gt && Bar&lt;U&gt;
      &nbsp; f(T x, U y);
    </div>
    
    <p>A side note: the syntax in the Concepts TS left it visually unclear whether a repeated constraint
      in the parameter list refers to one single or several distinct template parameters, e.g. whether
      <code>void f(Foo x, Foo y)</code> is <code>template &lt;typename T&gt; void foo(T, T)</code> or
      <code>template &lt;typename T1, typename T2&gt; void foo(T1, T2)</code>. (The TS does have
      a definite rule, but the point is that a reader needs to know and remember (or look up)
      that rule.) With the proposed adjective style, the function template might be spelled <code>void
      f(Foo auto x, Foo auto y)</code>, which, by analogy with existing uses of <code>auto</code> in C++17,
      makes it reasonably obvious that two distinct template parameters are being declared.</p>

    <h3>Variables and return types</h3>

    <p>Another kind of type that may be decorated with constraints is the type of a variable or the return
      type of a function. At present, <code>auto</code> is allowed for both; adding a constraint attribute
      may conceivably be useful. Moreover, deduction could be allowed for template parameters.</p>
    <div class="code">template &lt;typename T&gt; void f(T t) {
      &nbsp; Sortable auto x = t.GetAll(); &nbsp;<span class="comment">// ill-formed unless &ldquo;requires Sortable&lt;decltype(x)&gt;&rdquo;</span>
      &nbsp; std::vector&lt;Desirable typename&gt; v = t.RetrieveEvery(); &nbsp;<span class="comment">// not &ldquo;Desirable auto&rdquo;; type, not value</span>
      }

      Sortable auto g(auto y) { &nbsp;<span class="comment">// maybe ill-formed, maybe SFINAE-friendly</span>
      &nbsp; return y.GetAll();
      }
    </div>

    <h3>Multiple concepts</h3>

    <p>Finally, we might consider allowing more than one concept name to appear before the noun,
      interpreted as &ldquo;and&rdquo;, as in <code>template &lt;Sortable Movable typename C&gt;</code>.
      The presence of the noun (here <code>typename</code>) makes it clear that <code>Sortable</code> and
      <code>Movable</code> are concepts.</p>

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

    <p>The obvious alternative to the proposed change is to retain the status quo. The current
      <em>constrained-parameter</em> syntax is shorter. Type parameters occur much more often
      than value and template parameters, and so the loss of information about the parameter
      kind may be an acceptable trade-off. (After all, the purpose of syntactic sugar is to make
      common constructions convenient.)</p>

    <p>We see the value of this proposal only partly in its increased generality and explicitness.
      The other part lies in the future directions for other kinds of syntactic shorthands. Reusing
      the syntax of the status quo is problematic, since for even shorter kinds of abbreviations
      it is prone to ambiguities. By contrast, this proposal offers a simple principle by which
      the keywords <code>auto</code>, <code>typename</code>, and <code>template</code> are consistently
      present to signal that a kind of template argument deduction is in place. Additionally, they
      offer a natural place for constraints on those arguments.</p>

    <p>Another alternative is to place the concept adjective in predicative rather than
      attributive position (<em>The door is red.</em> vs. <em>the red door</em>). This would
      perhaps require some additional punctuators, e.g. <code>typename T : Sortable</code>. This
      idea seems overly inventive, and even though it is not substantially different from the
      proposed attributive position, it would perhaps not play as nicely with future directions
      (e.g. <code>vector&lt;Sortable typename&gt;</code> vs. <code>vector&lt;typename :
      Sortable&gt;</code>), or <code>Sortable auto x</code> vs.
      <code>auto : Sortable x</code> (or even <code>auto x : Sortable</code>).</p>

    <h2 id="questions">Questions</h2>
    <ol>
      <li>Do we want an &ldquo;adjective&rdquo; style for constrained parameters (i.e. the subject is mandatory)?</li>
      <li>Where should the adjective go: Attributive (<code>Sortable typename T</code>) vs. predicative (<code>typename T : Sortable</code>)</li>
      <li>Support for <code>auto</code> parameters: a) Only <code>auto</code> concepts, b) allow <code>decltype</code>-unwrapping use of type concepts,
        c) allow value concepts (subject to matching types), d) allow both?</li>
      <li>Do we want constrained generic lambdas now, or defer to future proposals?</li>
    </ol>

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

    <p>Many thanks to Tom Honermann for valuable feedback.</p>
    
  </body>
</html>
