On Dec 31, 2019, at 17:54, David Mertz <me...@gnosis.cx> wrote:
> 
> 
>> On Tue, Dec 31, 2019 at 8:23 PM Andrew Barnert via Python-ideas 
>> <python-ideas@python.org> wrote:
> 
>> > K = 42
>> > x, K, z = vec
>> Yes. I’m surveying the way other languages deal with this to try to figure 
>> out what might fit best for Python.
>> Some languages use special syntax to mark either values or targets:
>> 
>>     let x, K, let z = vec
>>     x, @K, z = vec
>> 
>> But the simplest solution is to nothing: you have to stick it in an 
>> expression that isn’t a valid target, or
>> It’s a target. And I think that might actually work. If the pattern matching 
>> library includes this (or you write it yourself):
> 
> What is and isn't a valid target.  For example: 'map[key]', 'seq[pos]', 
> 'obj.attr'.

Sorry, I thought that was obvious, but it isn’t.

Anything that’s _syntactically_ a valid target is a target. It doesn’t matter 
if assigning to it would raise at runtime. Which is pretty much what you ended 
up working out anyway, but I should have actually said it.

> The bigger problem in my mind is that what I'd like to match isn't generally 
> a specific value.  It's more like:
> 
>     type[int], type[int], type[float] = vec

That can be done a library, so it doesn’t need any magic syntax.

Remember, anything that’s an expression, we’re going to compare with ==. So 
(ignoring the error handling, documentation, etc. you’d want in a real library):

    class MatchType(type):
        def __eq__(self, other):
            return self == type(other)

Now, this:

>     type[int], y, z = vec

is spelled (with that library):

    MatchType(int), y, z = vec

(And if there’s a better way to spell it, or better behavior—maybe using 
issubclass, since, as I said elsewhere, Scala does go out of its way to let you 
integrate case pattern matching and inheritance, so maybe there’s a good reason 
for that—a competing library will do it better.)

> Or I even want to match:
> 
>     type[int], y < 42, z = vec

Well, I can’t think of a language where you can actually match that way. That 
doesn’t necessarily mean we should disallow it, but I can’t imagine how the 
compiler and interpreter are supposed to figure this out.

So, what do you do in other languages? Normally you handle that with a guard 
clause, which is usually spelled with a postfix “where” or “if” clause that 
looks exactly like the if clause in a comprehension:

    MatchType(int), y, z = vec if y < 42

And we could add that. Although I think it belongs on the if try statement, not 
on assignment statements and expressions. (If you’re just doing a bare 
assignment, just do the if separately.)

But with an as clause, you could actually do it pretty easily with a custom 
matcher:

    class MatchFunc:
        def __init__(self, func): self.func = func
        def __eq__(self, other): return self.func(other)

And now:

    MatchType(int), MatchFunc(lambda y: y<42) as y, z = vec

… which I don’t think you could do this way in any language. But I don’t think 
you actually want to do it this way.

One last possibility is to put the smarts in the de-constructor function you 
use to get the right side:

    MatchType(int), 42, y, z = vec.deconstruct_with_ymax()

… which you can do (with different syntax—the “unapplier” goes around the left 
side rather than the right) in at least Scala, but I don’t think it’s very 
readable here.

> So your syntax gets me maybe 20% of what I'd want to do if we had pattern 
> matching. 

Sure, expanded unpacking alone doesn’t get you pattern matching at all. It’s 
just one of the primitives needed to built pattern matching.

Swift or Haskell’s unpacking alone (without function definitions, case 
statements/expressions, if let, etc.) also only get you 20% of what you want, 
in exactly the same way. Most of the time, to do anything useful, you need to 
use it inside one of those other features, and the same would be true in Python.

If people want to see a fully worked out proposal for pattern matching built on 
these primitives—which I think will get you 80% of what you want, and even more 
with a better library—I can work it out. If not, at least look at the 
off-the-cuff example I posted in the second message.

> And it has edge cases that of course I could learn, but would not be 
> intuitive.

What edge cases?

_______________________________________________
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/C7VEJTAKQUZUQYNP5JKVYV5BIQKDZDLK/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to