<html>

<head>
  <meta http-equiv="Content-Type" content="text/html;charset=UTF8">

  <meta name="description" content="Proposal for C++ Standard">
  <meta name="keywords" content="C++,cplusplus,wg21,nested,inline,namespace">
  <meta name="author" content="Alisdair Meredith">

  <title>Nested Inline Namespaces</title>

  <style type="text/css">
    ins {background-color:#A0FFA0}
    del {background-color:#FFA0A0}
    p {text-align:justify}
    li {text-align:justify}
    blockquote.note
    {
      background-color:#E0E0E0;
      padding-left: 15px;
      padding-right: 15px;
      padding-top: 1px;
      padding-bottom: 1px;
    }
    blockquote.recommend
    {
      background-color:#ffffb0;
      padding-left: 10px;
      padding-right: 10px;
      padding-top: 1px;
      padding-bottom: 1px;
    }
  </style>
</head>

<body>
<table>
<tr>
  <td align="left">Doc. no.</td>
  <td align="left">P1094R2</td>
</tr>
<tr>
  <td align="left">Date:</td>
  <td align="left">2018-11-09</td>
</tr>
<tr>
  <td align="left">Project:</td>
  <td align="left">Programming Language C++</td>
</tr>
<tr>
  <td align="left">Audience:</td>
  <td align="left">Evolution Working Group</td>
</tr>
<tr>
  <td align="left">Reply to:</td>
  <td align="left">Alisdair Meredith &lt;<a href="mailto:ameredith1@bloomberg.net">ameredith1@bloomberg.net</a>&gt;</td>
</tr>
</table>

<h1>Nested Inline Namespaces</h1>

<h2>Table of Contents</h2>
<ol start="0">
<li><a href="#rev.hist">Revision History</a></li>
  <ul>
  <li><a href="#rev.2">Revision 2</a></li>
  <li><a href="#rev.1">Revision 1</a></li>
  <li><a href="#rev.0">Revision 0</a></li>
  </ul>
<li><a href="#1.0">Introduction</a></li>
<li><a href="#2.0">Stating the problem</a></li>
  <ul>
  <li><a href="#2.1">Impact on the Language</a></li>
  <li><a href="#2.2">Impact on the Library</a></li>
  </ul>
<li><a href="#3.0">Propose Solution</a></li>
  <ul>
  <li><a href="#3.1">Compatibility Concerns</a></li>
  <li><a href="#3.2">Initial Reception</a></li>
  <li><a href="#3.3">Review in San Diego</a></li>
  </ul>
<li><a href="#4.0">Other Directions</a></li>
  <ul>
  <li><a href="#4.1">Extend Existing <tt>inline</tt> Syntax</a></li>
  <li><a href="#4.2">Harmonize for the Leading Namespace</a></li>
  <li><a href="#4.3">Attributes on Nested Namespace</a></li>
  </ul>
<li><a href="#5.0">Formal Wording</a></li>
</ol>


<h2><a name="rev.hist">Revision History</a></h2>

<h3><a name="rev.2">Revision 2</a></h3>
<p>
Updated proposed wording after initial feedback from Jens Mauer.
</p>
<p>
Recorded the poll results of review in San Diego.
</p>
<p>
Revised all the examples to use the more realistic example of the inline
namespace <tt>parallelism_v2</tt> consistently through the paper, rather than
just in the motivating example.
</p>

<h3><a name="rev.1">Revision 1</a></h3>
<p>
Updated alternative considerations of where <tt>inline</tt> keyword may appear,
following review at Rapperswil 2018.
</p>

<h3><a name="rev.0">Revision 0</a></h3>
<p>
Original version of the paper for the 2017 post-Albuquerque mailing.
</p>

<h2><a name="1.0">1 Introduction</a></h2>
<p>
Inline namespaces are not supported in nested namespace definitions,
and it is surprising that the "obvious" syntax is not supported.
</p>


<h2><a name="2.0">2 Stating the problem</a></h2>
<p>
While working on the header synopses for several TSes, it is apparent
how convenient the nested namespace feature is.  However, it is equally
surprising that the inline versioning namespace cannot be similarly
declared.  For example, in the Concurrency TS v2 it would be nice to
specify the <tt>&lt;experimental/execution&gt;</tt> synopsis as:
</p>
<blockquote><pre>
namespace std::experimental::<b>inline</b> parallelism_v2::execution {
  // 5.7, Unsequenced execution policy
  class unsequenced_policy;

  // 5.8, Vector execution policy
  class vector_policy;

  // 5.10, execution policy objects
  inline constexpr sequenced_policy seq{ unspecified };
  inline constexpr parallel_policy par{ unspecified };
}
</pre></blockquote>

<p>
Instead, we must open and close namespaces three separate times,
essentially rendering the nested namespace feature useless in this case:
</p>

<blockquote><pre>
namespace std::experimental {
inline namespace parallelism_v2 {
namespace execution {
  // 5.7, Unsequenced execution policy
  class unsequenced_policy;

  // 5.8, Vector execution policy
  class vector_policy;

  // 5.10, execution policy objects
  inline constexpr sequenced_policy seq{ unspecified };
  inline constexpr parallel_policy par{ unspecified };
}
}
}
</pre></blockquote>

<h3><a name="2.1">2.1 Impact on the Language</a></h3>
<p>
The concern raised is an inconvenient embarrassment, rather than a fundamental
flaw.  It would be nice to see this fixed, and hopefully should be possible
with a minimal investment of time by the committee.  If it is not seen as
immediately useful, it is probably not worth further committee time to discuss
alternative designs.
</p>

<h3><a name="2.2">2.2 Impact on the Library</a></h3>
<p>
This is a pure language extension that cannot have any breaking impact on
existing standard library wording.  It does open a possibility for slightly
cleaner specification of some standard library headers if LWG want to adopt
this feature, but that most applies to TS specifications.  The only use of
inline namespaces in the standard library of ISO 14882 is to declare user
defined literals, and it is not clear that there is an improvement in how
those particular namespaces might be opened using this facility.  There are
no library wording udpates as part of this proposal.
</p>

<h2><a name="3.0">3 Propose Solution</a></h2>
<p>
The proposed solution is fairly simple: allow the <tt>inline</tt> keyword
to optionally precede the identifier naming a namespace at each step of a
nested namespace declaration.  It is believed that editing the grammar is
a sufficient change, as the existing text would be interpreted as having
the desired meaning after this change.
</p>

<h3><a name="3.1">3.1 Compatibility Concerns</a></h3>
<p>
The proposed solution is a pure extension where the new syntax was not
valid before, and could not show up even in a SFINAE context.  There are
not expected to be any backwards compatibility concerns.  As such, there
is nothing to add to the compatibility annex of the standard (Annex C).
</p>

<p>
A fine-grained feature macro is not warranted in this case, as use of
the macro to enable the convenience feature would be more work than the
convenience returned.  The regular <tt>__cplusplus</tt> macro should
suffice for those keen to create a codebase anticipating a future cleanup
that can assume this feature once support for older dialects (by that
user) is dropped.
</p>


<h3><a name="3.2">3.2 Initial Reception</a></h3>
<p>
This proposal was briefly presented to EWG at the end of the Rapperswil 2018 meeting,
and polling in the room was broadly in favor, although it would like to
see it again, with a little feedback, before sending to Core:
</p>
<table>
<tr><td>SF</td> <td>F</td> <td>N</td> <td>A</td> <td>SA</td></tr>
<tr><td>9 </td> <td>7</td> <td>1</td> <td>0</td> <td>0 </td></tr>
</table>

<h3><a name="3.3">3.3 Review in San Diego</a></h3>
<p>
Two polls were taken in San Diego, which resulted in sending the proposal
to Core to review for C++20.
</p>

<ol>
<li>Do we want to have support for inline namespaces in nested namespace definitions?
<table>
<tr><td>SF</td> <td>F</td> <td>N</td> <td>A</td> <td>SA</td></tr>
<tr><td>3 </td> <td>9</td> <td>8</td> <td>4</td> <td>0</td></tr>
</table>
</li>
<li>Do we want to allow inline in the leading position when declaring namespaces?
<table>
<tr><td>SF</td> <td>F</td> <td>N</td> <td>A</td> <td>SA</td></tr>
<tr><td>0 </td> <td>2</td> <td>13</td> <td>4</td> <td>2</td></tr>
</table>
</li>
</ol>

<h2><a name="4.0">4 Other Directions</a></h2>

<p>
A few options were considered and rejected by the author of this proposal
during the design.  A quick summary of these other directions follows.
</p>

<h3><a name="4.1">4.1 Extend Existing <tt>inline</tt> Syntax</a></h3>

<p>
Given the existing syntax does not support an <tt>inline</tt> <i>before</i> the
<tt>namespace</tt> keyword for a nested namespace declaration, which is the
position required in the grammar for a non-nested namespace declaration,
careful consideration was given to supporting this as an option too, if for no
other reason than the notion of consistency.
</p>

<blockquote><pre>
inline namespace std::experimental::parallelism_v2;  // not immediately to reader,
                                                     // is std or parallelism_v2 inline?
</pre></blockquote>

<p>
Which namespace is intended to be inline in such cases?  The trailing
namespace?  The leading namespace? All of the namespaces?  Just the trailing
namespace?  Requiring the <tt>inline</tt> keyword to precede the namespace that
it inlines cleanly resolves such concerns, so there should be no other syntax
supported to introduce such confusion, along with endless style-guide debates.
</p>


<h3><a name="4.2">4.2 Harmonize for the Leading Namespace</a></h3>

<p>
The other side of the question is whether a top-level namespace can be declared
as inline with this new syntax, by simply moving <tt>inline</tt> to the other
side of the <tt>namespace</tt> keyword.
</p>

<blockquote><pre>
inline namespace parallelism_v2;  // legal today, and unambiguous to reader
namespace inline parallelism_v2;  // should this be equivalent?
</pre></blockquote>

<p>
This idea is rejected as potentially confusing once nested namespaces are
involved.
</p>

<blockquote><pre>
namespace inline std::experimental::parallelism_v2;  // immediately to reader?
                                                     // std or parallelism_v2 inline?
</pre></blockquote>

<p>
This has all the same concerns of ambiguity to the reader that are raised in
(4.1) above, although it is a little clearer what the grammar must mean in this
case, if we wanted to apply such a rule.  Instead, we require that the leading
namespace cannot be inline, and must be separately opened with the old syntax.
Given a quick polling of folks offline, we are not aware of any motivation to
support an inline top-level namespace, so prefer to keep an unambiguously read
grammar than support this terse syntax for a questionable use case.
</p>

<p>
A second concern is that the grammar for the first (current) form allows for
annotating namespaces with attributes, whereas the grammar for nested namespace
declarations, used by the second form, does not - see (4.3) below.
</p>

<p>
A minor concern is that introducing a second way to express exactly the same
semantic that we can express today invites as many awkward questions about
which to choose as the consistency problem it is intended to solve.
</p>

<p>
This point came up quickly at the end of the Rapperswil discussion, and the
counterpoint was not clearly presented.  The quick poll in the room was in
favor of making the change to harmonize, so the wording change to effect that
change is included below, in the event that EWG is strongly in favor of making
this change.  It involves adding one additional optional <tt>inline</tt> into
the grammar.
</p>

<blockquote><pre>
<i>enclosing-namespace-specifier:</i>
    <ins><tt><b>inline</b></tt><sub><i>opt</i></sub></ins> <i>identifier</i>
    <i>enclosing-namespace-specifier :: <ins><tt><b>inline</b></tt><sub><i>opt</i></sub></ins> identifier</i>
</pre></blockquote>


<h3><a name="4.3">4.3 Attributes on Nested Namespace</a></h3>

<p>
It was also observed, while drafting this paper, that nested namespaces do
not support attributes.  That was deemed a separate issue beyond the scope
of this paper, and is not a topic the author is motivated to solve himself.
</p>


<h2><a name="5.0">5 Formal Wording</a></h2>
<p>
Make the following changes to the specified working paper:
</p>

<blockquote>

<h4>9.7.1 Namespace definition [namespace.def]</h4>
<blockquote><pre>
<i>namespace-name:</i>
    <i>identifier</i>
    <i>namespace-alias</i>

<i>namespace-definition:</i>
    <i>named-namespace-definition</i>
    <i>unnamed-namespace-definition</i>
    <i>nested-namespace-definition</i>

<i>named-namespace-definition:</i>
    <tt><b>inline</b></tt><sub><i>opt</i></sub> <tt><b>namespace</b></tt> <i>attribute-specifier-seq<sub>opt</sub> identifier </i><tt>{</tt><i> namespace-body </i><tt>}</tt>

<i>unnamed-namespace-definition:</i>
    <tt><b>inline</b></tt><sub><i>opt</i></sub> <tt><b>namespace</b></tt> <i>attribute-specifier-seq<sub>opt</sub> </i><tt>{</tt><i> namespace-body </i><tt>}</tt>

<i>nested-namespace-definition:</i>
    <tt><b>namespace</b></tt> <i>enclosing-namespace-specifier :: </i><ins><tt><b>inline</b></tt><sub><i>opt</i></sub></ins><i> identifier  </i><tt>{</tt><i> namespace-body </i><tt>}</tt>
    
<i>enclosing-namespace-specifier:</i>
    <i>identifier</i>
    <i>enclosing-namespace-specifier :: </i><ins><tt><b>inline</b></tt><sub><i>opt</i></sub></ins><i> identifier</i>

<i>namespace-body :</i>
    <i>declaration-seq<sub>opt</sub></i>
</pre></blockquote>

<ol start="9">
<li>
A <i>nested-namespace-definition</i> with an <i>enclosing-namespace-specifier</i> <tt>E</tt>,
<i>identifier</i> <tt>I</tt> and <i>namespace-body</i> <tt>B</tt> is equivalent to
<blockquote><pre>
namespace E { <ins><tt><b>inline</b></tt><sub><i>opt</i></sub></ins> namespace I { B } }
</pre></blockquote>
<ins>where the optional <tt>inline</tt> is present if and only if the <i>identifier</i>
<tt>I</tt> is preceded by <tt>inline</tt>.</ins>
<br/>
[<i>Example:</i>
<blockquote><pre>
namespace A::<ins>inline </ins>B::C {
  int i;
}
</pre></blockquote>

The above has the same effect as:
<blockquote><pre>
namespace A {
  <ins>inline </ins>namespace B {
    namespace C {
      int i;
    } 
  }
}
</pre></blockquote>
&mdash; <i>end example</i>]
</li>
</ol>

</blockquote>

</body>
</html>
