<!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="2024-09-16" />
  <title>Syntax for Reflection</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%;}
      div.csl-block{margin-left: 1.5em;}
      ul.task-list{list-style: none;}
      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; }
      .sourceCode { overflow: visible; }
      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;
text-align: justify;
}
@media screen and (max-width: 30em) {
body {
margin: 1.5em;
}
}
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; }
</style>
  <style type="text/css">a {
color : #4183C4;
text-decoration: underline;
}
a.marginalized {
text-decoration: none;
}
a.self-link {
text-decoration: none;
}
h1#toctitle {
border-bottom: 1px solid #cccccc;
}
#TOC li {
margin-top: 1px;
margin-bottom: 1px;
}
#TOC ul>li:before { display: none; }
h3.subtitle { margin-top: -15px; }
h1:target { background-color: transparent; }
h2:target { background-color: transparent; }
h3:target { background-color: transparent; }
h4:target { background-color: transparent; }
h5:target { background-color: transparent; }
h6:target { background-color: transparent; }
code span.co { font-family: monospace; }
table tr {
background-color: white;
}
table tr:nth-child(2n) {
background-color: #f6f8fa;
}
#title-block-header > table tr:nth-child(2n) {
background-color: white;
}
td > div.sourceCode {
background-color: inherit;
}
table {
border-collapse: collapse;
}
table td, table th {
border: 1px solid #cccccc;
}
table th {
border-bottom: 1px solid black;
text-align: center;
}
table tr:first-child th {
border-top: 0;
}
table tr:last-child td {
border-bottom: 0;
}
table tr td:first-child,
table tr th:first-child {
border-left: 0;
}
table tr td:last-child,
table tr th:last-child {
border-right: 0;
}
table tbody tr:first-child td {
border-top: 1px solid black;
}
#title-block-header td { border: 0; }
@media all {
body {
margin: 2em;
}
}
@media screen and (min-width: 480px) {
body {
margin: 5em;
}
}
#refs code{padding-left: 0px; text-indent: 0px;}
:root {
--diff-ins: #C9FBC9;
--diff-strongins: #acf2bd;
--diff-del: #FFC8EB;
--diff-strongdel: #ff8888;
}
span.diffins {
background-color: var(--diff-strongins);
}
span.diffdel {
background-color: var(--diff-strongdel);
}
div.rm { text-decoration: line-through; }
div.rm code.sourceCode { text-decoration: line-through; }
div.addu, span.addu {
color: #006e28;
background-color: var(--diff-ins);
}

div.rm pre, div.add pre { background-color: #f6f8fa; }
div.addu pre { background-color: var(--diff-ins); }
div.add, div.add pre { background-color: var(--diff-ins); }
div.addu blockquote {
border-left: 4px solid #00a000;
padding: 0 15px;
color: #006e28;
text-decoration: none;
}
div.addu blockquote code.sourceCode { text-decoration: none; }
div.addu blockquote pre { text-decoration: none; }
div.addu blockquote pre code { text-decoration: none; }
div.quote {
border-left: 7px solid #ccc;
background: #f9f9f9;
margin: 1.5em 10px;
padding-left: 20px;
}
code.diff span.va { color: #000000; background-color: var(--diff-ins); }
code.diff span.st { color: #000000; background-color: var(--diff-del); }
div.std blockquote { color: #000000; background-color: #F1F1F1;
border: 1px solid #D1D1D1;
padding-left: 0.5em; padding-right: 0.5em; }
div.std.ins blockquote {
color: #000000; background-color: #C8FFC8;
border: 1px solid #B3EBB3;
}
div.ins > div.example {
color: #000000; background-color: #C8FFC8;
border: 1px solid #B3EBB3;
}
div.std div.sourceCode { background-color: inherit; margin-left: 1em; }
div.std blockquote del { text-decoration: line-through;
color: #000000; background-color: var(--diff-del);
border: none; }
code del { border: 1px solid #ECB3C7; }
span.orange {
background-color: #ffa500;
}
span.yellow {
background-color: #ffff00;
}</style>
  <link href="data:image/x-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">Syntax for Reflection</h1>
<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P3381R0 <a href="https://wg21.link/P3381">[Latest]</a> <a href="https://wg21.link/P3381/status">[Status]</a></td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2024-09-16</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Project:</td>
    <td>Programming Language C++</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Audience:</td>
    <td>
      EWG<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      Wyatt Childers<br>&lt;<a href="mailto:wcc@edg.com" class="email">wcc@edg.com</a>&gt;<br>
      Peter Dimov<br>&lt;<a href="mailto:pdimov@gmail.com" class="email">pdimov@gmail.com</a>&gt;<br>
      Dan Katz<br>&lt;<a href="mailto:dkatz85@bloomberg.net" class="email">dkatz85@bloomberg.net</a>&gt;<br>
      Barry Revzin<br>&lt;<a href="mailto:barry.revzin@gmail.com" class="email">barry.revzin@gmail.com</a>&gt;<br>
      Andrew Sutton<br>&lt;<a href="mailto:andrew.n.sutton@gmail.com" class="email">andrew.n.sutton@gmail.com</a>&gt;<br>
      Faisal Vali<br>&lt;<a href="mailto:faisalv@gmail.com" class="email">faisalv@gmail.com</a>&gt;<br>
      Daveed Vandevoorde<br>&lt;<a href="mailto:daveed@edg.com" class="email">daveed@edg.com</a>&gt;<br>
    </td>
  </tr>
</table>
</header>
<div style="clear:both">
<div id="TOC" role="doc-toc">
<h1 id="toctitle">Contents</h1>
<ul>
<li><a href="#introduction" id="toc-introduction"><span class="toc-section-number">1</span> Introduction<span></span></a></li>
<li><a href="#single-character" id="toc-single-character"><span class="toc-section-number">2</span> Single
Character<span></span></a></li>
<li><a href="#multiple-characters" id="toc-multiple-characters"><span class="toc-section-number">3</span> Multiple
Characters<span></span></a></li>
<li><a href="#proposal" id="toc-proposal"><span class="toc-section-number">4</span> Proposal<span></span></a></li>
<li><a href="#why-not-a-keyword" id="toc-why-not-a-keyword"><span class="toc-section-number">5</span> Why Not A
Keyword?<span></span></a></li>
<li><a href="#bibliography" id="toc-bibliography"><span class="toc-section-number">6</span> References<span></span></a></li>
</ul>
</div>
<h1 data-number="1" style="border-bottom:1px solid #cccccc" id="introduction"><span class="header-section-number">1</span>
Introduction<a href="#introduction" class="self-link"></a></h1>
<p><span class="citation" data-cites="P1240R2">[<a href="https://wg21.link/p1240r2" role="doc-biblioref">P1240R2</a>]</span> originally proposed
<code class="sourceCode cpp"><span class="op">^</span></code> as the
reflection operator, which was also what <span class="citation" data-cites="P2996R5">[<a href="https://wg21.link/p2996r5" role="doc-biblioref">P2996R5</a>]</span> proposed and what both existing
implementations (EDG and Clang) used. We’ve grown to really like the
syntax: it’s terse and stands out visually.</p>
<p>Unfortunately, it turns out that
<code class="sourceCode cpp"><span class="op">^</span></code> is not a
viable choice for reflection for C++26, due to the collision with the
block extension used by Clang and commonly used in Objective-C++.</p>
<p>It was pointed out that the syntax:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><em>type-id</em><span class="op">(^</span>ident<span class="op">)()</span>;</span></code></pre></div>
</blockquote>
</div>
<p>is ambiguous. This can be parsed as both:</p>
<ul>
<li>a variable named <code class="sourceCode cpp">ident</code> holding a
block returning <code class="sourceCode cpp"><em>type-id</em></code> and
taking no arguments, and</li>
<li>a cast of <code class="sourceCode cpp">std<span class="op">::</span>meta<span class="op">::</span>info</code>
(a reflection of <code class="sourceCode cpp">ident</code>) into a
<code class="sourceCode cpp"><em>type-id</em></code> and then a call of
<code class="sourceCode cpp"><span class="kw">operator</span><span class="op">()</span></code>.</li>
</ul>
<p>This gets worse with the <span class="citation" data-cites="P3294R1">[<a href="https://wg21.link/p3294r1" role="doc-biblioref">P3294R1</a>]</span> usage of <code class="sourceCode cpp"><span class="op">^{</span> <span class="op">...</span> <span class="op">}</span></code>
as a token sequence. This sequence is completely ambiguous:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> A <span class="op">=</span> <span class="op">^{</span> f<span class="op">()</span>; <span class="op">}</span>;</span></code></pre></div>
</blockquote>
</div>
<p>As such, the goal of this paper is to come up with new syntax for the
reflection operator.</p>
<p>There are three approaches that we can go with this:</p>
<ul>
<li>a keyword,</li>
<li><a href="#single-character">a single character</a>, or</li>
<li><a href="#multiple-characters">multiple characters</a>.</li>
</ul>
<p>The original reflection design did use a keyword — <code class="sourceCode cpp">reflexpr<span class="op">(</span>e<span class="op">)</span></code>.
But that is far too verbose, which is why the design had changed to
<code class="sourceCode cpp"><span class="op">^</span></code> to begin
with. We would strongly prefer not to go back down that road.</p>
<p>That leaves either of the other choices.</p>
<h1 data-number="2" style="border-bottom:1px solid #cccccc" id="single-character"><span class="header-section-number">2</span>
Single Character<a href="#single-character" class="self-link"></a></h1>
<p>There are not too many single character options available to us,
presuming we want to stick with the characters that are easy to type and
not just start perusing the available Unicode characters
(<code class="sourceCode cpp">↑</code> is available after all). It also
makes life much easier if we do not need to add new basic source
characters (which a character like <code class="sourceCode cpp">↑</code>
would require).</p>
<p>Ignoring those characters that are already unary operators in C++ and
the quotation marks, these are all the options available to us and what
we think of them:</p>
<table>
<tr>
<th>
Token
</th>
<th>
Notes
</th>
<th>
Disposition
</th>
</tr>
<tr>
<td>
<code><span class="op">#e</span></code>
</td>
<td>
<p>The problem with <code><span class="op">#e</span></code> is that
precludes use in existing C macros. This code already has meaning:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#define MACRO</span><span class="op">(</span>x<span class="op">)</span><span class="pp"> </span>do_something_with<span class="op">(</span><span class="pp">#</span>x<span class="op">)</span></span></code></pre></div>
</blockquote>
</div>
And that meaning is not taking the reflection of
<code class="sourceCode cpp">x</code> and cannot change.
</td>
<td>
❌
</td>
</tr>
<tr>
<td>
<code><span class="op">$e</span></code>
</td>
<td>
<p>Syntactically <code><span class="op">$e</span></code> is pretty nice
and doesn’t conflict with anything else in C++ since we only just added
it to the basic character set.</p>
Unfortunately, compilers support the use of
<code><span class="op">$</span></code> in identifiers as an extension,
so the simplest usage of <code><span class="op">$T</span></code> as the
reflection of the type <code class="sourceCode cpp">T</code> is already
ambiguous with the use an identifier that happens to start with a dollar
sign.
</td>
<td>
❌
</td>
</tr>
<tr>
<td>
<code class="sourceCode cpp"><span class="op">%</span>e</code>
</td>
<td>
<p>We were initially fairly excited about the use of
<code class="sourceCode cpp"><span class="op">%</span>e</code>. Like
<code class="sourceCode cpp"><span class="op">^</span>e</code>, this
token is already used as a binary operator — but not an especially
common one, so it seemed potentially viable as a reflection
operator.</p>
<p>Unfortunately, one way to use a reflection would be to pass it
directly as the first template argument:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>C<span class="op">&lt;%</span>T<span class="op">&gt;</span> c;</span></code></pre></div>
</blockquote>
</div>
And it turns out that
<code class="sourceCode cpp"><span class="op">&lt;%</span></code> is a
digraph, for
<code class="sourceCode cpp"><span class="op">{</span></code>. This
doesn’t make it a complete non-starter, since this <em>is</em> something
that can be worked around with use of parens or a space. But it’s not
great!
</td>
<td>
😞
</td>
</tr>
<tr>
<td>
<code class="sourceCode cpp">,e</code>
</td>
<td>
No.
</td>
<td>
❌
</td>
</tr>
<tr>
<td>
<code class="sourceCode cpp"><span class="op">/</span>e</code>
</td>
<td>
<p>The forward slash is the first character we come to that seems like a
viable option. Here is some usage of it:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb5"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="kw">auto</span> r <span class="op">=</span> <span class="op">/</span><span class="dt">int</span>;</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="cf">for</span> <span class="op">(</span><span class="kw">constexpr</span> <span class="kw">auto</span> e <span class="op">:</span> enumerators_of<span class="op">(/</span>E<span class="op">))</span> ;</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>fn<span class="op">&lt;/</span>R<span class="op">&gt;()</span>;</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a><span class="op">[:</span> <span class="op">/</span><span class="dt">int</span> <span class="op">:]</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a><span class="op">[:/</span><span class="dt">int</span><span class="op">:]</span></span></code></pre></div>
</blockquote>
</div>
<p>Use of <code class="sourceCode cpp"><span class="op">/</span></code>
also offers nice symmetry with the use of
<code class="sourceCode cpp">\</code> for interpolation in code
injection (or perhaps arguably the wrong kind of symmetry, since the
splice syntax we’re not proposing to change).</p>
The downside of
<code class="sourceCode cpp"><span class="op">/</span></code> is that
it’s pretty close to opening a comment. Now, we don’t intend on
<code class="sourceCode cpp"><span class="co">//e</span></code> to be
valid syntax — reflecting an expression would require parentheses, so it
would have to be <code class="sourceCode cpp"><span class="op">/(/</span>e<span class="op">)</span></code>.
Ditto <code class="sourceCode cpp"><span class="co">/*e</span></code> is
not valid, would have to be <code class="sourceCode cpp"><span class="op">/(*</span>e<span class="op">)</span></code>.
Are those too close to comments?
</td>
<td>
✅
</td>
</tr>
<tr>
<td>
<code class="sourceCode cpp"><span class="op">:</span>e</code>
</td>
<td>
<p>Similar to the problems we ran into with <code class="sourceCode cpp">C<span class="op">&lt;%</span>T<span class="op">&gt;</span></code>
not working because
<code class="sourceCode cpp"><span class="op">&lt;%</span></code> is a
digraph for
<code class="sourceCode cpp"><span class="op">{</span></code>, <code class="sourceCode cpp">C<span class="op">&lt;:</span>T<span class="op">&gt;</span></code>
would also not work because
<code class="sourceCode cpp"><span class="op">&lt;:</span></code> is a
digraph for
<code class="sourceCode cpp"><span class="op">[</span></code>. If we’re
going to pick a token that has digraph problems,
<code class="sourceCode cpp"><span class="op">%</span></code> is
definitely the better option.</p>
</td>
<td>
❌
</td>
</tr>
<tr>
<td>
<code class="sourceCode cpp"><span class="op">=</span>e</code>
</td>
<td>
While <code class="sourceCode cpp"><span class="op">^</span></code> and
<code class="sourceCode cpp"><span class="op">%</span></code> already
exist as binary operators, they are fairly rare.
<code class="sourceCode cpp"><span class="op">=</span></code> just seems
way too common to be viable to overload to mean reflection
</td>
<td>
❌
</td>
<tr>
<td>
<code class="sourceCode cpp"><span class="op">?</span>e</code>
</td>
<td>
<p>While <code class="sourceCode cpp"><span class="op">?</span></code>
already exists in the language today, we do not believe that using
<code class="sourceCode cpp"><span class="op">?</span>e</code> would be
ambiguous with the conditional operator. We could even come up with a
story for why the question mark — we are asking what an entity is, and
getting a reflection back to answer the question. It’s just not our
favorite, but it is potentially viable.</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb6"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="kw">auto</span> r <span class="op">=</span> <span class="op">?</span><span class="dt">int</span>;</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="cf">for</span> <span class="op">(</span><span class="kw">constexpr</span> <span class="kw">auto</span> e <span class="op">:</span> enumerators_of<span class="op">(?</span>E<span class="op">))</span> ;</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>fn<span class="op">&lt;?</span>R<span class="op">&gt;()</span>;</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a><span class="op">[:</span> <span class="op">?</span><span class="dt">int</span> <span class="op">:]</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a><span class="op">[:?</span><span class="dt">int</span><span class="op">:]</span></span></code></pre></div>
</blockquote>
</div>
<p>The downside of
<code class="sourceCode cpp"><span class="op">?</span></code> is that
this token tends to be strongly associated with predicates across
programming languages. In C++ we just have the conditional operator, but
in other languages we have null coalescing, optional chaining, and error
propagation all spelled with
<code class="sourceCode cpp"><span class="op">?</span></code> - plus for
some languages it’s convention to spell predicates as <code class="sourceCode cpp">v<span class="op">.</span>empty<span class="op">?</span></code>,
all of which has nothing to do with reflection.</p>
Pattern Matching (<span class="citation" data-cites="P2688R1">[<a href="https://wg21.link/p2688r1" role="doc-biblioref">P2688R1</a>]</span>) additionally proposes using
<code class="sourceCode cpp"><span class="op">?</span> <em>pattern</em></code>
as the optional pattern, which would conflict with the use of
<code class="sourceCode cpp"><span class="op">?</span></code> as the
reflection operator. So while it’s technically available for use today,
The optional pattern strikes us as a better use of unary
<code class="sourceCode cpp"><span class="op">?</span></code> than
reflection.
</td>
<td>
🤷
</td>
</tr>
<tr>
<td>
<code class="sourceCode cpp"><span class="op">@</span>e</code>
</td>
<td>
<p><code class="sourceCode cpp"><span class="op">@</span></code> is
already used as an extension in Objective-C.</p>
For many potential identifiers, there is already concrete meaning
(<code class="sourceCode cpp"><span class="op">@</span>property</code>,
<code class="sourceCode cpp"><span class="op">@</span>dynamic</code>,
<code class="sourceCode cpp"><span class="op">@</span>optional</code>,
etc.). There is no way to escape this either, since <code class="sourceCode cpp"><span class="op">@(</span>e<span class="op">)</span></code>
is a boxed expression, and <code class="sourceCode cpp"><span class="op">@[</span>e<span class="op">]</span></code>
and <code class="sourceCode cpp"><span class="op">@{</span>e<span class="op">}</span></code>
are container literals.
</td>
<td>
❌
</td>
</tr>
<tr>
<td>
<code class="sourceCode cpp">\e</code>
</td>
<td>
<p>Similar to
<code class="sourceCode cpp"><span class="op">/</span>e</code>, this is
viable. But we prefer it as an interpolator (for which there is prior
art), so we’d rather not use it here.</p>
Additionally, this runs into issues with UCNs:
<code class="sourceCode cpp">\u0</code> is parsed as a UCN, not a
reflection of <code class="sourceCode cpp">u0</code>.
</td>
<td>
❌
</td>
</tr>
<tr>
<td>
`<code class="sourceCode cpp">e</code>
</td>
<td>
<p>The third character recently added to the basic character set (after
<code class="sourceCode cpp"><span class="er">$</span></code> and
<code class="sourceCode cpp"><span class="op">@</span></code>) is the
backtick (or GRAVE ACCENT). The backtick has the advantage that it’s
pretty small, even smaller than
<code class="sourceCode cpp"><span class="op">^</span></code>.</p>
But it has the disadvantage that backtick is used by Markdown everywhere
inline code blocks, and not all Markdown implementations properly give
you mechanisms to escape it. While not necessarily a show-stopper, we
also just don’t think it’s good enough to reasonably pursue.
</td>
<td>
❌
</td>
</tr>
<tr>
<td>
<code class="sourceCode cpp"><span class="op">|</span>e</code>
</td>
<td>
<p>The last available single token, this one is also viable,
unambiguous, and not a part of a digraph:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="kw">auto</span> r <span class="op">=</span> <span class="op">|</span><span class="dt">int</span>;</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="cf">for</span> <span class="op">(</span><span class="kw">constexpr</span> <span class="kw">auto</span> e <span class="op">:</span> enumerators_of<span class="op">(|</span>E<span class="op">))</span> ;</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>fn<span class="op">&lt;|</span>R<span class="op">&gt;()</span>;</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a><span class="op">[:</span> <span class="op">|</span><span class="dt">int</span> <span class="op">:]</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a><span class="op">[:|</span><span class="dt">int</span><span class="op">:]</span></span></code></pre></div>
</blockquote>
</div>
<p>One potential issue with
<code class="sourceCode cpp"><span class="op">|</span></code> is when
using multiple reflections in a single line, for instance:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb8"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="op">(|</span>T <span class="op">==</span> <span class="op">|</span>U<span class="op">)</span></span></code></pre></div>
</blockquote>
</div>
While not ambiguous to the compiler, those with math backgrounds might
want to see <code class="sourceCode cpp"><span class="op">|</span>T <span class="op">==</span> <span class="op">|</span></code>
as a magnitude of some sort.
</td>
<td>
✅
</td>
</tr>
</table>
<p>To summarize, there are only a few single tokens that we feel are
completely viable:</p>
<ul>
<li><code class="sourceCode cpp"><span class="op">/</span>e</code></li>
<li><code class="sourceCode cpp"><span class="op">|</span>e</code></li>
<li><code class="sourceCode cpp"><span class="op">?</span>e</code> is
viable today, but would compete with pattern matching</li>
<li><code class="sourceCode cpp"><span class="op">%</span>e</code> if
we’re open to people struggling with digraphs</li>
</ul>
<h1 data-number="3" style="border-bottom:1px solid #cccccc" id="multiple-characters"><span class="header-section-number">3</span>
Multiple Characters<a href="#multiple-characters" class="self-link"></a></h1>
<p>Once we extend our search space to multiple characters, there are an
infinite amount of possibilities to explorer — it’s easy enough to come
up with some sequence of tokens that is not a digraph and isn’t
ambiguous to parse.</p>
<p>For help with this investigation, Wyatt Childers put together a <a href="https://syntax-tester.haxing.ninja/?op=%5E%5B&amp;sop=%5D">simple
utility</a> to test various alternatives for syntax. That utility allows
you choose a prefix and/or suffix tokens and see what that looks like
using various expected usage patterns.</p>
<p>Some choices that we have considered:</p>
<ul>
<li><code class="sourceCode cpp"><span class="op">^^</span>e</code> —
While a single caret isn’t viable, two carets would have no ambiguity
with blocks. It’s twice as long as the status quo, but requiring an
additional character wouldn’t be the end of the world. Two characters is
short enough.</li>
<li><code class="sourceCode cpp"><span class="op">^[</span>e<span class="op">]</span></code>
— A different way to work around the block ambiguity is to throw more
characters at it, in this case surrounding the operand with square
brackets. On the one hand, this is more symmetric with splicing. On the
other hand, it’s a heavier syntax.</li>
<li><code><span class="op">${e}</span></code> or
<code><span class="op">$(e)</span></code> — One way to work around the
identifier issue with <code><span class="op">$</span></code> presented
in the previous section is to use additional tokens that cannot be in
identifiers. This would work fine for reflection, but doesn’t have as
nice a mirror for token sequences — would those use an extra set of
braces? Additionally <code><span class="op">$</span></code> seems more
associated with interpolation than reflection in many languages, so
simply seems like the opposite choice here. In contrast,
<code><span class="op">$$(e)</span></code> might be an interesting
choice for a splice operator — and could arguably have some symmetry
with <code class="sourceCode cpp"><span class="op">^^</span>e</code>
with reflection (both having a double character).</li>
<li><code><span class="op">/\e</span></code> — If we can’t have a small
caret, can we have a big caret? This actually has the same issue as just
<code class="sourceCode cpp">\e</code> because of the UCN issue.</li>
</ul>
<h1 data-number="4" style="border-bottom:1px solid #cccccc" id="proposal"><span class="header-section-number">4</span> Proposal<a href="#proposal" class="self-link"></a></h1>
<p>As a group, our preference is
<code class="sourceCode cpp"><span class="op">^^</span>e</code> (where
<code class="sourceCode cpp"><span class="op">^^</span></code> is a new,
single token).</p>
<p>It doesn’t have any of the issues of the single-character solutions.
Having the reflection operator be two characters as compared to only one
isn’t really a sufficiently large cost that we feel the need to
reconsider it in favor of
<code class="sourceCode cpp"><span class="op">|</span>e</code>,
<code class="sourceCode cpp"><span class="op">/</span>e</code>, or
<code class="sourceCode cpp"><span class="op">%</span>e</code>. A
two-character reflection operator is still overwhelmingly shorter than
the 10-character operator that we started from (<code class="sourceCode cpp">reflexpr<span class="op">(</span>e<span class="op">)</span></code>,
if you count the parentheses), and that’s good enough for us.</p>
<p>This has already been implemented in both EDG and Clang. Pending
Evolution approval, we will simply update <span class="citation" data-cites="P2996R5">[<a href="https://wg21.link/p2996r5" role="doc-biblioref">P2996R5</a>]</span> to use the new syntax
throughout — mostly just a search and replace, but with the extra
addition in the wording of
<code class="sourceCode cpp"><span class="op">^^</span></code> to the
grammar of
<code class="sourceCode cpp"><em>operator-or-punctuator</em></code>.</p>
<h1 data-number="5" style="border-bottom:1px solid #cccccc" id="why-not-a-keyword"><span class="header-section-number">5</span> Why
Not A Keyword?<a href="#why-not-a-keyword" class="self-link"></a></h1>
<p>The question that always comes up is: why some kind of punctuation
mark (<code class="sourceCode cpp"><span class="op">^^</span></code> as
proposed) instead of a keyword as originally proposed?</p>
<table>
<thead>
<tr class="header">
<th><div style="text-align:center">
<strong><span class="citation" data-cites="P1240R0">[<a href="https://wg21.link/p1240r0" role="doc-biblioref">P1240R0</a>]</span></strong>
</div></th>
<th><div style="text-align:center">
<strong>Proposed</strong>
</div></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><div>

<div class="sourceCode" id="cb9"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="kw">auto</span> r <span class="op">=</span> reflexpr<span class="op">(</span>S<span class="op">::</span>m<span class="op">)</span>;</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> m <span class="op">=</span> s<span class="op">.</span>unreflexpr<span class="op">(</span>r<span class="op">)</span>;</span></code></pre></div>

</div></td>
<td><div>

<div class="sourceCode" id="cb10"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="kw">auto</span> r <span class="op">=</span> <span class="op">^^</span>S<span class="op">::</span>m;</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> m <span class="op">=</span> s<span class="op">.[:</span>r<span class="op">:]</span>;</span></code></pre></div>

</div></td>
</tr>
</tbody>
</table>
<p>Whether that keyword is <code class="sourceCode cpp">reflexpr</code>
or <code class="sourceCode cpp">reflectof</code> or
<code class="sourceCode cpp">reflof</code> or
<code class="sourceCode cpp">metaof</code>, we feel that a keyword would
be the wrong choice for a reflection (or, especially, a splice) operator
and are strongly opposed to that direction.</p>
<p>The primary reason for this is how heavy any keyword solution is
compared to a punctuation solution, and how much that distracts from the
intent of the code being presented.</p>
<p>We can start with a simple example of a typelist:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb11"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a>mp_list<span class="op">&lt;</span><span class="dt">signed</span> <span class="dt">char</span>, <span class="dt">short</span>, <span class="dt">int</span>, <span class="dt">long</span>, <span class="dt">long</span> <span class="dt">long</span><span class="op">&gt;</span></span></code></pre></div>
</blockquote>
</div>
<p>Which corresponds to this as proposed, which still makes the types
themselves stand out:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb12"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="op">{^^</span><span class="dt">signed</span> <span class="dt">char</span>, <span class="op">^^</span><span class="dt">short</span>, <span class="op">^^</span><span class="dt">int</span>,  <span class="op">^^</span><span class="dt">long</span>, <span class="op">^^</span><span class="dt">long</span> <span class="dt">long</span><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>But is much uglier and filled with tons of syntactic noise that
doesn’t contribute at all to readability if using a keyword:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb13"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="op">{</span>metaof<span class="op">(</span><span class="dt">signed</span> <span class="dt">char</span><span class="op">)</span>, metaof<span class="op">(</span><span class="dt">short</span><span class="op">)</span>, metaof<span class="op">(</span><span class="dt">int</span><span class="op">)</span>, metaof<span class="op">(</span><span class="dt">long</span><span class="op">)</span>, metaof<span class="op">(</span><span class="dt">long</span> <span class="dt">long</span><span class="op">)}</span></span></code></pre></div>
</blockquote>
</div>
<p>The impulse to emphasize the reflection operation by making it stand
out is, while understandable, fundamentally misguided. The code is never
about taking a reflection; it’s always about passing an entity to a
function that then operates on it. The fact that we need to prefix the
entity with
<code class="sourceCode cpp"><span class="op">^^</span></code> is the
price we’re paying because entities aren’t ordinary values so we need to
apply an operator to turn them into ones. Not something to proudly write
home about.</p>
<p>Or, in other words, we cannot <a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a> write the expression
<code class="sourceCode cpp">f<span class="op">(</span><span class="dt">int</span>, <span class="dt">float</span><span class="op">)</span></code>
so we have to write <code class="sourceCode cpp">f<span class="op">(^^</span><span class="dt">int</span>, <span class="op">^^</span><span class="dt">float</span><span class="op">)</span></code>,
which is the next best thing. Adding a ton of
<code class="sourceCode cpp">metaof</code> is not a feature.</p>
<p>We can see this more clearly if we compare some language operators
with their reflection equivalents. We have several operators in the
language that take a type and produce a value of specific type — which
makes them initially seem like precedent for how the reflection operator
should behave. But:</p>
<table>
<thead>
<tr class="header">
<th><div style="text-align:center">
<strong>Operation</strong>
</div></th>
<th><div style="text-align:center">
<strong>Language Operator</strong>
</div></th>
<th><div style="text-align:center">
<strong>Reflection</strong>
</div></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>size</td>
<td><code class="sourceCode cpp"><span class="kw">sizeof</span><span class="op">(</span>T<span class="op">)</span></code></td>
<td><code class="sourceCode cpp">size_of<span class="op">(^^</span>T<span class="op">)</span></code></td>
</tr>
<tr class="even">
<td>alignment</td>
<td><code class="sourceCode cpp"><span class="kw">alignof</span><span class="op">(</span>T<span class="op">)</span></code></td>
<td><code class="sourceCode cpp">align_of<span class="op">(^^</span>T<span class="op">)</span></code></td>
</tr>
<tr class="odd">
<td>is noexcept?</td>
<td><code class="sourceCode cpp"><span class="kw">noexcept</span><span class="op">(</span>E<span class="op">)</span></code></td>
<td><code class="sourceCode cpp">is_noexcept<span class="op">(^^(</span>E<span class="op">))</span></code></td>
</tr>
</tbody>
</table>
<p>In all cases, the operation being performed is to get the size of the
type (<code class="sourceCode cpp"><span class="kw">sizeof</span></code>
or <code class="sourceCode cpp">size_of</code>), the alignment of the
type
(<code class="sourceCode cpp"><span class="kw">alignof</span></code> or
<code class="sourceCode cpp">align_of</code>), or to check whether the
expression is noexcept
(<code class="sourceCode cpp"><span class="kw">noexcept</span></code> or
<code class="sourceCode cpp">is_noexcept</code>, noting that we don’t
have expression reflection yet — but when we do it’ll look like this)
and the operand is the type (<code class="sourceCode cpp">T</code>) or
expression (<code class="sourceCode cpp">E</code>). Getting the
reflection of the type/expression is <em>not</em> an important operation
here. Making it stand out more does not have value. It would hide the
actual operation.</p>
<p>The same is true for all operations that we might want to perform.
Consider wanting to iterate over the numerators of
<code class="sourceCode cpp">Color</code>:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb14"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="co">// reads as the enumerators of Color</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>enumerators_of<span class="op">(^^</span>Color<span class="op">)</span></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a><span class="co">// reads as the enumerators of the reflection of Color</span></span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>enumerators_of<span class="op">(</span>reflectof<span class="op">(</span>Color<span class="op">))</span></span></code></pre></div>
</blockquote>
</div>
<p>Or to substituting
<code class="sourceCode cpp">std<span class="op">::</span>map</code>
with
<code class="sourceCode cpp">std<span class="op">::</span>string</code>
and <code class="sourceCode cpp"><span class="dt">int</span></code>:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb15"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="co">// reads as substitute map with string and int</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>substitute<span class="op">(^^</span>std<span class="op">::</span>map, <span class="op">{^^</span>std<span class="op">::</span>string, <span class="op">^^</span><span class="dt">int</span><span class="op">})</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a><span class="co">// reads as substitute the reflection of map of with</span></span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a><span class="co">// the reflection of string and the reflection of int</span></span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>substitute<span class="op">(</span>reflectof<span class="op">(</span>std<span class="op">::</span>map<span class="op">)</span>, <span class="op">{</span>reflectof<span class="op">(</span>std<span class="op">::</span>string<span class="op">)</span>, reflectof<span class="op">(</span><span class="dt">int</span><span class="op">)}))</span></span></code></pre></div>
</blockquote>
</div>
<p>The former reading more clearly expresses the intent. Keywords demand
to be read, whereas sigils may be internally skipped over. Eliding the
sigil from the internal dialogue lets the user put aside the fact that
reflection is happening. They may read it as “enumerators of
<code class="sourceCode cpp">Color</code>” or “substitute
<code class="sourceCode cpp">map</code> with
<code class="sourceCode cpp">string</code> and
<code class="sourceCode cpp"><span class="dt">int</span></code>.” Once
the keyword-name enters the “internal token stream,” the user cannot
hope to understand the meaning of the expression without learning the
meaning of <code class="sourceCode cpp">reflectof</code> (or
<code class="sourceCode cpp">metaof</code> or
<code class="sourceCode cpp">reflof</code> or …). That is exactly the
opposite of novice-friendly.</p>
<p>A parallel can be made with templates. In <code class="sourceCode cpp">vector<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span></code>
the template machinery is often “invisible”. the
<code class="sourceCode cpp"><span class="op">&lt;&gt;</span></code>
could be replaced by a keyword here as well. For instance, we could’ve
had a keyword <code class="sourceCode cpp">substitute</code> and made
forming a template something like <code class="sourceCode cpp">substitute<span class="op">(</span>vector, <span class="dt">int</span><span class="op">)</span></code>
instead of <code class="sourceCode cpp">vector<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span></code>.
However, we think most people would agree the punctuator puts the focus
on the operation itself not the grammatical limitations of the language.
Lots of novices engage in using templates long before writing templates,
and while we’ve seen arguments in favor of a <em>different</em>
punctuator for template arguments (such as <code class="sourceCode cpp">vector<span class="op">(</span><span class="dt">int</span><span class="op">)</span></code>
or D’s <code class="sourceCode cpp">vector<span class="op">!(</span><span class="dt">int</span><span class="op">)</span></code>,
which avoid the
<code class="sourceCode cpp"><span class="op">&lt;</span></code>
ambiguity), we’ve never seen an argument for a keyword here.</p>
<p>The other thing to point out is that reflection is not necessarily
going to be a prominently user-facing facility. Certainly not a
novice-facing one. Reflection opens the door to a large variety of
libraries that can make otherwise very complex operations very easy —
from even expert-unfriendly to novice-friendly. But the user-facing API
of those libraries need not actually expose the reflection operator at
all, and most use-cases would not do so at all. Arguing for a reflection
keyword to be novice-friendly thus doubly misses the point — not only is
it not novice friendly, but novices may rarely even have to look at such
code.</p>
<h1 data-number="6" style="border-bottom:1px solid #cccccc" id="bibliography"><span class="header-section-number">6</span>
References<a href="#bibliography" class="self-link"></a></h1>
<div id="refs" class="references csl-bib-body hanging-indent" data-entry-spacing="1" role="doc-bibliography">
<div id="ref-P1240R0" class="csl-entry" role="doc-biblioentry">
[P1240R0] Andrew Sutton, Faisal Vali, Daveed Vandevoorde. 2018-10-08.
Scalable Reflection in C++. <a href="https://wg21.link/p1240r0"><div class="csl-block">https://wg21.link/p1240r0</div></a>
</div>
<div id="ref-P1240R2" class="csl-entry" role="doc-biblioentry">
[P1240R2] Daveed Vandevoorde, Wyatt Childers, Andrew Sutton, Faisal
Vali. 2022-01-14. Scalable Reflection. <a href="https://wg21.link/p1240r2"><div class="csl-block">https://wg21.link/p1240r2</div></a>
</div>
<div id="ref-P2688R1" class="csl-entry" role="doc-biblioentry">
[P2688R1] Michael Park. 2024-02-15. Pattern Matching: `match`
Expression. <a href="https://wg21.link/p2688r1"><div class="csl-block">https://wg21.link/p2688r1</div></a>
</div>
<div id="ref-P2996R5" class="csl-entry" role="doc-biblioentry">
[P2996R5] Barry Revzin, Wyatt Childers, Peter Dimov, Andrew Sutton,
Faisal Vali, Daveed Vandevoorde, Dan Katz. 2024-08-14. Reflection for
C++26. <a href="https://wg21.link/p2996r5"><div class="csl-block">https://wg21.link/p2996r5</div></a>
</div>
<div id="ref-P3294R1" class="csl-entry" role="doc-biblioentry">
[P3294R1] Barry Revzin, Andrei Alexandrescu, Daveed Vandevoorde.
2024-07-16. Code Injection with Token Sequences. <a href="https://wg21.link/p3294r1"><div class="csl-block">https://wg21.link/p3294r1</div></a>
</div>
</div>
<section class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1" role="doc-endnote"><p>Consider the expression <code class="sourceCode cpp">f<span class="op">(</span>X<span class="op">(</span><span class="dt">int</span><span class="op">))</span></code>,
where <code class="sourceCode cpp">X</code> is a type. This could be
calling <code class="sourceCode cpp">f</code> with the function type
<code class="sourceCode cpp">X<span class="op">(</span><span class="dt">int</span><span class="op">)</span></code>
or with a value of <code class="sourceCode cpp">X</code> constructed
with <code class="sourceCode cpp"><span class="dt">int</span></code>.
How do you differentiate?<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
</div>
</div>
</body>
</html>
