<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=US-ASCII">
<title>Unified Function Syntax</title>
</head>
<body>
<h1>Unified Function Syntax</h1>

<p>
ISO/IEC JTC1 SC22 WG21 N2825 = 09-0015 - 2009-02-08
</p>

<p>
Lawrence Crowl, crowl@google.com, Lawrence@Crowl.org
<br>
Alisdair Meredith, public@alisdairm.net
</p>

<p>
This paper is a substantial revision of
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2763.htm">N2763</a>.
</p>

<dl>
<dt><a href="#intro">Introduction</a></dt>
<dd><a href="#newdecl">New Function Declaration Syntax</a></dd>
<dd><a href="#empty">The Type of Empty&ndash;Capture-List Lambdas</a></dd>
<dd><a href="#typeid">New Type-ID and Parameter Syntax</a></dd>
<dd><a href="#local">Local Functions</a></dd>
<dd><a href="#named">Named Lambdas</a></dd>
<dd><a href="#auto">Auto with Function Definitions</a></dd>

<dt><a href="#wording">Proposed Wording</a></dt>
<dd><a href="#basic.scope.pdecl">3.3.1 Point of declaration [basic.scope.pdecl]</a></dd>
<dd><a href="#basic.scope.local">3.3.2 Local scope [basic.scope.local]</a></dd>
<dd><a href="#basic.link">3.5 Program and linkage [basic.link]</a></dd>
<dd><a href="#expr.prim.lambda">5.1.1 Lambda expressions [expr.prim.lambda]</a></dd>
<dd><a href="#dcl.dcl">7 Declarations [dcl.dcl]</a></dd>
<dd><a href="#dcl.spec">7.1 Specifiers [dcl.spec]</a></dd>
<dd><a href="#dcl.stc">7.1.1 Storage class specifiers [dcl.stc]</a></dd>
<dd><a href="#dcl.spec.auto">7.1.6.4 <code>auto</code> specifier [dcl.spec.auto]</a></dd>
<dd><a href="#dcl.decl">8 Declarators [dcl.decl]</a></dd>
<dd><a href="#dcl.name">8.1 Type names [dcl.name]</a></dd>
<dd><a href="#dcl.fct">8.3.5 Functions [dcl.fct]</a></dd>
<dd><a href="#dcl.fct.def">8.4 Function definitions [dcl.fct.def ]</a></dd>
<dd><a href="#over">13 Overloading [over]</a></dd>
</dl>

<h2><a name="intro">Introduction</a></h2>

<p>
The sytax for both
the new function declarator syntax
(<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2541.html">N2541
New Function Declarator Syntax Wording</a>)
and lambda expressions
(<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2550.pdf">N2550
Lambda Expressions and Closures:
Wording for Monomorphic Lambdas (Revision 4)</a>)
are similar.
As suggested by Alisdair Meredith
(<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2511.html">N2511
Named Lambdas and Local Functions</a>),
the syntax for both could be made more similar,
thus simplifying the view of the programmer.
The British position
(<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2510.pdf">N2510
BSI Position on Lambda Functions</a>)
supports this work.
</p>

<p>
Such a unification would address the concerns of Daveed Vandevoorde
(<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2007/n2337.pdf">N2337
The Syntax of auto Declarations</a>)
that the <code>auto</code> keyword was too overloaded
in its use for both a new function declarator syntax
and for automatically deducing variable type
(<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2006/n1984.pdf">N1984
Deducing the type of variable from its initializer expression (revision 4)</a>).
</p>

<p>
This paper proposes the syntactic unification
of function declarations and lambda expressions.
The key technical insight enabling this unification
is that an empty lambda capture list
means that no local environment is captured,
which is exactly the semantics of a function.
That is, a function is a special case of a lambda.
</p>

<p>
The paper takes the new lambda syntax
(<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2550.pdf">N2550</a>)
as the starting point for syntactic unifications,
and specific syntactic suggestions in
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2511.html">N2511</a>
no longer apply.
As a simplistic unification
would introduce unfortunate irregularities in semantics,
we also propose regularizing the semantics of such declarations.
</p>

<p>
This paper presents a unification
that includes more capability than in prior papers.
This change in approach addresses a concern
that earlier proposals did not go far enough to justify any support.
Rather than prematurely select
those parts of the end state are acceptable for C++0x,
we choose to propose the full end state and let the committee
decide if and how to scale back the proposal.
However, we believe that everything within this proposal
is both desirable and implementable within C++0x
given the existing presence of lambda expressions.
</p>


<h3><a name="newdecl">New Function Declaration Syntax</a></h3>

<p>
Based on direction from the September 2008 meeting,
our general approach is to replace function declarations
using an <code>auto</code> type specifier
and a "<code>-&gt;</code>" return type
(<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2541.html">N2541</a>)
with new declaration syntax for functions. 
</p>

<p>
The syntax for function declarations extends the syntax for lambda expressions
with declaration specifiers and an id expression to name the function.
A lambda expression is distinct from a function
by the presence of an id expression.
</p>
<dl>
<dt><var>lambda-expression:</var></dt>
<dd><var>lambda-introducer function-heading<sub>opt</sub> compound-statement</var></dd>
<dt><var>function-declaration:</var></dt>
<dd><var>func-decl-specifier-seq<sub>opt</sub> lambda-introducer id-expression function-heading</var></dd>
</dl>

<p>
For functions at namespace scope,
the <var>lambda-introducer</var> of the form <code>[]</code>
is semantically correct.
For functions at class scope,
the <var>lambda-introducer</var> of the form <code>[]</code>
is semantically correct,
with the understanding that class-scope non-static functions
still have an implicit <code>this</code> parameter.
(That is, <code>this</code> is passed, not captured.)
</p>

<blockquote><pre><code>
int x=0, y=0;
[] f(int z)-&gt;int { return x+y+z; }
struct s {
    int k;
    [] g(int z)-&gt;int;
};
[] s::g(int z)-&gt;int { return k+x+z; }
</code></pre></blockquote>

<p>
In the process of unifying the syntax,
we refactored and unified the grammar.
There are, however, some context-dependent textual restrictions
on the use of that grammar.
</p>


<h3><a name="empty">The Type of Empty&ndash;Capture-List Lambdas</a></h3>

<p>
To ensure that lambdas and functions have uniform semantics where possible,
we change a lambda with an empty capture list to name a function
rather than return a closure object.
Naming a function rather than returning a function pointer is important
to template specialization when the lambda is a template argument.
The implicit conversion to function pointer also enables
use of a lambda expression in existing interfaces requiring function pointers.
</p>

<h3><a name="typeid">New Type-ID and Parameter Syntax</a></h3>

<p>
The <code>auto-&gt;</code> syntax was usable in type-ids and parameters,
and so the equivalent new syntax must be added.
</p>

<dl>
<dt><var>type-id:</var></dt>
<dd><var>type-specifier-seq attribute-specifier<sub>opt</sub> abstract-declarator<sub>opt</sub></var></dd>
<dd><var>lambda-introducer function-heading</var></dd>
<dt><var>parameter-declaration:</var></dt>
<dd><var>decl-specifier-seq attribute-specifier<sub>opt</sub> declarator parameter-default<sub>opt</sub></var></dd>
<dd><var>decl-specifier-seq attribute-specifier<sub>opt</sub> abstract-declarator<sub>opt</sub> parameter-default<sub>opt</sub></var></dd>
<dd><var>lambda-introducer declarator-id<sub>opt</sub> function-heading parameter-default<sub>opt</sub></var></dd>
</dl>

<p>
The primary likely concern with this syntax of type-ids
is ambiguity with lambda expressions.
These are unambiguously resolved
by the presence or absence of a following compound statement.
While the common prefix is non-trivial,
it shares the same grammar rules
and provides the same information.
</p>

<h3><a name="local">Local Functions</a></h3>

<p>
The new function syntax enables defining functions at local scope.
Local functions can improve program clarity
by not affecting containing scopes
and by keeping the definition and use of functions closer together.
</p>

<blockquote><pre><code>
bool halvable(int n) {
    [] even(unsigned n)-&gt;bool;
    [] odd(unsigned n)-&gt;int { return n == 0 ? false : even(n-1); }
    [] even(unsigned n)-&gt;bool { return n == 0 ? true : odd(n-1); }
    return even(n);
}
</code></pre></blockquote>

<p>
Note that we preserve the existing non-local interpretation
of the existing local function declarations.
</p>

<blockquote><pre><code>
void halvable(int n) {
    int even( int n ); // implicit extern declaration
    return even(n);
}
</code></pre></blockquote>

<h3><a name="named">Named Lambdas</a></h3>

<p>
Local functions with non-empty capture lists are simply named lambdas.
</p>

<blockquote><pre><code>
int h(int b) {
    [] m(int z)-&gt;int // local function
        { return x+z; } // b is not in scope
    [&amp;] n(int z)-&gt;int // named lambda
        { return b+x+z; } // b is in scope, by reference
    return m(b) + n(b);
}
</code></pre></blockquote>

<p>
Named lambdas provide a way to use a lambda at multiple places,
though this could be done with a variable holding the closure object instead.
</p>

<blockquote><pre><code>
int h(int b) {
    auto m = [&amp;](int z)-&gt;int { return b+x+z; };
    return m(b) + m(b);
}
</code></pre></blockquote>

<p>
Named lambdas provide two advantages over this variable approach.
First, they can enter into overload sets.
</p>

<blockquote><pre><code>
double a(int n) {
    [n] p(int m) { return m+n; }
    [n] p(double m) { return m+n; }
    return p(3.0);
}
</code></pre></blockquote>

<p>
Second, they can enable forward declaration.
The point of capture is at the elaboration of the definition,
not the declaration,
so named lambdas must not be invoked or copied
before the elaboration of their definition.
As a consequence, mutually recursive named lambdas
must capture the other by reference.
</p>

<blockquote><pre><code>
int a(int n) {
    [&amp;,n] p(int m)-&gt;int;
    [&amp;,n] q(int m) { return p(m-1)+n; }
    // okay, use of p in a lambda body is not yet invoked
    int x = p(3);
    // error, the definition of p has not been elaborated
    [&amp;,n] p(int m)-&gt;int { return m&gt;0 ? q(m-1)+n : 0; }
    int y = p(4);
    // okay, p has been defined
}
</code></pre></blockquote>

<h3><a name="auto">Auto with Function Definitions</a></h3>

<p>
Since the <code>auto</code> keyword
is not longer used to specify late return types,
there is a choice in whether or not it applies to function definitions.
The simplest approach is to reserve it strictly to object definitions.
However, the "infer from initializer" interpretation
can also permit infering a return type of a function definition.
</p>

<blockquote><pre><code>
auto twice( int x ) { return x+x; }
</code></pre></blockquote>

<p>
As with lambdas, we require that the body consist only of a return statement.
</p>

<p>
Likewise, one can infer the return type of function defintions
using <code>auto</code> within the new syntax.
</p>

<blockquote><pre><code>
[] twice( int x ) -&gt; auto { return x+x; }
</code></pre></blockquote>


<h2><a name="wording">Proposed Wording</a></h2>

<p>
The proposed wording shows changes from working draft
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2798.pdf">N2798</a>.
</p>


<h3><a name="basic.scope.pdecl">3.3.1 Point of declaration [basic.scope.pdecl]</a></h3>

<p>
Edit paragraph 9 as follows.
The intent is to enable local functions
while preserving existing semantics for existing code.
This edit should remain even if local functions are not adopted now,
so as to preserve future possible standardization.
</p>
<blockquote>
<p>
[<i>Note:</i>
<code>friend</code> declarations refer to functions or classes
that are members of the nearest enclosing namespace,
but they do not introduce new names into that namespace (7.3.1.2).
Function declarations <ins>via a <var>simple-declaration</var></ins>
at block scope
and <ins>function or</ins> object declarations
with the <code>extern</code> specifier at block scope
refer to delarations
that are members of an enclosing namespace,
but they do not introduce new names into that scope
<ins>(3.5 [basic.link])</ins>.
&mdash;<i>end note</i>]
</p>
</blockquote>


<h3><a name="basic.scope.local">3.3.2 Local scope [basic.scope.local]</a></h3>

<p>
Edit paragraph 2 as follows.
Note the added comma in the second sentence.
This edit simply adjusts to grammar simplification.
</p>
<blockquote>
<p>
The potential scope of a function parameter name
(<del>including one appearing</del> in a
<del><var>lambda-parameter-declaration-clause</var></del>
<ins><var>parameter-declaration-clause</var></ins>)
or of a function-local predefined variable in a function definition (8.4)
begins at its point of declaration.
If the function has a <var>function-try-block</var><ins>,</ins>
the potential scope of a parameter
or of a function-local predefined variable
ends at the end of the last associated handler,
otherwise it ends at the end of the outermost block of the function definition.
A parameter name shall not be redeclared
in the outermost block of the function definition
nor in the outermost block of any handler
associated with a <var>function-try-block</var>.
</p>
</blockquote>


<h3><a name="basic.link">3.5 Program and linkage [basic.link]</a></h3>

<p>
Edit paragraph 6 as follows.
The intent is to enable local functions
while preserving existing semantics for existing code.
This edit should remain even if local functions are not adopted now,
so as to preserve future possible standardization.
</p>

<blockquote>
<p>
The name of a function declared in block scope
<ins>via a <var>simple-declaration</var>
[<i>Footnote:</i>
See [dcl.fct] for function declarations
not via <var>simple-declaration</var>.
&mdash;<i>end footnote</i>]</ins>,
and the name of <ins>a function or</ins> an object
declared by a block scope extern declaration,
have linkage.
If there is a visible declaration of an entity with linkage
having the same name and type,
ignoring entities declared outside the innermost enclosing namespace scope,
the block scope declaration
declares that same entity
and receives the linkage of the previous declaration.
If there is more than one such matching entity, the program is ill-formed.
Otherwise, if no matching entity is found,
the block scope entity receives external linkage.
</p>
</blockquote>

<p>
Note that if local function definitions are not permitted,
the following sentence needs to be added to this paragraph.
</p>
<blockquote>
<p>
<ins>If a declared function has no linkage, the program is ill-formed.</ins>
</p>
</blockquote>


<h3><a name="expr.prim.lambda">5.1.1 Lambda expressions [expr.prim.lambda]</a></h3>

<p>
Edit the syntax as follows.
This edit refactors the lambda syntax
to reuse the function syntax,
which includes modifications to support lambda.
</p>

<blockquote>
<dl>

<dt><var>lambda-expression:</var></dt>
<dd><del><var>lambda-introducer lambda-parameter-declaration<sub>opt</sub> compound-statement</var></del></dd>
<dd><ins><var>lambda-introducer function-heading<sub>opt</sub> compound-statement</var></ins></dd>

<dt><var>lambda-introducer:</var></dt>
<dd><code>[</code> <var>lambda-capture<sub>opt</sub></var> <code>]</code></dd>

<dt><var>lambda-capture:</var></dt>
<dd><var>capture-default</var></dd>
<dd><var>capture-list</var></dd>
<dd><var>capture-default</var> <code>,</code> <var>capture-list</var></dd>

<dt><var>capture-default:</var></dt>
<dd><code>&amp;</code></dd>
<dd><code>=</code></dd>

<dt><var>capture-list:</var></dt>
<dd><var>capture</var></dd>
<dd><var>capture-list</var> <code>,</code> <var>capture</var></dd>

<dt><var>capture:</var></dt>
<dd><var>identifier</var></dd>
<dd><code>&amp;</code> <var>identifier</var></dd>
<dd><code>this</code></dd>

<dt><del><var>lambda-parameter-declaration:</var></del></dt>
<dd><del><code>(</code> <var>lambda-parameter-declaration-list<sub>opt</sub></var> <code>) mutable</code><var><sub>opt</sub> attribute-specifier<sub>opt</sub> exception-specification<sub>opt</sub> lambda-return-type-clause<sub>opt</sub></var></del></dd>

<dt><del><var>lambda-parameter-declaration-list:</var></del></dt>
<dd><del><var>lambda-parameter</var></del></dd>
<dd><del><var>lambda-parameter</var> <code>,</code> <var>lambda-parameter</var></del></dd>

<dt><del><var>lambda-parameter:</var></del></dt>
<dd><del><var>decl-specifier-seq attribute-specifier<sub>opt</sub> declarator</var></del></dd>

<dt><del><var>lambda-return-type-clause:</var></del></dt>
<dd><del><code>-&gt;</code> <var>attribute-specifier<sub>opt</sub> type-id</var></del></dd>

</dl>
</blockquote>

<p>
Edit paragraph 1 as follows.
The intent of this edit is to follow the unification of the grammar,
and then add restrictions to remain consistent with the existing lambda syntax.
</p>
<blockquote>
<p>
In <del>a <var>lambda-parameter-declaration</var></del>
<ins>the <var>function-qualifiers</var>
of a <var>function-heading</var> ([dcl.fct])</ins>
the <var>attribute-specifier</var> appertains to the lambda.
In a <del><var>lambda-return-type-clause</var></del>
<ins><var>return-type-clause</var></ins>
the attribute appertains to the lambda return type.
<ins>The <code>mutable</code> qualifier shall occur only
when the <var>lambda-introducer</var> is not empty.
The <var>cv-qualifier-seq</var> or <var>ref-qualifier</var>
shall not be present.
Each parameter in the <var>function-heading</var>
shall have a <var>declarator-id</var>.</ins>
</p>
</blockquote>

<p>
Edit paragraph 7 as follows.
The intent of this edit
is make empty&ndash;capture-list lambdas name functions.
</p>
<blockquote>
<p>
<ins>If the effective capture set is empty,
the <var>lambda-expression</var> names an anonymous function
of type <code>R(P)</code>,
where <code>R</code> is the return type
and <code>P</code> is the <var>parameter-type-list</var>
of the lambda expression.
The corresponding function pointer [conv.func]
is the closure object.</ins>
<del>The</del> <ins>Otherwise, the</ins> type of the closure object
is a class with a unique name,
call it <code>F</code>,
considered to be defined at the point where the lambda expression occurs.
</p>
</blockquote>

<p>
Edit paragraph 10 as follows.
Note the insertion of a comma.
The intent of this edit is to follow the changes to the grammar.
</p>
<blockquote>
<ul>
<li>....</li>
<li>
The return type is the type denoted by the <var>type-id</var>
in the <del><var>lambda-return-type-clause</var></del>
<ins><var>return-type-clause</var></ins>;
for a lambda expression
that does not contain a
<del><var>lambda-return-type-clause</var></del>
<ins><var>return-type-clause</var>,</ins>
the return type is <code>void</code>,
unless the compound-statement is of the form
<code>{ return</code> <var>expression</var> <code>; }</code>,
in which case the return type is the type of expression.
[<i>Note:</i>
See also (8.3.5 [dcl.fct]).
&mdash;<i>end note</i>]
</li>
<li>....</li>
</ul>
</blockquote>

<p>
Edit paragraph 12 as follows.
The intent of this edit is to follow the changes to the grammar.
</p>
<blockquote>
<p>
If every name in the effective capture set is preceded by <code>&amp;</code>
and the lambda expression is not <code>mutable</code>,
<code>F</code> is publicly derived
from <code>std::reference_closure&lt;R(P)&gt;</code> (20.6.18),
where <code>R</code> is the return type
and <code>P</code> is the <del><var>parameter-type-list</var></del>
<ins><var>parameter-declaration-clause</var></ins>
of the lambda expression.
Converting an object of type <code>F</code>
to type <code>std::reference_closure&lt;R(P)&gt;</code>
and invoking its function call operator
shall have the same effect as
invoking the function call operator of <code>F</code>.
[<i>Note:</i>
This requirement effectively means that such <code>F</code>'s
must be implemented using a pair
of a function pointer and a static scope pointer.
&mdash;<i>end note</i>]
</p>
</blockquote>

<h3><a name="dcl.dcl">7 Declarations [dcl.dcl]</a></h3>

<p>
Edit paragraph 1 as follows.
The intent of this edit
is to enable function-local function declarations and definitions.
</p>
<blockquote>
<dl>

<dt>....</dt>

<dt><var>declaration:</var></dt>
<dd><var>block-declaration</var></dd>
<dd><del><var>function-definition</var></del></dd>
<dd><var>template-declaration</var></dd>
<dd><var>explicit-instantiation</var></dd>
<dd><var>explicit-specialization</var></dd>
<dd><var>linkage-specification</var></dd>
<dd><var>namespace-definition</var></dd>
<dd><var>concept-definition</var></dd>
<dd><var>concept-map-definition</var></dd>
<dd><var>attribute-declaration</var></dd>

<dt><var>block-declaration:</var></dt>
<dd><var>simple-declaration</var></dd>
<dd><ins><var>function-declaration</var></ins></dd>
<dd><ins><var>function-definition</var></ins></dd>
<dd><var>asm-definition</var></dd>
<dd><var>namespace-alias-definition</var></dd>
<dd><var>using-declaration</var></dd>
<dd><var>using-directive</var></dd>
<dd><var>static_assert-declaration</var></dd>
<dd><var>alias-declaration</var></dd>
<dd><var>opaque-enum-declaration</var></dd>

<dt>....</dt>

</dl>
</blockquote>


<h3><a name="dcl.spec">7.1 Specifiers [dcl.spec]</a></h3>

<p>
Edit paragraph 1 as follows.
The intent of this edit
is provide a grammar subroutine for function declarations.
</p>
<blockquote>
<p>
The specifiers that can be used in a declaration are
</p>
<dl>

<dt><var>decl-specifier:</var></dt>
<dd><var>storage-class-specifier</var></dd>
<dd><var>type-specifier</var></dd>
<dd><del><var>function-specifier</var></del></dd>
<dd><del><code>friend</code></del></dd>
<dd><del><code>typedef</code></del></dd>
<dd><del><code>constexpr</code></del></dd>
<dd><var>alignment-specifier</var></dd>
<dd><ins><var>func-decl-specifier</var></ins></dd>

<dt><var>decl-specifier-seq:</var></dt>
<dd><var>decl-specifier-seq<sub>opt</sub> decl-specifier</var></dd>

<dt><ins><var>func-decl-specifier:</var></ins></dt>
<dd><ins><var>func-storage-class-specifier</var></ins></dd>
<dd><ins><var>function-specifier</var></ins></dd>
<dd><ins><code>friend</code></ins></dd>
<dd><ins><code>typedef</code></ins></dd>
<dd><ins><code>constexpr</code></ins></dd>

<dt><ins><var>func-decl-specifier-seq:</var></ins></dt>
<dd><ins><var>func-decl-specifier-seq<sub>opt</sub> func-decl-specifier</var></ins></dd>

</dl>
</blockquote>


<h3><a name="dcl.stc">7.1.1 Storage class specifiers [dcl.stc]</a></h3>

<p>
Edit paragraph 1 as follows.
The intent of this edit
is provide a grammar subroutine for function declarations.
</p>
<blockquote>
<p>
The storage class specifiers are
</p>
<dl>

<dt><var>storage-class-specifier:</var></dt>
<dd><code>register</code></dd>
<dd><del><code>static</code></del></dd>
<dd><code>thread_local</code></dd>
<dd><del><code>extern</code></del></dd>
<dd><code>mutable</code></dd>
<dd><ins><var>func-storage-class-specifier:</var></ins></dd>

<dt><ins><var>func-storage-class-specifier:</var></ins></dt>
<dd><ins><code>static</code></ins></dd>
<dd><ins><code>extern</code></ins></dd>

</dl>
<p>
....
</p>
</blockquote>


<h3><a name="dcl.spec.auto">7.1.6.4 <code>auto</code> specifier [dcl.spec.auto]</a></h3>

<p>
Remove paragraph 1.
The intent of this edit is to remove the <code>auto-&gt;</code> syntax.
</p>

<blockquote>
<p>
<del>The <code>auto</code> <var>type-specifier</var>
signifies that the type of an object being declared
shall be deduced from its initializer
or specified explicitly at the end of a function declarator.</del>
</p>
</blockquote>

<p>
Edit paragraph 2 as follows.
The intent of this edit is to remove the <code>auto-&gt;</code> syntax
and to enable <code>auto</code> with function definitions.
If that latter feature is not desired, this paragraph would be removed.
</p>

<blockquote>
<p>
The <code>auto</code> <var>type-specifier</var>
may appear with a function <del>declarator
with a late-specified return type (8.3.5)
in any context where such a declarator is valid,
and the use of <code>auto</code>
is replaced by the type specified at the end of the declarator.</del>
<ins>definition ([dcl.fct.def])</ins>
</p>
</blockquote>

<p>
Edit paragraph 3 as follows.
The intent of the edit is ensure flow of text from the above.
</p>

<blockquote>
<p>
Otherwise, the <del>type of the object is</del>
<ins><code>auto</code> <var>type-specifier</var>
signifies that the type of an object being declared
shall be</ins>
deduced from its initializer.
The name of the object being declared
shall not appear in the initializer expression.
The auto type-specifier is allowed when declaring objects
in a block (6.3),
in namespace scope (3.3.5),
and in a for-init-statement (6.5.3).
The decl-specifier-seq shall be followed
by one or more init-declarators,
each of which shall have a non-empty initializer
of either of the following forms:
</p>
<blockquote>
<p>
<code>=</code> <var>assignment-expression</var>
<br><code>(</code> <var>assignment-expression</var> <code>)</code>
</p>
</blockquote>
</blockquote>


<h3><a name="dcl.decl">8 Declarators [dcl.decl]</a></h3>

<p>
Edit paragraph 4 as follows.
The intent of the edit
is to remove the <code>auto-&gt;</code> syntax.
In the process, the <var>ptr-declarator</var> rule becomes redundant
and is eliminated.
Furthermore, the edit refactors the grammar.
</p>
<blockquote>
<p>
Declarators have the syntax
</p>
<dl>

<dt><del><var>declarator:</var></del></dt>
<dd><del><var>ptr-declarator</var></del></dd>
<dd><del><var>noptr-declarator parameters-and-qualifiers</var> <code>-&gt;</code> <var>attribute-specifier<sub>opt</sub> type-id</var></del></dd>

<dt><var><del>ptr-</del>declarator:</var></dt>
<dd><var>noptr-declarator</var></dd>
<dd><var>ptr-operator <del>ptr-</del>declarator</var></dd>

<dt><var>noptr-declarator:</var></dt>
<dd><var>declarator-id attribute-specifier<sub>opt</sub></var></dd>
<dd><var>noptr-declarator parameters-and-qualifiers</var></dd>
<dd><var>noptr-declarator</var> <code>[</code> <var>constant-expression<sub>opt</sub></var> <code>]</code> <var>attribute-specifier<sub>opt</sub></var></dd>
<dd><var>( <del>ptr-</del>declarator )</var></dd>

<dt><var>parameters-and-qualifiers:</var></dt>
<dd><del><var>( parameter-declaration-clause ) attribute-specifier<sub>opt</sub> cv-qualifier-seq<sub>opt</sub> ref-qualifier<sub>opt</sub> exception-specification<sub>opt</sub></var></del></dd>
<dd><ins><var>( parameter-declaration-clause ) function-qualifiers</var></ins></dd>

<dt><var>ptr-operator:</var></dt>
<dd><code>*</code> <var>attribute-specifier<sub>opt</sub> cv-qualifier-seq<sub>opt</sub></var></dd>
<dd><del><code>&amp;</code></del></dd>
<dd><del><code>&amp;&amp;</code></del></dd>
<dd><ins><var>ref-qualifier</var></ins></dd>
<dd><code>::</code><var><sub>opt</sub> nested-name-specifier</var> <code>*</code> <var>attribute-specifier<sub>opt</sub> cv-qualifier-seq<sub>opt</sub></var></dd>

<dt><var>cv-qualifier-seq:</var></dt>
<dd><var>cv-qualifier cv-qualifier-seq<sub>opt</sub></var></dd>

<dt><var>cv-qualifier:</var></dt>
<dd><code>const</code></dd>
<dd><code>volatile</code></dd>

<dt><var>ref-qualifier:</var></dt>
<dd><code>&amp;</code></dd>
<dd><code>&amp;&amp;</code></dd>

<dt><var>declarator-id:</var></dt>
<dd><code>...</code><var><sub>opt</sub> id-expression</var></dd>
<dd><code>::</code><var><sub>opt</sub> nested-name-specifier<sub>opt</sub> class-name</var></dd>

</dl>
<p>
A <var>class-name</var> has special meaning
in a declaration of the class of that name
and when qualified by that name
using the scope resolution operator <code>::</code> (5.1, 12.1, 12.4).
</p>
</blockquote>


<h3><a name="dcl.name">8.1 Type names [dcl.name]</a></h3>

<p>
Edit paragraph 1 as follows.
The intent of this edit
is to remove the <code>auto-&gt;</code> syntax
and add the new function syntax.
</p>
<blockquote>
<dl>

<dt><var>type-id:</var></dt>
<dd><var>type-specifier-seq attribute-specifier<sub>opt</sub> abstract-declarator<sub>opt</sub></var></dd>
<dd><ins><var>lambda-introducer function-heading</var></ins></dd>

<dt><var>abstract-declarator:</var></dt>
<dd><var>ptr-abstract-declarator</var></dd>
<dd><del><var>noptr-abstract-declarator<sub>opt</sub> parameters-and-qualifiers</var> <code>-&gt;</code> <var>attribute-specifier<sub>opt</sub> type-id</var></del></dd>
<dd><code>...</code></dd>

<dt><var>ptr-abstract-declarator:</var></dt>
<dd><var>noptr-abstract-declarator</var></dd>
<dd><var>ptr-operator ptr-abstract-declarator<sub>opt</sub></var></dd>

<dt><var>noptr-abstract-declarator:</var></dt>
<dd><var>noptr-abstract-declarator<sub>opt</sub> parameters-and-qualifiers</var></dd>
<dd><var>noptr-abstract-declarator<sub>opt</sub></var> <code>[</code> <var>constant-expression</var> <code>]</code> <var>attribute-specifier<sub>opt</sub></var></dd>
<dd><code>(</code> <var>ptr-abstract-declarator</var> <code>)</code></dd>

</dl>
</blockquote>


<h3><a name="dcl.fct">8.3.5 Functions [dcl.fct]</a></h3>

<p>
Edit paragraph 1 as follows.
The intent of this edit is to follow the grammar refactoring.
</p>
<blockquote>
<p>
In a declaration <code>T D</code>
where <code>D</code> has the form
</p>
<blockquote>
<p>
<del><code>D1 (</code> <var>parameter-declaration-clause</var> <code>)</code>
<var>attribute-specifier<sub>opt</sub> cv-qualifier-seq<sub>opt</sub>
ref-qualifier<sub>opt</sub> exception-specification<sub>opt</sub></var></del>
<br>
<ins><code>D1 (</code> <var>parameter-declaration-clause</var> <code>)</code>
<var>function-qualifiers</var></ins>
</p>
</blockquote>
<p>
and the type of the contained <var>declarator-id</var>
in the declaration <code>T D1</code>
is "<var>derived-declarator-type-list</var> T",
the type of the <var>declarator-id</var> in <code>D</code>
is "<var>derived-declarator-type-list</var> function
of <code>(</code> <var>parameter-declaration-clause</var> <code>)</code>
<var>cv-qualifier-seq<sub>opt</sub> ref-qualifier<sub>opt</sub></var>
returning <code>T</code>".
The optional <var>attribute-specifier</var> appertains to the function type.
</p>
</blockquote>

<p>
Delete paragraph 2.
The intent of this edit is to remove the <code>auto-&gt;</code> syntax.
</p>

<blockquote>
<p>
<del>In a declaration <code>T D</code> where <code>D</code> has the form</del>
</p>
<blockquote>
<p>
<del><code>D1 (</code> <var>parameter-declaration-clause</var> <code>)</code>
<var>cv-qualifier-seq<sub>opt</sub> ref-qualifier<sub>opt</sub>
exception-specification<sub>opt</sub></var>
<code>-&gt;</code> <var>type-id</var></del>
</p>
</blockquote>
<p>
<del>and the type of the contained <var>declarator-id</var>
in the declaration <code>T D1</code>
is "<var>derived-declarator-type-list</var> <code>T</code>,"
<code>T</code> shall be the single <var>type-specifier</var>
<code>auto</code>
and the <var>derived-declarator-type-list</var> shall be empty.
Then the type of the <var>declarator-id</var> in <code>D</code>
is "function of
<code>(</code><var>parameter-declaration-clause</var><code>)</code>
<var>cv-qualifier-seq<sub>opt</sub> ref-qualifier<sub>opt</sub></var>
returning <var>type-id</var>".
Such a function type has a <dfn>late-specified</dfn> return type.</del>
</p>
</blockquote>

<p>
Delete paragraph 3.
The intent of this edit is to remove the <code>auto-&gt;</code> syntax.
</p>

<blockquote>
<p>
<del>The <var>type-id</var> in this form
includes the longest possible sequence of <var>abstract-declarator</var>s.
[<i>Note:</i>
This resolves the ambiguous binding of array and function declarators.
[<i>Example:</i></del>
</p>
<blockquote>
<p>
<del><code>auto f()-&gt;int(*)[4];</code>
<i>// function returning a pointer to array[4] of int</i>
<br><i>// not function returning array[4] of pointer to int</i></del>
</p>
</blockquote>
<p>
<del>
&mdash;<i>end example</i>]
&mdash;<i>end note</i>]
</del>
</p>
</blockquote>

<p>
Insert a new paragraph 2.
The intent of this edit is to add the new function syntax.
Note that the position of the <code>mutable</code> keyword seems out of place.
It is consistent with the existing grammar.
</p>
<blockquote>
<p>
<ins>Function declarations with late-specified return type have the form:</ins>
</p>
<dl>

<dt><ins><var>function-declaration:</var></ins></dt>
<dd><ins><var>func-decl-specifier-seq<sub>opt</sub> lambda-introducer id-expression function-heading</var></ins></dd>

<dt><ins><var>function-heading:</var></ins></dt>
<dd><ins><code>(</code> <var>parameter-declaration-clause</var> <code>)</code> <var>function-qualifiers return-type-clause<sub>opt</sub></var></ins></dd>

<dt><ins><var>function-qualifiers:</var></ins></dt>
<dd><ins><code>mutable</code><var><sub>opt</sub> attribute-specifier<sub>opt</sub> cv-qualifier-seq<sub>opt</sub> ref-qualifier<sub>opt</sub> exception-specification<sub>opt</sub></var></ins></dd>

<dt><ins><var>return-type-clause:</var></ins></dt>
<dd><ins><code>-&gt;</code> <var>attribute-specifier<sub>opt</sub> type-id</var></ins></dd>

</dl>
<p>
<ins>
[<i>Example:</i>
</ins>
<blockquote><pre><code>
<ins>int x=0, y=0;
[] f(int z)-&gt;int { return x+y+z; }
struct s {
    int k;
    [] g(int z)-&gt;int;
};
[] s::g(int z)-&gt;int { return k+x+z; }</ins>
</code></pre></blockquote>
<p>
<ins>
&mdash;<i>end example</i>]
</ins>
</p>
</blockquote>

<p>
Insert a new paragraph after the above paragraph.
The intent of this edit is to define the semantics of a missing
<var>return-type-clause</var>.
</p>
<blockquote>
<p>
<ins>
Within a <var>function-heading</var>,
a missing <var>return-type-clause</var>
indicates that the return type is <code>void</code>,
unless the heading is part of a lambda or function definition
with a <var>compound-statement</var> of the form
<code>{ return</code> <var>expression</var> <code>; }</code>,
in which case the return type is the type of expression.
[<i>Note:</i>
See also (5.1.1 [expr.prim.lambda]).
&mdash;<i>end note</i>]
[<i>Example:</i>
</ins>
</p>
<blockquote><pre><code>
<ins>[] p(int m); // return type is void
[] q(int m) { return m; } // return type is int
[] r(double m) { p(m); } // return type is void</ins>
</code></pre></blockquote>
<p>
<ins>
&mdash;<i>end example</i>]
</ins>
</p>
</blockquote>

<p>
Insert a new paragraph after the above paragraph.
The intent of this edit
is to reinforce the local functions implicit in the grammar change.
</p>
<blockquote>
<p>
<ins>
Functions using the late-specified return type
may be local to another function.
[<i>Example:</i>
</ins>
</p>
<blockquote><pre><code>
<ins>[] halvable(int k)-&gt;bool; {
    [] even(unsigned n)-&gt;bool;
    [] odd(unsigned n)-&gt;int { return n == 0 ? false : even(n-1); }
    [] even(unsigned n)-&gt;bool { return n == 0 ? true : odd(n-1); }
    return even(k);
}</ins>
</code></pre></blockquote>
<p>
&mdash;<i>end example</i>]
</p>
</blockquote>

<p>
Insert a new paragraph after the above paragraph.
The intent of this edit
is to tie the descriptions of lambda and function together.
Furthermore, we require capture lists not in local scope
to reflect the fact that they have nothing to capture.
</p>
<blockquote>
<p>
<ins>
The semantics of a non-empty <var>lambda-introducer</var>
are described in ([expr.prim.lambda]).
A non-empty <var>lambda-introducer</var>
shall only appear in block scope
with non-<code>extern</code> declarations.
These definitions are <dfn>named lambdas</dfn>.
The capture list for a named lambda declaration and its definition
must be identical.
The point-of-capture for a named lambda is its definition.
The invokation of a named lambda before the elaboration of its definition
is an error, no diagnostic required.
[<i>Example:</i>
</ins>
</p>
<blockquote><pre><code>
<ins>int a(int n) {
    [&amp;,n] p(int m)-&gt;int;
    [&amp;,n] q(int m) { return p(m-1)+n; }
    // okay, use of p in a lambda body is not yet invoked
    int x = p(3);
    // error, the definition of p has not been elaborated
    [&amp;,n] p(int m)-&gt;int { return m&gt;0 ? q(m-1)+n : 0; }
    int y = p(4);
    // okay, p has been defined
}</ins>
</code></pre></blockquote>
<p>
&mdash;<i>end example</i>]
</p>
</blockquote>

<p>
Edit the existing paragraph 4 as follows.
The intent of this edit
is to add the new function syntax for parameters.
In the process, we refactor the grammar for default parameters.
</p>
<blockquote>
<p>
A type of either form
is a <dfn>function type</dfn>.
[<i>Footnote:</i>
As indicated by syntax,
<var>cv-qualifier</var>s are a signficant component in function return types.
&mdash;<i>end footnote</i>]
</p>
<dl>

<dt><var>parameter-declaration-clause:</var></dt>
<dd><var>parameter-declaration-list<sub>opt</sub></var> <code>...</code><var><sub>opt</sub></var></dd>
<dd><var>parameter-declaration-list</var> <code>, ...</code></dd>

<dt><var>parameter-declaration-list:</var></dt>
<dd><var>parameter-declaration</var></dd>
<dd><var>parameter-declaration-list</var> <code>,</code> <var>parameter-declaration</var></dd>

<dt><var>parameter-declaration:</var></dt>
<dd><var>decl-specifier-seq attribute-specifier<sub>opt</sub> declarator <ins>parameter-default<sub>opt</sub></ins></var></dd>
<dd><del><var>decl-specifier-seq attribute-specifier<sub>opt</sub> declarator</var> <code>=</code> <var>assignment-expression</var></del></dd>
<dd><var>decl-specifier-seq attribute-specifier<sub>opt</sub> abstract-declarator<sub>opt</sub> <ins>parameter-default<sub>opt</sub></ins></var></dd>
<dd><del><var>decl-specifier-seq attribute-specifier<sub>opt</sub> abstract-declarator<sub>opt</sub></var> <code>=</code> <var>assignment-expression</var></del></dd>
<dd><ins><var>lambda-introducer declarator-id<sub>opt</sub> function-heading parameter-default<sub>opt</sub></var></ins></dd>
<dt><ins><var>parameter-default:</var></ins></dt>
<dd><ins><code>=</code> <var>assignment-expression</var></ins></dd>

</dl>
</blockquote>

<p>
Edit within paragraph 12 as follows.
The intent of this edit
is to make the examples follow the new syntax.
</p>

<blockquote>
<p>
[<i>Note:</i>
typedefs and late-specified return types
are sometimes convenient when the return type of a function is complex.
For example, the function <code>fpif</code> above
could have been declared
</p>
<blockquote><pre><code>
typedef int IFUNC(int);
IFUNC* fpif(int);
</code></pre></blockquote>
<p>
or
</p>
<blockquote><pre><code>
<del>auto</del> <ins>[]</ins> fpif(int)-&gt;int(*)(int)
</code></pre></blockquote>
<p>
A late-specified return type
is most useful for a type that would be more complicated to specify
before the <var>declarator-id</var>:
</p>
<blockquote><pre><code>
template &lt;class T, class U&gt;
<del>auto</del> <ins>[]</ins> add(T t, U u) -&gt; decltype(t + u);
</code></pre></blockquote>
<p>
rather than
</p>
<blockquote><pre><code>
template &lt;class T, class U&gt;
decltype((*(T*)0) + (*(U*)0)) add(T t, U u);
</code></pre></blockquote>
<p>
&mdash;<i>end note</i>]
</p>
</blockquote>


<h3><a name="dcl.fct.def">8.4 Function definitions [dcl.fct.def]</a></h3>

<p>
Edit paragraph 1 as follows.
The intent of the edit
is to add the new function syntax.
In the process, we refactor the grammar.
</p>
<blockquote>
<p>
Function definitions have the form
</p>
<dl>

<dt><var>function-definition:</var></dt>
<dd><var>decl-specifier-seq<sub>opt</sub> attribute-specifier<sub>opt</sub> declarator function-body</var></dd>
<dd><del><var>decl-specifier-seq<sub>opt</sub> attribute-specifier<sub>opt</sub> declarator</var> <code>= default ;</code></del></dd>
<dd><del><var>decl-specifier-seq<sub>opt</sub> attribute-specifier<sub>opt</sub> declarator</var> <code>= delete ;</code></del></dd>
<dd><ins><var>function-declaration function-body</var></ins></dd>

<dt><var>function-body:</var></dt>
<dd><var>ctor-initializer<sub>opt</sub> compound-statement</var></dd>
<dd><var>function-try-block</var></dd>
<dd><ins><code>= default ;</code></ins></dd>
<dd><ins><code>= delete ;</code></ins></dd>

</dl>
</blockquote>

<p>
After paragraph 8, insert a new paragraph.
The intent of this edit
is to allow <code>auto</code> in return types for function definitions.
</p>
<blockquote>
<p>
<ins>The <var>type-id</var> of a function or lambda definition
may contain the <code>auto</code> type specifier,
provided that the form of the <var>compound-statement</var>
is <code>{&nbsp;return</code> <var>expr</var><code>;&nbsp;}</code>
and the return type is determined from the type of the expression
using the rules for template argument deduction,
as in (7.1.6.4 [dcl.spec.auto]).
[<i>Example:</i>
</ins></p>
<blockquote><pre><code>
<ins>[] m( int a ) -&gt; auto { return a; }
auto m( int a ) { return a; }</ins>
</code></pre></blockquote>
<p>
&mdash;<i>end example</i>]
</p>
</blockquote>


<h3><a name="over">13 Overloading [over]</a></h3>

<p>
Edit paragraph 1 as follows.
The intent is to clarify overloading of named lambdas.
</p>

<blockquote>
<p>
When two or more different declarations
are specified for a single name in the same scope,
that name is said to be <dfn>overloaded</dfn>.
By extension, two declarations in the same scope
that declare the same name but with different types
are called <dfn>overloaded declarations</dfn>.
Only function
<ins>and named lambda</ins>
declarations
can be overloaded;
object and type declarations cannot be overloaded.
<ins>
[<i>Example:</i>
</ins>
</p>
<blockquote><pre><code>
<ins>double a(int n) {
    [n] p(int m) { return m+n; }
    [n] p(double m) { return m+n; }
    return p(3.0);
}</ins>
</code></pre></blockquote>
<p>
&mdash;<i>end example</i>]
</p>
</blockquote>

</body>
</html>
