<!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 N2989 = 09-0179 - 2009-10-23
</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/n2954.html">N2954</a> = 09-0144.
</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="#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="#class.conv.fct">12.3.2 Conversion functions [class.conv.fct]</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>bracket-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="wording">Proposed Wording</a></h2>

<p>
The proposed wording shows changes from working draft
<a href="../../papers/2009/n2914.pdf">N2914</a>,
presuming that the edits from
<a href="../../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 a function declaration
that is 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.
<ins>A program taking the address of this function call operator
is ill-formed.</ins>
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 there is no <var>lambda-capture</var>,
the <code>mutable</code> qualifier shall not occur.
There shall be no <var>cv-qualifier-seq</var>
or <var>ref-qualifier</var>
in the <var>function-qualifiers</var>
of the <var>parameters-and-qualifiers</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>

<p>
Add a new paragraph after paragraph 5.
</p>

<blockquote>
<p><ins>
The closure type for a <var>lambda-expression</var>
with no <var>lambda-capture</var>
has a public non-virtual non-explicit const conversion function
to pointer to function having
the same parameter and return types
as the closure type's function call operator.
The value returned by this conversion function
shall be the address of a function that, when invoked,
has the same effect as invoking the closure type's function call operator.
</ins></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>bracket-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="../../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>
Delete paragraph 2 as follows.
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>
may appear with 
a function 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>
</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>
<del>Otherwise, the type of the object is
deduced from its initializer.</del>
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>
The edits in this section apply to the text after applying N2927.
</p>

<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
and returns to old terminology.
</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>
    <var>trailing-return-type</var></del></dd>

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

<dt><var><del>noptr</del><ins>direct</ins>-declarator:</var></dt>
<dd><var>declarator-id attribute-specifier<sub>opt</sub></var></dd>
<dd><var><del>noptr</del><ins>direct</ins>-declarator parameters-and-qualifiers</var></dd>
<dd><var><del>noptr</del><ins>direct</ins>-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>trailing-return-type:</var></dt>
<dd><code>-&gt;</code> <var>attribute-specifier<sub>opt</sub>
    trailing-type-specifier-seq attribute-specifier<sub>opt</sub>
    abstract-declarator<sub>opt</sub></var></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>
The edits in this section apply to the text after applying N2927.
</p>

<p>
Edit within paragraph 1 as follows.
The intent of this edit
is to remove the <code>auto-&gt;</code> syntax.
The change also reverts to the terminology
used before the introduction of 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>trailing-return-type</var></del></dd>
<dd><code>...</code></dd>

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

<dt><var><del>noptr-</del><ins>direct-</ins>abstract-declarator:</var></dt>
<dd><var><del>noptr-</del><ins>direct-</ins>abstract-declarator<sub>opt</sub>
    parameters-and-qualifiers</var></dd>
<dd><var><del>noptr-</del><ins>direct-</ins>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>
The edits in this section apply to the text after applying N2927.
</p>

<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 <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>"<ins>,
using the components of <var>parameters-and-qualifiers</var></ins>.
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> trailing-return-type</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>".
The optional <var>attribute-specifier</var> appertains to the function type.
</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 <var>trailing-return-type</var>
have the form:</ins>
</p>
<dl>
<dt><ins><var>bracket-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>
The <var>decl-specifier-seq</var> of a <var>bracket-function-declaration</var>
may contain only those <var>decl-specifier</var>s 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 in the context of a <var>bracket-function-declaration</var>
or <var>lambda-expression</var>
with a non-empty <var>lambda-capture</var>.
</ins>
</p>
</blockquote>

<p>
Insert a new paragraph after the above paragraph.
</p>

<blockquote>
<p>
<ins>If a <var>bracket-function-declaration</var> is at block-scope
and not declared <code>extern</code>,
it shall be part of a <var>function-definition</var>
[<i>Footnote:</i>
This restriction prohibits forward declarations.
&mdash;<i>end footnote</i>],
the <var>id-expression</var> shall be an <var>identifier</var>,
and the <var>decl-specifier-seq</var> shall be empty.
Such a <var>bracket-function-declaration</var> defines a variable of closure type
initialized with the corresponding lambda expression
and is called a <dfn>named lambda</dfn>;
no other kind of <var>function-definition</var> is allowed at block scope.
Otherwise,
a <var>bracket-function-declaration</var> declares <var>id-expression</var>
to be of type
"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>",
from components of <var>lambda-declarator</var>
where <code>T</code> is
the type denoted by the <var>trailing-return-type</var>
of the <var>lambda-declarator</var>.
The trailing return type is required,
and the <var>lambda-capture</var> shall be empty.
</ins>
</p>

<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; }
[] halvable(int k)-&gt;bool {
    [] even(unsigned n)-&gt;bool { return (n &amp; 1) == 0; }
    return even(k);
}</ins>
</code></pre></blockquote>
<p>
<ins>
&mdash;<i>end example</i>]
</ins>
</p>
</blockquote>

<p>
Edit paragraph 4 as follows.
</p>

<blockquote>
<p>
<del>
A type of either form
is a function type.
[<i>Footnote:</i>
As indicated by syntax,
cv-qualifiers are a signficant component in function return types.
&mdash;<i>end footnote</i>]
</del>
</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 <code>, ...</code></var></dd>

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

<dt><var>parameter-declaration:</var></dt>
<dd><var>decl-specifier-seq attribute-specifier<sub>opt</sub>
declarator</var></dd>
<dd><var>decl-specifier-seq attribute-specifier<sub>opt</sub>
declarator</var> <code>=</code> <var>assignment-expression</var></dd>
<dd><var>decl-specifier-seq attribute-specifier<sub>opt</sub>
abstract-declarator<sub>opt</sub></var></dd>
<dd><var>decl-specifier-seq attribute-specifier<sub>opt</sub>
abstract-declarator<sub>opt</sub> <code>=</code>
assignment-expression</var></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 <var>trailing-return-type</var>s
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 <var>trailing-return-type</var>
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>bracket-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>
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>bracket-function-declaration</var> <code>= default ;</code></ins>
</p>
</blockquote>
<p>
<ins>it</ins> is called an
<var>explicitly-defaulted</var> 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>bracket-function-declaration</var> <code>= delete ;</code></ins>
</p>
</blockquote>
<p>
<ins>it</ins> is called a
<var>deleted definition</var>. ...
</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>
[<i>Note:</i>
Non-extern block-scope <var>bracket-function-declaration</var>s
cannot be overloaded.
[<i>Example:</i>
</ins>
</p>
<blockquote><pre>
<ins><code>double a(int n) {
    [n] p(int m) -&gt; int { return m+n; }
    [n] p(double m) -&gt; double { return m+n; }</code> // error: duplicate variable<code>
    return p(3.0);
}</code></ins>
</pre></blockquote>
<p>
<ins>
&mdash;<i>end example</i>]
&mdash;<i>end note</i>]
</ins>
</p>
</blockquote>

</body>
</html>
