To make things a little more concrete (still without actually defining the
library or searching for better motivating examples), here’s a slightly
rewritten example from the Scala tutorial:
def showNotification(notification: Notification) = {
notification match {
case Email(sender, title, _) =>
notify(s"You got an email from $sender with title: $title")
case SMS(6060842, message) =>
alert(s"The number's been reconnected! You got an SMS from
$number! Message: $message")
case SMS(number, message) =>
notify(s"You got an SMS from $number! Message: $message")
case VoiceRecording(name, link) =>
notify(s"You received a Voice Recording from $name! Click the
link to hear it: $link")
}
}
Here it is in more Python-like syntax, with a match/case statement:
def show_notification(notification: Notification):
match notification:
case Email(sender, title, _):
notify(f"You got an email from {sender} with title: {title}")
case SMS(6060842, message):
alert(f"The number's been reconnected! You got an SMS from
{number}! Message: {message}")
case SMS(number, message):
notify(f"You got an SMS from {number}! Message: {message}")
case VoiceRecording(name, link):
notify(f"You received a Voice Recording from {name}! Click the
link to hear it: {link}")
And here it is without needing two new keywords, just the if try and
target-or-expression unpacking syntax and a (non-magical) library:
def showNotification(notification: Notification):
with matching(notification) as m:
if try Email, sender, title, _ ::= m:
notify(f"You got an email from {sender} with title: {title}")
elif try SMS, 6060842, message := m
alert(f"The number's been reconnected! You got an SMS from
{number}! Message: {message}")
elif try SMS, number, message := m:
notify(f"You got an SMS from {number}! Message: {message}")
elif try VoiceRecording, name, link := m:
notify(f"You received a Voice Recording from {name}! Click the
link to hear it: {link}")
> On Dec 31, 2019, at 14:31, Andrew Barnert via Python-ideas
> <[email protected]> wrote:
>
> Every so often, someone suggests that Python should have a pattern matching
> case statement like Scala, C#, Swift, Haskell, etc. Or they just suggest that
> “Python needs algebraic data types” but end up concluding that the biggest
> part Python is missing is not the types themselves, but a practical way to do
> something useful with them, which basically means pattern matching.
>
> Anyway, with the addition of the walrus operator and @dataclass, Python is
> actually a lot closer than it used to be. I believe with just two smallish
> syntax features, it would be possible to do almost anything you’d ever want
> in a library.
>
> The first is to extend unpacking assignment to target-or-expression lists.
> Like this:
>
> x, 0, z = vec
>
> Just like `x, y, z = vec`, this raises a TypeError if vec isn’t Iterable, and
> a ValueError if it has more or fewer than 3 elements, and otherwise, it binds
> x and z to the first and third elements. But it doesn’t bind anything to the
> second element; instead, it checks if that element is 0, and, if not, raises
> a ValueError.
>
> The second is an “if try” statement, which tries an expression and runs the
> body if that doesn’t raise (instead of if it’s truthy), but jumps to the next
> elif/else/statement (swallowing the exception) if it does. The actual value
> of the expression is discarded, but the walrus operator takes care of that:
>
> if try 0, y, z := vec:
> # do yz plane stuff
> elif try x, 0, z := vec:
> # do xz plane stuff
> elif try x, y, 0 := vec:
> # do xy plane stuff
> elif x, y, z := vec:
> # do slow/imprecise/whatever 3D stuff
> else:
> raise TypeError(f'{vec} is not a 3-vector!')
>
> Alternatively, this could just be a try expression that can be used anywhere:
> it’s truthy if evaluating doesn’t raise, falsey if it does. But I don’t think
> it’s needed anywhere but if/elif.
>
> Anyway, neither of these features seems very useful on its own. (It should be
> obvious how to rewrite that example as something just as readable that just
> unpacks and then checks the values with normal if.)
>
> But I think the two of them together will allow a pure-library implementation
> of pattern matching syntax that reads nicely and can do everything most other
> languages do—in particular, concisely and readably pattern match and
> deconstruct dataclasses (and other types with an opt-in protocol or registry,
> but dataclasses would work out of the box the way Scala case classes, Swift
> structs, etc. do).
>
> If people think either of these features is too horrible to contemplate no
> matter what the potential benefits, I won’t bother working through the
> details.
>
> But if people do want to see the details (including some good motivating
> examples—I’ll go through tutorials for those other languages to find some
> that don’t involve recursing into cons lists and other stuff you wouldn’t
> want to do in Python…), I’ll be happy to do so, and, if it works out, turn
> this into a more detailed proposal.
>
> And obviously, if people want to bikeshed the spelling before even seeing
> what it’s good for, well, this is Python-ideas. :)
> _______________________________________________
> Python-ideas mailing list -- [email protected]
> To unsubscribe send an email to [email protected]
> https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at
> https://mail.python.org/archives/list/[email protected]/message/W64QFNZVAGU2EMHTLDXHRGJ7V7TYBR5R/
> Code of Conduct: http://python.org/psf/codeofconduct/
_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/P7KKJYSRQSLLYVKYNF4R73KG6PZCTN2K/
Code of Conduct: http://python.org/psf/codeofconduct/