<!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-04-18" />
  <title>switch 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">switch for Pattern Matching</h1>

<table style="border:none;float:right">
  <tr>
    <td>Document #: </td>
    <td>P2940R0</td>
  </tr>
  <tr>
    <td>Date: </td>
    <td>2022-04-18</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 argues, <code>switch</code> should be (re-)considered for Pattern Matching.</p>
</section>
<section id="background" data-number="2">
<h1 data-number="2"><span class="header-section-number">2</span> Background<a href="#background" class="self-link"></a></h1>
<p>Current Pattern Matching (PM) approaches (p1371<a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a> + discussion,<a href="#fn2" class="footnote-ref" id="fnref2" role="doc-noteref"><sup>2</sup></a> p2392<a href="#fn3" class="footnote-ref" id="fnref3" role="doc-noteref"><sup>3</sup></a>) steer away from basing the PM upon the <code>switch</code>, extending it. This is done for two reasons.</p>
<ul>
<li>Technical difficulties in determining if an expression is C-style <code>switch</code> or a PM.</li>
<li>Teachability concerns, because of perceived differences b/w <code>switch</code> and PM.</li>
</ul>
<p>The first issue is undoubtedly valid, but is not unsolvable and a solution will be presented in the next section.<br />
The second issue is more interesting. This paper argues <code>switch</code> <em>is already</em> PM.<br />
There are simply few restrictions to apply in order to make a <code>switch</code>:</p>
<ul>
<li>the only pattern allowed, alongside the wildcard pattern, is an expression with integer result;<br />
</li>
<li>all patterns must be consteval;<br />
</li>
<li>all patterns must be OR-ed together;</li>
</ul>
<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">auto</span> some_value <span class="op">=</span> <span class="dv">2</span>;</span>
<span id="cb1-2"><a href="#cb1-2"></a></span>
<span id="cb1-3"><a href="#cb1-3"></a><span class="cf">switch</span> <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="cf">case</span> <span class="dv">1</span><span class="op">:</span></span>
<span id="cb1-5"><a href="#cb1-5"></a>  <span class="cf">case</span> <span class="dv">2</span><span class="op">:</span></span>
<span id="cb1-6"><a href="#cb1-6"></a>  <span class="cf">case</span> <span class="dv">3</span><span class="op">:</span> <span class="co">// execute the same code for all 3</span></span>
<span id="cb1-7"><a href="#cb1-7"></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">auto</span> some_value <span class="op">=</span> <span class="dv">2</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="dv">1</span> OR <span class="co">// (placeholder OR syntax)</span></span>
<span id="cb2-5"><a href="#cb2-5"></a> <span class="dv">2</span> OR </span>
<span id="cb2-6"><a href="#cb2-6"></a> <span class="dv">3</span> <span class="op">=&gt;</span> <span class="co">// execute the same code for all 3 </span></span>
<span id="cb2-7"><a href="#cb2-7"></a><span class="op">}</span>;</span></code></pre></div>
</div>
</div>
<p>PM now acts as a <code>switch</code>, working only on compile time integer expressions and will continue matching until all patterns are checked.<br />
…This is… as long there is one statement to execute. As we know, classic switch can execute multiple cases, even these not matched, because of fallthrough. In PM, assuming OR functionality, we can have multiple patterns evaluated, but they will have to lead to the same code. As shown, this is similar to fallthrough with empty cases, with added bonus of being explicit about it.</p>
<p>Considering fallthrough with non-empty cases is, if not a bad practice, a bad default, it turns out PM is simply more feature rich and safer <code>switch</code>.</p>
<p>The fact, <code>switch</code> is really just a very limited PM, is recognized by other languages and some of them use it directly for PM (Swift, C#, Java). What is more, <em>all</em> languages recognize <code>switch</code> and PM are <em>not</em> different features and <strong>no language has them both side by side!</strong> Either <code>switch</code> is used from the get go (Swift), or <code>switch</code> is evolved to handle more general patterns (C#, Java) or a different spelling is used (<code>match</code>, <code>when</code>, etc).</p>
<p>If C++ introduces a separate construct while keeping <code>switch</code> it will be the only one do so. This will hardly ease teachability. A better approach would be to have two levels of the existing <code>switch</code>, old and new, much like we have already with <code>enum</code> and <code>enum class</code>.</p>
<blockquote>
<p>An argument can also be made, we intend to make PM an expression, not a statement like <code>switch</code>. In practice however, a switch-like PM will be returning void, making the difference b/w it a the old switch only the need to use a semicolon after it.</p>
</blockquote>
<hr />
<p>OK, say for a moment, we have both the old <code>switch</code> and a PM system, called “inspect”.<br />
<em>When we will teach to use <code>switch</code>?</em> When we would say <em>don’t</em> use “inspect”? We can perform this kind of test with other control flow elements. For example, we can say, don’t use <code>if-else</code> chains, <em>because</em> and list few reasons. We can say, use <code>for</code> over <code>while</code>, <em>because</em> and we list again few good reasons.<br />
<em>Don’t</em> use “inspect”, <em>because</em>…? And we really have no <em>good</em> reason, <em>one we would teach.</em> Sure, sometimes fallthrough with non-empty cases is “handy”, <em>but would we teach it?</em> No. We would teach to keep using “inspect” and present options to solve the needs in a more structured way, like using recursion for example. <code>switch</code> will never be “the better tool for the job” simply because “inspect” effectively subsume it for all cases that matter.<br />
Now, one can argue, we have a similar precedent in the face of <code>using</code> replacing <code>typedef</code>. We introduced a new, more powerful tool, “that does the same”, under a completely different name, and left the old name alone.<br />
Even if we ignore the inherent problem of introducing “one more way to do the same thing”, the situation here is not the same. <code>using</code> introduced a new way to do a declaration (variable-like, left to right assignment), one that would eventually, naturally support template arguments. Achieving the same, reusing <code>typedef</code> would have been forced and contrived, even if possible syntactically. It is not the case here, we don’t need new form of anything. As you can see from the example above, both forms are almost identical, with further similarities explored in this paper. It is not like for example <code>switch</code>, compared to <code>if-else</code> chain, where the difference in form is considerable (arbitrary number of queried items in a chain, vs one queried item in a tree).</p>
<p>We <em>could</em> have both side by side, but we <em>don’t have to.</em> Especially, considering the painful process we’ll have to come through when introducing a keyword with as popular spelling as “inspect” or “match”, that also can’t be context aware my definition.</p>
</section>
<section id="proposal" data-number="3">
<h1 data-number="3"><span class="header-section-number">3</span> Proposal<a href="#proposal" class="self-link"></a></h1>
<p>In the previous section we mentioned the parsing challenge of differentiating b/w regular <code>switch</code> and one that does PM, if we opt to reuse the introducer keyword.<br />
This issue can be resolved by altering the syntax slightly and <strong>instead of using round parenthesis, we use square ones:</strong></p>
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1"></a><span class="cf">switch</span> <span class="op">(</span>a<span class="op">)</span>      <span class="co">//&lt; old C-switch for `a`</span></span>
<span id="cb3-2"><a href="#cb3-2"></a><span class="op">...</span></span>
<span id="cb3-3"><a href="#cb3-3"></a><span class="cf">switch</span> <span class="op">[</span>a<span class="op">]</span>      <span class="co">//&lt; pattern match for `a`</span></span>
<span id="cb3-4"><a href="#cb3-4"></a><span class="op">...</span></span>
<span id="cb3-5"><a href="#cb3-5"></a><span class="cf">switch</span> <span class="op">[</span>a, b<span class="op">]</span>   <span class="co">//&lt; pattern match for both `a` and `b`</span></span></code></pre></div>
<p><em>With square brackets after <code>switch</code>, a PM expression is introduced, instead of a C-style <code>switch</code> statement.</em></p>
<p>This way we not only can continue to use the already reserved keyword, but also have a safe-by-default <code>switch</code>, one that does not fallthrough:</p>
<div class="columns">
<div class="column" style="width:50%;">
<p><strong>regular switch</strong></p>
<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">auto</span> some_value <span class="op">=</span> <span class="dv">2</span>;</span>
<span id="cb4-2"><a href="#cb4-2"></a></span>
<span id="cb4-3"><a href="#cb4-3"></a><span class="cf">switch</span> <span class="op">(</span>some_value<span class="op">)</span> <span class="op">{</span></span>
<span id="cb4-4"><a href="#cb4-4"></a>  <span class="cf">case</span> <span class="dv">1</span><span class="op">:</span>   </span>
<span id="cb4-5"><a href="#cb4-5"></a>    <span class="op">...</span> </span>
<span id="cb4-6"><a href="#cb4-6"></a>    <span class="cf">break</span>;</span>
<span id="cb4-7"><a href="#cb4-7"></a>  <span class="cf">case</span> <span class="dv">2</span><span class="op">:</span>   </span>
<span id="cb4-8"><a href="#cb4-8"></a>    <span class="op">...</span> </span>
<span id="cb4-9"><a href="#cb4-9"></a>    <span class="co">// missed break</span></span>
<span id="cb4-10"><a href="#cb4-10"></a>  <span class="cf">case</span> <span class="dv">3</span><span class="op">:</span> </span>
<span id="cb4-11"><a href="#cb4-11"></a>    <span class="op">...</span> </span>
<span id="cb4-12"><a href="#cb4-12"></a>    <span class="cf">break</span>;</span>
<span id="cb4-13"><a href="#cb4-13"></a>  <span class="op">...</span></span>
<span id="cb4-14"><a href="#cb4-14"></a><span class="op">}</span></span></code></pre></div>
</div><div class="column" style="width:50%;">
<p><strong>safer switch</strong></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">auto</span> some_value <span class="op">=</span> <span class="dv">2</span>;</span>
<span id="cb5-2"><a href="#cb5-2"></a></span>
<span id="cb5-3"><a href="#cb5-3"></a><span class="cf">switch</span> <span class="op">[</span>some_value<span class="op">]</span> <span class="op">{</span></span>
<span id="cb5-4"><a href="#cb5-4"></a>  <span class="cf">case</span> <span class="dv">1</span><span class="op">:</span>   </span>
<span id="cb5-5"><a href="#cb5-5"></a>    <span class="op">...</span> </span>
<span id="cb5-6"><a href="#cb5-6"></a>    <span class="cf">break</span>;</span>
<span id="cb5-7"><a href="#cb5-7"></a>  <span class="cf">case</span> <span class="dv">2</span><span class="op">:</span>   </span>
<span id="cb5-8"><a href="#cb5-8"></a>    <span class="op">...</span> </span>
<span id="cb5-9"><a href="#cb5-9"></a>    <span class="co">// missed break, but no fallthrough</span></span>
<span id="cb5-10"><a href="#cb5-10"></a>  <span class="cf">case</span> <span class="dv">3</span><span class="op">:</span> </span>
<span id="cb5-11"><a href="#cb5-11"></a>    <span class="op">...</span> </span>
<span id="cb5-12"><a href="#cb5-12"></a>    <span class="cf">break</span>;</span>
<span id="cb5-13"><a href="#cb5-13"></a>  <span class="op">...</span></span>
<span id="cb5-14"><a href="#cb5-14"></a><span class="op">}</span>;</span></code></pre></div>
</div>
</div>
<p><em>The only textual difference between these two are the brackets after <code>switch</code> and a semicolon at the end.</em></p>
<p>All functionality of <code>switch</code> remains the same, with the exception of fallthrough, in particular <code>default</code>, <code>break</code>, <code>return</code> and <code>continue</code> work exactly the same as they do currently.</p>
<p>Because this is now PM, many new patterns are available. For example we can match strings:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb6-1"><a href="#cb6-1"></a><span class="kw">auto</span> some_value <span class="op">=</span> string<span class="op">(</span><span class="st">&quot;hi&quot;</span><span class="op">)</span>;</span>
<span id="cb6-2"><a href="#cb6-2"></a></span>
<span id="cb6-3"><a href="#cb6-3"></a><span class="cf">switch</span> <span class="op">[</span>some_value<span class="op">]</span> <span class="op">{</span></span>
<span id="cb6-4"><a href="#cb6-4"></a>  <span class="cf">case</span> <span class="st">&quot;hi&quot;</span><span class="op">:</span>   <span class="co">// handle &quot;hi&quot;</span></span>
<span id="cb6-5"><a href="#cb6-5"></a>  <span class="cf">case</span> <span class="st">&quot;bye&quot;</span><span class="op">:</span>  <span class="co">// handle &quot;bye&quot; </span></span>
<span id="cb6-6"><a href="#cb6-6"></a>  <span class="cf">default</span><span class="op">:</span>     <span class="co">// handle all else</span></span>
<span id="cb6-7"><a href="#cb6-7"></a><span class="op">}</span>;</span></code></pre></div>
<p>Or use advanced patterns:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1"></a><span class="kw">auto</span> some_value <span class="op">=</span> Point<span class="op">(</span><span class="dv">12</span>, <span class="dv">13</span><span class="op">)</span>;</span>
<span id="cb7-2"><a href="#cb7-2"></a></span>
<span id="cb7-3"><a href="#cb7-3"></a><span class="cf">switch</span> <span class="op">[</span>some_value<span class="op">]</span> <span class="op">{</span></span>
<span id="cb7-4"><a href="#cb7-4"></a>  <span class="cf">case</span> <span class="op">[</span><span class="dv">0</span>, <span class="dv">0</span><span class="op">]:</span> <span class="co">// handle point at origin </span></span>
<span id="cb7-5"><a href="#cb7-5"></a>  <span class="cf">case</span> <span class="op">[</span><span class="dv">0</span>, _<span class="op">]:</span> <span class="co">// handle x at origin </span></span>
<span id="cb7-6"><a href="#cb7-6"></a>  <span class="cf">case</span> <span class="op">[</span>_, <span class="dv">0</span><span class="op">]:</span> <span class="co">// handle y at origin </span></span>
<span id="cb7-7"><a href="#cb7-7"></a>  <span class="op">...</span></span>
<span id="cb7-8"><a href="#cb7-8"></a><span class="op">}</span>;</span></code></pre></div>
<p>In other words, <code>switch</code> becomes full-featured PM, <em>with barely any new syntax.</em><br />
If we want the expression to have a result, we use a different case syntax and optionally a return type, as per current main proposal (p1371):</p>
<div class="columns">
<div class="column" style="width:50%;">
<div class="sourceCode" id="cb8"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb8-1"><a href="#cb8-1"></a><span class="kw">auto</span> some_value <span class="op">=</span> <span class="kw">true</span>;</span>
<span id="cb8-2"><a href="#cb8-2"></a></span>
<span id="cb8-3"><a href="#cb8-3"></a><span class="kw">auto</span> result <span class="op">=</span> <span class="cf">switch</span> <span class="op">[</span>some_value<span class="op">]</span> <span class="op">{</span></span>
<span id="cb8-4"><a href="#cb8-4"></a>  <span class="kw">true</span> <span class="op">=&gt;</span> <span class="st">&quot;yes&quot;</span>;</span>
<span id="cb8-5"><a href="#cb8-5"></a>  <span class="kw">false</span> <span class="op">=&gt;</span> <span class="st">&quot;no&quot;</span>;</span>
<span id="cb8-6"><a href="#cb8-6"></a><span class="op">}</span>;</span></code></pre></div>
<p><em><code>result</code> is <code>const char*</code></em></p>
</div><div class="column" style="width:50%;">
<div class="sourceCode" id="cb9"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb9-1"><a href="#cb9-1"></a><span class="kw">auto</span> some_value <span class="op">=</span> <span class="kw">true</span>;</span>
<span id="cb9-2"><a href="#cb9-2"></a></span>
<span id="cb9-3"><a href="#cb9-3"></a><span class="kw">auto</span> result <span class="op">=</span> <span class="cf">switch</span> <span class="op">[</span>some_value<span class="op">]</span> <span class="op">-&gt;</span> std<span class="op">::</span>string <span class="op">{</span></span>
<span id="cb9-4"><a href="#cb9-4"></a>  <span class="kw">true</span> <span class="op">=&gt;</span> <span class="st">&quot;yes&quot;</span>;</span>
<span id="cb9-5"><a href="#cb9-5"></a>  <span class="kw">false</span> <span class="op">=&gt;</span> <span class="st">&quot;no&quot;</span>;</span>
<span id="cb9-6"><a href="#cb9-6"></a><span class="op">}</span>;</span></code></pre></div>
<p><em><code>result</code> is <code>std::string</code></em></p>
</div>
</div>
<p>Lastly, we can mix both case types.<br />
We use <code>case:</code> and <code>default</code>, when we want a statement.<br />
We use <code>=&gt;</code> and <code>__</code>, when we want a result-producing expression:</p>
<div class="columns">
<div class="column" style="width:50%;">
<p><strong>P1371</strong></p>
<div class="sourceCode" id="cb10"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb10-1"><a href="#cb10-1"></a><span class="kw">enum</span> <span class="kw">class</span> Op <span class="op">{</span> Add, Sub, Mul, Div <span class="op">}</span>;</span>
<span id="cb10-2"><a href="#cb10-2"></a>Op parseOp<span class="op">(</span>Parser<span class="op">&amp;</span> parser<span class="op">)</span> <span class="op">{</span></span>
<span id="cb10-3"><a href="#cb10-3"></a>  <span class="cf">return</span> inspect <span class="op">(</span>parser<span class="op">.</span>consumeToken<span class="op">())</span> <span class="op">{</span></span>
<span id="cb10-4"><a href="#cb10-4"></a>    <span class="ch">&#39;+&#39;</span> <span class="op">=&gt;</span> Op<span class="op">::</span>Add;</span>
<span id="cb10-5"><a href="#cb10-5"></a>    <span class="ch">&#39;-&#39;</span> <span class="op">=&gt;</span> Op<span class="op">::</span>Sub;</span>
<span id="cb10-6"><a href="#cb10-6"></a>    <span class="ch">&#39;*&#39;</span> <span class="op">=&gt;</span> Op<span class="op">::</span>Mul;</span>
<span id="cb10-7"><a href="#cb10-7"></a>    <span class="ch">&#39;/&#39;</span> <span class="op">=&gt;</span> Op<span class="op">::</span>Div;</span>
<span id="cb10-8"><a href="#cb10-8"></a>    let token <span class="op">=&gt;</span> <span class="op">!{</span></span>
<span id="cb10-9"><a href="#cb10-9"></a>      std<span class="op">::</span>cerr <span class="op">&lt;&lt;</span> <span class="st">&quot;Unexpected: &quot;</span> <span class="op">&lt;&lt;</span> token;</span>
<span id="cb10-10"><a href="#cb10-10"></a>      std<span class="op">::</span>terminate<span class="op">()</span>;</span>
<span id="cb10-11"><a href="#cb10-11"></a>    <span class="op">}</span></span>
<span id="cb10-12"><a href="#cb10-12"></a>  <span class="op">}</span>;</span>
<span id="cb10-13"><a href="#cb10-13"></a><span class="op">}</span></span></code></pre></div>
<p><em>A special <code>!{}</code> block invented.</em></p>
</div><div class="column" style="width:50%;">
<p><strong>This Proposal</strong></p>
<div class="sourceCode" id="cb11"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb11-1"><a href="#cb11-1"></a><span class="kw">enum</span> <span class="kw">class</span> Op <span class="op">{</span> Add, Sub, Mul, Div <span class="op">}</span>;</span>
<span id="cb11-2"><a href="#cb11-2"></a>Op parseOp<span class="op">(</span>Parser<span class="op">&amp;</span> parser<span class="op">)</span> <span class="op">{</span></span>
<span id="cb11-3"><a href="#cb11-3"></a>  <span class="cf">return</span> <span class="cf">switch</span> <span class="op">[</span>parser<span class="op">.</span>consumeToken<span class="op">()]</span> <span class="op">{</span></span>
<span id="cb11-4"><a href="#cb11-4"></a>    <span class="ch">&#39;+&#39;</span> <span class="op">=&gt;</span> Op<span class="op">::</span>Add;</span>
<span id="cb11-5"><a href="#cb11-5"></a>    <span class="ch">&#39;-&#39;</span> <span class="op">=&gt;</span> Op<span class="op">::</span>Sub;</span>
<span id="cb11-6"><a href="#cb11-6"></a>    <span class="ch">&#39;*&#39;</span> <span class="op">=&gt;</span> Op<span class="op">::</span>Mul;</span>
<span id="cb11-7"><a href="#cb11-7"></a>    <span class="ch">&#39;/&#39;</span> <span class="op">=&gt;</span> Op<span class="op">::</span>Div;</span>
<span id="cb11-8"><a href="#cb11-8"></a>    <span class="cf">case</span> <span class="op">[[</span><span class="at">noreturn</span><span class="op">]]</span> let token<span class="op">:</span> <span class="op">{</span></span>
<span id="cb11-9"><a href="#cb11-9"></a>      std<span class="op">::</span>cerr <span class="op">&lt;&lt;</span> <span class="st">&quot;Unexpected: &quot;</span> <span class="op">&lt;&lt;</span> token;</span>
<span id="cb11-10"><a href="#cb11-10"></a>      std<span class="op">::</span>terminate<span class="op">()</span>;</span>
<span id="cb11-11"><a href="#cb11-11"></a>    <span class="op">}</span></span>
<span id="cb11-12"><a href="#cb11-12"></a>  <span class="op">}</span>;</span>
<span id="cb11-13"><a href="#cb11-13"></a><span class="op">}</span></span></code></pre></div>
<p><em><strong>Reuse</strong> of <code>case</code> statements. <strong>Reuse</strong> of <code>[[noreturn]]</code>.</em></p>
</div>
</div>
<blockquote>
<p>This paper leaves many details out as they are already handled by P1371.</p>
</blockquote>
<p>As you can see, evolving <code>switch</code> to handle PM is not only possible, but ultimately natural and beneficial, improving <em>both</em> the existing <code>switch</code> uses (safer, reacher) and the PM development as we can reuse its building blocks like introducer keyword, statement cases, etc.<br />
Evolving <code>switch</code> also <em>keeps the language smaller.</em> There is less new syntax, less new ways of doing the same thing (!) and ultimately less new to learn for a newcomer.</p>
<blockquote>
<p>If we have both PM and switch, which one should be thought first? Probably PM, the modern system. And this will have to be with something simple, so simple that will resemble <code>switch</code>. But at some point, one will have to learn <code>switch</code> as well, repeating the same process twice, once using the new form, once using the older, combined with a lesson why and how these two are different. <strong>The more those two overlap, the less learning to be done.</strong></p>
</blockquote>
<section id="but-wait-there-is-more" data-number="3.0.1">
<h3 data-number="3.0.1"><span class="header-section-number">3.0.1</span> But Wait, There is More!<a href="#but-wait-there-is-more" class="self-link"></a></h3>
<blockquote>
<p>This is section is <strong>not proposed</strong>. It is here for possible future direction.</p>
</blockquote>
<p>There is on more gift, <code>switch</code> can give us and this <strong>reusing patterns outside PM!</strong><br />
One problem every PM system has is that patterns always use <em>at least some</em> syntax that is already present in the language to mean something different.<br />
This is not defect or deficiency, this is by design. In PM a pattern is declaration of expectation, which often matches the syntax of some real declaration or expression. This is <em>desirable,</em> this is what makes PM <em>natural.</em> In the regular language, when we say <code>0</code>, we mean “create/set” <code>0</code>, in PM, when we say <code>0</code>, we mean “is it” <code>0</code>. This basic logic is <em>ideally</em> applied to all patterns, whenever possible, creating a syntax, which reuses the regular syntax in a different context.</p>
<p>Of course, this creates a problem. “Ideal” patterns can not be used in regular code, even if it is desirable - they already mean something else.<br />
And that’s where <code>switch</code> again can be of help, because in <code>switch</code> <strong>patterns have an introducer keyword</strong> - <code>case</code>.</p>
<p>We only have to lift <code>case</code> out of <code>switch</code> and voila - we can have patterns inside regular code:</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb12-1"><a href="#cb12-1"></a><span class="kw">auto</span> p <span class="op">=</span> Point<span class="op">(</span><span class="dv">12</span>, <span class="dv">13</span><span class="op">)</span>;</span>
<span id="cb12-2"><a href="#cb12-2"></a></span>
<span id="cb12-3"><a href="#cb12-3"></a><span class="cf">if</span><span class="op">(</span><span class="cf">case</span> <span class="op">[</span>_, let x<span class="op">]</span> <span class="op">&amp;&amp;</span> <span class="op">[</span><span class="dv">0</span>,<span class="dv">0</span><span class="op">]</span> <span class="op">=</span> p<span class="op">)</span> <span class="op">{</span> <span class="co">//&lt; (using the Kona 2022 suggested syntax for the pattern)</span></span>
<span id="cb12-4"><a href="#cb12-4"></a>  <span class="co">// get x iff point is at origin</span></span>
<span id="cb12-5"><a href="#cb12-5"></a><span class="op">}</span></span></code></pre></div>
<p>The use of <code>case</code> here tells both us and the compiler, what follows is a pattern not regular code. This can change completely the meaning of the code:</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb13-1"><a href="#cb13-1"></a><span class="kw">auto</span> p <span class="op">=</span> Point<span class="op">(</span><span class="dv">12</span>, <span class="dv">13</span><span class="op">)</span>;</span>
<span id="cb13-2"><a href="#cb13-2"></a><span class="kw">auto</span> o <span class="op">=</span> Point<span class="op">(</span><span class="dv">0</span>, <span class="dv">0</span><span class="op">)</span>;</span>
<span id="cb13-3"><a href="#cb13-3"></a></span>
<span id="cb13-4"><a href="#cb13-4"></a><span class="cf">if</span><span class="op">(</span><span class="cf">case</span> o <span class="op">=</span> p<span class="op">)</span> <span class="op">{</span></span>
<span id="cb13-5"><a href="#cb13-5"></a>  <span class="co">// point is at origin, same as o == p</span></span>
<span id="cb13-6"><a href="#cb13-6"></a><span class="op">}</span></span></code></pre></div>
<p>Without <code>case</code>, the expression would mean assign to <code>o</code> and test the assigned value, now it means “conditionally assign” where the condition is the pattern and the assignment itself is optional. (We opt not to assign in that example.)</p>
<p>Use of patterns inside <code>if</code> might not be to anyone’s liking because of the assignment inside <code>if</code> - something we had problems with for decades. Here however, <code>case</code> is a clear indicator, this <code>if</code> is different. This is considerable improvement, compared to any form, that might use patterns (+ assignment) directly inside <code>if</code>. Still, is might be easier to stomach an approach where not the assignment, but the test is prevalent. This is approach Kona 2022<a href="#fn4" class="footnote-ref" id="fnref4" role="doc-noteref"><sup>4</sup></a> suggests, where a special, short form of PM exists, consisting only of introduction and patterns, no code. In the <code>switch</code> syntax it will look like that:</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb14-1"><a href="#cb14-1"></a><span class="cf">if</span><span class="op">(</span><span class="cf">switch</span> <span class="op">[</span>p<span class="op">]</span> <span class="op">[</span>_, let x<span class="op">]</span> <span class="op">&amp;&amp;</span> <span class="op">[</span><span class="dv">0</span>,<span class="dv">0</span><span class="op">])</span> <span class="op">{</span> <span class="co">//&lt; (using the Kona 2022 suggested syntax for the patterns)</span></span>
<span id="cb14-2"><a href="#cb14-2"></a>  <span class="co">// get x iff point is at origin</span></span>
<span id="cb14-3"><a href="#cb14-3"></a><span class="op">}</span></span></code></pre></div>
<p>Notice, there is no explicit assignment inside <code>if</code>, the test is more visible due to the use of <code>switch</code>.</p>
<p>There is one big problem however - this can not be used <em>outside</em> <code>if</code>, like in regular assignments. In that scenario, only <code>case</code> can save us:</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb15-1"><a href="#cb15-1"></a><span class="kw">auto</span> r <span class="op">=</span> Rect<span class="op">(</span><span class="dv">12</span>, <span class="dv">13</span>, <span class="dv">100</span>, <span class="dv">200</span><span class="op">)</span>;</span>
<span id="cb15-2"><a href="#cb15-2"></a></span>
<span id="cb15-3"><a href="#cb15-3"></a><span class="cf">case</span> <span class="op">[</span>let p, let <span class="op">[</span>_, h<span class="op">]]</span> <span class="op">=</span> r;</span></code></pre></div>
<p>This is an unconditional assignment where we use an advanced pattern to deconstruct the rect. <code>case</code> here ensures, the syntax is interpreted as a pattern.</p>
<p>In other words, no matter how much of the regular syntax we reuse, we are safe from ambiguity. For example we can invent a syntax, were we assign to an existing variable:</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb16-1"><a href="#cb16-1"></a><span class="kw">auto</span> p <span class="op">=</span> Point<span class="op">(</span><span class="dv">12</span>, <span class="dv">13</span><span class="op">)</span>;</span>
<span id="cb16-2"><a href="#cb16-2"></a><span class="dt">int</span> x, y;</span>
<span id="cb16-3"><a href="#cb16-3"></a></span>
<span id="cb16-4"><a href="#cb16-4"></a><span class="cf">case</span> <span class="op">[&amp;</span>x, <span class="op">&amp;</span>y<span class="op">]</span> <span class="op">=</span> p;</span></code></pre></div>
<p><em><code>x</code> is now 12, <code>y</code> is now 13</em></p>
<p>Here we are <em>clearly</em> reusing syntax, yet we are safe to do so - it is in a well-defined different context.</p>
<blockquote>
<p>Please note, a pattern <code>[x, y]</code> means “is equal to” a <code>Point(x, y)</code> as per p1371. We must have a different syntax.<br />
The good news are, this new syntax <strong>does not have to be unique to the language.</strong></p>
</blockquote>
<p>As you can see, <code>switch</code> has some unique properties, that bring considerable value to PM. We should not let these go to waste.</p>
<hr />
</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/2022/p2392r2.pdf">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2392r2.pdf</a><a href="#fnref3" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn4" 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="#fnref4" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
</div>
</div>
</body>
</html>
