<!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 N2931 = 09-0121 - 2009-07-17
</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">N2890</a> = 09-0080.
</p>

<p>

<a href="#intro">Introduction</a><br>
<a href="#newdecl">New Function Declaration Syntax</a><br>
<a href="#named">Named Lambdas</a><br>
<a href="#empty">The Type of Empty&ndash;Lambda-Capture Lambdas</a><br>
<a href="#auto">Auto with Function Definitions</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.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. comment 42, and U.S. comment 43
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.
This paper presents a unification
that includes less capability than in some later papers.
This change in approach addresses a concern
that those later papers presented too much technical risk.
</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 lambda-declarator<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 lambda-declarator</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 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="named">Named Lambdas</a></h2>

<p>
The new function syntax at block scope named lambdas.
</p>

<blockquote><pre><code>
int h(int b) {
    [] m(int z)-&gt;int
        { return x+z; } // b is not in scope
    [&amp;] n(int z)-&gt;int
        { 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>
The advantage to named lambdas over this auto variable approach
is that it is possible to do forward declarations and overloading.
However, due to technical risk,
those possibilities are not supported at this time.
</p>

<p>
Due to concerns about the effects of argument-dependent lookup,
no operator names are permitted on named lambdas.
</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>
We adopt the suggested resolution.
</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>
Due to technical risk,
the return type must consist only of <code>auto</code>.
</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/n2914.pdf">N2914</a>,
presuming that the edits from
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2927.pdf">
N2927 New wording for C++0x Lambdas (rev 2)</a>
have been already applied.
</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 named lambdas
while preserving existing semantics for existing code.
</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.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
that are not a <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>


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

<p>
Edit the syntax in paragraph 1 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><var>lambda-introducer lambda-declarator<sub>opt</sub> compound-statement</var></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><var>lambda-declarator:</var></dt>
<dd><del><code>(</code> <var>parameter-declaration-clause</var> <code>)</code>
<var>attribute-specifier<sub>opt</sub></var>
<code>mutable</code><var><sub>opt</sub></var>
<var>exception-specification<sub>opt</sub></var>
<var>trailing-return-type<sub>opt</sub></var></del></dd>
<dd><ins><var>parameters-and-qualifiers</var> 
<var>trailing-return-type<sub>opt</sub></var></ins></dd>

</dl>
</blockquote>

<p>
Edit paragraph 4 as follows.
</p>
<blockquote>
<p>
If a <var>lambda-expression</var>
does not include a <var>lambda-declarator</var>,
it is as if the <var>lambda-declarator</var> were <code>()</code>.
If a <var>lambda-expression</var>
does not include a <var>trailing-return-type</var>,
<ins>or if the <var>trailing-return-type</var>
is <code>-&gt;auto</code>,</ins>
it is as if the <var>trailing-return-type</var>
denotes the following type:
</p>
<ul>
<li>
<p>
if the <var>compound-statement</var> is of the form
</p>
<blockquote>
<p>
<code>{ return</code> <var>attribute-specifier<sub>opt</sub> expression</var> <code>; }</code>
</p>
</blockquote>
<p>
the type of the returned expression
after lvalue-to-rvalue conversion (_conv.lval_ 4.1),
array-to-pointer conversion (_conv.array_ 4.2),
and function-to-pointer conversion (_conv.func_ 4.3);
</p>
</li>
<li>
otherwise, void.
</li>
</ul>
<p>
[<i>Example:</i>
</p>
<blockquote>
<p>
<code>auto x1 = [](int i){ return i; };</code><br>
<code>//</code> <em>OK: return type is int</em><br>
<code>auto x2 = []{ return { 1, 2 }; };</code><br>
<code>//</code> <em>error: the return type is void (a braced-init-list is not an expression)</em>
</p>
</blockquote>
<p>
&mdash;<i>end example</i>]
</p>
</blockquote>

<p>
Edit paragraph 5 as follows.
The intent of this edit is
to obtain a closure-to-function-pointer conversion
with no <var>lambda-capture</var>
and to restrict the qualifiers available
from the now more general syntax for <var>parameters-and-qualifiers</var>.
</p>
<blockquote>
<p>
The closure type for a <var>lambda-expression</var>
has a public inline function call operator (_over.call_ 13.5.4)
whose parameters and return type are described by the
<var>lambda-expression</var>'s <var>parameter-declaration-clause</var>
and <var>trailing-return-type</var> respectively.
This function call operator
is declared <code>const</code> (_class.mfct.non-static_ 9.3.1)
if and only if the <var>lambda-expression</var>'s
<var>parameter-declaration-clause</var>
is not followed by <code>mutable</code>.
<ins>When the there is no <var>lambda-capture</var>,
the <code>mutable</code> qualifier shall not occur;
the function call operator is declared <code>static</code>;
and a conversion operator to pointer to the type of the function call operator
is defined to return a pointer to the call operator function.
There shall be no <var>cv-qualifier-seq</var>
or <var>ref-qualifier</var>
following the <var>parameter-declaration-clause</var>.</ins>
<del>It</del> <ins>The function call operator</ins>
is not declared <code>volatile</code>.
Default arguments (_decl.fct.default_ 8.3.6)
shall not be specified in the <var>parameter-declaration-clause</var>
of a <var>lambda-declarator</var>.
Any <var>exception-specification</var>
specified on a <var>lambda-expression</var>
applies to the corresponding function call operator.
Any <var>attribute-specifiers</var>
appearing immediately after the <var>lambda-expression</var>'s
<var>parameter-declaration-clause</var>
appertain to the type of the corresponding function call operator.
[<i>Note:</i>
Names referenced in the <var>lambda-declarator</var>
are looked up in the context in which
the <var>lambda-expression</var> appears.
&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>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>
Edit paragraph 1 as follows.
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>
The <code>auto</code> <var>type-specifier</var>
signifies that the type of an object being declared
shall be deduced from its initializer
<del>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.
</p>

<blockquote>
<p>
The <code>auto</code> <var>type-specifier</var>
may appear <del>with</del> <ins>as the return type of</ins>
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])
and signifies that the return type
shall be deduced from the <var>function-body</var>.</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><ins><var>function-qualifiers:</var></ins></dt>
<dd><ins>
<var>attribute-specifier<sub>opt</sub></var>
<code>mutable</code><var><sub>opt</sub>
cv-qualifier-seq<sub>opt</sub>
ref-qualifier<sub>opt</sub>
exception-specification<sub>opt</sub></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><code>&amp;</code></dd>
<dd><code>&amp;&amp;</code></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.
</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>

<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.
</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 lambda-declarator</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>
shall 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>
within block scope
shall contain neither
a <var>operator-function-id</var> nor a <var>conversion-function-id</var>.
A non-extern block-scope <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>trailing-return-type</var>.
</p>
<blockquote>
<p>
<ins>
Within a <var>lambda-declarator</var>
of a <var>function-declaration</var>,
a missing <var>trailing-return-type</var>
indicates that the return type is <code>void</code>,
unless the heading is part of a definition
with a <var>function-body</var> of the form
<code>{ return</code> <var>expression</var> <code>; }</code>,
in which case the return type is deduced as in
(5.1.2 [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>
<var>Function-definition</var>s may be local to another function.
These definitions are <dfn>named lambdas</dfn>.
A named lambda defines a variable of closure type
equivalent to the corresponding lambda expression.
[<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.
</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>
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>function-body</var>
is <code>{&nbsp;return</code> <var>expr</var><code>;&nbsp;}</code>,
and that the return type specification
contains only the <code>auto</code> specifier.
The return type is deduced
as in (5.1.2 [expr.prim.lambda]).
[<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>
<del>A function definition of the form:</del>
<ins>If a function definition has one of the forms:</ins>
</p>
<blockquote>
<p>
<var>decl-specifier-seq<sub>opt</sub> attribute-specifier<sub>opt</sub> declarator</var> <code>= default ;</code><br>
<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>
<del>A function definition of the form:</del>
<ins>If a function definition has one of the forms:</ins>
</p>
<blockquote>
<p>
<var>decl-specifier-seq<sub>opt</sub> attribute-specifier<sub>opt</sub> declarator</var> <code>= delete ;</code><br>
<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 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 block-scope <var>function-declarations</var>
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>

</body>
</html>
