On Wed, 8 Jul 2020 at 16:05, Guido van Rossum <guido@python.org> wrote:
Today I’m happy (and a little trepidatious) to announce the next
version of PEP 622, Pattern Matching. As authors we welcome Daniel F
Moisset in our midst. Daniel wrote a lot of the new text in this
version, which introduces the subject matter much more gently than the
first version did. He also convinced us to drop the `__match__`
protocol for now: the proposal stands quite well without that kind of
extensibility, and postponing it will allow us to design it at a later
time when we have more experience with how `match` is being used.

That said, the new version does not differ dramatically in what we
propose. Apart from dropping `__match__` we’re dropping the leading
dot to mark named constants, without a replacement, and everything
else looks like we’re digging in our heels. Why is that? Given the
firestorm of feedback we received and the numerous proposals (still
coming) for alternative syntax, it seems a bad tactic not to give up
something more substantial in order to get this proposal passed. Let
me explain.

Language design is not like politics. It’s not like mathematics
either, but I don’t think this situation is at all similar to
negotiating a higher minimum wage in exchange for a lower pension,
where you can definitely argue about exactly how much lower/higher
you’re willing to go. So I don’t think it’s right to propose making
the feature a little bit uglier just to get it accepted.

Frankly, 90% of the issue is about what among the authors we’ve dubbed
the “load/store” problem (although Tobias never tires to explain that
the “load” part is really “load-and-compare”). There’s a considerable
section devoted to this topic in the PEP, but I’d like to give it
another try here.

In case you’ve been avoiding python-dev lately, the problem is
this. Pattern matching lets you capture values from the subject,
similar to sequence unpacking, so that you can write for example
```
    x = range(4)
    match x:
        case (a, b, *rest):
            print(f"first={a}, second={b}, rest={rest}")  # 0, 1, [2, 3]
```
Here the `case` line captures the contents of the subject `x` in three
variables named `a`, `b` and `rest`. This is easy to understand by
pretending that a pattern (i.e., what follows `case`) is like the LHS
of an assignment.

However, in order to make pattern matching more useful and versatile,
the pattern matching syntax also allows using literals instead of
capture variables. This is really handy when you want to distinguish
different cases based on some value, for example
```
    match t:
        case ("rect", real, imag):
            return complex(real, imag)
        case ("polar", r, phi):
            return complex(r * cos(phi), r * sin(phi))
```
You might not even notice anything funny here if I didn’t point out
that `"rect"` and `"polar"` are literals -- it’s really quite
natural for patterns to support this once you think about it.

The problem that everybody’s been concerned about is that Python
programmers, like C programmers before them, aren’t too keen to have
literals like this all over their code, and would rather give names to
the literals, for example
```
    USE_POLAR = "polar"
    USE_RECT = "rect"
```
Now we would like to be able to replace those literals with the
corresponding names throughout our code and have everything work like
before:
```
    match t:
        case (USE_RECT, real, imag):
            return complex(real, imag)
        case (USE_POLAR, r, phi):
            return complex(r * cos(phi), r * sin(phi))
```

Forgive the intrusion, in case this wasn't already mentioned (I only read a fraction of emails on this), we could say that name enclosed in parenthesis would mean loading a constant, instead of storing in a variable:

    match t:
        case ((USE_RECT), real, imag):  # matches the constant USE_RECT literal value
            return complex(real, imag)
        case (USE_POLAR, r, phi):  # the USE_POLAR portion matches anything and stores in a USE_POLAR variable 
            return complex(r * cos(phi), r * sin(phi)) 
 
Advantages: in Python (and most programming languages), (x) is the same thing as x.  So, no new syntax, or weird symbols, need to be introduced.  

But the parser can distinguish (I hope), and guide the match statement generation to the appropriate behaviour.

Yes, it's more typing, but hopefully the case is uncommon enough that the extra typing is not a lot of burden.

Yes, it's easy to type USE_RECT when you really meant (USE_RECT).  Hopefully linters can catch this case and warn you.

OK, that's it, I just thought it was worth throwing yet another idea into the pot :-)

--
Gustavo J. A. M. Carneiro
Gambit Research
"The universe is always one step beyond logic." -- Frank Herbert