<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang xml:lang>
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="mpark/wg21" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  <meta name="dcterms.date" content="2019-07-28" />
  <title>Guidelines For snake_case Concept Naming</title>
  <style>
      code{white-space: pre-wrap;}
      span.smallcaps{font-variant: small-caps;}
      span.underline{text-decoration: underline;}
      div.column{display: inline-block; vertical-align: top; width: 50%;}
  </style>
  <style>
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
  { counter-reset: source-line 0; }
pre.numberSource code > span
  { position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::before
  { content: counter(source-line);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
    color: #aaaaaa;
  }
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
div.sourceCode
  {  background-color: #f6f8fa; }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span. { } /* Normal */
code span.al { color: #ff0000; } /* Alert */
code span.an { } /* Annotation */
code span.at { } /* Attribute */
code span.bn { color: #9f6807; } /* BaseN */
code span.bu { color: #9f6807; } /* BuiltIn */
code span.cf { color: #00607c; } /* ControlFlow */
code span.ch { color: #9f6807; } /* Char */
code span.cn { } /* Constant */
code span.co { color: #008000; font-style: italic; } /* Comment */
code span.cv { color: #008000; font-style: italic; } /* CommentVar */
code span.do { color: #008000; } /* Documentation */
code span.dt { color: #00607c; } /* DataType */
code span.dv { color: #9f6807; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #9f6807; } /* Float */
code span.fu { } /* Function */
code span.im { } /* Import */
code span.in { color: #008000; } /* Information */
code span.kw { color: #00607c; } /* Keyword */
code span.op { color: #af1915; } /* Operator */
code span.ot { } /* Other */
code span.pp { color: #6f4e37; } /* Preprocessor */
code span.re { } /* RegionMarker */
code span.sc { color: #9f6807; } /* SpecialChar */
code span.ss { color: #9f6807; } /* SpecialString */
code span.st { color: #9f6807; } /* String */
code span.va { } /* Variable */
code span.vs { color: #9f6807; } /* VerbatimString */
code span.wa { color: #008000; font-weight: bold; } /* Warning */
code.diff {color: #898887}
code.diff span.va {color: #006e28}
code.diff span.st {color: #bf0303}
  </style>
  <style type="text/css">
body {
margin: 5em;
font-family: serif;

hyphens: auto;
line-height: 1.35;
}
div.wrapper {
max-width: 60em;
margin: auto;
}
ul {
list-style-type: none;
padding-left: 2em;
margin-top: -0.2em;
margin-bottom: -0.2em;
}
a {
text-decoration: none;
color: #4183C4;
}
a.hidden_link {
text-decoration: none;
color: inherit;
}
li {
margin-top: 0.6em;
margin-bottom: 0.6em;
}
h1, h2, h3, h4 {
position: relative;
line-height: 1;
}
a.self-link {
position: absolute;
top: 0;
left: calc(-1 * (3.5rem - 26px));
width: calc(3.5rem - 26px);
height: 2em;
text-align: center;
border: none;
transition: opacity .2s;
opacity: .5;
font-family: sans-serif;
font-weight: normal;
font-size: 83%;
}
a.self-link:hover { opacity: 1; }
a.self-link::before { content: "§"; }
ul > li:before {
content: "\2014";
position: absolute;
margin-left: -1.5em;
}
:target { background-color: #C9FBC9; }
:target .codeblock { background-color: #C9FBC9; }
:target ul { background-color: #C9FBC9; }
.abbr_ref { float: right; }
.folded_abbr_ref { float: right; }
:target .folded_abbr_ref { display: none; }
:target .unfolded_abbr_ref { float: right; display: inherit; }
.unfolded_abbr_ref { display: none; }
.secnum { display: inline-block; min-width: 35pt; }
.header-section-number { display: inline-block; min-width: 35pt; }
.annexnum { display: block; }
div.sourceLinkParent {
float: right;
}
a.sourceLink {
position: absolute;
opacity: 0;
margin-left: 10pt;
}
a.sourceLink:hover {
opacity: 1;
}
a.itemDeclLink {
position: absolute;
font-size: 75%;
text-align: right;
width: 5em;
opacity: 0;
}
a.itemDeclLink:hover { opacity: 1; }
span.marginalizedparent {
position: relative;
left: -5em;
}
li span.marginalizedparent { left: -7em; }
li ul > li span.marginalizedparent { left: -9em; }
li ul > li ul > li span.marginalizedparent { left: -11em; }
li ul > li ul > li ul > li span.marginalizedparent { left: -13em; }
div.footnoteNumberParent {
position: relative;
left: -4.7em;
}
a.marginalized {
position: absolute;
font-size: 75%;
text-align: right;
width: 5em;
}
a.enumerated_item_num {
position: relative;
left: -3.5em;
display: inline-block;
margin-right: -3em;
text-align: right;
width: 3em;
}
div.para { margin-bottom: 0.6em; margin-top: 0.6em; text-align: justify; }
div.section { text-align: justify; }
div.sentence { display: inline; }
span.indexparent {
display: inline;
position: relative;
float: right;
right: -1em;
}
a.index {
position: absolute;
display: none;
}
a.index:before { content: "⟵"; }

a.index:target {
display: inline;
}
.indexitems {
margin-left: 2em;
text-indent: -2em;
}
div.itemdescr {
margin-left: 3em;
}
.bnf {
font-family: serif;
margin-left: 40pt;
margin-top: 0.5em;
margin-bottom: 0.5em;
}
.ncbnf {
font-family: serif;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-left: 40pt;
}
.ncsimplebnf {
font-family: serif;
font-style: italic;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-left: 40pt;
background: inherit; 
}
span.textnormal {
font-style: normal;
font-family: serif;
white-space: normal;
display: inline-block;
}
span.rlap {
display: inline-block;
width: 0px;
}
span.descr { font-style: normal; font-family: serif; }
span.grammarterm { font-style: italic; }
span.term { font-style: italic; }
span.terminal { font-family: monospace; font-style: normal; }
span.nonterminal { font-style: italic; }
span.tcode { font-family: monospace; font-style: normal; }
span.textbf { font-weight: bold; }
span.textsc { font-variant: small-caps; }
a.nontermdef { font-style: italic; font-family: serif; }
span.emph { font-style: italic; }
span.techterm { font-style: italic; }
span.mathit { font-style: italic; }
span.mathsf { font-family: sans-serif; }
span.mathrm { font-family: serif; font-style: normal; }
span.textrm { font-family: serif; }
span.textsl { font-style: italic; }
span.mathtt { font-family: monospace; font-style: normal; }
span.mbox { font-family: serif; font-style: normal; }
span.ungap { display: inline-block; width: 2pt; }
span.textit { font-style: italic; }
span.texttt { font-family: monospace; }
span.tcode_in_codeblock { font-family: monospace; font-style: normal; }
span.phantom { color: white; }

span.math { font-style: normal; }
span.mathblock {
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 1.2em;
margin-bottom: 1.2em;
text-align: center;
}
span.mathalpha {
font-style: italic;
}
span.synopsis {
font-weight: bold;
margin-top: 0.5em;
display: block;
}
span.definition {
font-weight: bold;
display: block;
}
.codeblock {
margin-left: 1.2em;
line-height: 127%;
}
.outputblock {
margin-left: 1.2em;
line-height: 127%;
}
div.itemdecl {
margin-top: 2ex;
}
code.itemdeclcode {
white-space: pre;
display: block;
}
span.textsuperscript {
vertical-align: super;
font-size: smaller;
line-height: 0;
}
.footnotenum { vertical-align: super; font-size: smaller; line-height: 0; }
.footnote {
font-size: small;
margin-left: 2em;
margin-right: 2em;
margin-top: 0.6em;
margin-bottom: 0.6em;
}
div.minipage {
display: inline-block;
margin-right: 3em;
}
div.numberedTable {
text-align: center;
margin: 2em;
}
div.figure {
text-align: center;
margin: 2em;
}
table {
border: 1px solid black;
border-collapse: collapse;
margin-left: auto;
margin-right: auto;
margin-top: 0.8em;
text-align: left;
hyphens: none; 
}
td, th {
padding-left: 1em;
padding-right: 1em;
vertical-align: top;
}
td.empty {
padding: 0px;
padding-left: 1px;
}
td.left {
text-align: left;
}
td.right {
text-align: right;
}
td.center {
text-align: center;
}
td.justify {
text-align: justify;
}
td.border {
border-left: 1px solid black;
}
tr.rowsep, td.cline {
border-top: 1px solid black;
}
tr.even, tr.odd {
border-bottom: 1px solid black;
}
tr.capsep {
border-top: 3px solid black;
border-top-style: double;
}
tr.header {
border-bottom: 3px solid black;
border-bottom-style: double;
}
th {
border-bottom: 1px solid black;
}
span.centry {
font-weight: bold;
}
div.table {
display: block;
margin-left: auto;
margin-right: auto;
text-align: center;
width: 90%;
}
span.indented {
display: block;
margin-left: 2em;
margin-bottom: 1em;
margin-top: 1em;
}
ol.enumeratea { list-style-type: none; background: inherit; }
ol.enumerate { list-style-type: none; background: inherit; }

code.sourceCode > span { display: inline; }

div#refs p { padding-left: 32px; text-indent: -32px; }
</style>
  <link href="data:image/vnd.microsoft.icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAVoJEAN6CRADegkQAWIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wCCRAAAgkQAAIJEAACCRAAsgkQAvoJEAP+CRAD/gkQA/4JEAP+CRADAgkQALoJEAACCRAAAgkQAAP///wD///8AgkQAAIJEABSCRACSgkQA/IJEAP99PQD/dzMA/3czAP99PQD/gkQA/4JEAPyCRACUgkQAFIJEAAD///8A////AHw+AFiBQwDqgkQA/4BBAP9/PxP/uZd6/9rJtf/bybX/upd7/39AFP+AQQD/gkQA/4FDAOqAQgBc////AP///wDKklv4jlEa/3o7AP+PWC//8+3o///////////////////////z7un/kFox/35AAP+GRwD/mVYA+v///wD///8A0Zpk+NmibP+0d0T/8evj///////+/fv/1sKz/9bCs//9/fr//////+/m2/+NRwL/nloA/5xYAPj///8A////ANKaZPjRmGH/5cKh////////////k149/3UwAP91MQD/lmQ//86rhv+USg3/m1YA/5hSAP+bVgD4////AP///wDSmmT4zpJY/+/bx///////8+TV/8mLT/+TVx//gkIA/5lVAP+VTAD/x6B//7aEVv/JpH7/s39J+P///wD///8A0ppk+M6SWP/u2sf///////Pj1f/Nj1T/2KFs/8mOUv+eWhD/lEsA/8aee/+0glT/x6F7/7J8Rvj///8A////ANKaZPjRmGH/48Cf///////+/v7/2qt//82PVP/OkFX/37KJ/86siv+USg7/mVQA/5hRAP+bVgD4////AP///wDSmmT40ppk/9CVXP/69O////////7+/v/x4M//8d/P//7+/f//////9u7n/6tnJf+XUgD/nFgA+P///wD///8A0ppk+NKaZP/RmWL/1qNy//r07///////////////////////+vXw/9akdP/Wnmn/y5FY/6JfFvj///8A////ANKaZFTSmmTo0ppk/9GYYv/Ql1//5cWm//Hg0P/x4ND/5cWm/9GXYP/RmGH/0ppk/9KaZOjVnmpY////AP///wDSmmQA0ppkEtKaZI7SmmT60ppk/9CWX//OkVb/zpFW/9CWX//SmmT/0ppk/NKaZJDSmmQS0ppkAP///wD///8A0ppkANKaZADSmmQA0ppkKtKaZLrSmmT/0ppk/9KaZP/SmmT/0ppkvNKaZCrSmmQA0ppkANKaZAD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkUtKaZNzSmmTc0ppkVNKaZADSmmQA0ppkANKaZADSmmQA////AP5/AAD4HwAA4AcAAMADAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAMADAADgBwAA+B8AAP5/AAAoAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAyCRACMgkQA6oJEAOqCRACQgkQAEIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRABigkQA5oJEAP+CRAD/gkQA/4JEAP+CRADqgkQAZoJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAA4gkQAwoJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQAxIJEADyCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAP///wD///8A////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAWgkQAmIJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAJyCRAAYgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAdIJEAPCCRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAPSCRAB4gkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQASoJEANKCRAD/gkQA/4JEAP+CRAD/g0YA/39AAP9zLgD/bSQA/2shAP9rIQD/bSQA/3MuAP9/PwD/g0YA/4JEAP+CRAD/gkQA/4JEAP+CRADUgkQAToJEAACCRAAAgkQAAP///wD///8A////AP///wB+PwAAgkUAIoJEAKiCRAD/gkQA/4JEAP+CRAD/hEcA/4BBAP9sIwD/dTAA/5RfKv+viF7/vp56/76ee/+wiF7/lWAr/3YxAP9sIwD/f0AA/4RHAP+CRAD/gkQA/4JEAP+CRAD/gkQArIJEACaBQwAA////AP///wD///8A////AIBCAEBzNAD6f0EA/4NFAP+CRAD/gkQA/4VIAP92MwD/bSUA/6N1Tv/ezsL/////////////////////////////////38/D/6V3Uv9uJgD/dTEA/4VJAP+CRAD/gkQA/4JEAP+BQwD/fUAA/4FDAEj///8A////AP///wD///8AzJRd5qBlKf91NgD/dDUA/4JEAP+FSQD/cy4A/3YyAP/PuKP//////////////////////////////////////////////////////9K7qP94NQD/ciwA/4VJAP+CRAD/fkEA/35BAP+LSwD/mlYA6v///wD///8A////AP///wDdpnL/4qx3/8KJUv+PUhf/cTMA/3AsAP90LgD/4dK+/////////////////////////////////////////////////////////////////+TYxf91MAD/dTIA/31CAP+GRwD/llQA/6FcAP+gWwD8////AP///wD///8A////ANGZY/LSm2X/4ap3/92mcP+wdT3/byQA/8mwj////////////////////////////////////////////////////////////////////////////+LYxv9zLgP/jUoA/59bAP+hXAD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/RmWL/1p9q/9ubXv/XqXj////////////////////////////7+fD/vZyG/6BxS/+gcUr/vJuE//r37f//////////////////////3MOr/5dQBf+dVQD/nVkA/5xYAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmWP/yohJ//jo2P//////////////////////4NTG/4JDFf9lGAD/bSQA/20kAP9kGAD/fz8S/+Xb0f//////5NG9/6txN/+LOgD/m1QA/51aAP+cWAD/m1cA/5xYAP+cWADy////AP///wD///8A////ANKaZPLSmmT/0ppk/8+TWf/Unmv//v37//////////////////////+TWRr/VwsA/35AAP+ERgD/g0UA/4JGAP9lHgD/kFga/8KXX/+TRwD/jT4A/49CAP+VTQD/n10A/5xYAP+OQQD/lk4A/55cAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/y4tO/92yiP//////////////////////8NnE/8eCQP+rcTT/ez0A/3IyAP98PgD/gEMA/5FSAP+USwD/jj8A/5lUAP+JNwD/yqV2/694Mf+HNQD/jkAA/82rf/+laBj/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/LiUr/4byY///////////////////////gupX/0I5P/+Wuev/Lklz/l1sj/308AP+QSwD/ol0A/59aAP+aVQD/k0oA/8yoh///////+fXv/6pwO//Lp3v///////Pr4f+oay7y////AP///wD///8A////ANKaZPLSmmT/0ppk/8uJSv/hvJj//////////////////////+G7l//Jhkb/0ppk/96nc//fqXX/x4xO/6dkFP+QSQD/llEA/5xXAP+USgD/yaOA///////38uv/qG05/8ijdv//////8efb/6ZpLPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/zIxO/9yxh///////////////////////7dbA/8iEQf/Sm2X/0Zlj/9ScZv/eqHf/2KJv/7yAQf+XTgD/iToA/5lSAP+JNgD/yKFv/611LP+HNQD/jT8A/8qmeP+kZRT/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/Pk1n/1J5q//78+//////////////////+/fv/1aFv/8iEQv/Tm2b/0ppl/9GZY//Wn2z/1pZc/9eldf/Bl2b/kUcA/4w9AP+OQAD/lUwA/59eAP+cWQD/jT8A/5ZOAP+eXADy////AP///wD///8A////ANKaZPLSmmT/0ppk/9KZY//KiEn/8d/P///////////////////////47+f/05tm/8iCP//KiEj/yohJ/8eCP//RmGH//vfy///////n1sP/rXQ7/4k4AP+TTAD/nVoA/5xYAP+cVwD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/0ptl/8uLTf/aq37////////////////////////////+/fz/6c2y/961jv/etY7/6Myx//78+v//////////////////////3MWv/5xXD/+ORAD/mFQA/51ZAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmmT/0ppk/8mFRP/s1b//////////////////////////////////////////////////////////////////////////////+PD/0JFU/7NzMv+WUQD/kUsA/5tXAP+dWQDy////AP///wD///8A////ANKaZP/SmmT/0ppk/9KaZP/Sm2X/z5NZ/8yMT//z5NX/////////////////////////////////////////////////////////////////9Ofa/8yNUP/UmGH/36p5/8yTWv+qaSD/kksA/5ROAPz///8A////AP///wD///8A0ppk5NKaZP/SmmT/0ppk/9KaZP/TnGf/zY9T/82OUv/t1sD//////////////////////////////////////////////////////+7Yw//OkFX/zI5R/9OcZ//SmmP/26V0/9ymdf/BhUf/ol8R6P///wD///8A////AP///wDSmmQ80ppk9tKaZP/SmmT/0ppk/9KaZP/TnGj/zpFW/8qJSv/dson/8uHS//////////////////////////////////Lj0//etIv/y4lL/86QVf/TnGj/0ppk/9KaZP/RmWP/05xn/9ymdfjUnWdC////AP///wD///8A////ANKaZADSmmQc0ppkotKaZP/SmmT/0ppk/9KaZP/Tm2b/0Zli/8qJSf/NjlH/16Z3/+G8mP/myKr/5siq/+G8mP/Xp3f/zY5S/8qISf/RmGH/05tm/9KaZP/SmmT/0ppk/9KaZP/SmmSm0pljINWdaQD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkQtKaZMrSmmT/0ppk/9KaZP/SmmT/0ptl/9GYYf/Nj1P/y4lL/8qISP/KiEj/y4lK/82PU//RmGH/0ptl/9KaZP/SmmT/0ppk/9KaZP/SmmTO0ppkRtKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZGzSmmTu0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmTw0ppkcNKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZBLSmmSQ0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppklNKaZBTSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQy0ppkutKaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppkvtKaZDbSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkXNKaZODSmmT/0ppk/9KaZP/SmmT/0ppk5NKaZGDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkBtKaZIbSmmTo0ppk6tKaZIrSmmQK0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP/8P///+B///+AH//+AAf//AAD//AAAP/AAAA/gAAAHwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA+AAAAfwAAAP/AAAP/8AAP//gAH//+AH///4H////D//" rel="icon" />
  <!--[if lt IE 9]>
    <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
  <![endif]-->
  
</head>
<body>
<div class="wrapper">
<header id="title-block-header">
<h1 class="title" style="text-align:center">Guidelines For <code>snake_case</code> Concept Naming</h1>

<table style="border:none;float:right">
  <tr>
    <td>Document #: </td>
    <td>P1851R0</td>
  </tr>
  <tr>
    <td>Date: </td>
    <td>2019-07-28</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Project: </td>
    <td>Programming Language C++<br>
      Library Evolution Working Group<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to: </td>
    <td>
      Jonathan Müller<br>&lt;<a href="mailto:jonathan.mueller@foonathan.net" class="email">jonathan.mueller@foonathan.net</a>&gt;<br>
    </td>
  </tr>
</table>

</header>
<div style="clear:both">
<h1 id="introduction"><span class="header-section-number">1</span> Introduction<a href="#introduction" class="self-link"></a></h1>
<p>In Cologne, <span class="citation" data-cites="P1754R1">[<a href="#ref-P1754R1" role="doc-biblioref">P1754R1</a>]</span> was adopted changing the naming convention for concepts from <code>PascalCase</code> to <code>snake_case</code>. While this arguably creates a more consistent standard library naming style, it also opens up the possibility for naming conflicts between concepts and other entities. To tackle this problem, LEWG created guidelines for naming concepts to minimize name conflicts. This paper refines them and proposes to add them to the upcoming LEWG policy standing document (see <span class="citation" data-cites="P1655R0">[<a href="#ref-P1655R0" role="doc-biblioref">P1655R0</a>]</span>).</p>
<p>Note: throughout this paper, I will use <code>ConceptName</code> to refer to the theoretical “concept” without prescribing a given name, and <code>concept_name</code> to refer to the concrete C++ <code>concept</code> with a name following the strategies.</p>
<h1 id="cologne-renaming-guidelines"><span class="header-section-number">2</span> Cologne Renaming Guidelines<a href="#cologne-renaming-guidelines" class="self-link"></a></h1>
<p>In Cologne, LEWG used the following guidelines for renaming all the concepts:</p>
<ol type="1">
<li>Concept names are all <code>snake_case</code>.</li>
<li>Concept names should not have any consistent prefix/suffix to disambiguate (such as <code>_type</code> or <code>_c</code>).</li>
<li>Concepts are renamed according to their category:
<ul>
<li><em>Abstractions</em>, which are high-level concepts like <code>ForwardIterator</code>, <code>View</code>, or <code>Sentinel</code>, are renamed using very generic nouns.</li>
<li><em>Capabilities</em>, which are single requirement concepts like <code>Swappable</code> or <code>Constructible</code>, are named to adjectives <code>-ible</code> or <code>-able</code>.</li>
<li>Other misc. predicate concepts like <code>Same</code> or <code>CommonType</code> are given names ending in prepositions.</li>
</ul></li>
</ol>
<p>The naming of abstractions (generic nouns) combined with guidelines 1. and 2. allowed for name conflicts. There were two of those: <code>Iterator</code> (there is a deprecated class <code>std::iterator</code>) and <code>View</code> (there is a namespace <code>std::view</code>). They were resolved using creativity (<code>Iterator</code> is now <code>input_or_output_iterator</code>) and renaming of the conflicts (namespace is now <code>std::views</code>).</p>
<p>The naming of capabilities and the misc. predicates is free from name conflicts as no entity in the standard library uses such names. As the majority of current standard library concepts fall into this category, the naming guidelines are good at preventing name conflicts.</p>
<h1 id="problems-with-the-cologne-renaming-guidelines"><span class="header-section-number">3</span> Problems With The Cologne Renaming Guidelines<a href="#problems-with-the-cologne-renaming-guidelines" class="self-link"></a></h1>
<p>However, those guidelines are not quite perfect given that they were quickly developed during the meeting.</p>
<h2 id="problem-1-misc.-predicate-category-and-prepositions"><span class="header-section-number">3.1</span> Problem 1: Misc. Predicate Category And Prepositions<a href="#problem-1-misc.-predicate-category-and-prepositions" class="self-link"></a></h2>
<p>The guideline that misc. predicates should end in a preposition has two problems. First, the “misc. predicate” category is (by design) not well-defined, and second, there are other concepts ending in a preposition like <code>sentinel_for</code>. It would be nice if there was a more general guideline that covers those cases as well.</p>
<p>There is, and it has to do with the way the concepts are used. In general, a concept can be used in two places:</p>
<ol type="1">
<li><p>In a <code>requires</code> or concept definition:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb1-2"><a href="#cb1-2"></a>  <span class="kw">requires</span> swappable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="cb1-3"><a href="#cb1-3"></a><span class="dt">void</span> foo<span class="op">(</span>T<span class="op">)</span>;</span>
<span id="cb1-4"><a href="#cb1-4"></a></span>
<span id="cb1-5"><a href="#cb1-5"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb1-6"><a href="#cb1-6"></a> <span class="kw">requires</span> same_as<span class="op">&lt;</span>T, <span class="dt">int</span><span class="op">&gt;</span></span>
<span id="cb1-7"><a href="#cb1-7"></a><span class="dt">void</span> bar<span class="op">(</span>T<span class="op">)</span>;</span></code></pre></div></li>
<li><p>As a type constraint:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1"></a><span class="kw">template</span> <span class="op">&lt;</span>swappable T<span class="op">&gt;</span></span>
<span id="cb2-2"><a href="#cb2-2"></a><span class="dt">void</span> foo<span class="op">(</span>T<span class="op">)</span>;</span>
<span id="cb2-3"><a href="#cb2-3"></a></span>
<span id="cb2-4"><a href="#cb2-4"></a><span class="kw">template</span> <span class="op">&lt;</span>same_as<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> T<span class="op">&gt;</span></span>
<span id="cb2-5"><a href="#cb2-5"></a><span class="dt">void</span> foo<span class="op">(</span>T<span class="op">)</span>;</span></code></pre></div></li>
</ol>
<p>Note that if the concept is used as a type constraint, the first parameter is omitted. For concepts that only have a single parameter, no angle brackets after the name are necessary at all. Also note that <code>requires same_as&lt;T, int&gt;</code> reads a bit weird, whereas <code>same_as&lt;int&gt; T</code> is completely natural. From that, the following guideline follows:</p>
<blockquote>
<p>If a concept is mainly used as a type constraint and requires more than one argument, the name should end in a preposition. If a concept is often used in <code>requires</code> or in the definition of another concept, the name should not end in a preposition.</p>
</blockquote>
<p>This explains all the “misc. predicate” names and also <code>sentinel_for</code> and also prevents name conflicts. But it is not completely followed by the current concept names; these ones have multiple required arguments and do not end in a preposition:</p>
<ul>
<li><code>(regular_)invocable&lt;F, Args...&gt;</code></li>
<li><code>predicate&lt;F, Args...&gt;</code></li>
<li><code>relation&lt;R, T, U&gt;</code></li>
<li><code>strict_weak_order&lt;R, T, U&gt;</code></li>
<li><code>writable&lt;Out, T&gt;</code></li>
<li><code>output_iterator&lt;I, T&gt;</code></li>
<li><code>indirectly_(regular_)unary_invocable&lt;F, I&gt;</code></li>
<li><code>indirect_unary_predicate&lt;F, I&gt;</code></li>
<li><code>indirect_relation&lt;F, I1&gt;</code></li>
<li><code>indirect_streak_weak_order&lt;F, I1&gt;</code></li>
<li><code>indirectly_moveable(_storeable)&lt;In, Out&gt;</code></li>
<li><code>indirectly_copyable(_storeable)&lt;In, Out&gt;</code></li>
<li><code>indirectly_comparable&lt;I1, I2, R&gt;</code></li>
<li><code>mergeable&lt;I1, I2, Out&gt;</code></li>
</ul>
<p>Of those concepts, <code>mergeable</code> is always used as <code>requires</code> and not as type constraint, but I do not know about the other ones. If this revised guidelines is adopted, the ones that are mainly used as type constraints could still be renamed to follow it. But the guideline could simply be that - a guideline, and those concepts reasonable exceptions of the guideline.</p>
<h3 id="problem-2-how-to-deal-with-abstraction-conflicts"><span class="header-section-number">3.1.1</span> Problem 2: How to Deal with Abstraction Conflicts?<a href="#problem-2-how-to-deal-with-abstraction-conflicts" class="self-link"></a></h3>
<p>Name conflicts between abstraction concepts and types is still a possibility. While there are currently not many of them, this can change as new abstractions are developed (e.g. executors).</p>
<p>Solving the conflicts depends on the situation:</p>
<ol type="1">
<li><p>A type-erased wrapper is added for a concept.</p>
<p>Then the existing LEWG guideline of using an <code>any_</code> prefix applies.</p></li>
<li><p>A new type is added as an implementation of an existing concept.</p>
<p>Then the name of the type should encode what is being special about the type compared to the generic concept.</p></li>
<li><p>A concept is added together with a default implementation for the majority of use cases.</p>
<p>Even though the majority of use case use the type as the default, the existence of a concept still encourages generic programming: Functions should either be templated or using type erasure. So the name of the concept should be the better and shorter name, as it will be used in the actual applications.</p>
<p>If the default has special properties, they should be encoded in the name like in the case above. If its only defining property is that it is the default, the name can be just that - <code>default_&lt;concept&gt;</code>.</p>
<p>For example, suppose <code>std::allocator</code> did not exist and it is to be added together with an <code>Allocator</code> concept. As code will be written in terms of the concept, the name of the concept should be <code>std::allocator</code>. The default type can be <code>std::new_allocator</code> (naming it after the special property) or <code>std::default_allocator</code> (as it is the default).</p></li>
<li><p>A concept is created to allow replacement of a fixed type in a function.</p>
<p>For example, suppose there is code that uses <code>std::string</code> which should be generalized into a concept. Then the ideal name <code>string</code> is already taken, so the concept needs a different name.</p>
<p>However, this is the wrong approach for designing concepts: the concept requirements should be gathered from the function, not from the type. Doing that will usually also lead to a better name that covers the exact set of requirements.</p></li>
<li><p>An existing named requirement is conceptified, like creating a concept for the <code>Allocator</code> requirement.</p>
<p>With the new naming scheme, this simply cannot be done in all situations, as the good name is often taken (there is the <code>std::allocator</code> type).</p></li>
</ol>
<p>There is no good solution for 4. and 5., but 4. is a bad idea and we can live in a world where we do not do 5. So with the rules for type-erased wrappers and <code>default_&lt;concept&gt;</code>, as well as the guideline that the concept name is the better and shorter name, there is a guideline that handles conflicts.</p>
<h1 id="proposal"><span class="header-section-number">4</span> Proposal<a href="#proposal" class="self-link"></a></h1>
<blockquote>
<p>Note that it is quite difficult to provide wording changes to a document that does not exist yet. I have no idea how the style of the document is supposed to be.</p>
</blockquote>
<p>Add a new section to the upcoming policy document “Naming of Concepts”:</p>
<div class="add" style="color: #006e28">
<p><span class="marginalizedparent"><a class="marginalized">1</a></span> Concept names are:</p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">(1.1)</a></span> <code>snake_case</code>,</li>
<li><span class="marginalizedparent"><a class="marginalized">(1.2)</a></span> without a suffix or prefix designating them as concepts,</li>
<li><span class="marginalizedparent"><a class="marginalized">(1.3)</a></span> and following the name of a type trait (without the <code>is_</code> prefix) if applicable.</li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span> If a concept is mainly used as a type constraint and has multiple required arguments, the name should end in a suitable preposition. If however the concept is often used in a <code>requires</code> clause or concept definition, it should not end in a preposition.</p>
<p>For example, <code>swappable</code> requires only a single argument, so it does not end in a preposition, but <code>swappable_with</code> requires an additional argument, so it does. Likewise, it is <code>same_as&lt;int&gt; T</code>, <code>constructible_with&lt;args&gt; T</code> and <code>sentinel_for&lt;iterator&gt; S</code>. But <code>mergeable</code>, which also requires multiple arguments, does not have a preposition as it is often used in a <code>requires</code> clause.</p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span> The name of a type-erased wrapper of a concept is <code>any_&lt;concept&gt;</code>.</p>
<p>For example, it is <code>any_invocable</code> instead of <code>unique_function</code>.</p>
</div>
<p>Add a subsection of “Naming of Concepts”, “Naming of Capability Concepts”:</p>
<div class="add" style="color: #006e28">
<p><span class="marginalizedparent"><a class="marginalized">1</a></span> A capability is a concept that has a single requirement, usually a (member) function.</p>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span> The name of a capability concept is an adjective describing the requirement.</p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span> If the capability is a function, the concept name is formed by taken the function name and using the <code>-ible</code> or <code>-able</code> suffix.</p>
<p>For example, <code>swappable</code> requires <code>swap()</code>; <code>copy_constructible</code> requires a copy constructor.</p>
</div>
<p>Add a subsection of “Naming of Concepts”, “Naming of Abstraction Concepts”:</p>
<div class="add" style="color: #006e28">
<p><span class="marginalizedparent"><a class="marginalized">1</a></span> An abstraction is a high-level concept with often multiple requirements or the root of a concept hierarchy.</p>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span> The name of an abstraction concept is a noun introducing new terminology; unlike a capability it does not describe the requirement verbatim.</p>
<p>For example, it is <code>forward_iterator</code> not <code>has_increment_equality_and_dereference</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span> The name of an abstraction concept is more general than the name of the types satisfying it.</p>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span> If there is a type whose only purpose is to provide a default implementation of an abstraction concept, it can be named <code>default_&lt;concept&gt;</code>.</p>
</div>
<h1 id="references"><span class="header-section-number">5</span> References<a href="#references" class="self-link"></a></h1>

<div id="refs" role="doc-bibliography">
<div id="ref-P1655R0">
<p>[P1655R0] Zach Laine. 2019. LEWG Omnibus Design Policy Paper. <br />
<a href="https://wg21.link/p1655r0">https://wg21.link/p1655r0</a></p>
</div>
<div id="ref-P1754R1">
<p>[P1754R1] Herb Sutter, Casey Carter, Gabriel Dos Reis, Eric Niebler, Bjarne Stroustrup, Andrew Sutton, Ville Voutilainen. 2019. Rename concepts to standard_case for C++20, while we still can. <br />
<a href="https://wg21.link/p1754r1">https://wg21.link/p1754r1</a></p>
</div>
</div>
</div>
</div>
</body>
</html>
