﻿<!DOCTYPE HTML>
<!DOCTYPE html PUBLIC "" ""><HTML><HEAD><META content="IE=11.0000" 
http-equiv="X-UA-Compatible">
 <TITLE>D0056_SoftKeywords</TITLE> 
<META http-equiv="Content-Type" content="text/html; charset=utf-8"> 
<STYLE type="text/css">
/* GitHub stylesheet for MarkdownPad (http://markdownpad.com) */
/* Author: Nicolas Hery - http://nicolashery.com */
/* Version: b13fe65ca28d2e568c6ed5d7f06581183df8f2ff */
/* Source: https://github.com/nicolahery/markdownpad-github */

/* RESET
=============================================================================*/

html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
}

/* BODY
=============================================================================*/

body {
  font-family: Helvetica, arial, freesans, clean, sans-serif;
  font-size: 14px;
  line-height: 1.6;
  color: #333;
  background-color: #fff;
  padding: 20px;
  max-width: 960px;
  margin: 0 auto;
}

body>*:first-child {
  margin-top: 0 !important;
}

body>*:last-child {
  margin-bottom: 0 !important;
}

/* BLOCKS
=============================================================================*/

p, blockquote, ul, ol, dl, table, pre {
  margin: 15px 0;
}

/* HEADERS
=============================================================================*/

h1, h2, h3, h4, h5, h6 {
  margin: 20px 0 10px;
  padding: 0;
  font-weight: bold;
  -webkit-font-smoothing: antialiased;
}

h1 tt, h1 code, h2 tt, h2 code, h3 tt, h3 code, h4 tt, h4 code, h5 tt, h5 code, h6 tt, h6 code {
  font-size: inherit;
}

h1 {
  font-size: 28px;
  color: #000;
}

h2 {
  font-size: 24px;
  border-bottom: 1px solid #ccc;
  color: #000;
}

h3 {
  font-size: 18px;
}

h4 {
  font-size: 16px;
}

h5 {
  font-size: 14px;
}

h6 {
  color: #777;
  font-size: 14px;
}

body>h2:first-child, body>h1:first-child, body>h1:first-child+h2, body>h3:first-child, body>h4:first-child, body>h5:first-child, body>h6:first-child {
  margin-top: 0;
  padding-top: 0;
}

a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 {
  margin-top: 0;
  padding-top: 0;
}

h1+p, h2+p, h3+p, h4+p, h5+p, h6+p {
  margin-top: 10px;
}

/* LINKS
=============================================================================*/

a {
  color: #4183C4;
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

/* LISTS
=============================================================================*/

ul, ol {
  padding-left: 30px;
}

ul li > :first-child, 
ol li > :first-child, 
ul li ul:first-of-type, 
ol li ol:first-of-type, 
ul li ol:first-of-type, 
ol li ul:first-of-type {
  margin-top: 0px;
}

ul ul, ul ol, ol ol, ol ul {
  margin-bottom: 0;
}

dl {
  padding: 0;
}

dl dt {
  font-size: 14px;
  font-weight: bold;
  font-style: italic;
  padding: 0;
  margin: 15px 0 5px;
}

dl dt:first-child {
  padding: 0;
}

dl dt>:first-child {
  margin-top: 0px;
}

dl dt>:last-child {
  margin-bottom: 0px;
}

dl dd {
  margin: 0 0 15px;
  padding: 0 15px;
}

dl dd>:first-child {
  margin-top: 0px;
}

dl dd>:last-child {
  margin-bottom: 0px;
}

/* CODE
=============================================================================*/

pre, code, tt {
  font-size: 12px;
  font-family: Consolas, "Liberation Mono", Courier, monospace;
}

code, tt {
  margin: 0 0px;
  padding: 0px 0px;
  white-space: nowrap;
  border: 1px solid #eaeaea;
  background-color: #f8f8f8;
  border-radius: 3px;
}

pre>code {
  margin: 0;
  padding: 0;
  white-space: pre;
  border: none;
  background: transparent;
}

pre {
  background-color: #f8f8f8;
  border: 1px solid #ccc;
  font-size: 13px;
  line-height: 19px;
  overflow: auto;
  padding: 6px 10px;
  border-radius: 3px;
}

pre code, pre tt {
  background-color: transparent;
  border: none;
}

kbd {
    -moz-border-bottom-colors: none;
    -moz-border-left-colors: none;
    -moz-border-right-colors: none;
    -moz-border-top-colors: none;
    background-color: #DDDDDD;
    background-image: linear-gradient(#F1F1F1, #DDDDDD);
    background-repeat: repeat-x;
    border-color: #DDDDDD #CCCCCC #CCCCCC #DDDDDD;
    border-image: none;
    border-radius: 2px 2px 2px 2px;
    border-style: solid;
    border-width: 1px;
    font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
    line-height: 10px;
    padding: 1px 4px;
}

/* QUOTES
=============================================================================*/

blockquote {
  border-left: 4px solid #DDD;
  padding: 0 15px;
  color: #777;
}

blockquote>:first-child {
  margin-top: 0px;
}

blockquote>:last-child {
  margin-bottom: 0px;
}

/* HORIZONTAL RULES
=============================================================================*/

hr {
  clear: both;
  margin: 15px 0;
  height: 0px;
  overflow: hidden;
  border: none;
  background: transparent;
  border-bottom: 4px solid #ddd;
  padding: 0;
}

/* TABLES
=============================================================================*/

table th {
  font-weight: bold;
}

table th, table td {
  border: 1px solid #ccc;
  padding: 6px 13px;
}

table tr {
  border-top: 1px solid #ccc;
  background-color: #fff;
}

table tr:nth-child(2n) {
  background-color: #f8f8f8;
}

/* IMAGES
=============================================================================*/

img {
  max-width: 100%
}
</STYLE>
 
<STYLE type="text/css">
.highlight  { background: #ffffff; }
.highlight .c { color: #999988; font-style: italic } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { font-weight: bold } /* Keyword */
.highlight .o { font-weight: bold } /* Operator */
.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #999999 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #aaaaaa } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { font-weight: bold } /* Keyword.Constant */
.highlight .kd { font-weight: bold } /* Keyword.Declaration */
.highlight .kp { font-weight: bold } /* Keyword.Pseudo */
.highlight .kr { font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #009999 } /* Literal.Number */
.highlight .s { color: #d14 } /* Literal.String */
.highlight .na { color: #008080 } /* Name.Attribute */
.highlight .nb { color: #0086B3 } /* Name.Builtin */
.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
.highlight .no { color: #008080 } /* Name.Constant */
.highlight .ni { color: #800080 } /* Name.Entity */
.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
.highlight .nn { color: #555555 } /* Name.Namespace */
.highlight .nt { color: #000080 } /* Name.Tag */
.highlight .nv { color: #008080 } /* Name.Variable */
.highlight .ow { font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mf { color: #009999 } /* Literal.Number.Float */
.highlight .mh { color: #009999 } /* Literal.Number.Hex */
.highlight .mi { color: #009999 } /* Literal.Number.Integer */
.highlight .mo { color: #009999 } /* Literal.Number.Oct */
.highlight .sb { color: #d14 } /* Literal.String.Backtick */
.highlight .sc { color: #d14 } /* Literal.String.Char */
.highlight .sd { color: #d14 } /* Literal.String.Doc */
.highlight .s2 { color: #d14 } /* Literal.String.Double */
.highlight .se { color: #d14 } /* Literal.String.Escape */
.highlight .sh { color: #d14 } /* Literal.String.Heredoc */
.highlight .si { color: #d14 } /* Literal.String.Interpol */
.highlight .sx { color: #d14 } /* Literal.String.Other */
.highlight .sr { color: #009926 } /* Literal.String.Regex */
.highlight .s1 { color: #d14 } /* Literal.String.Single */
.highlight .ss { color: #990073 } /* Literal.String.Symbol */
.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
.highlight .vc { color: #008080 } /* Name.Variable.Class */
.highlight .vg { color: #008080 } /* Name.Variable.Global */
.highlight .vi { color: #008080 } /* Name.Variable.Instance */
.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */
.pl-c {
    color: #969896;
}

.pl-c1,.pl-mdh,.pl-mm,.pl-mp,.pl-mr,.pl-s1 .pl-v,.pl-s3,.pl-sc,.pl-sv {
    color: #0086b3;
}

.pl-e,.pl-en {
    color: #795da3;
}

.pl-s1 .pl-s2,.pl-smi,.pl-smp,.pl-stj,.pl-vo,.pl-vpf {
    color: #333;
}

.pl-ent {
    color: #63a35c;
}

.pl-k,.pl-s,.pl-st {
    color: #a71d5d;
}

.pl-pds,.pl-s1,.pl-s1 .pl-pse .pl-s2,.pl-sr,.pl-sr .pl-cce,.pl-sr .pl-sra,.pl-sr .pl-sre,.pl-src,.pl-v {
    color: #df5000;
}

.pl-id {
    color: #b52a1d;
}

.pl-ii {
    background-color: #b52a1d;
    color: #f8f8f8;
}

.pl-sr .pl-cce {
    color: #63a35c;
    font-weight: bold;
}

.pl-ml {
    color: #693a17;
}

.pl-mh,.pl-mh .pl-en,.pl-ms {
    color: #1d3e81;
    font-weight: bold;
}

.pl-mq {
    color: #008080;
}

.pl-mi {
    color: #333;
    font-style: italic;
}

.pl-mb {
    color: #333;
    font-weight: bold;
}

.pl-md,.pl-mdhf {
    background-color: #ffecec;
    color: #bd2c00;
}

.pl-mdht,.pl-mi1 {
    background-color: #eaffea;
    color: #55a532;
}

.pl-mdr {
    color: #795da3;
    font-weight: bold;
}

.pl-mo {
    color: #1d3e81;
}
.task-list {
padding-left:10px;
margin-bottom:0;
}

.task-list li {
    margin-left: 20px;
}

.task-list-item {
list-style-type:none;
padding-left:10px;
}

.task-list-item label {
font-weight:400;
}

.task-list-item.enabled label {
cursor:pointer;
}

.task-list-item+.task-list-item {
margin-top:3px;
}

.task-list-item-checkbox {
display:inline-block;
margin-left:-20px;
margin-right:3px;
vertical-align:1px;
}
</STYLE>
 
<META name="GENERATOR" content="MSHTML 11.00.9600.18036"></HEAD> 
<BODY>
<TABLE>
  <THEAD>
  <TR>
    <TH>Document Number:</TH>
    <TH>P0056R00</TH></TR></THEAD>
  <TBODY>
  <TR>
    <TD>Date:</TD>
    <TD>2015-09-12</TD></TR>
  <TR>
    <TD>Project:</TD>
    <TD>Programming Language C++, EWG</TD></TR>
  <TR>
    <TD>Revises:</TD>
    <TD>none</TD></TR>
  <TR>
    <TD>Reply to:</TD>
    <TD>gorn@microsoft.com</TD></TR></TBODY></TABLE>
<H1 id="p0056r00-soft-keywords">P0056R00: Soft Keywords</H1>
<P><STRONG>Bikeshed alternatives:</STRONG> scoped keywords, std-qualified 
keywords, named keywords.</P>
<H2 id="introduction">Introduction</H2>
<P><EM>"We have to go with the odd ones, as all of the good ones are already 
taken"</EM>. This was said a few times at different WG21 meetings. It was in a 
reference to keywords. C++ is a mature language with large existing codebases 
and an attempt to introduce a new keyword into the language will necessarily 
break existing code. </P>
<P>Quick sampling of some of the proposed keywords from Concepts, Modules, 
Transaction Memory, Pattern Matching, and Coroutines papers (<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3449.pdf">N3449</A>, 
<A 
href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4134.pdf">N4134</A>, 
<A 
href="http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4361.pdf">N4361</A>, 
<A 
href="http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4466.pdf">N4466</A>, 
<A 
href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4513.pdf">N4513</A>, 
[PatternMatch]) in private and public codebases reveals that identifiers 
<CODE>await</CODE>, <CODE>concept</CODE>, <CODE>requires</CODE>, 
<CODE>synchronized</CODE>, <CODE>module</CODE>, <CODE>inspect</CODE>, 
<CODE>when</CODE> are used as names of variables, fields, parameters, namespaces 
and classes.</P>
<P>This paper explores the idea of adding <EM>soft keywords</EM> to the C++ 
language. This will enable new language features to select best possible keyword 
names without breaking existing software. The idea is simple. <EM>Soft 
keyword</EM> is a named entity implicitly defined in <CODE>std</CODE> or 
<CODE>std::experimental</CODE> namespaces that participates in the name lookup 
and name hiding according to existing language rules. If a name lookup finds an 
implicit declaration of a <EM>soft keyword</EM> it is treated in the same way as 
other context-dependent keyword resolved by the name lookup such as 
<CODE>typedef-name</CODE>, <CODE>namespace-name</CODE>, <CODE>class-name</CODE>, 
etc.</P>
<P>In the example below <CODE>yield</CODE> is a <EM>soft keyword</EM> implicitly 
defined in the <CODE>std</CODE> namespace.</P>
<PRE><CODE class="lang-~">namespace N1 { void yield(int); }
auto coro2() {
  using std::yield;
  yield(2);           // yields value 2
  N1::yield(3);       // invokes N1::yield
} 
auto coro3() {
  using namespace N1;
  yield(1);           // invokes N1::yield
  std::yield(3);      // yields value 3
}
auto coro4() {
  using namespace N1;
  using namespace std;
  yield(4);           // error: ambiguous
}
</CODE></PRE>
<H2 id="discussion">Discussion</H2>
<P>Drawback of the simple model described in the introduction is that without a 
using declaration or using directive, the developer need to always use std:: 
with the <EM>soft keyword</EM>. This is troublesome as people would have to 
remember which keywords are the soft keywords and which are the good old "hard 
ones". This can be alleviated by adding a paragraph to the section 3.5 
[basic.lookup] stating:</P>
<BLOCKQUOTE>(5) if an unqualified name lookup [basic.lookup.unqual] or an 
  argument-dependent name lookup [basic.lookup.argdep] fails to find a 
  declaration and an identifier being looked up is a soft keyword identifier, it 
  is treated as the corresponding context-dependent keyword</BLOCKQUOTE>
<P>With this addition, we are getting to near <EM>perfect</EM> keyword 
experience. In the following example <CODE>module</CODE> is a soft keyword.</P>
<PRE><CODE>module A; // OK. Lookup did not find any

Xyz::Pcmf *module; // OK

bool FileHandleList::Find(LPCWSTR file)
{
    FileHandleCachePaths::iterator
        module = _Find(file); // OK

    return module != m_hInstPaths.end(); // OK
}
</CODE></PRE>
<H3 id="dependent-names">Dependent names</H3>
<P>If a grammar construct utilizing a particular soft keyword can be interpreted 
as a function call when used in the template definition and being a dependent 
name, the current rules will result in the construct being treated as a function 
call. This preserves the property that a template can be correctly parsed prior 
to instantiation. That means that for some constructs, in templates, one must 
use explicitly qualified soft keywords, unless there a preceding using directive 
or declaration.  </P>
<P>In the examples bellow, <CODE>inspect</CODE> and <CODE>when</CODE> are 
<EM>soft keywords</EM>.</P>
<PRE><CODE>template &lt;typename T&gt;
double area(const Shape&amp; s, T u)
{
    inspect (s) { // OK: not a dependent name
      when Circle:    return 2*pi*radius();
      when Square:     return height()*width();
      default:        error(“unknown shape”);
    }
    std::inspect(u) { // must be qualified, otherwise will be parsed as a function call
      when X: return 1.0;
    }
}
</CODE></PRE>
<P>Similarly, with <CODE>yield</CODE> soft keyword, in some cases, qualification 
will be needed.</P>
<PRE><CODE>template &lt;typename T&gt; 
auto g() {
  T v;
  T* p;
  yield v;       // yield expression (not a dependent name, not a function call expr)
  yield(5);      // yield expression (not a dependent name)
  std::yield(v); // yield expression (not a dependent name, since qualified) 
  std::yield *p; // yield expression (not a dependent name, since qualified)

  yield *p;      // operator * call, yield is not a soft keyword
  yield(v);      // function call, yield is a dependent name
}
</CODE></PRE>
<P>This is unfortunate, but, developers are already trained to deal with two 
phase lookup in templates and take care of it, by inserting 
<CODE>typename</CODE>, <CODE>template</CODE> and <CODE>this-&gt;</CODE> as 
needed. Soft keywords add one more annoyance they have to deal with, unless we 
can take advantage of modules.</P>
<H3 id="modules-to-the-rescue">Modules to the rescue</H3>
<P>However, situation is not as bleak as it may seem. Modules get us to perfect 
keyword experience, as they allow free use of using directives / declarations 
without exporting using directives / declarations outside of the module.</P>
<PRE><CODE>module A;

using namespace std;

template&lt;typename T, typename U&gt;
export void f(T&amp; x, U xx)
{
    inspect (x,xx) { // OK: not a dependent name, as the lookup finds std::inspect
       when {int* p,0}:         p=nullptr;
       when {_a,int}:     …    // _a is a placeholder matching everything
                // shorthand for auto _a
    }
}
</CODE></PRE>
<P>If someone finds using directive too broad, one can define a module with all 
of their favorite soft keywords exported in using declarations as follows:</P>
<PRE><CODE>module Cpp17keywords;
export {
  using std::inspect;
  using std::when;
  using std::await;
  using std::yield;
  ...
}
</CODE></PRE>
<P>and now, any module can take advantage of using unqualified soft keywords by 
having <CODE>import Cpp17keywords;</CODE> declaration.</P>
<H2 id="but-it-can-still-break-some-code">But it can still break some code</H2>
<P>Yes. If a source file uses <CODE>using namespace std</CODE> and defines an 
entity with the name matching the soft keyword <CODE>xyz</CODE> in the global 
namespace or in another namespace X that is available for unqualified name 
lookup due to <CODE>using namespace X</CODE>, then, the lookup will be 
ambiguous. The fix would be to explicitly qualify the name in question with 
<CODE>::xyz</CODE> or <CODE>X::xyz</CODE>.</P>
<P>We can also do not break existing code, by altering paragraph 2 of section 
[namespace.udir] as follows (changes are in <STRONG>bold</STRONG>):</P>
<BLOCKQUOTE> A <EM>using-directive</EM> specifies that the names in the 
  nominated namespace can be used in the scope in which 
  the<BR><EM>using-directive</EM> appears after the <EM>using-directive</EM>. 
  During unqualified name lookup (3.4.1), the names appear<BR>as if they were 
  declared in the nearest enclosing namespace which contains both the 
  using-directive and the<BR>nominated namespace. <STRONG>This affects all names 
  except the names of the soft keywords.</STRONG><BR></BLOCKQUOTE>
<P>One may ask, why should we do this? We don't guard against introducing new 
library functions in <CODE>std</CODE> namespace, why should we do this for 
keywords? For functions, library can rely on overloading and SFINAE to remove 
function names from consideration and reduce the chance of collision. We don't 
have this ability for keywords. Nevertheless, authors feel ambivalent about this 
rule and would like committee guidance. </P>
<H2 id="other-concerns">Other concerns</H2>
<P>What about tools? Would soft keywords confuse them? Not necessarily. If we 
introduce new constructs to the language tools need to be adapt to them.</P>
<P>Precise tools already have to rely on name lookup to figure out if <CODE>X * 
y;</CODE> is a declaration of a variable of type pointer to <CODE>X</CODE> or 
multiplication of <CODE>X</CODE> and <CODE>y</CODE>. Thus, they should be able 
to distinguish between identifiers and soft keywords.</P>
<P>Imprecise tools rely on heuristics to decide how to parse without having 
complete knowledge  of all the symbols. In that case, they would have to use 
heuristics depending on the construct. For example, if <CODE>inspect(x)</CODE> 
is followed by the <CODE>{</CODE>, then heuristic would be that 
<CODE>inspect</CODE> is a keyword, otherwise, assume function name.</P>
<H2 id="implementation-experience">Implementation experience</H2>
<P>A version of this proposal was implemented in non-shipping version of 
Microsoft C++ compiler.</P>
<H2 id="rough-wording">Rough Wording</H2>
<P>Here is a very rough sketch of how the wording might look for soft keywords. 
As an illustration, I use the soft keywords <CODE>yield</CODE> and 
<CODE>await</CODE>. </P>
<H3 id="2-10-identifiers">2.10 Identifiers</H3>
<P>Add <CODE>yield</CODE> and <CODE>await</CODE> to the table 2 (Identifiers 
with special meaning).</P>
<H3 id="3-basic-concepts-basic-">3 Basic Concepts [basic]</H3>
<P>In paragraph 3 add the text in <STRONG>bold</STRONG>.</P>
<BLOCKQUOTE>An <EM>entity</EM> is a value, object, reference, function, 
  enumerator, type,<BR>class member, template, template specialization, 
  namespace, parameter<BR>pack, <STRONG>soft keyword,</STRONG>  or 
  <CODE>this</CODE>.</BLOCKQUOTE>
<P>Add the following paragraph after paragraph 4. </P>
<BLOCKQUOTE>If an unqualified name lookup [basic.lookup.unqual] or an 
  argument-dependent name lookup [basic.lookup.argdep] fails to find a 
  declaration and an identifier being looked up is a soft keyword identifier, it 
  is treated as corresponding context-dependent keyword</BLOCKQUOTE>
<H3 id="3-4-name-lookup-basic-lookup-">3.4 Name lookup [basic.lookup]</H3>
<P>In paragraph 1, add the text in bold.</P>
<BLOCKQUOTE>The name lookup rules apply uniformly to all names (including 
  <EM>typedef-names</EM> (7.1.3), <EM>namespace-names</EM> (7.3), 
  <STRONG><EM>soft-keyword-names</EM></STRONG> (3.12),<BR>and 
  <EM>class-names</EM> (9.1)) ... </BLOCKQUOTE>
<H3 id="3-12-soft-keywords">3.12 Soft keywords</H3>
<P>Soft keywords <CODE>yield</CODE> and <CODE>await</CODE> are implicitly 
declared in the <CODE>std::experimental</CODE> namespace. In the grammar 
productions, <CODE>yield-soft-keyword-name</CODE> and 
<CODE>await-soft-keyword-name</CODE> represent context-dependent keywords 
resulted from the name lookup according to the rules in 3.4 [basic.lookup].</P>
<H3 id="5-3-unary-expressions">5.3 Unary expressions</H3>
<P>[Note: This is an illustration of soft keywords used in grammar 
production]</P>
<P><EM>await-expression</EM>: <CODE>await-soft-keyword-name</CODE> 
<EM>cast-expression</EM></P>
<H2 id="references">References</H2>
<P><A 
href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4134.pdf">N4134</A>: 
Resumable Functions v2 (<A href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4134.pdf">http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4134.pdf</A>)<BR><A 
href="http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4361.pdf">N4361</A>: 
C++ extensions for Concepts (<A href="http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4361.pdf">http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4361.pdf</A>)<BR><A 
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3449.pdf">N3449</A>: 
Open and Efficient Type Switch for C++ (<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3449.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3449.pdf</A>)<BR><A 
href="http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4466.pdf">N4466</A>: 
Wording for Modules (<A href="http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4466.pdf">http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4466.pdf</A>)<BR><A 
href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4513.pdf">N4513</A>: 
Working Draft Technical Specification for C++ Extensions for Transactional 
Memory (<A href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4513.pdf">http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4513.pdf</A>)<BR>[PatternMatch]: 
Presentation from the evening session at Urbana 2014</P><!--
### synchronized

Quick sampling of the Microsoft internal codebases revealed that lower case synchronized is C++ code is used
parameters 2 hits
bit field names 1 hit
member functions
local variables

git://pkgs.fedoraproject.org/log4cxx 
git://github.com/hpcc-systems/HPCC-Platform.git 
used as a class name

macro name: https://searchcode.com/?q=synchronized%20lang%3AC%2B%2B%20repo:libprocess/libprocess

https://searchcode.com/?q=synchronized%20lang%3AC%2B%2B%20repo:libprocess/libprocess

variable name: https://github.com/yibaolin/Open-Source-Research.git 

function: https://bitbucket.org/cleto/zeroc-ice-package.git 

### await

Apache Mesos: https://bitbucket.org/c0s/mesos.git - member function
Microsoft internal: local variables
git://github.com/jedi4ever/mcollective-cpp-agents.git - member functions 
https://github.com/t-0/quantlib.git 

### when

used as parameters: https://bitbucket.org/slukk/atsmp_4.2-frameworks_base.git
used as member variables: https://bitbucket.org/slukk/atsmp_4.2-frameworks_base.git
https://bitbucket.org/brettmurphy/singularityviewer.git | 

### concept

## Sketch of the wording changes

### Add scoped keywords to the list of 

### Function Call syntax disambiguation

If the grammar rule containing the scoped keyword has the shape `g1: scoped-keyword expression`, there will be a need for disambiguation when `scoped-keyword(type-dependent-expression)`. There could be two approaches to take:

1. If the rule `g1` is an expression itself. The is left to template instantiation time. Since whether `scoped-keyword(type-dependent-expression)` does not alter the parsing of the expression.
2. If the rule `g1` is a different syntactic construct than an expression,



### Drawback of a simplifying rule

In a template definition, the expression of the form 
````
template <typename T>
auto g() {
  T v;
  T* p;
  yield v;       // yield expression (not a dependent name)
  yield(5);      // yield expression (not a dependent name)
  std::yield(v); // yield expression (not a dependent name) 

  yield(v);      // function call, yield is a dependent name
}
````
The latter case 


# 14.6 Name Resolution [temp.res]

Modify paragraph 1 as follows. (Changes are in *bold*).
<blockquote> **Four ~~Three~~** kinds of names can be used within a template definition:
(1.1) The name of the template itself, and names declared within the template itself.
(1.2) Names dependent on a *template-parameter* (14.6.2).
(1.3) Names from scopes which are visible within the template definition.
**(1.4) Names of qualified keywords.**
</blockquote>

Add the following at the end of the example in paragraph 2.

````
template <typename T>
auto g() {
  T val;
  yield val;      // OK, yield is a qualified keyword name
  std::yield val; // OK, yield is a qualified keyword name
}
````
--> 
</BODY></HTML><!-- This document was created with MarkdownPad, the Markdown editor for Windows (http://markdownpad.com) -->
