[Python-ideas] Pattern matching

Chris Angelico rosuav at gmail.com
Wed Apr 8 11:00:28 CEST 2015


On Wed, Apr 8, 2015 at 4:39 PM, Andrew Barnert <abarnert at yahoo.com> wrote:
>> So basically, what we have here is a cross between a 'with' statement
>> and an 'if'.
>
> I understand why people keep reaching for "with" here, but I really don't like it.
>
> Part of the attraction is the "as" clause, which looks like the "as" clause in an ML case expression. But that's missing the point of patterns: what you mostly want to do is decompose the pattern, binding variables to (some of) the components; you don't want to bind a variable to the whole thing. Except that _occasionally_ you _also_ want to bind the whole thing (or bind a subexpression and also some of its own subexpressions), which is what "as" can add.
>

The other similar syntax that I looked at was the from-import.
Positing a new keyword "patmatch":

regex = re.compile('(?P<x>[0-9]+)-(?P<y>[0-9])+')
case line:
    from regex patmatch x, y:
        print(x,y)

(or possibly combine in the "case" part into a single statement, to
remove the two-level indentation and some of the magic)

What this means is:

1) Evaluate line and regex (they'd allow arbitrary expressions)
2) Call regex.__patmatch__(line) - I'll call that "ret"
3a) If it returns None, skip to the next patmatch statement.
3b) If it returns a tuple, assign x=ret[0]; y=ret[1]
3c) If it returns a dict, assign x=ret["x"]; y=ret["y"]
3d) If it returns any other object, assign x=ret.x; y=ret.y
4) Discard "ret" itself (ie it never actually gets bound to a name)
5) Execute the block.

This would cover all the obvious use-cases. Specifically for cases 3c
and 3d, you could also use 'as' syntax to bind to other names:

case line:
    from re.compile('(?P<x>[0-9]+)') patmatch x as y:
        print(y)

This would also deal with ambiguities like namedtuple; you can either
use "patmatch x, y" to treat it as a tuple, or "patmatch x as x, y as
y" to force attribute access.

ChrisA


More information about the Python-ideas mailing list