[Python-ideas] Match statement brainstorm
jim.baker at python.org
Tue May 24 15:20:57 EDT 2016
Structural pattern matching should address the following, somewhat similar
to regex pattern matching:
1. Patterns are quoted. This can be implicitly done, because of built-in
syntactic support; or one is supplying the pattern to a library using
regular Python quoting.
2. Patterns should support bind variables for the unpacking. In languages
like Scala, this is very natural to do, with bop, v1, v2 lexically scoped
to the RHS of =>.
case Binary(bop @ (Lt|Le|Gt|Ge), v1, v2) if isValue(v1) && isValue(v2) =>
doreturn(B(inequalityVal(bop, v1, v2)) )
This is an example from an interpreter used in a lab exercise in a class I
teach, with patterns against ASTs. The ASTs are themselves defined in terms
of Scala's case classes, which are more or less equivalent to namedtuples
Clearly the scoping of bind variables can be emulated by the match object,
much as we do in regexes, at the cost of some minor overhead.
3. Some protocol to connect together objects like tuples, namedtuples, and
arbitrary classes with the matching. In Scala, this is called unapply, and
given that Scala has similar object-oriented aspects that are similar to
Python in making life more difficult ;), when compared to Haskell's
comparatively simple rules, it's probably close to what we need to do for
__match__ or something like that.
The challenge is making this work together, especially distinguishing
patterns from bind variables. Haskell makes it easy by a requirement that
algebraic types have constructors which start with an upper case letter.
Scala can do simple scope analysis of names to determine if it's a case
class or a bind variable. For Python, presumably more syntax is necessary
in the pattern specifier. Maybe something like the following, which seems
unambiguous, possibly not so ugly:
case Binary(bop @ (Lt|Le|Gt|Ge), v1@, v2@) if isValue(v1) and isValue(v2):
# bop, v1, v2 are lexically scoped here
Am I missing anything? It seems to me that one can do structural pattern
matching as a library (do obvious changes to above); although having it
supported with specific syntax might make it much nicer.
On Tue, May 24, 2016 at 11:42 AM, Koos Zevenhoven <k7hoven at gmail.com> wrote:
> On Tue, May 24, 2016 at 5:59 PM, Michel Desmoulin
> <desmoulinmichel at gmail.com> wrote:
> > What about making it a function ?
> > Pattern matching is complex, it can be like a mini language inside the
> > language, just like regex.
> > To match text we do:
> > import re
> > re.match('pattern', 'string')
> > We could do the same for matching structures:
> > from inspect import match
> > def do(stuff):
> > m = match(stuff): # m implements __call__
> > if m('whatever mini language you like'):
> > return foo
> > if m('again'):
> > return m.thing_your_extracted
> Or with methods:
> m = match(stuff)
> if m.by_type(SomeType):
> # handle SomeType
> elif m.by_attrs('x', 'y'):
> # do things with stuff.x and stuff.y
> elif m.by_len(3):
> x,y,z = stuff
> # do things with x, y, z
> > Pros:
> > - no need for a new syntax
> > - very explicit
> > - use well know constructs
> > - we can easily start experimenting with the matching language in a lib
> > in Pypy
> + can be extended easily
> > Cons:
> > - much more verbose;
> > - debugging your mini language and handling error is not as good;
> + probably slower
> + need to separately get the desired attributes/elements after matching.
> -- Koos
> Python-ideas mailing list
> Python-ideas at python.org
> Code of Conduct: http://python.org/psf/codeofconduct/
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Python-ideas