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 
> <python-ideas@python.org> 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 -- python-ideas@python.org
> To unsubscribe send an email to python-ideas-le...@python.org
> https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at 
> https://mail.python.org/archives/list/python-ideas@python.org/message/W64QFNZVAGU2EMHTLDXHRGJ7V7TYBR5R/
> Code of Conduct: http://python.org/psf/codeofconduct/
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/P7KKJYSRQSLLYVKYNF4R73KG6PZCTN2K/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to