[Python-ideas] Pattern Matching Syntax

Robert Roskam raiderrobert at gmail.com
Thu May 3 14:36:27 EDT 2018


Hey Chris,

So I started extremely generally with my syntax, but it seems like I should 
provide a lot more examples of real use. Examples are hard. Here's my 
hastily put together example from an existing piece of production code:


# Existing Production Code
from datetime import timedelta, date
from django.utils import timezone


def convert_time_to_timedelta(unit:str, amount:int, now:date):
    if unit in ['days', 'hours', 'weeks']:
        return timedelta(**{unit: amount})
    elif unit == 'months':
        return timedelta(days=30 * amount)
    elif unit == 'years':
        return timedelta(days=365 * amount)
    elif unit == 'cal_years':
        return now - now.replace(year=now.year - amount)




# New Syntax for same problem


def convert_time_to_timedelta_with_match(unit:str, amount:int, now:date):
 return match unit:
     'days', 'hours', 'weeks' => timedelta(**{unit: amount})
     'months' => timedelta(days=30 * amount)
     'years' => timedelta(days=365 * amount)
     'cal_years' => now - now.replace(year=now.year - amount)







On Thursday, May 3, 2018 at 2:02:54 PM UTC-4, Chris Angelico wrote:
>
> On Fri, May 4, 2018 at 3:18 AM, Ed Kellett <e+pytho... at kellett.im 
> <javascript:>> 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... at python.org <javascript:> 
> 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/ff3a5105/attachment-0001.html>


More information about the Python-ideas mailing list