<!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 N2890 = 09-0080 - 2009-06-21
</p>

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

<p>
This paper is a revision of
<a href="../../papers/2009/n2825.html">N2825</a>.
</p>

<p>

<a href="#intro">Introduction</a><br>
<a href="#newdecl">New Function Declaration Syntax</a><br>
<a href="#empty">The Type of Empty&ndash;Lambda-Capture Lambdas</a><br>
<a href="#typeid">New Type-ID and Parameter Syntax</a><br>
<a href="#local">Local Functions</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#overloadfunc">Overloading Local Functions</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#forwardfunc">Forwarding Local Functions</a><br>
<a href="#named">Named Lambdas</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#overloadname">Overloading Named Lambdas</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#forwardname">Forwarding Named Lambdas</a><br>
<a href="#auto">Auto with Function Definitions</a><br>
<a href="#other">Other Issues</a><br>
<a href="#wording">Proposed Wording</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#basic.scope.pdecl">3.3.2 Point of declaration [basic.scope.pdecl]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#basic.scope.local">3.3.3 Local scope [basic.scope.local]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#basic.link">3.5 Program and linkage [basic.link]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#expr.prim.lambda">5.1.2 Lambda expressions [expr.prim.lambda]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#dcl.dcl">7 Declarations [dcl.dcl]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#dcl.spec.auto">7.1.6.4 <code>auto</code> specifier [dcl.spec.auto]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#dcl.decl">8 Declarators [dcl.decl]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#dcl.name">8.1 Type names [dcl.name]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#dcl.fct">8.3.5 Functions [dcl.fct]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#dcl.fct.def">8.4 Function definitions [dcl.fct.def]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#over">13 Overloading [over]</a><br>

</p>


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

<p>
The sytax for both
the new function declarator syntax
(<a href="../../papers/2008/n2541.html">N2541
New Function Declarator Syntax Wording</a>)
and lambda expressions
(<a href="../../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="../../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="../../papers/2008/n2510.pdf">N2510
BSI Position on Lambda Functions</a>),
U.K. comments, and U.S. comments
support this work.
</p>

<p>
Such a unification would address the concerns of Daveed Vandevoorde
(<a href="../../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="../../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
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="../../papers/2008/n2550.pdf">N2550</a>)
as the starting point for syntactic unifications,
and specific syntactic suggestions in
<a href="../../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 the earliest 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.
We have also incorporated straightforward comments from the
core working group meeting in during the March 2009 ISO C++ meeting.
Furthermore, we expose some of the more substantive suggestions
from core so that the receive a broader exposure
before the committee commits to them.
</p>


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

<p>
Based on direction from the September 2008 ISO C++ 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="../../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>decl-specifier-seq<sub>opt</sub> lambda-introducer id-expression function-heading</var></dd>
</dl>

<p>
[Note: Clark Nelson suggested using <var>function-introducer</var>
rather than <var>lambda-introducer</var>.]
</p>

<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 still 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>


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

<p>
The semantics of a lambda with an empty capture list and a function
are nearly uniform.
This uniformity was noted in U.K.&nbsp;national body comment 226.
Exposing this uniformity 
would allow programmers to use lambdas
and exploit existing function-based interfaces.
</p>
<blockquote>
<p>
<i>Problem:</i>
A lambda with an empty capture list has identical semantics
to a regular function type.
By requiring this mapping we get an efficient lambda type with a known API
that is also compatible with existing operating system and C library functions.
</p>
<p>
<i>Resolution:</i>
Add a new paragraph:
"A lambda expression with an empty capture set
shall be convertible to pointer to function type R(P),
where R is the return type and P is the parameter-type-list
of the lambda expression."
Additionally it might be good to
(a) allow conversion to function reference and
(b) allow extern "C" function pointer types.
</p>
</blockquote>

<p>
There are two approaches to expressing this uniformity.
</p>
<ol>
<li><p>
Provide an implicit conversion operator
from the closure object to a function pointer.
</p></li>
<li><p>
Have a lambda with an empty lambda capture <em>name</em> a function
rather than return a closure object.
</p></li>
</ol>

<p>
These two approaches have different effects on the programmer model.
</p>
<ol>
<li><p>
All function-local uses of <code>[</code>....<code>]</code>
produce a lambda object.
Only non-local uses of <code>[]</code>
may appear as template non-type arguments.
Only non-local uses of <code>[]</code>
are affected by argument-dependent lookup.
</p></li>
<li><p>
All uses of <code>[]</code> name a function.
All such uses may appear as template arguments of function type.
All uses of <code>[]</code>,
but none with a non-empty <var>lambda-capture</var>,
are affected by argument-dependent lookup.
</p></li>
</ol>

<p>
They also have different effects on program optimization.
</p>
<ol>
<li><p>
The closure object retains a unique type,
which means that when the lambda
appears as a function argument to a standard template algorithm,
the corresponding algorithm instance
will be unique to the lambda.
This specificity enables inlining in the compiler front end,
which in turn enables a very specialized algorithm.
</p></li>
<li><p>
The lambda will decay to a function pointer
when a function argument to standard template algorithm.
While the same specialized algorithm above is still possible,
it requires inter-procedural constant-value propogation,
which is typically done only in the compiler back ends
at higher levels of optimization.
On the other hand,
the number of template instances is much reduced,
and so when specializing the algorithm is not profitable,
the code size will be smaller.
</p></li>
</ol>


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

<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 <var>type-id</var>s
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.
That is, the parse can proceed without backtracking.
</p>

<p>
A secondary likely concern with this syntax
is that it cannot currently represent all declarations.
While this limitation was understood by the authors in prior versions,
it was not obvious,
and Clark Nelson noticed.
</p>

<blockquote>
<p>
There doesn't seem to be any way to rewrite this declaration:
</p>
<blockquote><pre><code>
int (*fpfi())();
</code></pre></blockquote>
<p>
using exclusively postfix return specifications.
It would look something like:
</p>
<blockquote><pre><code>
[]fpfi()-&gt;[]()-&gt;int;
</code></pre></blockquote>
<p>
Of course this omits the pointer-declarator,
but the grammar doesn't seem to provide any place for it.
Worse, my intuition doesn't suggest to me exactly where it ought to go.
Worse still, the principles on which the grammar seems to be based
really don't allow for it anywhere.
</p>
</blockquote>

<p>
In fact, the intent was to enable just such a declaration.
The mechanism to enable such declarations
is the implicit function to pointer-to-function conversion of parameter types.
Unfortunately, previous revisions of the paper
failed to modify the appropriate text.
That failure has been corrected.
</p>

<p>
Even so, previous revisions of the paper did permit a simlar declaration,
</p>
<blockquote><pre><code>
[]fpfi()-&gt;int (*)();
</code></pre></blockquote>
<p>
because the return type is a <var>type-id</var>,
which includes abstract declarators.
</p>

<p>
However, the proposed syntax still does not permit full declarations.
In particular,
the syntax does not permit declaring a pointer to a pointer to a function.
An intermediate typedef is necessary.
Such intermediate typedefs are also required
when mixing <code>extern "C"</code>
and <code>extern "C++"</code> function types
in the same declaration.
</p>


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

<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 { return n &amp; 0 ? true : false; }
    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>

<p>
Due to concerns about the effects of argument-dependent lookup,
the core commitee recommends
that no operator names be permitted on local functions.
</p>


<h3><a name="overloadfunc">Overloading Local Functions</a></h3>

<p>
The syntax naturally permits overloading of local functions.
</p>

<blockquote><pre><code>
double a(int n) {
    const double pi = 3.14159;
    [] p(int m) { return m*pi; }
    [] p(double m) { return m*pi; }
    return p(3.0);
}
</code></pre></blockquote>

<p>
However, because of concern over interoperability with named lambdas,
the core committee has a preference for
not permitting overloading of local functions at this time.
Relaxing that restriction in the future would likely be upwards compatible.
</p>


<h3><a name="forwardfunc">Forwarding Local Functions</a></h3>

<p>
The new syntax also enables the forward declaration of local functions.
For example, and excusing the algorithm,
</p>

<blockquote><pre><code>
bool halvable(int n) {
    [] even(unsigned n)-&gt;bool;
    [] odd(unsigned n)-&gt;bool { 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>
However, because of concern over interoperability with named lambdas,
the core committee has a preference for
not permitting forwarding of local functions at this time.
Relaxing that restriction in the future would likely be upwards compatible.
</p>


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

<p>
Local functions with non-empty lambda captures 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>
Due to concerns about the effects of argument-dependent lookup,
the core commitee recommends
that no operator names be permitted on named lambdas.
</p>

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


<h3><a name="overloadname">Overloading Named Lambdas</a></h3>

<p>
Overloading named lambdas is conceptually
as simple as overloading local functions.
However, the implementation is more intrusive on the compiler
because it must now keep add named lambdas into overload sets.
Because of this difficulty,
the core committee has a preference for
not permitting overloading of named lambdas at this time.
Relaxing that restriction in the future would likely be upwards compatible.
</p>

<h3><a name="forwardname">Forwarding Named Lambdas</a></h3>

<p>
Using a forward-declared named lambda
require that the implementation know the type of the closure object,
which in turn requires that the compiler know the effective capture set.
While it is possible to determine the effective capture set
at the point of named lambda definition,
such an approach would require considerable compiler effort.
A more pragmatic approach requires determining the effective capture list
at the point of declaration.
This determination can be done in one of two ways.
</p>
<ol>
<li>
<p>
Require that all captured variables be explicitly listed in the declaration,
default captures would not be allowed.
</p>
</li>
<li>
<p>
As above, except that
a default capture of "<code>&amp;</code>" (by-reference) is permitted.
The practical implication is that
references are captured via a frame pointer
rather by a set of references to individual variables.
While the frame-pointer implementation is clearly superior,
the committee should make an explicit decision to require it.
</p>
</li>
</ol>

<p>
Whatever choices are made above,
there is still the issue of redundancy and consistency
in the specification of the capture set
between declaration and definition.
To minimize confusion on the part of programmers,
this proposal requires that the <var>lambda-capture</var>
be identical between declaration and definition.
This requirement comes at the cost of some redundancy in declarations.
</p>

<p>
In addition to knowing the effective capture set,
the compiler must capture that set.
The capture can be done either at the first declaration
or at the definition.
Capturing at the elaboration of the definition
seems to provide the greatest programmer flexibility,
and is the basis for this proposal.
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,
which in turn constrains the representation of reference captures
as discussed above.
</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>

<p>
Because of the definitional complexities above,
the core committee has a preference for
not permitting forward declaration of named lambdas at this time.
Relaxing that restriction in the future would likely be upwards compatible.
</p>


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

<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 and constexpr functions,
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>

<p>
That is, the <code>auto</code> specifier
is syntactic sugar for <code>decltype(</code><var>expr</var><code>)</code>,
where <var>expr</var> is the expression in the <code>return</code> statement.
</p>

<h2><a name="other">Other Issues</a></h2>

<p>
There is some concern about whether the appropriate wording for a closure
is <em>closure object</em>, <em>closure value</em>, or simply <em>closure</em>.
</p>

<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/2009/n2857.pdf">N2857</a>.
Note that in particular,
it does not reflect the wholesale changes to lambda wording
proposed in
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2859.pdf">
N2859 New wording for C++0x Lambdas</a>, Daveed Vandevoorde, 2009-03-19.
</p>


<h3><a name="basic.scope.pdecl">3.3.2 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.3 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 within 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.2 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>
<ins>In the <var>function-heading</var> ([dcl.fct])
of a <var>lambda-expression</var>:</ins>
<del>In a <var>lambda-parameter-declaration</var></del>
<ins>in the <var>function-qualifiers</var>,</ins>
the <var>attribute-specifier</var>
appertains to the lambda<del>.
In a <var>lambda-return-type-clause</var></del><ins>;
in the <var>return-type-clause</var>,</ins>
the attribute appertains to the lambda return <del>type.</del>
<ins>type; the <code>mutable</code> qualifier shall occur only
when there is no <var>lambda-capture</var>;
there shall be no <var>cv-qualifier-seq</var> or <var>ref-qualifier</var>;
and
each parameter shall have a <var>declarator-id</var>.</ins>
</p>
</blockquote>

<p>
Edit paragraph 7 as follows.
The intent of this edit
is make an empty <var>lambda-capture</var> indicate a function,
which is option 2 of
<a href="#empty">The Type of Empty&ndash;Lambda-Capture Lambdas</a>.
</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> of the <var>function-heading</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>


<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>empty-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> <code>;</code></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.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
of <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2541.htm">
N2541 New Function Declarator Syntax Wording</a>.
</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.
In that event, the lead-in to paragraph 3 also changes.
</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 within 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 within 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>parameters-and-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 <del><code>(</code> <var>parameter-declaration-clause</var> <code>)</code>
<var>cv-qualifier-seq<sub>opt</sub> ref-qualifier<sub>opt</sub></var></del>
<ins><var>parameters-and-qualifiers</var></ins>
returning <code>T</code>".
The optional <var>attribute-specifier</var>
<ins>of the <var>function-qualifiers</var>
of the <var>parameters-and-qualifiers</var></ins>
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,
but a more self-consistent grammar
would place the <code>mutable</code> keyword
after the <var>attribute-specifier</var>.
</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>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><var>parameter-and-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>
</p>
<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 is to restrict use of <var>decl-specifier</var>s;
to restrict the use of <code>mutable</code> in <var>function-qualifiers</var>;
to prohibit operators;
and to prohibit forwarding.
</p>
<blockquote>
<p>
<ins>
The <var>decl-specifier-seq</var> of a <var>function-declaration</var>
may contain only those that apply to functions:
<code>static</code>,
<code>extern</code>,
<code>friend</code>,
<code>typedef</code>,
<code>constexpr</code>, and
<var>function-specifier</var>.
The <var>function-qualifiers</var>
shal contain <code>mutable</code>
only when part of a <var>function-declaration</var>
or <var>lambda-expression</var>
with a non-empty <var>lambda-capture</var>.
The <var>id-expression</var> of a <var>function-declaration</var>
may contain neither
a <var>operator-function-id</var> nor a <var>conversion-function-id</var>.
A non-extern local <var>function-declaration</var>
shall be part of a <var>function-definition</var>.
[<i>Footnote:</i>
This restriction prohibits forward declarations.
&mdash;<i>end footnote</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 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 { return (n &amp; 1) == 0; }
    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-capture</var>
are described in ([expr.prim.lambda]).
A non-empty <var>lambda-capture</var>
shall only appear in block scope,
but may not appear in <code>extern</code> declarations.
These definitions are <dfn>named lambdas</dfn>.
</ins>
</p>
</blockquote>

<p>
If forward declarations are permitted,
then add the following paragraph after the above paragraph.
</p>
<blockquote>
<p>
<ins>
The <var>lambda-capture</var> for a named lambda declaration and its definition
must be identical.
The point-of-capture for a named lambda is its definition.
The invocation 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>
Within the existing paragraph 6, edit as follows.
</p>

<blockquote>
<p>
....
After determining the type of each parameter,
any parameter of type "array of T" or "function returning T"
is adjusted to be "pointer to T" or "pointer to function returning T,"
respectively.
<ins>After determining the return type,
a return type of "array of T" or "function returning T"
is adjusted to be "pointer to T" or "pointer to function returning T,"
respectively.</ins>
....
</p>
</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>
<ins>or, exploiting implicit function-to-pointer conversion in return types,</ins>
</p>
<blockquote><pre><code>
<ins>[] fpif(int)-&gt;[](int)-&gt;int</ins>
</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>simple-type-specifier</var>
of the return type 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>

<p>
Within paragraph 9, edit as follows.
</p>

<blockquote>
<p>
A function definition of the <del>form</del> <ins>forms</ins>:
</p>
<blockquote>
<p>
<var>decl-specifier-seq<sub>opt</sub> attribute-specifier<sub>opt</sub> declarator</var> <code>= default ;</code>
<ins><var>function-declaration</var> <code>= default ;</code></ins>
</p>
</blockquote>
<p>
is called an explicitly-defaulted definition. ...
</p>
</blockquote>

<p>
Within paragraph 10, edit as follows.
</p>

<blockquote>
<p>
A function definition of the <del>form</del> <ins>forms</ins>:
</p>
<blockquote>
<p>
<var>decl-specifier-seq<sub>opt</sub> attribute-specifier<sub>opt</sub> declarator</var> <code>= delete ;</code>
<ins><var>function-declaration</var> <code>= delete ;</code></ins>
</p>
</blockquote>
<p>
is called a deleted definition. ...
</p>
</blockquote>


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

<p>
Edit paragraph 1 as follows.
The intent is to prohibit overloading
of local functions and 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
declarations
can be overloaded;
object and type declarations cannot be overloaded.
<ins>Futhermore,
non-extern local function and named lambdas
shall not be overloaded.
[<i>Example:</i>
</ins>
</p>
<blockquote><pre>
<ins><code>double a(int n) {
    [n] p(int m) { return m+n; }
    [n] p(double m) { return m+n; }</code> // error: local overload<code>
    return p(3.0);
}</code></ins>
</pre></blockquote>
<p>
&mdash;<i>end example</i>]
</p>
</blockquote>

<p>
Alternatively, edit paragraph 1 as follows.
The intent is to clarify the permissible overloading
of local functions and 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>
