Pattern Matching in Python

Brian Goetz brian.goetz at
Thu Feb 11 16:10:47 UTC 2021

Overall a good read, and a nice window into the problems they view as 
most worth solving (in their world.)  I think they did a good job in 
integrating this into the Python view of the world.

I'll note that the vision of pattern matching we've taken on is somewhat 
more ambitious -- treating patterns as a part of the object model -- and 
so some of the choices they've made make sense only when viewed through 
that perspective, but would not carry over to ours.

> The accepted PEP is
> And the rational is

It's a little hard to follow these.  634/635 seem to be the spec and 
rationale respectively for the basics, and 642 is an alternative syntax 
to 634.  But 634 is listed as Accepted whereas 642 is listed as Draft.  
Are you saying 642 was accepted now?

> Compared to us,
> - bindings are visually like variables not a special keyword (a previous proposal was using 'as')
634 uses "x" and 642 uses "as x".  So that makes 642 the "previous", 
even though it is later numbered?
>    so "case foo:" capture the value inside and store it into foo which is obviously very controversial
>    (it's even worst because "foo" doesn't have to be a fresh variable).
>    I'm happy that we have not chosen that way :)

This is a nice example of how what makes sense in one language doesn't 
make sense in another.  Java is statically typed, so declarations of 
pattern variables should look like declarations.

We do have an open question, though, as to whether we want to support a 
way to have a pattern bind to an existing variable.  This shows up when 
writing patterns that want to delegate to other patterns to get some of 
their bindings; if we don't support this, then writing these patterns 
becomes more clunky (have to make up silly extra names.)  Obviously 
something like

     int x;
     if (t instanceof Foo(x)) { ... }

is going to be too cryptic (is it an invocation with x, or a binding of 
x?), but an additional syntactic hint (`&x`, `x=`, `bind x`, etc)  Not 
to be painted here, just registering this as being on the open-questions 

> - guards are introduced with "if", which i find more readable than & or &&.
>    Using 'if' can be an issue for us because it means that we can not have a guard inside the instanceof pattern, but i am not sure this is really a problem.

This is one of those examples that makes sense under "less ambitious 
target."  If your patterns are simpler, you are less likely to combine 
the with each other (witness, they have no & patterns), and therefore 
less likely to need to treat guards unformly.  So nailing guards on the 
side (as almost all languages do) as part of the construct works fine in 
that case.  I think for us, this would bite us as patterns got richer.

> - constants can be used directly
>    I'm still on the fence about that, it's certainly confusing that case Point(0,0) means case Point(var x, var y) if x == 0 && y == 0 and not
Yes, at first look, constant patterns look very cool, but then you 
realize that they don't really buy you that much, and you're bouncing 
out to guards pretty quickly anyway.  So the space in between "patterns 
plus guards" and "patterns plus constant patterns plus guards" is pretty 
small; the return on complexity there seems low.

One place where we might want to revisit this is when we get to 
structural patterns; using  a string literal as a map value is likely to 
be pretty useful.  (We need to do collection literals first, and 
collection literals and patterns are duals just as constructors and 
deconstructors are.)

>    like in C#, case Point(== 0, == 0) doesn't worth the fuss.
Agree, at least for now.  We can revisit when we get to "collection 

> - no support for comma separated values because the syntax is too close to the tuple syntax,
>    we have already chosen to support comma separated values but only at top level, not inside a nested pattern.
>    They have introduced '|' for OR and it can be used as top level and inside nested patterns.
>    Note: in Java, using ',' vs '|' in the syntax is not something new, we are using '|' for catch and not ','.
>    So question, should we introduce a OR pattern ??
We had an OR pattern (which corresponds to special treatment of bindings 
when merging two expressions with ||, such as `(x instanceof Foo(var a) 
|| x instanceof Bar(var a)`.)  We backed off on this at least 
temporarily because people were concerned about "variables with multiple 
declarations", and this isn't relevant until we have deconstruction 
patterns anyway, so it is "to be revisited."
> - no support for AND and NOT pattern,
>    because as i said in an early mail, using tuples is already an implicit AND.
Additional thoughts:

  - It's sad that they went the "moar statements" route.
  - They went the "merging" route with OR patterns that we considered, 
but at least temporarily backed off of.  This is a reasonable fit for 
their style of declarations; our main concern was "a variable with two 
declarations, weird!", but they don't seem to be at all concerned that 
variables don't even have declarations, so that's not a problem.
  - Overall, I rate this a "solid, but unambitious" effort.  It will 
surely be useful for unpacking things like HTTP requests.

More information about the amber-spec-experts mailing list