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)
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)
I believe the intention in the example you quoted is syntax something
On Fri, May 4, 2018 at 3:18 AM, Ed Kellett <e+pytho...@kellett.im>
wrote:
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...@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/