peps/pep-0275/index.html

480 lines
31 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="color-scheme" content="light dark">
<title>PEP 275 Switching on Multiple Values | peps.python.org</title>
<link rel="shortcut icon" href="../_static/py.png">
<link rel="canonical" href="https://peps.python.org/pep-0275/">
<link rel="stylesheet" href="../_static/style.css" type="text/css">
<link rel="stylesheet" href="../_static/mq.css" type="text/css">
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" media="(prefers-color-scheme: light)" id="pyg-light">
<link rel="stylesheet" href="../_static/pygments_dark.css" type="text/css" media="(prefers-color-scheme: dark)" id="pyg-dark">
<link rel="alternate" type="application/rss+xml" title="Latest PEPs" href="https://peps.python.org/peps.rss">
<meta property="og:title" content='PEP 275 Switching on Multiple Values | peps.python.org'>
<meta property="og:type" content="website">
<meta property="og:url" content="https://peps.python.org/pep-0275/">
<meta property="og:site_name" content="Python Enhancement Proposals (PEPs)">
<meta property="og:image" content="https://peps.python.org/_static/og-image.png">
<meta property="og:image:alt" content="Python PEPs">
<meta property="og:image:width" content="200">
<meta property="og:image:height" content="200">
<meta name="description" content="Python Enhancement Proposals (PEPs)">
<meta name="theme-color" content="#3776ab">
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="svg-sun-half" viewBox="0 0 24 24" pointer-events="all">
<title>Following system colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="9"></circle>
<path d="M12 3v18m0-12l4.65-4.65M12 14.3l7.37-7.37M12 19.6l8.85-8.85"></path>
</svg>
</symbol>
<symbol id="svg-moon" viewBox="0 0 24 24" pointer-events="all">
<title>Selected dark colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z"></path>
</svg>
</symbol>
<symbol id="svg-sun" viewBox="0 0 24 24" pointer-events="all">
<title>Selected light colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="5"></circle>
<line x1="12" y1="1" x2="12" y2="3"></line>
<line x1="12" y1="21" x2="12" y2="23"></line>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
<line x1="1" y1="12" x2="3" y2="12"></line>
<line x1="21" y1="12" x2="23" y2="12"></line>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
</svg>
</symbol>
</svg>
<script>
document.documentElement.dataset.colour_scheme = localStorage.getItem("colour_scheme") || "auto"
</script>
<section id="pep-page-section">
<header>
<h1>Python Enhancement Proposals</h1>
<ul class="breadcrumbs">
<li><a href="https://www.python.org/" title="The Python Programming Language">Python</a> &raquo; </li>
<li><a href="../pep-0000/">PEP Index</a> &raquo; </li>
<li>PEP 275</li>
</ul>
<button id="colour-scheme-cycler" onClick="setColourScheme(nextColourScheme())">
<svg aria-hidden="true" class="colour-scheme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
<svg aria-hidden="true" class="colour-scheme-icon-when-dark"><use href="#svg-moon"></use></svg>
<svg aria-hidden="true" class="colour-scheme-icon-when-light"><use href="#svg-sun"></use></svg>
<span class="visually-hidden">Toggle light / dark / auto colour theme</span>
</button>
</header>
<article>
<section id="pep-content">
<h1 class="page-title">PEP 275 Switching on Multiple Values</h1>
<dl class="rfc2822 field-list simple">
<dt class="field-odd">Author<span class="colon">:</span></dt>
<dd class="field-odd">Marc-André Lemburg &lt;mal&#32;&#97;t&#32;lemburg.com&gt;</dd>
<dt class="field-even">Status<span class="colon">:</span></dt>
<dd class="field-even"><abbr title="Formally declined and will not be accepted">Rejected</abbr></dd>
<dt class="field-odd">Type<span class="colon">:</span></dt>
<dd class="field-odd"><abbr title="Normative PEP with a new feature for Python, implementation change for CPython or interoperability standard for the ecosystem">Standards Track</abbr></dd>
<dt class="field-even">Created<span class="colon">:</span></dt>
<dd class="field-even">10-Nov-2001</dd>
<dt class="field-odd">Python-Version<span class="colon">:</span></dt>
<dd class="field-odd">2.6</dd>
<dt class="field-even">Post-History<span class="colon">:</span></dt>
<dd class="field-even"><p></p></dd>
</dl>
<hr class="docutils" />
<section id="contents">
<details><summary>Table of Contents</summary><ul class="simple">
<li><a class="reference internal" href="#rejection-notice">Rejection Notice</a></li>
<li><a class="reference internal" href="#abstract">Abstract</a></li>
<li><a class="reference internal" href="#problem">Problem</a></li>
<li><a class="reference internal" href="#proposed-solutions">Proposed Solutions</a><ul>
<li><a class="reference internal" href="#solution-1-optimizing-if-elif-else">Solution 1: Optimizing if-elif-else</a></li>
<li><a class="reference internal" href="#solution-2-adding-a-switch-statement-to-python">Solution 2: Adding a switch statement to Python</a><ul>
<li><a class="reference internal" href="#new-syntax">New Syntax</a></li>
<li><a class="reference internal" href="#implementation">Implementation</a></li>
<li><a class="reference internal" href="#issues">Issues</a></li>
</ul>
</li>
<li><a class="reference internal" href="#examples">Examples</a></li>
</ul>
</li>
<li><a class="reference internal" href="#scope">Scope</a></li>
<li><a class="reference internal" href="#credits">Credits</a></li>
<li><a class="reference internal" href="#references">References</a></li>
<li><a class="reference internal" href="#copyright">Copyright</a></li>
</ul>
</details></section>
<section id="rejection-notice">
<h2><a class="toc-backref" href="#rejection-notice" role="doc-backlink">Rejection Notice</a></h2>
<p>A similar PEP for Python 3000, <a class="pep reference internal" href="../pep-3103/" title="PEP 3103 A Switch/Case Statement">PEP 3103</a>, was already rejected,
so this proposal has no chance of being accepted either.</p>
</section>
<section id="abstract">
<h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2>
<p>This PEP proposes strategies to enhance Pythons performance
with respect to handling switching on a single variable having
one of multiple possible values.</p>
</section>
<section id="problem">
<h2><a class="toc-backref" href="#problem" role="doc-backlink">Problem</a></h2>
<p>Up to Python 2.5, the typical way of writing multi-value switches
has been to use long switch constructs of the following type:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="n">x</span> <span class="o">==</span> <span class="s1">&#39;first state&#39;</span><span class="p">:</span>
<span class="o">...</span>
<span class="k">elif</span> <span class="n">x</span> <span class="o">==</span> <span class="s1">&#39;second state&#39;</span><span class="p">:</span>
<span class="o">...</span>
<span class="k">elif</span> <span class="n">x</span> <span class="o">==</span> <span class="s1">&#39;third state&#39;</span><span class="p">:</span>
<span class="o">...</span>
<span class="k">elif</span> <span class="n">x</span> <span class="o">==</span> <span class="s1">&#39;fourth state&#39;</span><span class="p">:</span>
<span class="o">...</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># default handling</span>
<span class="o">...</span>
</pre></div>
</div>
<p>This works fine for short switch constructs, since the overhead of
repeated loading of a local (the variable x in this case) and
comparing it to some constant is low (it has a complexity of O(n)
on average). However, when using such a construct to write a state
machine such as is needed for writing parsers the number of
possible states can easily reach 10 or more cases.</p>
<p>The current solution to this problem lies in using a dispatch
table to find the case implementing method to execute depending on
the value of the switch variable (this can be tuned to have a
complexity of O(1) on average, e.g. by using perfect hash
tables). This works well for state machines which require complex
and lengthy processing in the different case methods. It does not
perform well for ones which only process one or two instructions
per case, e.g.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">handle_data</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">stack</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
</pre></div>
</div>
<p>A nice example of this is the state machine implemented in
pickle.py which is used to serialize Python objects. Other
prominent cases include XML SAX parsers and Internet protocol
handlers.</p>
</section>
<section id="proposed-solutions">
<h2><a class="toc-backref" href="#proposed-solutions" role="doc-backlink">Proposed Solutions</a></h2>
<p>This PEP proposes two different but not necessarily conflicting
solutions:</p>
<ol class="arabic simple">
<li>Adding an optimization to the Python compiler and VM
which detects the above if-elif-else construct and
generates special opcodes for it which use a read-only
dictionary for storing jump offsets.</li>
<li>Adding new syntax to Python which mimics the C style
switch statement.</li>
</ol>
<p>The first solution has the benefit of not relying on adding new
keywords to the language, while the second looks cleaner. Both
involve some run-time overhead to assure that the switching
variable is immutable and hashable.</p>
<p>Both solutions use a dictionary lookup to find the right
jump location, so they both share the same problem space in
terms of requiring that both the switch variable and the
constants need to be compatible to the dictionary implementation
(hashable, comparable, a==b =&gt; hash(a)==hash(b)).</p>
<section id="solution-1-optimizing-if-elif-else">
<h3><a class="toc-backref" href="#solution-1-optimizing-if-elif-else" role="doc-backlink">Solution 1: Optimizing if-elif-else</a></h3>
<p>Implementation:</p>
<p>It should be possible for the compiler to detect an
if-elif-else construct which has the following signature:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="n">x</span> <span class="o">==</span> <span class="s1">&#39;first&#39;</span><span class="p">:</span><span class="o">...</span>
<span class="k">elif</span> <span class="n">x</span> <span class="o">==</span> <span class="s1">&#39;second&#39;</span><span class="p">:</span><span class="o">...</span>
<span class="k">else</span><span class="p">:</span><span class="o">...</span>
</pre></div>
</div>
<p>i.e. the left hand side always references the same variable,
the right hand side a hashable immutable builtin type. The
right hand sides need not be all of the same type, but they
should be comparable to the type of the left hand switch
variable.</p>
<p>The compiler could then setup a read-only (perfect) hash
table, store it in the constants and add an opcode SWITCH in
front of the standard if-elif-else byte code stream which
triggers the following run-time behaviour:</p>
<p>At runtime, SWITCH would check x for being one of the
well-known immutable types (strings, unicode, numbers) and
use the hash table for finding the right opcode snippet. If
this condition is not met, the interpreter should revert to
the standard if-elif-else processing by simply skipping the
SWITCH opcode and proceeding with the usual if-elif-else byte
code stream.</p>
<p>Issues:</p>
<p>The new optimization should not change the current Python
semantics (by reducing the number of <code class="docutils literal notranslate"><span class="pre">__cmp__</span></code> calls and adding
<code class="docutils literal notranslate"><span class="pre">__hash__</span></code> calls in if-elif-else constructs which are affected
by the optimization). To assure this, switching can only
safely be implemented either if a “from __future__” style
flag is used, or the switching variable is one of the builtin
immutable types: int, float, string, unicode, etc. (not
subtypes, since its not clear whether these are still
immutable or not)</p>
<p>To prevent post-modifications of the jump-table dictionary
(which could be used to reach protected code), the jump-table
will have to be a read-only type (e.g. a read-only
dictionary).</p>
<p>The optimization should only be used for if-elif-else
constructs which have a minimum number of n cases (where n is
a number which has yet to be defined depending on performance
tests).</p>
</section>
<section id="solution-2-adding-a-switch-statement-to-python">
<h3><a class="toc-backref" href="#solution-2-adding-a-switch-statement-to-python" role="doc-backlink">Solution 2: Adding a switch statement to Python</a></h3>
<section id="new-syntax">
<h4><a class="toc-backref" href="#new-syntax" role="doc-backlink">New Syntax</a></h4>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">switch</span> <span class="n">EXPR</span><span class="p">:</span>
<span class="k">case</span> <span class="n">CONSTANT</span><span class="p">:</span>
<span class="n">SUITE</span>
<span class="k">case</span> <span class="n">CONSTANT</span><span class="p">:</span>
<span class="n">SUITE</span>
<span class="o">...</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">SUITE</span>
</pre></div>
</div>
<p>(modulo indentation variations)</p>
<p>The “else” part is optional. If no else part is given and
none of the defined cases matches, no action is taken and
the switch statement is ignored. This is in line with the
current if-behaviour. A user who wants to signal this
situation using an exception can define an else-branch
which then implements the intended action.</p>
<p>Note that the constants need not be all of the same type, but
they should be comparable to the type of the switch variable.</p>
</section>
<section id="implementation">
<h4><a class="toc-backref" href="#implementation" role="doc-backlink">Implementation</a></h4>
<p>The compiler would have to compile this into byte code
similar to this:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">whatis</span><span class="p">(</span><span class="n">x</span><span class="p">):</span>
<span class="n">switch</span><span class="p">(</span><span class="n">x</span><span class="p">):</span>
<span class="k">case</span> <span class="s1">&#39;one&#39;</span><span class="p">:</span>
<span class="nb">print</span> <span class="s1">&#39;1&#39;</span>
<span class="k">case</span> <span class="s1">&#39;two&#39;</span><span class="p">:</span>
<span class="nb">print</span> <span class="s1">&#39;2&#39;</span>
<span class="k">case</span> <span class="s1">&#39;three&#39;</span><span class="p">:</span>
<span class="nb">print</span> <span class="s1">&#39;3&#39;</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span> <span class="s2">&quot;D&#39;oh!&quot;</span>
</pre></div>
</div>
<p>into (omitting POP_TOPs and SET_LINENOs):</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="mi">6</span> <span class="n">LOAD_FAST</span> <span class="mi">0</span> <span class="p">(</span><span class="n">x</span><span class="p">)</span>
<span class="mi">9</span> <span class="n">LOAD_CONST</span> <span class="mi">1</span> <span class="p">(</span><span class="n">switch</span><span class="o">-</span><span class="n">table</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span>
<span class="mi">12</span> <span class="n">SWITCH</span> <span class="mi">26</span> <span class="p">(</span><span class="n">to</span> <span class="mi">38</span><span class="p">)</span>
<span class="mi">14</span> <span class="n">LOAD_CONST</span> <span class="mi">2</span> <span class="p">(</span><span class="s1">&#39;1&#39;</span><span class="p">)</span>
<span class="mi">17</span> <span class="n">PRINT_ITEM</span>
<span class="mi">18</span> <span class="n">PRINT_NEWLINE</span>
<span class="mi">19</span> <span class="n">JUMP</span> <span class="mi">43</span>
<span class="mi">22</span> <span class="n">LOAD_CONST</span> <span class="mi">3</span> <span class="p">(</span><span class="s1">&#39;2&#39;</span><span class="p">)</span>
<span class="mi">25</span> <span class="n">PRINT_ITEM</span>
<span class="mi">26</span> <span class="n">PRINT_NEWLINE</span>
<span class="mi">27</span> <span class="n">JUMP</span> <span class="mi">43</span>
<span class="mi">30</span> <span class="n">LOAD_CONST</span> <span class="mi">4</span> <span class="p">(</span><span class="s1">&#39;3&#39;</span><span class="p">)</span>
<span class="mi">33</span> <span class="n">PRINT_ITEM</span>
<span class="mi">34</span> <span class="n">PRINT_NEWLINE</span>
<span class="mi">35</span> <span class="n">JUMP</span> <span class="mi">43</span>
<span class="mi">38</span> <span class="n">LOAD_CONST</span> <span class="mi">5</span> <span class="p">(</span><span class="s2">&quot;D&#39;oh!&quot;</span><span class="p">)</span>
<span class="mi">41</span> <span class="n">PRINT_ITEM</span>
<span class="mi">42</span> <span class="n">PRINT_NEWLINE</span>
<span class="o">&gt;&gt;</span><span class="mi">43</span> <span class="n">LOAD_CONST</span> <span class="mi">0</span> <span class="p">(</span><span class="kc">None</span><span class="p">)</span>
<span class="mi">46</span> <span class="n">RETURN_VALUE</span>
</pre></div>
</div>
<p>Where the SWITCH opcode would jump to 14, 22, 30 or 38
depending on x.</p>
<p>Thomas Wouters has written a patch which demonstrates the
above. You can download it from <a class="footnote-reference brackets" href="#id2" id="id1">[1]</a>.</p>
</section>
<section id="issues">
<h4><a class="toc-backref" href="#issues" role="doc-backlink">Issues</a></h4>
<p>The switch statement should not implement fall-through
behaviour (as does the switch statement in C). Each case
defines a complete and independent suite; much like in an
if-elif-else statement. This also enables using break in
switch statements inside loops.</p>
<p>If the interpreter finds that the switch variable x is
not hashable, it should raise a TypeError at run-time
pointing out the problem.</p>
<p>There have been other proposals for the syntax which reuse
existing keywords and avoid adding two new ones (“switch” and
“case”). Others have argued that the keywords should use new
terms to avoid confusion with the C keywords of the same name
but slightly different semantics (e.g. fall-through without
break). Some of the proposed variants:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">case</span> <span class="n">EXPR</span><span class="p">:</span>
<span class="n">of</span> <span class="n">CONSTANT</span><span class="p">:</span>
<span class="n">SUITE</span>
<span class="n">of</span> <span class="n">CONSTANT</span><span class="p">:</span>
<span class="n">SUITE</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">SUITE</span>
<span class="k">case</span> <span class="n">EXPR</span><span class="p">:</span>
<span class="k">if</span> <span class="n">CONSTANT</span><span class="p">:</span>
<span class="n">SUITE</span>
<span class="k">if</span> <span class="n">CONSTANT</span><span class="p">:</span>
<span class="n">SUITE</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">SUITE</span>
<span class="n">when</span> <span class="n">EXPR</span><span class="p">:</span>
<span class="ow">in</span> <span class="n">CONSTANT_TUPLE</span><span class="p">:</span>
<span class="n">SUITE</span>
<span class="ow">in</span> <span class="n">CONSTANT_TUPLE</span><span class="p">:</span>
<span class="n">SUITE</span>
<span class="o">...</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">SUITE</span>
</pre></div>
</div>
<p>The switch statement could be extended to allow multiple
values for one section (e.g. case a, b, c: …). Another
proposed extension would allow ranges of values (e.g. case
10..14: …). These should probably be post-poned, but already
kept in mind when designing and implementing a first version.</p>
</section>
</section>
<section id="examples">
<h3><a class="toc-backref" href="#examples" role="doc-backlink">Examples</a></h3>
<p>The following examples all use a new syntax as proposed by
solution 2. However, all of these examples would work with
solution 1 as well.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">switch</span> <span class="n">EXPR</span><span class="p">:</span> <span class="n">switch</span> <span class="n">x</span><span class="p">:</span>
<span class="k">case</span> <span class="n">CONSTANT</span><span class="p">:</span> <span class="n">case</span> <span class="s2">&quot;first&quot;</span><span class="p">:</span>
<span class="n">SUITE</span> <span class="nb">print</span> <span class="n">x</span>
<span class="k">case</span> <span class="n">CONSTANT</span><span class="p">:</span> <span class="n">case</span> <span class="s2">&quot;second&quot;</span><span class="p">:</span>
<span class="n">SUITE</span> <span class="n">x</span> <span class="o">=</span> <span class="n">x</span><span class="o">**</span><span class="mi">2</span>
<span class="o">...</span> <span class="nb">print</span> <span class="n">x</span>
<span class="k">else</span><span class="p">:</span> <span class="k">else</span><span class="p">:</span>
<span class="n">SUITE</span> <span class="nb">print</span> <span class="s2">&quot;whoops!&quot;</span>
<span class="k">case</span> <span class="n">EXPR</span><span class="p">:</span> <span class="n">case</span> <span class="n">x</span><span class="p">:</span>
<span class="n">of</span> <span class="n">CONSTANT</span><span class="p">:</span> <span class="n">of</span> <span class="s2">&quot;first&quot;</span><span class="p">:</span>
<span class="n">SUITE</span> <span class="nb">print</span> <span class="n">x</span>
<span class="n">of</span> <span class="n">CONSTANT</span><span class="p">:</span> <span class="n">of</span> <span class="s2">&quot;second&quot;</span><span class="p">:</span>
<span class="n">SUITE</span> <span class="nb">print</span> <span class="n">x</span><span class="o">**</span><span class="mi">2</span>
<span class="k">else</span><span class="p">:</span> <span class="k">else</span><span class="p">:</span>
<span class="n">SUITE</span> <span class="nb">print</span> <span class="s2">&quot;whoops!&quot;</span>
<span class="k">case</span> <span class="n">EXPR</span><span class="p">:</span> <span class="n">case</span> <span class="n">state</span><span class="p">:</span>
<span class="k">if</span> <span class="n">CONSTANT</span><span class="p">:</span> <span class="k">if</span> <span class="s2">&quot;first&quot;</span><span class="p">:</span>
<span class="n">SUITE</span> <span class="n">state</span> <span class="o">=</span> <span class="s2">&quot;second&quot;</span>
<span class="k">if</span> <span class="n">CONSTANT</span><span class="p">:</span> <span class="k">if</span> <span class="s2">&quot;second&quot;</span><span class="p">:</span>
<span class="n">SUITE</span> <span class="n">state</span> <span class="o">=</span> <span class="s2">&quot;third&quot;</span>
<span class="k">else</span><span class="p">:</span> <span class="k">else</span><span class="p">:</span>
<span class="n">SUITE</span> <span class="n">state</span> <span class="o">=</span> <span class="s2">&quot;first&quot;</span>
<span class="n">when</span> <span class="n">EXPR</span><span class="p">:</span> <span class="n">when</span> <span class="n">state</span><span class="p">:</span>
<span class="ow">in</span> <span class="n">CONSTANT_TUPLE</span><span class="p">:</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;first&quot;</span><span class="p">,</span> <span class="s2">&quot;second&quot;</span><span class="p">):</span>
<span class="n">SUITE</span> <span class="nb">print</span> <span class="n">state</span>
<span class="ow">in</span> <span class="n">CONSTANT_TUPLE</span><span class="p">:</span> <span class="n">state</span> <span class="o">=</span> <span class="n">next_state</span><span class="p">(</span><span class="n">state</span><span class="p">)</span>
<span class="n">SUITE</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;seventh&quot;</span><span class="p">,):</span>
<span class="o">...</span> <span class="nb">print</span> <span class="s2">&quot;done&quot;</span>
<span class="k">else</span><span class="p">:</span> <span class="k">break</span> <span class="c1"># out of loop!</span>
<span class="n">SUITE</span> <span class="k">else</span><span class="p">:</span>
<span class="nb">print</span> <span class="s2">&quot;middle state&quot;</span>
<span class="n">state</span> <span class="o">=</span> <span class="n">next_state</span><span class="p">(</span><span class="n">state</span><span class="p">)</span>
</pre></div>
</div>
<p>Heres another nice application found by Jack Jansen (switching
on argument types):</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">switch</span> <span class="nb">type</span><span class="p">(</span><span class="n">x</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="p">:</span>
<span class="k">case</span> <span class="s1">&#39;int&#39;</span><span class="p">:</span>
<span class="n">SUITE</span>
<span class="k">case</span> <span class="s1">&#39;string&#39;</span><span class="p">:</span>
<span class="n">SUITE</span>
</pre></div>
</div>
</section>
</section>
<section id="scope">
<h2><a class="toc-backref" href="#scope" role="doc-backlink">Scope</a></h2>
<p>XXX Explain “from __future__ import switch”</p>
</section>
<section id="credits">
<h2><a class="toc-backref" href="#credits" role="doc-backlink">Credits</a></h2>
<ul class="simple">
<li>Martin von Löwis (issues with the optimization idea)</li>
<li>Thomas Wouters (switch statement + byte code compiler example)</li>
<li>Skip Montanaro (dispatching ideas, examples)</li>
<li>Donald Beaudry (switch syntax)</li>
<li>Greg Ewing (switch syntax)</li>
<li>Jack Jansen (type switching examples)</li>
</ul>
</section>
<section id="references">
<h2><a class="toc-backref" href="#references" role="doc-backlink">References</a></h2>
<aside class="footnote-list brackets">
<aside class="footnote brackets" id="id2" role="doc-footnote">
<dt class="label" id="id2">[<a href="#id1">1</a>]</dt>
<dd><a class="reference external" href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=481118&amp;group_id=5470&amp;atid=305470">https://sourceforge.net/tracker/index.php?func=detail&amp;aid=481118&amp;group_id=5470&amp;atid=305470</a></aside>
</aside>
</section>
<section id="copyright">
<h2><a class="toc-backref" href="#copyright" role="doc-backlink">Copyright</a></h2>
<p>This document has been placed in the public domain.</p>
</section>
</section>
<hr class="docutils" />
<p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-0275.rst">https://github.com/python/peps/blob/main/peps/pep-0275.rst</a></p>
<p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0275.rst">2023-09-09 17:39:29 GMT</a></p>
</article>
<nav id="pep-sidebar">
<h2>Contents</h2>
<ul>
<li><a class="reference internal" href="#rejection-notice">Rejection Notice</a></li>
<li><a class="reference internal" href="#abstract">Abstract</a></li>
<li><a class="reference internal" href="#problem">Problem</a></li>
<li><a class="reference internal" href="#proposed-solutions">Proposed Solutions</a><ul>
<li><a class="reference internal" href="#solution-1-optimizing-if-elif-else">Solution 1: Optimizing if-elif-else</a></li>
<li><a class="reference internal" href="#solution-2-adding-a-switch-statement-to-python">Solution 2: Adding a switch statement to Python</a><ul>
<li><a class="reference internal" href="#new-syntax">New Syntax</a></li>
<li><a class="reference internal" href="#implementation">Implementation</a></li>
<li><a class="reference internal" href="#issues">Issues</a></li>
</ul>
</li>
<li><a class="reference internal" href="#examples">Examples</a></li>
</ul>
</li>
<li><a class="reference internal" href="#scope">Scope</a></li>
<li><a class="reference internal" href="#credits">Credits</a></li>
<li><a class="reference internal" href="#references">References</a></li>
<li><a class="reference internal" href="#copyright">Copyright</a></li>
</ul>
<br>
<a id="source" href="https://github.com/python/peps/blob/main/peps/pep-0275.rst">Page Source (GitHub)</a>
</nav>
</section>
<script src="../_static/colour_scheme.js"></script>
<script src="../_static/wrap_tables.js"></script>
<script src="../_static/sticky_banner.js"></script>
</body>
</html>