<story><title>Pattern matching accepted for Python</title><url>https://lwn.net/Articles/845480/</url></story><parent_chain><item><author>toxik</author><text>A previous mistake does not make a convincing argument for making a new mistake. Also, the mutable default arguments problem is quite difficult to solve in any other way. Python never copies things for you.&lt;p&gt;Pattern matching is a desired feature, but the shortcomings are too costly for what it provides. You just outlined yourself the quickest foot-gun I&amp;#x27;ve ever seen.&lt;p&gt;My second problem is that this violates many of the invariants you rely on while programming Python. f(x) always gives you the value of applying f to x. Nope, not in case. | means bitwise or. Nope, not in case. a means the value of a. NOPE. Not in case.</text></item><item><author>davesque</author><text>Honestly I&amp;#x27;m not sure what all the fuss is about.  I just skimmed over PEP 634 and PEP 636 (the accompanying tutorial) and I&amp;#x27;m actually kind of excited to use this.  I&amp;#x27;ve missed this feature after using langs like Rust, Haskell, and Scala.  People have pointed out some surprising edge cases such as this:&lt;p&gt;&lt;pre&gt;&lt;code&gt;    NOT_FOUND = 404
    match get_status():
        case NOT_FOUND:
            # this actually assigns to the global NOT_FOUND
            # and is effectively the default case
        case _:
            # this never gets triggered
&lt;/code&gt;&lt;/pre&gt;
Yeah, I agree that&amp;#x27;s a bit ugly.  But you &lt;i&gt;can&lt;/i&gt; apparently do this:&lt;p&gt;&lt;pre&gt;&lt;code&gt;    class Status(Enum):
        NOT_FOUND = 404

    match get_status():
        case Status.NOT_FOUND:
            # works as expected
        ...
&lt;/code&gt;&lt;/pre&gt;
And really how is any of that more ugly than this?&lt;p&gt;&lt;pre&gt;&lt;code&gt;    def func_with_default(foo={}):
        if &amp;quot;bar&amp;quot; not in foo:
            # &amp;quot;bar&amp;quot; is set in the module-level dict that
            # was initialized when the func def was parsed,
            # not in a dict that is created per call
            foo[&amp;quot;bar&amp;quot;] = ...
        ...
&lt;/code&gt;&lt;/pre&gt;
And we&amp;#x27;ve been living with that one for years.  These are just the things that you have to learn when you start using Python, just like any other language.&lt;p&gt;I, for one, am excited to start using this syntax.</text></item></parent_chain><comment><author>yatac42</author><text>&amp;gt; Also, the mutable default arguments problem is quite difficult to solve in any other way. Python never copies things for you.&lt;p&gt;Why would it need to copy anything? What&amp;#x27;s wrong with just evaluating the default argument expression every time the function is called with a default argument rather than once at definition-time? That&amp;#x27;s how it works in other languages.</text></comment>
<story><title>Pattern matching accepted for Python</title><url>https://lwn.net/Articles/845480/</url></story><parent_chain><item><author>toxik</author><text>A previous mistake does not make a convincing argument for making a new mistake. Also, the mutable default arguments problem is quite difficult to solve in any other way. Python never copies things for you.&lt;p&gt;Pattern matching is a desired feature, but the shortcomings are too costly for what it provides. You just outlined yourself the quickest foot-gun I&amp;#x27;ve ever seen.&lt;p&gt;My second problem is that this violates many of the invariants you rely on while programming Python. f(x) always gives you the value of applying f to x. Nope, not in case. | means bitwise or. Nope, not in case. a means the value of a. NOPE. Not in case.</text></item><item><author>davesque</author><text>Honestly I&amp;#x27;m not sure what all the fuss is about.  I just skimmed over PEP 634 and PEP 636 (the accompanying tutorial) and I&amp;#x27;m actually kind of excited to use this.  I&amp;#x27;ve missed this feature after using langs like Rust, Haskell, and Scala.  People have pointed out some surprising edge cases such as this:&lt;p&gt;&lt;pre&gt;&lt;code&gt;    NOT_FOUND = 404
    match get_status():
        case NOT_FOUND:
            # this actually assigns to the global NOT_FOUND
            # and is effectively the default case
        case _:
            # this never gets triggered
&lt;/code&gt;&lt;/pre&gt;
Yeah, I agree that&amp;#x27;s a bit ugly.  But you &lt;i&gt;can&lt;/i&gt; apparently do this:&lt;p&gt;&lt;pre&gt;&lt;code&gt;    class Status(Enum):
        NOT_FOUND = 404

    match get_status():
        case Status.NOT_FOUND:
            # works as expected
        ...
&lt;/code&gt;&lt;/pre&gt;
And really how is any of that more ugly than this?&lt;p&gt;&lt;pre&gt;&lt;code&gt;    def func_with_default(foo={}):
        if &amp;quot;bar&amp;quot; not in foo:
            # &amp;quot;bar&amp;quot; is set in the module-level dict that
            # was initialized when the func def was parsed,
            # not in a dict that is created per call
            foo[&amp;quot;bar&amp;quot;] = ...
        ...
&lt;/code&gt;&lt;/pre&gt;
And we&amp;#x27;ve been living with that one for years.  These are just the things that you have to learn when you start using Python, just like any other language.&lt;p&gt;I, for one, am excited to start using this syntax.</text></item></parent_chain><comment><author>globuous</author><text>Isn&amp;#x27;t it the same in ML though (using the same syntax in different contexts) ? Compare `| [a, b] =&amp;gt; a + b` and `let my_list = [a, b]`. Same in JS, `let {a, b} = {a: 1, b: 2}` and `let d = {a, b}`. It&amp;#x27;s weird at first but then you just get used to it.&lt;p&gt;edit: updated list name since pipe (&amp;quot;|&amp;quot;) and small L (&amp;quot;l&amp;quot;) look kind similar in the code snippets.</text></comment>