26 votes

Python has accepted the proposal for a new pattern-matching structure, will be added in version 3.10

Tags: python

5 comments

  1. Deimos
    Link
    I submitted the main link as the "tutorial" page (PEP 636), since I think it's the best overview of this new structure and how it will work. Multiple other relevant links: Message to the mailing...

    I submitted the main link as the "tutorial" page (PEP 636), since I think it's the best overview of this new structure and how it will work. Multiple other relevant links:

    Python 3.10 is scheduled to release in October 2021, so this is still relatively far in the future.

    13 votes
  2. [4]
    bhrgunatha
    Link
    This comment on Hacker News highlights a gotcha which is not at all intuitive and alarming (to me).
    10 votes
    1. [3]
      Comment deleted by author
      Link Parent
      1. skybrian
        Link Parent
        Many languages with pattern matching don't even have mutation. One would expect it to define a new variable scoped to the pattern match.

        Many languages with pattern matching don't even have mutation. One would expect it to define a new variable scoped to the pattern match.

        7 votes
      2. bhrgunatha
        Link Parent
        I think it must be because I'm used to the situation where the "case" identifier introduces a new scope hiding the outer variable rather than assigning it.

        I think it must be because I'm used to the situation where the "case" identifier introduces a new scope hiding the outer variable rather than assigning it.

    2. jzimbel
      (edited )
      Link Parent
      At least coming from elixir, I don’t see a problem with this. The case some_variable simply matches any value and binds it to the variable some_variable. Semi-realistic code for handling http...

      At least coming from elixir, I don’t see a problem with this. The case some_variable simply matches any value and binds it to the variable some_variable.

      Semi-realistic code for handling http responses:

      response = {:ok, %{status: 404, body: "Not Found"}}
      
      case response do
        :error ->
          "network error"
      
        {:ok, %{status: 200}} ->
          "ok"
      
        # this will match and bind {:ok, %{status: 404, body: "Not Found"}} to `other`
        other ->
          log_bad_response(other)
          "bad response"
      end
      

      It might help if Python’s match construct had something like elixir’s pin operator ^ which lets you reference the value of a previously bound variable in a match case instead of binding to it.

      foo = "hello"
      bar = "world"
      
      case bar do
        ^foo -> "will not match since \"world\" != \"hello\""
        foo -> "matches and rebinds foo to \"world\" within the scope of this match clause"
      end
      

      Edit: I think I see what you meant now. In the linked example does the rebinding happen outside the scope of the pattern match? If so then yeah, that’s not great.

      2 votes