<!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="2022-02-24" />
  <title>Identifiers for Pattern Matching</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 { } /* 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 { } /* 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;
}
:not(pre) > code {
background-color: #f6f8fa;
padding: 2px 4px 2px 4px;
}
div.sourceCode {
padding: 4px;
}
blockquote {
color: #666666;
margin: 0;
padding-left: 1em;
border-left: 0.5em #f2f4f7 solid;
}
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">Identifiers for Pattern Matching</h1>

<table style="border:none;float:right">
  <tr>
    <td>Document #: </td>
    <td>P2941R0</td>
  </tr>
  <tr>
    <td>Date: </td>
    <td>2022-02-24</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Project: </td>
    <td>Programming Language C++<br>
      SG17<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to: </td>
    <td>
      Mihail Naydenov<br>&lt;<a href="mailto:mihailnajdenov@gmail.com" class="email">mihailnajdenov@gmail.com</a>&gt;<br>
    </td>
  </tr>
</table>

</header>
<div style="clear:both">
<section id="abstract" data-number="1">
<h1 data-number="1"><span class="header-section-number">1</span> Abstract<a href="#abstract" class="self-link"></a></h1>
<p>This paper investigates the challenges we face with identifiers inside Pattern Matching (PM). It also proposes a method for their introduction, one that is inline with current practices, without new language syntax.</p>
</section>
<section id="challenges" data-number="2">
<h1 data-number="2"><span class="header-section-number">2</span> Challenges<a href="#challenges" class="self-link"></a></h1>
<p>One of the many challenges in PM has to do with identifiers. There is an unavoidable ambiguity in what we mean by a variable named <code>x</code>: Is it a newly introduced entity or a reference to an existing one? There is no right answer and each system decides on its own. For example in Python, <code>x</code> is a new name and if the user whats to access an existing one it must contain a dot (essentially to be a path) - <code>something.x</code>. In Rust also <code>x</code> is a new name. Swift and C# introduce new names the same way this is done outside PM - with <code>let</code> and <code>var</code> respectively.<br />
Variable introduction style might seem like a minor, “esthetics” issue, but is really not, especially in C++, for two important reasons:</p>
<ul>
<li>First, in C++ <em>there is no variable introduction keyword.</em> This is in contrast to the above mentioned Swift and C#.<br />
</li>
<li>Second, <em>types and variables can have the same name</em> - <code>class s{}; s s;</code>.</li>
</ul>
<p>These two just add up to the preexisting ambiguities inside PM, creating an even more complicated context.</p>
<section id="so-many-identifiers-so-little-syntax" data-number="2.0.1">
<h3 data-number="2.0.1"><span class="header-section-number">2.0.1</span> So many identifiers, so little syntax<a href="#so-many-identifiers-so-little-syntax" class="self-link"></a></h3>
<p>Let’s examine the number of possibilities for what an identifier could mean in the C++ pattern matching scenario. We mentioned some of them already:</p>
<ul>
<li><code>x</code> can be a PM variable, a binding</li>
<li><code>x</code> can be a non-PM variable, one to compare against</li>
<li><code>x</code> can be a type</li>
</ul>
<p>Before continuing, here are our current solutions for the above 3.<br />
The main PM proposal, p1371<a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a>, as of its latest iteration at the time of writing:</p>
<ul>
<li>creating a binding is the default, with the explicit limitation, one can not bind an arbitrary pattern. This is, only the last value, after all matching is done, can be captured behind the name <code>x</code>.<br />
</li>
<li>non-PM variables must be proceeded with <code>case</code> - <code>case x</code>.</li>
<li>types are used inside the “Alternative Pattern”, which surrounds their names with angle brackets - <code>&lt;x&gt;</code>.</li>
</ul>
<p>However, according to p2688<a href="#fn2" class="footnote-ref" id="fnref2" role="doc-noteref"><sup>2</sup></a>, the above will be revisited in future versions and will be as follows:</p>
<ul>
<li>creating a binding will be done via a <code>let</code> keyword.</li>
<li>non-PM variables will be “just expression” and used directly, making the “non-PM variable for comparison” the default.</li>
<li>(“Alternative Pattern” is unchanged.)</li>
</ul>
<p>The “is as” proposal (p2392)<a href="#fn3" class="footnote-ref" id="fnref3" role="doc-noteref"><sup>3</sup></a> is as follows:</p>
<ul>
<li>binding is created if the identifier is to the left of <code>is</code> or <code>as</code>.</li>
<li>non-PM variables are the ones that appear to the right of <code>is</code>.</li>
<li>types <em>also</em> appear to the right, same as non-PM variables.</li>
</ul>
<p><strong>The problem with type selector</strong></p>
<p>It is worth taking a special attention to type selector in our current approaches.<br />
Both current solutions accept an expression <em>and</em> a typename behind the same syntax:</p>
<p><strong>Main Proposal</strong></p>
<div class="columns">
<div class="column" style="width:50%;">
<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">constexpr</span> <span class="kw">auto</span> size <span class="op">=</span> <span class="dv">13</span>;</span>
<span id="cb1-2"><a href="#cb1-2"></a></span>
<span id="cb1-3"><a href="#cb1-3"></a>inspect <span class="op">(</span>some_value<span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-4"><a href="#cb1-4"></a> <span class="op">&lt;</span>size<span class="op">&gt;</span> <span class="op">=&gt;</span> <span class="co">// select a some_value alternative, using the value 13</span></span>
<span id="cb1-5"><a href="#cb1-5"></a><span class="op">}</span>;</span></code></pre></div>
</div><div class="column" style="width:50%;">
<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">using</span> size <span class="op">=</span> <span class="dt">int</span>;</span>
<span id="cb2-2"><a href="#cb2-2"></a></span>
<span id="cb2-3"><a href="#cb2-3"></a>inspect <span class="op">(</span>some_value<span class="op">)</span> <span class="op">{</span></span>
<span id="cb2-4"><a href="#cb2-4"></a> <span class="op">&lt;</span>size<span class="op">&gt;</span> <span class="op">=&gt;</span> <span class="co">// select a some_value alternative, using the type int</span></span>
<span id="cb2-5"><a href="#cb2-5"></a><span class="op">}</span>;</span></code></pre></div>
</div>
</div>
<p><em>Exact same syntax in both cases</em></p>
<p><strong>Is As</strong></p>
<div class="columns">
<div class="column" style="width:50%;">
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1"></a><span class="kw">constexpr</span> <span class="kw">auto</span> size <span class="op">=</span> <span class="dv">13</span>;</span>
<span id="cb3-2"><a href="#cb3-2"></a></span>
<span id="cb3-3"><a href="#cb3-3"></a>inspect <span class="op">(</span>some_value<span class="op">)</span> <span class="op">{</span></span>
<span id="cb3-4"><a href="#cb3-4"></a> is size <span class="op">=&gt;</span> <span class="co">// some_value is equal to the value 13</span></span>
<span id="cb3-5"><a href="#cb3-5"></a><span class="op">}</span>;</span></code></pre></div>
</div><div class="column" style="width:50%;">
<div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb4-1"><a href="#cb4-1"></a><span class="kw">using</span> size <span class="op">=</span> <span class="dt">int</span>;</span>
<span id="cb4-2"><a href="#cb4-2"></a></span>
<span id="cb4-3"><a href="#cb4-3"></a>inspect <span class="op">(</span>some_value<span class="op">)</span> <span class="op">{</span></span>
<span id="cb4-4"><a href="#cb4-4"></a> is size <span class="op">=&gt;</span> <span class="co">// some_value is of type int</span></span>
<span id="cb4-5"><a href="#cb4-5"></a><span class="op">}</span>;</span></code></pre></div>
</div>
</div>
<p><em>Exact same syntax in both cases</em></p>
<p>This situation is not perfect because it makes the PM expression <em>fragile</em> - one extra variable definition (or <code>using enum</code>), anywhere prior to the PM, <em>could change its meaning</em>.</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb5-1"><a href="#cb5-1"></a><span class="kw">struct</span> size<span class="op">{...}</span>;</span>
<span id="cb5-2"><a href="#cb5-2"></a><span class="kw">enum</span> <span class="kw">class</span> Selector <span class="op">{</span> size, <span class="op">...}</span>;</span>
<span id="cb5-3"><a href="#cb5-3"></a><span class="op">...</span></span>
<span id="cb5-4"><a href="#cb5-4"></a><span class="dt">void</span> function<span class="op">()</span> <span class="op">{</span></span>
<span id="cb5-5"><a href="#cb5-5"></a><span class="co">// constexpr auto size = 13; //&lt; if someone, or an include, adds this, in either global or local scope,</span></span>
<span id="cb5-6"><a href="#cb5-6"></a>                             <span class="co">// the definition of the PM will change. It might even still compile, but give a different answer.</span></span>
<span id="cb5-7"><a href="#cb5-7"></a></span>
<span id="cb5-8"><a href="#cb5-8"></a><span class="co">// using enum Selector;      //&lt; same here</span></span>
<span id="cb5-9"><a href="#cb5-9"></a></span>
<span id="cb5-10"><a href="#cb5-10"></a>  <span class="op">...</span></span>
<span id="cb5-11"><a href="#cb5-11"></a></span>
<span id="cb5-12"><a href="#cb5-12"></a>  inspect <span class="op">(</span>some_value<span class="op">)</span> <span class="op">{</span></span>
<span id="cb5-13"><a href="#cb5-13"></a>   <span class="op">&lt;</span>size<span class="op">&gt;</span> <span class="op">=&gt;</span> <span class="co">// We can&#39;t really be sure, a selection based on type is made</span></span>
<span id="cb5-14"><a href="#cb5-14"></a>  <span class="op">}</span>;</span>
<span id="cb5-15"><a href="#cb5-15"></a><span class="op">}</span></span></code></pre></div>
<p>In a bigger function, it is not hard to imagine this scenario arising.<br />
Also note, it might happen in reverse. Both a <code>size</code> type and a <code>size</code> variable could already be defined, after all there is no issue doing so, and someone might write an PM expression, being aware only of one of the definitions. He/she will scratch their head why the PM is not doing what it is expected, or worse, appear to do so but really not.</p>
<p>Why this is not an issue today?<br />
In general, there are effectively no places where there is a competition b/w type and variable, a place where one must explicitly select one or another in order to <em>choose and have a different result</em>. We must specifically <em>create</em> such scenarios, like a function which takes either a non type or type. However, and this is the big difference to PM, such a function will be an API that we code against. That API will either be such from the beginning, and we take precaution when using it, or it will evolve into such, then it will/should be documented of the hazard when upgrading.<br />
This is not the case with PM, and it should not be. PM is a <em>native expression</em>, not an API to some library. <em>Expressions in C++ do not switch meaning, based on the presence (or not) of type and variable with the same name.</em> They might fail to compile, but will not change meaning, <em>there are no alternative implementations</em>. PM should behave no worse than that, hopefully better. If not, we create a “foot gun”, for which we must write yet another guide on how to avoid (“always use different naming conventions for type and variable”, “always use elaborate type specifier in PM”, etc). We don’t want that.</p>
<p>As you can see, things are already not easy with these 3 cases, but there is more:<br />
- <code>x</code> can be an existing, non-PM variable, used for binding, an assignment.</p>
<p>Arguably, this last case mainly concerns patterns <em>outside</em> PM. For example, we can imagine extending structured bindings to bind to existing variables:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb6-1"><a href="#cb6-1"></a>some_t a,b;</span>
<span id="cb6-2"><a href="#cb6-2"></a><span class="op">[</span>a,b<span class="op">]</span> <span class="op">=</span> something; <span class="co">//&lt; bind to preexisting variables</span></span></code></pre></div>
<p>Although, there is <code>std::tie</code>, it’s a hidden, non-obvious way of doing things. More importantly, it is <em>not composable</em> with any patterns:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1"></a>some_t a,b;</span>
<span id="cb7-2"><a href="#cb7-2"></a><span class="co">// some-pattern below is a hypothetical pattern-used-outside-PM.</span></span>
<span id="cb7-3"><a href="#cb7-3"></a>some<span class="op">-</span>pattern std<span class="op">::</span>tie<span class="op">(</span>some<span class="op">-</span>pattern a, b<span class="op">)</span> <span class="op">=</span> something; <span class="co">//&lt; can&#39;t bind to preexisting variables from within patterns</span></span></code></pre></div>
<p>Outside PM we will certainly need to bind to existing variables, but binding to existing variables <em>inside</em> PM could also be beneficial. We might want to fill a preexisting data structure directly. Something along the lines of:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb8-1"><a href="#cb8-1"></a><span class="dt">void</span> useSize<span class="op">(</span><span class="dt">size_t</span><span class="op">&amp;</span> size<span class="op">)</span>;</span>
<span id="cb8-2"><a href="#cb8-2"></a></span>
<span id="cb8-3"><a href="#cb8-3"></a><span class="dt">size_t</span> useAndReturnSize<span class="op">()</span> <span class="op">{</span></span>
<span id="cb8-4"><a href="#cb8-4"></a>  <span class="dt">size_t</span> size<span class="op">{}</span>;</span>
<span id="cb8-5"><a href="#cb8-5"></a>  inspect<span class="op">(</span>some_rect<span class="op">)</span> <span class="op">{</span></span>
<span id="cb8-6"><a href="#cb8-6"></a>    <span class="op">[</span>__, let sz <span class="op">=</span> <span class="op">{</span><span class="dv">5</span>,<span class="dv">5</span><span class="op">}]</span> <span class="op">=&gt;</span> useSize<span class="op">(</span>size <span class="op">=</span> sz<span class="op">)</span>;</span>
<span id="cb8-7"><a href="#cb8-7"></a>    <span class="op">...</span></span>
<span id="cb8-8"><a href="#cb8-8"></a>  <span class="op">}</span></span>
<span id="cb8-9"><a href="#cb8-9"></a>  <span class="op">...</span></span>
<span id="cb8-10"><a href="#cb8-10"></a>  <span class="cf">return</span> size;</span>
<span id="cb8-11"><a href="#cb8-11"></a><span class="op">}</span>;</span></code></pre></div>
<p>Here, <em>ideally</em> we would have just used the <code>size</code> variable directly. <code>sz</code> is just a crutch to carry us around the fact, we can’t bind directly to preexisting variables. Granted, this use is not that important exactly because the workaround is easy and as such, current proposals do not address this usage.</p>
<p>There is however, much more important case, missing from the discussions so far.</p>
<p>We talk about introducing a variable for PM, a binding, but this binding should have control of its mutability, much like any other variable in the language. We should have both a binding for reading and a binding for writing.<br />
That scenario is not handled directly by the current proposals and a simplified approach is taken, where <em>all bindings are mutable</em>, unless the object we “inspect” is const. In that case all binding are const by the regular constness preservation rules. Needless to say, this is far from perfect for two reasons:</p>
<ul>
<li>Pattern Matching, in contrast to <code>switch</code> and <code>if-else</code> is recursive, which results in a lot of complexity, with many branches in an overall three structure. We will absolutely encounter the need to have <em>almost</em> all branches be const, but <em>some</em> be mutable simply because not all paths will have the same requirements and usage. An “all or nothing” approach will be suboptimal, hurting const correctness overall - if you want that one variable, in that one arm to be mutable, <em>all</em> of them will have to be, the root can no longer be const.</li>
<li>Making the root const will have no effect on the mutability of the data if the data is accessed indirectly (pointer, view). Considering the widespread use of such objects in C++, both modern and classical, this will be a half-measure or even useless. A practical mutability can only be achieved by having it be defined as part of the particular binding and not for the containing object we inspect.</li>
</ul>
<p>At this point it should be evident, there are plenty of complications regarding identifiers in the PM context, with many potential uses and very limited ways to express them. Here is the complete list:</p>
<ul>
<li><code>x</code> can be a PM variable, used for observation</li>
<li><code>x</code> can be a PM variable, used for modification</li>
<li><code>x</code> can be a non-PM variable, one to compare against</li>
<li><code>x</code> can be a non-PM variable, one to write to</li>
<li><code>x</code> can be a type</li>
</ul>
<p>Of course, not all uses are equally important, but all must be taken into account as part of the overall requirements and a view into “the bigger picture”. Otherwise we <em>will</em> write ourselves into a corner, as the syntax options are extremely limited.</p>
</section>
<section id="type-selector" data-number="2.1">
<h2 data-number="2.1"><span class="header-section-number">2.1</span> Type selector<a href="#type-selector" class="self-link"></a></h2>
<p>Identifiers for type selector need a special mention. If we step back and consider what syntax we would <em>like</em> to see as a natural way of doing type switching, we should look no further then the very first proposals for Pattern Matching like pattern-matching-November-2014<a href="#fn4" class="footnote-ref" id="fnref4" role="doc-noteref"><sup>4</sup></a> or the early p0095.<a href="#fn5" class="footnote-ref" id="fnref5" role="doc-noteref"><sup>5</sup></a> They both advertise something like:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb9-1"><a href="#cb9-1"></a> Some{...} </span></code></pre></div>
<p>to select (and deconstruct) a type <code>Some</code> from a polymorphic source value. This makes sense - deconstructing is the opposite of constructing and often programming languages use a syntax, very similar to either class definition or construction:</p>
<div class="columns">
<div class="column" style="width:50%;">
<p><strong>Rust class definition</strong></p>
<div class="sourceCode" id="cb10"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb10-1"><a href="#cb10-1"></a>... Some{...}</span></code></pre></div>
<p><strong>C# class definition</strong></p>
<div class="sourceCode" id="cb11"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb11-1"><a href="#cb11-1"></a>... Some{...}</span></code></pre></div>
<p><strong>Python class construction</strong></p>
<div class="sourceCode" id="cb12"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb12-1"><a href="#cb12-1"></a>... Some(...)</span></code></pre></div>
<p><strong>Scala class definition</strong></p>
<div class="sourceCode" id="cb13"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb13-1"><a href="#cb13-1"></a>... Some(...)</span></code></pre></div>
</div><div class="column" style="width:50%;">
<p><strong>Rust class deconstruction</strong></p>
<div class="sourceCode" id="cb14"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb14-1"><a href="#cb14-1"></a>... Some{...}</span></code></pre></div>
<p><strong>C# class deconstruction</strong></p>
<div class="sourceCode" id="cb15"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb15-1"><a href="#cb15-1"></a>... Some{...}</span></code></pre></div>
<p><strong>Python class deconstruction</strong></p>
<div class="sourceCode" id="cb16"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb16-1"><a href="#cb16-1"></a>... Some(...)</span></code></pre></div>
<p><strong>Scala class deconstruction</strong></p>
<div class="sourceCode" id="cb17"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb17-1"><a href="#cb17-1"></a>... Some(...)</span></code></pre></div>
</div>
</div>
<p>In other words, our initial intention to have deconstruction mirroring construction was more or less “right”. Something however happen in the process and we drifted away of it. Using square instead of curly brackets for deconstruction is understandable, considering Structured Bindings are already in the language. However, we also lost the natural way of expressing the desired type:</p>
<div class="columns">
<div class="column" style="width:50%;">
<p><strong>Main Proposal</strong></p>
<div class="sourceCode" id="cb18"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb18-1"><a href="#cb18-1"></a>&lt;Some&gt;[...]</span></code></pre></div>
<p><em>extra angle brackets</em></p>
</div><div class="column" style="width:50%;">
<p><strong>Is As Proposal</strong></p>
<div class="sourceCode" id="cb19"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb19-1"><a href="#cb19-1"></a>[...] as Some</span></code></pre></div>
<p><em>a new <code>as</code> idiom</em></p>
</div>
</div>
<p>The <code>as</code>, although looking nice, is foreign to C++. To change this fact, we must alter the language, adding <code>as</code> outside PM also. On the other hand, angle brackets can hardly be perceived as pretty or natural and, considering the recursive nature of PM, will bring considerable visual noise.</p>
</section>
</section>
<section id="the-bigger-picture" data-number="3">
<h1 data-number="3"><span class="header-section-number">3</span> The Bigger Picture<a href="#the-bigger-picture" class="self-link"></a></h1>
<blockquote>
<p>This is an overview, including future directions. For the concretely proposed items see next section.</p>
</blockquote>
<p>In the previous section we made the observation, an identifier can be one of those:</p>
<ul>
<li>а binding, creating a new variable</li>
<li>а binding, reusing an existing variable</li>
<li>аn existing variable to compare against</li>
<li>аn existing variable to write to</li>
<li>а type name</li>
</ul>
<p>It is clear, it is not possible to have a simple, single identifier without encountering multiple ambiguities. To account for that, we must “mark” identifiers for their specific use. In the main proposal this is done by either using <code>case</code> for “existing variable to compare against” (p1371) or with <code>let</code> (p2688) to mark new identifiers. Angle brackets are used around type names. In the “is as” proposal, the location of the identifier in relation to <code>is</code> or <code>as</code> is the determining factor.</p>
<p>Regarding the latter, we can make the observation, <code>is</code> is quite similar to an operator, we already have, the <code>operator==</code>. This means, marking values for comparison with an <code>==</code> can be a reasonable approach as well, one that does not need introducing new language features:</p>
<div class="sourceCode" id="cb20"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb20-1"><a href="#cb20-1"></a><span class="dt">int</span> value <span class="op">=</span> <span class="dv">5</span>;</span>
<span id="cb20-2"><a href="#cb20-2"></a><span class="dt">int</span> number <span class="op">=</span> <span class="op">...</span>;</span>
<span id="cb20-3"><a href="#cb20-3"></a></span>
<span id="cb20-4"><a href="#cb20-4"></a>inspect <span class="op">(</span>number<span class="op">)</span> <span class="op">{</span></span>
<span id="cb20-5"><a href="#cb20-5"></a>  <span class="op">==</span>value <span class="op">=&gt;</span> <span class="co">//&lt; matches `value`</span></span>
<span id="cb20-6"><a href="#cb20-6"></a>  <span class="co">// or !=value if we want!</span></span>
<span id="cb20-7"><a href="#cb20-7"></a>  <span class="op">...</span></span>
<span id="cb20-8"><a href="#cb20-8"></a><span class="op">}</span>;</span></code></pre></div>
<p>This looks promising, the code is self-explanatory, free from ambiguity, though arguably a bit verbose. Later, in the proposal part, this issue is addressed as well.</p>
<blockquote>
<p>Please note, <code>inspect</code>, and much of the syntax, is just a placeholder, reusing it from the main PM proposal (p1371). The authors seem to be moving away from it in p2688, but it can still serve us here.<br />
Also, having <code>==</code> does <em>not exclude</em> intruding <code>is</code> in the future. <code>is</code> will be just another operator, both in and outside PM.</p>
</blockquote>
<p>One very interesting side effect is that by using <code>==</code> (or possibly <code>!=</code>), we can also <em>naturally</em> introduce the other comparison operators:</p>
<div class="sourceCode" id="cb21"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb21-1"><a href="#cb21-1"></a>inspect <span class="op">(</span>number<span class="op">)</span> <span class="op">{</span></span>
<span id="cb21-2"><a href="#cb21-2"></a>  <span class="op">&gt;=</span>value <span class="op">=&gt;</span> <span class="co">//&lt; greater or equal</span></span>
<span id="cb21-3"><a href="#cb21-3"></a>  <span class="op">&lt;=</span>value <span class="op">=&gt;</span> <span class="co">//&lt; less or equal</span></span>
<span id="cb21-4"><a href="#cb21-4"></a>  <span class="op">&lt;</span> value <span class="op">=&gt;</span> <span class="co">//&lt; less then</span></span>
<span id="cb21-5"><a href="#cb21-5"></a>  <span class="op">&gt;</span> value <span class="op">=&gt;</span> <span class="co">//&lt; greater then</span></span>
<span id="cb21-6"><a href="#cb21-6"></a>  <span class="op">...</span></span>
<span id="cb21-7"><a href="#cb21-7"></a><span class="op">}</span>;</span></code></pre></div>
<p>This is a really nice bonus feature, already available in C# PM for example.</p>
<p>Moving forward. We saw how we can introduce existing identifiers for comparison naturally, now let’s get to the much harder cases - introducing new variables. In C++, much like C before that, <em>there is no special keyword or any other syntactical marking</em>. Identifiers for variables are introduced by a preceding identifier of a type:</p>
<div class="sourceCode" id="cb22"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb22-1"><a href="#cb22-1"></a>id_of_type id_of_var;</span></code></pre></div>
<p><em><code>id_of_var</code> is new variable, indicated only by the fact, it has a preceding type <code>id_of_type</code>.</em></p>
<p>This is a though place to be as this kind of introduction is completely unusable for PM.<br />
The route current proposals take is to introduce a new language syntax. This is either special mini language, in the main PM proposal case, where having new variables are introduced with the <code>let</code> keyword. Or, in the “is as” proposal, by having new language feature, the <code>is</code> and <code>as</code> operators, which in PM can create new variables among other things. Having to introduce a new language is high price to pay and it leads to inconsistencies - in and outside PM the variables are introduced differently. Faced with the issue, we must either address it by changing the rest of the language (the “is as” proposal) or ignored it (main proposal).</p>
<blockquote>
<p>The described is not the case with languages, which <em>already</em> have a keyword for variable introduction. Swift using <code>let</code> inside PM is <em>fundamentally</em> different then C++ doing it - <code>let</code> is already the way to introduce variables. Same for C# and its <code>var</code> keyword. C++ using <code>let</code> <em>just for PM</em> creates an “one-off” within the language in a place where semantically there is no new functionality - bindings are still variables, just in a different context.</p>
</blockquote>
<p>This negativistic scenario is not the only one possible however.</p>
<p>Interestingly, having to precede the identifier with a type has one notable exception - the lambda capture. There we don’t have to supply the type before a new variable:</p>
<div class="sourceCode" id="cb23"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb23-1"><a href="#cb23-1"></a><span class="op">[</span>a<span class="op">=</span>something<span class="op">]</span> <span class="op">{</span> <span class="co">// New variable `a` is introduced for the lambda with the same value as `something`.</span></span>
<span id="cb23-2"><a href="#cb23-2"></a> <span class="op">...</span> </span>
<span id="cb23-3"><a href="#cb23-3"></a><span class="op">}</span> </span></code></pre></div>
<p>This is used to make the syntax <em>concise</em> and it works because there are <em>no uninitialized captures</em>.<br />
Coincidentally, <em>both</em> of those are true for the PM as well - we need a concise syntax <em>and</em> there are no uninitialized bindings!</p>
<p>Reusing the syntax seems like a very sensible option:</p>
<div class="sourceCode" id="cb24"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb24-1"><a href="#cb24-1"></a><span class="dt">int</span> number <span class="op">=</span> <span class="op">...</span>;</span>
<span id="cb24-2"><a href="#cb24-2"></a></span>
<span id="cb24-3"><a href="#cb24-3"></a>inspect <span class="op">(</span>number<span class="op">)</span> <span class="op">{</span></span>
<span id="cb24-4"><a href="#cb24-4"></a>  n<span class="op">=</span>__ <span class="op">=&gt;</span> <span class="co">// new binding `n` is introduced for the PM with same value as the matched ::number</span></span>
<span id="cb24-5"><a href="#cb24-5"></a>  <span class="co">// or just n= omitting the __ </span></span>
<span id="cb24-6"><a href="#cb24-6"></a>  <span class="op">...</span></span>
<span id="cb24-7"><a href="#cb24-7"></a><span class="op">}</span>;</span></code></pre></div>
<p>Similarly how we create a <em>lambda-local</em> variable, <em>always</em> initialized to some preexisting value, we can create a <em>PM-local</em> variable, again <em>always</em> initialized to a preexisting value. This time however the value is coming <em>implicitly</em> from the object we “inspect” instead of assigning it manually.<br />
In the above example, we might continue matching, adding an expected value:</p>
<div class="sourceCode" id="cb25"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb25-1"><a href="#cb25-1"></a><span class="dt">int</span> number <span class="op">=</span> <span class="op">...</span>;</span>
<span id="cb25-2"><a href="#cb25-2"></a></span>
<span id="cb25-3"><a href="#cb25-3"></a>inspect <span class="op">(</span>number<span class="op">)</span> <span class="op">{</span></span>
<span id="cb25-4"><a href="#cb25-4"></a>  n<span class="op">=</span><span class="dv">5</span> <span class="op">=&gt;</span> <span class="co">// new binding `n` is introduced for the PM, iff ::number is 5</span></span>
<span id="cb25-5"><a href="#cb25-5"></a>  <span class="op">...</span></span>
<span id="cb25-6"><a href="#cb25-6"></a><span class="op">}</span>;</span></code></pre></div>
<p>Here we create a binding <code>n</code>, equal to <code>5</code>. Of course, it is not we that “assign” <code>5</code> to the binding, in contrast to lambda. It is the PM system that will create the binding, with a value, equal to the <code>number</code> variable, but only if <code>number</code> is <code>5</code>. The end result is the same and what is written will not be misleading - <code>n</code> is (equal to) <code>5</code>.</p>
<p>Moving to lambda-like identifiers introduction has a major benefit - we have syntax ready for all other identifiers!</p>
<p><strong>Mutable and immutable</strong> bindings:</p>
<div class="sourceCode" id="cb26"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb26-1"><a href="#cb26-1"></a><span class="dt">int</span> number <span class="op">=</span> <span class="op">...</span>;</span>
<span id="cb26-2"><a href="#cb26-2"></a></span>
<span id="cb26-3"><a href="#cb26-3"></a><span class="dt">void</span> mutate<span class="op">(</span><span class="dt">int</span><span class="op">&amp;){...}</span></span>
<span id="cb26-4"><a href="#cb26-4"></a></span>
<span id="cb26-5"><a href="#cb26-5"></a>inspect <span class="op">(</span>number<span class="op">)</span> <span class="op">{</span></span>
<span id="cb26-6"><a href="#cb26-6"></a>   n<span class="op">=</span>__ <span class="op">=&gt;</span> mutate<span class="op">(</span>n<span class="op">)</span>; <span class="co">// FAILS, n is immutable by default!</span></span>
<span id="cb26-7"><a href="#cb26-7"></a>  <span class="op">&amp;</span>n<span class="op">=</span>__ <span class="op">=&gt;</span> mutate<span class="op">(</span>n<span class="op">)</span>; <span class="co">// SUCCEEDS, n is requested to be mutable</span></span>
<span id="cb26-8"><a href="#cb26-8"></a>  <span class="op">...</span></span>
<span id="cb26-9"><a href="#cb26-9"></a><span class="op">}</span>;</span></code></pre></div>
<p><strong>Binding to preexisting variables</strong>:</p>
<div class="sourceCode" id="cb27"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb27-1"><a href="#cb27-1"></a><span class="dt">int</span> number <span class="op">=</span> <span class="op">...</span>;</span>
<span id="cb27-2"><a href="#cb27-2"></a></span>
<span id="cb27-3"><a href="#cb27-3"></a><span class="dt">int</span> n;</span>
<span id="cb27-4"><a href="#cb27-4"></a></span>
<span id="cb27-5"><a href="#cb27-5"></a>inspect <span class="op">(</span>number<span class="op">)</span> <span class="op">{</span></span>
<span id="cb27-6"><a href="#cb27-6"></a>  <span class="op">&amp;</span>n __ <span class="op">=&gt;</span> mutate<span class="op">(</span>n<span class="op">)</span>; <span class="co">// binding to existing variable with the same value as ::number</span></span>
<span id="cb27-7"><a href="#cb27-7"></a>  <span class="co">// or just &amp;n omitting the __ </span></span>
<span id="cb27-8"><a href="#cb27-8"></a>  <span class="op">...</span></span>
<span id="cb27-9"><a href="#cb27-9"></a><span class="op">}</span></span></code></pre></div>
<p>Compared to lambda side by side:</p>
<div class="columns">
<div class="column" style="width:50%;">
<p><strong>lambda capture</strong></p>
<div class="sourceCode" id="cb28"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb28-1"><a href="#cb28-1"></a><span class="dt">int</span> x,y,z;</span>
<span id="cb28-2"><a href="#cb28-2"></a></span>
<span id="cb28-3"><a href="#cb28-3"></a></span>
<span id="cb28-4"><a href="#cb28-4"></a><span class="op">[</span> x<span class="op">=</span> <span class="op">...</span>, <span class="co">// new x</span></span>
<span id="cb28-5"><a href="#cb28-5"></a> <span class="op">&amp;</span>y<span class="op">=</span> <span class="op">...</span>, <span class="co">// new y, but reference </span></span>
<span id="cb28-6"><a href="#cb28-6"></a> <span class="op">&amp;</span>z       <span class="co">// existing z reference</span></span>
<span id="cb28-7"><a href="#cb28-7"></a><span class="op">]{...}</span>;</span></code></pre></div>
</div><div class="column" style="width:50%;">
<p><strong>PM bindings</strong></p>
<div class="sourceCode" id="cb29"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb29-1"><a href="#cb29-1"></a><span class="dt">int</span> x,y,z;</span>
<span id="cb29-2"><a href="#cb29-2"></a></span>
<span id="cb29-3"><a href="#cb29-3"></a>inspect <span class="op">(...)</span> <span class="op">{</span></span>
<span id="cb29-4"><a href="#cb29-4"></a>  x<span class="op">=</span> <span class="op">...</span> <span class="op">=&gt;</span> <span class="co">// new x</span></span>
<span id="cb29-5"><a href="#cb29-5"></a> <span class="op">&amp;</span>y<span class="op">=</span> <span class="op">...</span> <span class="op">=&gt;</span> <span class="co">// new y, but reference </span></span>
<span id="cb29-6"><a href="#cb29-6"></a> <span class="op">&amp;</span>z  <span class="op">...</span> <span class="op">=&gt;</span> <span class="co">// existing z reference</span></span>
<span id="cb29-7"><a href="#cb29-7"></a><span class="op">}</span>;</span></code></pre></div>
</div>
</div>
<blockquote>
<p>Arguably, assignment to existing variable in PM could look confusing when combined with other patterns. For example <code>&amp;z 5</code> will be the syntax to assign to a preexisting <code>z</code> if its value is <code>5</code>. We have assignment without <code>=</code>, which is far from great. However, this use-case is rare, it is not even proposed in currently active proposals. As such, this paper is willing to accept this downside for the other benefits this approach brings.</p>
</blockquote>
<p>As suggested, lambda captures and PM bindings are quite similar. In both minimal syntax is paramount. In both there are no uninitialized state. Both introduce the variables in a special, limited scope. The variables themselves in both cases have the same restricted, concise requirements - to introduce a value name, to introduce a reference name, to reuse a value name. This is a bit different to regular variables, which have greater available options to choose from, like opting for a pointer. Here, in lambda and PM, we have only 3 options, covering our use cases in a more manageable, simple manner.</p>
<blockquote>
<p>In fact PM bindings, because they are not manually assigned, will be more limited even then lambda captures as type conversion is not possible.</p>
</blockquote>
<p>Of course the details b/w bindings and captures will not be the same, but this is mainly due to different liftime and implementation requirements, not so much because semantic differences. In fact, there are no semantic difference b/w regular variables and captures and bindings, and this is why it is of benefit to not introduce a completely new syntax just to cover one of those. More over, it should be reminded, the capture syntax is not a new syntax, just a cut down version of the existing one. Adopting it for PM <em>will</em> see differences in the internal representation and it might no longer match the representation of a regular variable, or capture, written with the same syntax: Bindings might be represented by const references, not copies; mutable bindings might be represented by pointers, even views, not straight-as-written C++ references. None of those however are changes, that introduce a different meaning of the code, creating new abstractions which require a different form of expression.</p>
<p>Moving further, another significant gain by this approach is the fact, <strong>we can name types directly!</strong><br />
Because all identifiers so far were “marked” by additional tokens, we could finally have “unmarked” names for types:</p>
<div class="sourceCode" id="cb30"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb30-1"><a href="#cb30-1"></a>inspect <span class="op">(...)</span> <span class="op">{</span></span>
<span id="cb30-2"><a href="#cb30-2"></a>  <span class="dt">int</span> __ <span class="op">=&gt;</span> <span class="co">// match int</span></span>
<span id="cb30-3"><a href="#cb30-3"></a>  <span class="op">...</span></span>
<span id="cb30-4"><a href="#cb30-4"></a><span class="op">}</span>;</span></code></pre></div>
<p>Having natural type selection is a fundamental benefit, resurrecting the “dream syntax” from a decade ago, one w/o special tokens like <code>&lt;&gt;</code> or additional language features like <code>as</code>.</p>
<p>Putting it all together, we have <strong>a complete set with zero ambiguity:</strong></p>
<div class="sourceCode" id="cb31"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb31-1"><a href="#cb31-1"></a><span class="kw">struct</span> size<span class="op">{...}</span>;</span>
<span id="cb31-2"><a href="#cb31-2"></a>size size;</span>
<span id="cb31-3"><a href="#cb31-3"></a>inspect <span class="op">(...)</span> <span class="op">{</span></span>
<span id="cb31-4"><a href="#cb31-4"></a>   size  <span class="op">=&gt;</span> <span class="co">// match the ::size type</span></span>
<span id="cb31-5"><a href="#cb31-5"></a>   size<span class="op">=</span> <span class="op">=&gt;</span> <span class="co">// new `size` binding, hiding ::size</span></span>
<span id="cb31-6"><a href="#cb31-6"></a>  <span class="op">&amp;</span>size<span class="op">=</span> <span class="op">=&gt;</span> <span class="co">// new `size` binding, hiding ::size, mutable</span></span>
<span id="cb31-7"><a href="#cb31-7"></a>  <span class="op">&amp;</span>size  <span class="op">=&gt;</span> <span class="co">// assign to the ::size variable</span></span>
<span id="cb31-8"><a href="#cb31-8"></a>  <span class="op">==</span>size <span class="op">=&gt;</span> <span class="co">// match sizes, same as ::size</span></span>
<span id="cb31-9"><a href="#cb31-9"></a>  <span class="op">&lt;=</span>size <span class="op">=&gt;</span> <span class="co">// match sizes, less-then-or-equal to ::size</span></span>
<span id="cb31-10"><a href="#cb31-10"></a>  <span class="op">&gt;=</span>size <span class="op">=&gt;</span> <span class="co">// match sizes, greater-then-or-equal to ::size</span></span>
<span id="cb31-11"><a href="#cb31-11"></a>  <span class="op">&gt;</span> size <span class="op">=&gt;</span> <span class="co">// match sizes, greater then ::size</span></span>
<span id="cb31-12"><a href="#cb31-12"></a>  <span class="op">&lt;</span> size <span class="op">=&gt;</span> <span class="co">// match sizes, less then ::size</span></span>
<span id="cb31-13"><a href="#cb31-13"></a>  <span class="op">...</span></span>
<span id="cb31-14"><a href="#cb31-14"></a><span class="op">}</span>;</span></code></pre></div>
</section>
<section id="proposal" data-number="4">
<h1 data-number="4"><span class="header-section-number">4</span> Proposal<a href="#proposal" class="self-link"></a></h1>
<p>The above study is not proposed in its entirety or detail. In particular, <em>binding to existing variables, as well as the greater-then and less-then comparisons are <strong>not</strong> proposed.</em> This proposal considers these to be future direction or at least future proofing for not writing ourselves into a corner.</p>
<p>With that out of the way, <strong>proposed identifiers are</strong>:</p>
<ul>
<li><em>id</em> - type name<br />
</li>
<li><em>id</em><code>=</code> - immutable binding<br />
</li>
<li><code>&amp;</code><em>id</em><code>=</code> - mutable binding<br />
</li>
<li><code>==</code><em>id</em> - variable for equality comparison</li>
</ul>
<p>Proposed is also a slightly different, more user-friendly version of the above specification.<br />
In particular, having to compare to a value using <code>==</code> can get verbose and might seem atypical. Similarly, but to a lesser degree, having single identifier to mean a type name might be confusing:</p>
<div class="sourceCode" id="cb32"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb32-1"><a href="#cb32-1"></a><span class="kw">struct</span> size<span class="op">{...}</span>;</span>
<span id="cb32-2"><a href="#cb32-2"></a>size size;</span>
<span id="cb32-3"><a href="#cb32-3"></a></span>
<span id="cb32-4"><a href="#cb32-4"></a>inspect <span class="op">(...){</span></span>
<span id="cb32-5"><a href="#cb32-5"></a>   size         <span class="op">=&gt;</span> <span class="co">//&lt; There is a certain expectation, this is a value, not a type, we compare against!</span></span>
<span id="cb32-6"><a href="#cb32-6"></a>   <span class="op">[</span>size, size<span class="op">]</span> <span class="op">=&gt;</span> <span class="co">//&lt; Here as well</span></span>
<span id="cb32-7"><a href="#cb32-7"></a><span class="op">}</span>;</span></code></pre></div>
<p>To account for that, <strong>proposed</strong> is to have the <code>==</code> be <em>optional</em> if it is the last pattern, which is often the case.</p>
<blockquote>
<p>“Last pattern” is the one that is matched after all other patters in the current branch of the PM tree structure are matched.<br />
For example the pattern <code>[x=5, x]</code> is a tree structure as follows:<br />
<strong>1:</strong> match layout of two items.<br />
<strong>2a:</strong> bind value of the first item to an <code>x</code>. <strong>2b:</strong> test second value for equality to <code>x</code>.<br />
<strong>2a.1:</strong> test first value for equality to 5.<br />
Both <strong>2b</strong> and <strong>2a.1</strong> are last patterns, because it is where each branch, <strong>2a</strong> and <strong>2b</strong>, ends.</p>
</blockquote>
<p>Further, to avoid ambiguity, the type name must never be the last pattern. In practice this means, to match on type alone, one must follow up it’s name with another pattern, like <code>__</code>:</p>
<div class="sourceCode" id="cb33"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb33-1"><a href="#cb33-1"></a><span class="kw">struct</span> size<span class="op">{...}</span>;</span>
<span id="cb33-2"><a href="#cb33-2"></a>size size;</span>
<span id="cb33-3"><a href="#cb33-3"></a></span>
<span id="cb33-4"><a href="#cb33-4"></a>inspect <span class="op">(...){</span></span>
<span id="cb33-5"><a href="#cb33-5"></a>   size __          <span class="op">=&gt;</span> <span class="co">//&lt; Size is definitely a type</span></span>
<span id="cb33-6"><a href="#cb33-6"></a>   size             <span class="op">=&gt;</span> <span class="co">//&lt; Value matched, &quot;as expected&quot;</span></span>
<span id="cb33-7"><a href="#cb33-7"></a>   <span class="op">[</span>size, size<span class="op">]</span>     <span class="op">=&gt;</span> <span class="co">//&lt; Values here as well*</span></span>
<span id="cb33-8"><a href="#cb33-8"></a>   <span class="op">[==</span>size, <span class="op">==</span>size<span class="op">]</span> <span class="op">=&gt;</span> <span class="co">//&lt; Same as above, more verbose, but more clear?</span></span>
<span id="cb33-9"><a href="#cb33-9"></a>   </span>
<span id="cb33-10"><a href="#cb33-10"></a>   size size     <span class="op">=&gt;</span>       <span class="co">//&lt; also valid, type is size, value equals the ::size variable</span></span>
<span id="cb33-11"><a href="#cb33-11"></a>   size <span class="op">(==</span>size<span class="op">)</span> <span class="op">=&gt;</span>       <span class="co">//&lt; same as above, but more clear</span></span>
<span id="cb33-12"><a href="#cb33-12"></a><span class="op">}</span>;</span>
<span id="cb33-13"><a href="#cb33-13"></a></span>
<span id="cb33-14"><a href="#cb33-14"></a><span class="co">// *assuming some hypothetical structure, deconstructed into 2 sizes</span></span></code></pre></div>
<p>There are cases however, where <code>==</code> <strong>is still required</strong>:</p>
<div class="sourceCode" id="cb34"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb34-1"><a href="#cb34-1"></a><span class="kw">struct</span> Size<span class="op">{...}</span>;</span>
<span id="cb34-2"><a href="#cb34-2"></a>Size size;</span>
<span id="cb34-3"><a href="#cb34-3"></a></span>
<span id="cb34-4"><a href="#cb34-4"></a>inspect <span class="op">(...){</span></span>
<span id="cb34-5"><a href="#cb34-5"></a><span class="co">//     size[w=, h=]  =&gt;  // Error, no type named size</span></span>
<span id="cb34-6"><a href="#cb34-6"></a><span class="co">// Size size[w=, h=] =&gt;  // Same, also an error (attempt for two type matches one after another)</span></span>
<span id="cb34-7"><a href="#cb34-7"></a>     <span class="op">==</span>size<span class="op">[</span>w<span class="op">=</span>, h<span class="op">=]</span>  <span class="op">=&gt;</span>  <span class="co">// OK, match ::size </span></span>
<span id="cb34-8"><a href="#cb34-8"></a><span class="op">}</span>;</span></code></pre></div>
<p>Omitting the <code>==</code> here is not allowed because the pattern <em>is not</em> the last one. We continue with a deconstruction and binding the width and height to <code>w</code> and <code>h</code> respectively. In that case an attempt is made to match on a type, named <code>size</code>, not a value. To request match by value instead, <code>==</code> must be is used.</p>
<p>Likewise the type match <em>must not</em> be the last pattern:</p>
<div class="sourceCode" id="cb35"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb35-1"><a href="#cb35-1"></a><span class="kw">struct</span> Size<span class="op">{...}</span>;</span>
<span id="cb35-2"><a href="#cb35-2"></a>Size size;</span>
<span id="cb35-3"><a href="#cb35-3"></a></span>
<span id="cb35-4"><a href="#cb35-4"></a><span class="kw">struct</span> Rectangle <span class="op">{</span> <span class="dt">int</span> x; <span class="dt">int</span> y; Size size; <span class="op">}</span>;</span>
<span id="cb35-5"><a href="#cb35-5"></a>Rectangle rect <span class="op">=</span> <span class="op">...</span>;</span>
<span id="cb35-6"><a href="#cb35-6"></a></span>
<span id="cb35-7"><a href="#cb35-7"></a>inspect <span class="op">(</span>rect<span class="op">)</span> <span class="op">{</span></span>
<span id="cb35-8"><a href="#cb35-8"></a><span class="co">//    [__, __, size __] =&gt; // Error, no type named size</span></span>
<span id="cb35-9"><a href="#cb35-9"></a>    <span class="op">[</span>__, __, <span class="op">==</span>size __<span class="op">]</span> <span class="op">=&gt;</span> <span class="co">// OK, explicit value match</span></span>
<span id="cb35-10"><a href="#cb35-10"></a>         <span class="op">[</span>__, __, size<span class="op">]</span> <span class="op">=&gt;</span> <span class="co">// OK, last pattern, match value</span></span>
<span id="cb35-11"><a href="#cb35-11"></a></span>
<span id="cb35-12"><a href="#cb35-12"></a><span class="co">//       [__, __, Size] =&gt; // Error, no such value (type match must not be last)</span></span>
<span id="cb35-13"><a href="#cb35-13"></a>      <span class="op">[</span>__, __, Size __<span class="op">]</span> <span class="op">=&gt;</span> <span class="co">// OK, not last pattern, match type</span></span>
<span id="cb35-14"><a href="#cb35-14"></a><span class="op">[</span>__, __, Size <span class="op">[</span>w<span class="op">=</span>, h<span class="op">=]]</span> <span class="op">=&gt;</span> <span class="co">// OK, not last pattern, match type</span></span>
<span id="cb35-15"><a href="#cb35-15"></a><span class="op">}</span>;</span></code></pre></div>
<p><strong>Advanced example</strong></p>
<div class="sourceCode" id="cb36"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb36-1"><a href="#cb36-1"></a><span class="dt">int</span> x <span class="op">=</span> <span class="dv">5</span>;</span>
<span id="cb36-2"><a href="#cb36-2"></a></span>
<span id="cb36-3"><a href="#cb36-3"></a>inspect <span class="op">(...){</span></span>
<span id="cb36-4"><a href="#cb36-4"></a>    x     <span class="op">=&gt;</span>        <span class="co">// match ::x</span></span>
<span id="cb36-5"><a href="#cb36-5"></a>    <span class="op">==</span>x   <span class="op">=&gt;</span>        <span class="co">// same as above, but explicit</span></span>
<span id="cb36-6"><a href="#cb36-6"></a>    x<span class="op">=</span>    <span class="op">=&gt;</span>        <span class="co">// new binding, hiding ::x</span></span>
<span id="cb36-7"><a href="#cb36-7"></a>    x<span class="op">=</span>x   <span class="op">=&gt;</span>        <span class="co">// new binding, match value ::x</span></span>
<span id="cb36-8"><a href="#cb36-8"></a>  x<span class="op">=(==</span>x<span class="op">)</span> <span class="op">=&gt;</span>        <span class="co">// same as above, but explicit</span></span>
<span id="cb36-9"><a href="#cb36-9"></a>  <span class="dt">int</span> x   <span class="op">=&gt;</span>        <span class="co">// match int, match value ::x</span></span>
<span id="cb36-10"><a href="#cb36-10"></a>  px<span class="op">=</span> <span class="op">(</span><span class="dt">int</span> x<span class="op">=</span>x<span class="op">)</span> <span class="op">=&gt;</span>  <span class="co">// bind px to a polymorphic type, then match the type to int, bind to int value named `x`, match value to ::x </span></span>
<span id="cb36-11"><a href="#cb36-11"></a>  <span class="dt">int</span> <span class="op">&amp;</span>x<span class="op">=</span>x      <span class="op">=&gt;</span>  <span class="co">// match int, bind to int value reference named `x`, match value of ::x</span></span>
<span id="cb36-12"><a href="#cb36-12"></a>  <span class="op">...</span></span>
<span id="cb36-13"><a href="#cb36-13"></a><span class="op">}</span>;</span></code></pre></div>
<section id="conclusion" data-number="4.1">
<h2 data-number="4.1"><span class="header-section-number">4.1</span> Conclusion<a href="#conclusion" class="self-link"></a></h2>
<p>Presented here was an investigation of identifiers usage inside PM, with the hope all limitations and use-cases are accounted for, at least in principal.<br />
Along that, a system of identifiers is presented, which accounts for all use cases, does not require new language syntax and is based on existing practices. A small, most useful subset is proposed as a way to handle identifiers in a practical PM implementation.<br />
Last but not least, suggested is that, by using the described system, it will be possible to have type matching in a natural way by just naming the type. This is the preferred way in most PM frameworks, both in C++ (all initial proposals) and other languages.</p>
<ul>
<li><code>int</code> - type matching (just state the type!)<br />
</li>
<li><code>x=</code> - immutable binding (<strong>safe default</strong> with minimal syntax)</li>
<li><code>&amp;x=</code> - mutable binding (<strong>explicit</strong> when modifying the inspeced object)</li>
</ul>
<p>Future extension</p>
<ul>
<li><code>&amp;x</code> - assign to an existing variable</li>
</ul>
</section>
<section id="more-examples" data-number="4.2">
<h2 data-number="4.2"><span class="header-section-number">4.2</span> More Examples<a href="#more-examples" class="self-link"></a></h2>
<section id="point-type-matching-and-deconstruction" data-number="4.2.1">
<h3 data-number="4.2.1"><span class="header-section-number">4.2.1</span> Point type matching and deconstruction<a href="#point-type-matching-and-deconstruction" class="self-link"></a></h3>
<div class="columns">
<div class="column" style="width:52%;">
<p><strong>This Proposal</strong></p>
<div class="sourceCode" id="cb37"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb37-1"><a href="#cb37-1"></a><span class="kw">struct</span> Point <span class="op">{...}</span>;</span>
<span id="cb37-2"><a href="#cb37-2"></a>Point p;</span>
<span id="cb37-3"><a href="#cb37-3"></a></span>
<span id="cb37-4"><a href="#cb37-4"></a><span class="dt">int</span> x <span class="op">=</span> <span class="dv">10</span>;</span>
<span id="cb37-5"><a href="#cb37-5"></a><span class="dt">int</span> y <span class="op">=</span> <span class="dv">20</span>;</span>
<span id="cb37-6"><a href="#cb37-6"></a></span>
<span id="cb37-7"><a href="#cb37-7"></a>inspect <span class="op">(...)</span> <span class="op">{</span></span>
<span id="cb37-8"><a href="#cb37-8"></a>  Point <span class="op">[</span>x, y<span class="op">]</span> <span class="op">=&gt;</span>     <span class="co">//&lt; Point type, at pos (::x, ::y)</span></span>
<span id="cb37-9"><a href="#cb37-9"></a>  Point <span class="op">[</span>x<span class="op">=</span>, y<span class="op">=]</span> <span class="op">=&gt;</span>   <span class="co">//&lt; Point type, bind x, y read only</span></span>
<span id="cb37-10"><a href="#cb37-10"></a>  Point <span class="op">[&amp;</span>x<span class="op">=</span>, <span class="op">&amp;</span>y<span class="op">=]</span> <span class="op">=&gt;</span> <span class="co">//&lt; Point type, bind x, y for read and write</span></span>
<span id="cb37-11"><a href="#cb37-11"></a></span>
<span id="cb37-12"><a href="#cb37-12"></a>  Point <span class="op">[</span>x<span class="op">=</span>, y<span class="op">]</span> <span class="op">=&gt;</span>    <span class="co">//&lt; Point type, at ::y pos, bind x pos to `x`</span></span>
<span id="cb37-13"><a href="#cb37-13"></a>  Point <span class="op">[</span>x, y<span class="op">=]</span> <span class="op">=&gt;</span>    <span class="co">//&lt; Point type, at ::x pos, bind x pos to `y`</span></span>
<span id="cb37-14"><a href="#cb37-14"></a>  Point <span class="op">[</span>x<span class="op">=</span>x, y<span class="op">=</span>y<span class="op">]</span> <span class="op">=&gt;</span> <span class="co">//&lt; Point type, at pos (::x, ::y), bind x, y</span></span>
<span id="cb37-15"><a href="#cb37-15"></a><span class="op">}</span>;</span></code></pre></div>
</div><div class="column" style="width:24%;">
<p><strong>Main Proposal</strong></p>
<div class="sourceCode" id="cb38"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb38-1"><a href="#cb38-1"></a><span class="kw">struct</span> Point <span class="op">{...}</span>;</span>
<span id="cb38-2"><a href="#cb38-2"></a>Point p;</span>
<span id="cb38-3"><a href="#cb38-3"></a></span>
<span id="cb38-4"><a href="#cb38-4"></a><span class="dt">int</span> x <span class="op">=</span> <span class="dv">10</span>;</span>
<span id="cb38-5"><a href="#cb38-5"></a><span class="dt">int</span> y <span class="op">=</span> <span class="dv">20</span>;</span>
<span id="cb38-6"><a href="#cb38-6"></a></span>
<span id="cb38-7"><a href="#cb38-7"></a>inspect <span class="op">(...)</span> <span class="op">{</span></span>
<span id="cb38-8"><a href="#cb38-8"></a>  <span class="op">&lt;</span>Point<span class="op">&gt;</span> <span class="op">[</span>x, y<span class="op">]</span> <span class="op">=&gt;</span>    </span>
<span id="cb38-9"><a href="#cb38-9"></a><span class="co">// N/A, always mutable</span></span>
<span id="cb38-10"><a href="#cb38-10"></a>  <span class="op">&lt;</span>Point<span class="op">&gt;</span> let <span class="op">[</span>x, y<span class="op">]</span> <span class="op">=&gt;</span>    </span>
<span id="cb38-11"><a href="#cb38-11"></a></span>
<span id="cb38-12"><a href="#cb38-12"></a>  <span class="op">&lt;</span>Point<span class="op">&gt;</span> <span class="op">[</span>let x, y<span class="op">]</span> <span class="op">=&gt;</span>    </span>
<span id="cb38-13"><a href="#cb38-13"></a>  <span class="op">&lt;</span>Point<span class="op">&gt;</span> <span class="op">[</span>x, let y<span class="op">]</span> <span class="op">=&gt;</span>    </span>
<span id="cb38-14"><a href="#cb38-14"></a>  <span class="op">&lt;</span>Point<span class="op">&gt;</span> <span class="op">[</span>let x<span class="op">=</span>x, let y<span class="op">=</span>y<span class="op">]</span> <span class="op">=&gt;</span></span>
<span id="cb38-15"><a href="#cb38-15"></a><span class="op">}</span>;</span></code></pre></div>
</div><div class="column" style="width:24%;">
<p><strong>Is As Proposal</strong></p>
<div class="sourceCode" id="cb39"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb39-1"><a href="#cb39-1"></a><span class="kw">struct</span> Point <span class="op">{...}</span>;</span>
<span id="cb39-2"><a href="#cb39-2"></a>Point p;</span>
<span id="cb39-3"><a href="#cb39-3"></a></span>
<span id="cb39-4"><a href="#cb39-4"></a><span class="dt">int</span> x <span class="op">=</span> <span class="dv">10</span>;</span>
<span id="cb39-5"><a href="#cb39-5"></a><span class="dt">int</span> y <span class="op">=</span> <span class="dv">20</span>;</span>
<span id="cb39-6"><a href="#cb39-6"></a></span>
<span id="cb39-7"><a href="#cb39-7"></a>inspect <span class="op">(...)</span> <span class="op">{</span></span>
<span id="cb39-8"><a href="#cb39-8"></a>  <span class="op">[</span>is x, is y<span class="op">]</span> as Point <span class="op">=&gt;</span>    </span>
<span id="cb39-9"><a href="#cb39-9"></a><span class="co">// N/A, always mutable</span></span>
<span id="cb39-10"><a href="#cb39-10"></a>  <span class="op">[</span>x, y<span class="op">]</span> as Point <span class="op">=&gt;</span>    </span>
<span id="cb39-11"><a href="#cb39-11"></a></span>
<span id="cb39-12"><a href="#cb39-12"></a>  <span class="op">[</span>x, is y<span class="op">]</span> as Point <span class="op">=&gt;</span>    </span>
<span id="cb39-13"><a href="#cb39-13"></a>  <span class="op">[</span>is x, y<span class="op">]</span> as Point <span class="op">=&gt;</span>    </span>
<span id="cb39-14"><a href="#cb39-14"></a>  <span class="op">[</span>x is x, y is y<span class="op">]</span> as Point <span class="op">=&gt;</span></span>
<span id="cb39-15"><a href="#cb39-15"></a><span class="op">}</span>;</span></code></pre></div>
</div>
</div>
</section>
<section id="explicitly-mutable-implicitly-immutable-bindings" data-number="4.2.2">
<h3 data-number="4.2.2"><span class="header-section-number">4.2.2</span> Explicitly mutable, implicitly immutable bindings<a href="#explicitly-mutable-implicitly-immutable-bindings" class="self-link"></a></h3>
<div class="sourceCode" id="cb40"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb40-1"><a href="#cb40-1"></a><span class="kw">struct</span> Person<span class="op">{</span> std<span class="op">::</span>string name; <span class="ex">uint</span> age; <span class="op">}</span>;</span>
<span id="cb40-2"><a href="#cb40-2"></a></span>
<span id="cb40-3"><a href="#cb40-3"></a><span class="dt">void</span> yearCycle<span class="op">(</span>Person<span class="op">&amp;</span> p<span class="op">)</span> <span class="op">{</span></span>
<span id="cb40-4"><a href="#cb40-4"></a>  <span class="op">...</span></span>
<span id="cb40-5"><a href="#cb40-5"></a>  inspect <span class="op">(</span>p<span class="op">)</span> <span class="op">{</span></span>
<span id="cb40-6"><a href="#cb40-6"></a>    <span class="op">[</span>name<span class="op">=</span>, <span class="op">&amp;</span>age<span class="op">=]</span> <span class="op">=&gt;</span> std<span class="op">::</span>invoke<span class="op">([&amp;]{</span></span>
<span id="cb40-7"><a href="#cb40-7"></a>      age<span class="op">++</span>;           <span class="co">// increase age</span></span>
<span id="cb40-8"><a href="#cb40-8"></a>      <span class="cf">if</span><span class="op">(</span>name <span class="op">=</span> <span class="st">&quot;Bob&quot;</span><span class="op">)</span> <span class="co">// Error, name is immutable</span></span>
<span id="cb40-9"><a href="#cb40-9"></a>        sendHappyBirthdayToBob<span class="op">()</span>;</span>
<span id="cb40-10"><a href="#cb40-10"></a>    <span class="op">})</span>;</span>
<span id="cb40-11"><a href="#cb40-11"></a>  <span class="op">}</span>;</span>
<span id="cb40-12"><a href="#cb40-12"></a><span class="op">}</span></span></code></pre></div>
</section>
<section id="pattern-matching-class-hierarchies" data-number="4.2.3">
<h3 data-number="4.2.3"><span class="header-section-number">4.2.3</span> Pattern matching class hierarchies<a href="#pattern-matching-class-hierarchies" class="self-link"></a></h3>
<div class="sourceCode" id="cb41"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb41-1"><a href="#cb41-1"></a><span class="kw">class</span> Animal <span class="op">{</span> <span class="kw">public</span><span class="op">:</span> <span class="kw">virtual</span> <span class="dt">void</span> speak<span class="op">()</span> <span class="kw">const</span> <span class="op">=</span> <span class="dv">0</span>; <span class="op">}</span>;</span>
<span id="cb41-2"><a href="#cb41-2"></a></span>
<span id="cb41-3"><a href="#cb41-3"></a><span class="kw">class</span> Cat <span class="op">:</span> <span class="kw">public</span> Animal <span class="op">{</span></span>
<span id="cb41-4"><a href="#cb41-4"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb41-5"><a href="#cb41-5"></a>  <span class="kw">virtual</span> <span class="dt">void</span> speak<span class="op">()</span> <span class="kw">const</span> <span class="kw">override</span> <span class="op">{</span>  std<span class="op">::</span>cout <span class="op">&lt;&lt;</span> <span class="st">&quot;Meow from &quot;</span> <span class="op">&lt;&lt;</span> name <span class="op">&lt;&lt;</span> std<span class="op">::</span>endl; <span class="op">}</span></span>
<span id="cb41-6"><a href="#cb41-6"></a></span>
<span id="cb41-7"><a href="#cb41-7"></a>  std<span class="op">::</span>string name;</span>
<span id="cb41-8"><a href="#cb41-8"></a><span class="op">}</span>;</span>
<span id="cb41-9"><a href="#cb41-9"></a></span>
<span id="cb41-10"><a href="#cb41-10"></a><span class="kw">class</span> Crow <span class="op">:</span> <span class="kw">public</span> Animal <span class="op">{</span></span>
<span id="cb41-11"><a href="#cb41-11"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb41-12"><a href="#cb41-12"></a>  <span class="kw">virtual</span> <span class="dt">void</span> speak<span class="op">()</span> <span class="kw">const</span> <span class="kw">override</span> <span class="op">{</span> std<span class="op">::</span>cout <span class="op">&lt;&lt;</span> <span class="st">&quot;Caaaw!&quot;</span> <span class="op">&lt;&lt;</span> std<span class="op">::</span>endl; <span class="op">}</span></span>
<span id="cb41-13"><a href="#cb41-13"></a><span class="op">}</span>;</span>
<span id="cb41-14"><a href="#cb41-14"></a></span>
<span id="cb41-15"><a href="#cb41-15"></a><span class="kw">const</span> <span class="dt">char</span><span class="op">*</span> fluffy <span class="op">=</span> <span class="st">&quot;Fluffy&quot;</span>;</span></code></pre></div>
<div class="columns">
<div class="column" style="width:33%;">
<p><strong>This Proposal</strong></p>
<div class="sourceCode" id="cb42"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb42-1"><a href="#cb42-1"></a><span class="dt">void</span> listen<span class="op">(</span><span class="kw">const</span> Animal <span class="op">&amp;</span>a<span class="op">)</span> <span class="op">{</span></span>
<span id="cb42-2"><a href="#cb42-2"></a>  inspect <span class="op">(</span>a<span class="op">)</span> <span class="op">{</span></span>
<span id="cb42-3"><a href="#cb42-3"></a>    Cat c<span class="op">=[</span>fluffy<span class="op">]</span> <span class="op">=&gt;</span> <span class="co">// use cat c</span></span>
<span id="cb42-4"><a href="#cb42-4"></a>    Cat <span class="op">[</span>name<span class="op">=]</span> <span class="op">=&gt;</span> <span class="co">// use name</span></span>
<span id="cb42-5"><a href="#cb42-5"></a>    Crow c<span class="op">=</span> <span class="op">=&gt;</span> <span class="co">// use crow c</span></span>
<span id="cb42-6"><a href="#cb42-6"></a>  <span class="op">}</span>;</span>
<span id="cb42-7"><a href="#cb42-7"></a><span class="op">}</span></span></code></pre></div>
</div><div class="column" style="width:33%;">
<p><strong>Main Proposal</strong></p>
<div class="sourceCode" id="cb43"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb43-1"><a href="#cb43-1"></a><span class="dt">void</span> listen<span class="op">(</span><span class="kw">const</span> Animal <span class="op">&amp;</span>a<span class="op">)</span> <span class="op">{</span></span>
<span id="cb43-2"><a href="#cb43-2"></a>  inspect<span class="op">(</span>a<span class="op">)</span> <span class="op">{</span></span>
<span id="cb43-3"><a href="#cb43-3"></a>    <span class="op">&lt;</span>Cat<span class="op">&gt;</span> <span class="op">(</span>at<span class="op">!)[</span>let c, <span class="op">[</span>fluffy<span class="op">]]</span> <span class="op">=&gt;</span> <span class="co">// use cat c</span></span>
<span id="cb43-4"><a href="#cb43-4"></a>    <span class="op">&lt;</span>Cat<span class="op">&gt;</span> <span class="op">[</span>name<span class="op">]</span> <span class="op">=&gt;</span> <span class="co">// use name</span></span>
<span id="cb43-5"><a href="#cb43-5"></a>    <span class="op">&lt;</span>Crow<span class="op">&gt;</span> let c <span class="op">=&gt;</span> <span class="co">// use crow c</span></span>
<span id="cb43-6"><a href="#cb43-6"></a>  <span class="op">}</span>;</span>
<span id="cb43-7"><a href="#cb43-7"></a><span class="op">}</span></span></code></pre></div>
</div><div class="column" style="width:33%;">
<p><strong>Is As Proposal</strong></p>
<div class="sourceCode" id="cb44"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb44-1"><a href="#cb44-1"></a><span class="dt">void</span> listen<span class="op">(</span><span class="kw">const</span> Animal <span class="op">&amp;</span>a<span class="op">)</span> <span class="op">{</span></span>
<span id="cb44-2"><a href="#cb44-2"></a> inspect <span class="op">(</span>a<span class="op">)</span> <span class="op">{</span></span>
<span id="cb44-3"><a href="#cb44-3"></a>  c as Cat is <span class="op">[</span>_ is fluffy<span class="op">]</span> <span class="op">=&gt;</span> <span class="co">// use cat c</span></span>
<span id="cb44-4"><a href="#cb44-4"></a>  c as Cat is <span class="op">[</span>name is _<span class="op">]</span> <span class="op">=&gt;</span> <span class="co">// use name</span></span>
<span id="cb44-5"><a href="#cb44-5"></a>  c as Crow <span class="op">=&gt;</span> <span class="co">// use crow c</span></span>
<span id="cb44-6"><a href="#cb44-6"></a> <span class="op">}</span>;</span>
<span id="cb44-7"><a href="#cb44-7"></a><span class="op">}</span></span></code></pre></div>
</div>
</div>
</section>
<section id="extreme-example" data-number="4.2.4">
<h3 data-number="4.2.4"><span class="header-section-number">4.2.4</span> Extreme example<a href="#extreme-example" class="self-link"></a></h3>
<p>The following example extremity stems for the fact, both value matching and binding are assumed to be commutative. If this is not the case, then the patterns must appear in some predefined order. Composability is out of scope for this paper</p>
<div class="sourceCode" id="cb45"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb45-1"><a href="#cb45-1"></a><span class="kw">struct</span> Size<span class="op">{...}</span>;</span>
<span id="cb45-2"><a href="#cb45-2"></a>Size size;</span>
<span id="cb45-3"><a href="#cb45-3"></a></span>
<span id="cb45-4"><a href="#cb45-4"></a>inspect <span class="op">(...){</span></span>
<span id="cb45-5"><a href="#cb45-5"></a>   Size size <span class="op">[</span>w<span class="op">=</span>, h<span class="op">=]</span> <span class="op">=&gt;</span>        <span class="co">//&lt; type is ::Size, value equals ::size, w and h are introduced</span></span>
<span id="cb45-6"><a href="#cb45-6"></a>   Size <span class="op">[</span>w<span class="op">=</span>, h<span class="op">=]</span> size  <span class="op">=&gt;</span>       <span class="co">//&lt; same as above</span></span>
<span id="cb45-7"><a href="#cb45-7"></a></span>
<span id="cb45-8"><a href="#cb45-8"></a>   Size sz<span class="op">=</span> <span class="op">[</span>w<span class="op">=</span>, h<span class="op">=]</span> size  <span class="op">=&gt;</span>   <span class="co">//&lt; same as above, but we also bind the size value to `sz`</span></span>
<span id="cb45-9"><a href="#cb45-9"></a>   Size size <span class="op">[</span>w<span class="op">=</span>, h<span class="op">=]</span> sz<span class="op">=</span>  <span class="op">=&gt;</span>   <span class="co">//&lt; same as above</span></span>
<span id="cb45-10"><a href="#cb45-10"></a>   Size sz<span class="op">=</span> <span class="op">[</span>w<span class="op">=</span>, h<span class="op">=]</span> <span class="op">==</span>size  <span class="op">=&gt;</span> <span class="co">//&lt; same as above (more clear)</span></span>
<span id="cb45-11"><a href="#cb45-11"></a></span>
<span id="cb45-12"><a href="#cb45-12"></a>   sz<span class="op">=</span> <span class="op">[</span>w<span class="op">=</span>, h<span class="op">=]</span> <span class="op">==</span>size  <span class="op">=&gt;</span>      <span class="co">//&lt; same as above, but valid for any type, not just ::Size</span></span>
<span id="cb45-13"><a href="#cb45-13"></a>   <span class="op">==</span>size <span class="op">[</span>w<span class="op">=</span>, h<span class="op">=]</span> sz<span class="op">=</span>  <span class="op">=&gt;</span>      <span class="co">//&lt; same as above</span></span>
<span id="cb45-14"><a href="#cb45-14"></a><span class="op">}</span>;</span></code></pre></div>
<hr />
</section>
</section>
</section>
<section class="footnotes" role="doc-endnotes">
<hr />
<ol>
<li id="fn1" role="doc-endnote"><p>Pattern Matching: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1371r3.pdf">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1371r3.pdf</a><a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn2" role="doc-endnote"><p>Pattern Matching Discussion for Kona 2022: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2688r0.pdf">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2688r0.pdf</a><a href="#fnref2" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn3" role="doc-endnote"><p>Pattern matching using is and as: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2392r1.pdf">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2392r1.pdf</a><a href="#fnref3" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn4" role="doc-endnote"><p>Pattern Matching for C++: <a href="https://www.stroustrup.com/pattern-matching-November-2014.pdf">https://www.stroustrup.com/pattern-matching-November-2014.pdf</a><a href="#fnref4" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn5" role="doc-endnote"><p>Pattern Matching and Language Variants: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0095r1.html">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0095r1.html</a><a href="#fnref5" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
</div>
</div>
</body>
</html>
