[Python-ideas] Pattern Matching Syntax

David Mertz mertz at gnosis.cx
Thu May 3 14:25:48 EDT 2018


Calculating the Ackermann function as Knuth up-arrows really has little
practical user. The first few values are well known, the rest won't be
calculated before the heat death of the universe.

On Thu, May 3, 2018, 2:02 PM Chris Angelico <rosuav at gmail.com> wrote:

> On Fri, May 4, 2018 at 3:18 AM, Ed Kellett <e+python-ideas at kellett.im>
> wrote:
> > I believe the intention in the example you quoted is syntax something
> like:
> >
> >     <match-case> ::= <pattern>
> >                    | <pattern> "if" <expression>
> >
> > where the expression is a guard expression evaluated in the context of
> > the matched pattern.
> >
> > IOW, it could be written like this, too:
> >
> > number = match x:
> >     1 if True => "one"
> >     y if isinstance(y, str) => f'The string is {y}'
> >     _ if True => "anything"
> >
> > I do see a lot of room for bikeshedding around the specific spelling.
> > I'm going to try to resist the temptation ;)
>
> Okay, let me try to tease apart your example.
>
> 1) A literal matches anything that compares equal to that value.
> 2) A name matches anything at all, and binds it to that name.
> 2a) An underscore matches anything at all. It's just a name, and
> follows a common convention.
> 3) "if cond" modifies the prior match; if the condition evaluates as
> falsey, the match does not match.
> 4) As evidenced below, a comma-separated list of comparisons matches a
> tuple with as many elements, and each element must match.
>
> Ultimately, this has to be a series of conditions, so this is
> effectively a syntax for an elif tree as an expression.
>
> For another example, here's a way to use inequalities to pick a
> numeric formatting:
>
> display = match number:
>     x if x < 1e3: f"{number}"
>     x if x < 1e6: f"{number/1e3} thousand"
>     x if x < 1e9: f"** {number/1e6} million **"
>     x if x < 1e12: f"an incredible {number/1e9} billion"
>     _: "way WAY too many"
>
> I guarantee you that people are going to ask for this to be spelled
> simply "< 1e3" instead of having the "x if x" part. :)
>
> > How about this?
> >
> > def hyperop(n, a, b):
> >     return match (n, a, b):
> >         (0, _, b) => b + 1
> >         (1, a, 0) => a
> >         (2, _, 0) => 0
> >         (_, _, 0) => 1
> >         (n, a, b) => hyperop(n-1, a, hyperop(n, a, b-1))
> >
> > versus:
> >
> > def hyperop(n, a, b):
> >     if n == 0:
> >         return b + 1
> >     if n == 1 and b == 0:
> >         return a
> >     if n == 2 and b == 0:
> >         return 0
> >     if b == 0:
> >         return 1
> >     return hyperop(n-1, a, hyperop(n, a, b-1))
>
> I have no idea what this is actually doing, and it looks like a port
> of Haskell code. I'd want to rewrite it as a 'while' loop with maybe
> one level of recursion in it, instead of two. (Zero would be better,
> but I think that's not possible. Maybe?) Is this something that you do
> a lot of? Is the tuple (n, a, b) meaningful as a whole, or are the
> three values independently of interest?
>
> Not sure how this is useful without a lot more context.
>
> ChrisA
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20180503/d90eec49/attachment.html>


More information about the Python-ideas mailing list