On Sat, Nov 14, 2020 at 11:11:37PM +1000, Nick Coghlan wrote:
> On Fri, 13 Nov 2020 at 09:39, David Mertz <me...@gnosis.cx> wrote:
> >
> > I have read a great deal of discussion on the pattern matching PEPs and 
> > less formal discussions.  It is possible I have overlooked some post in all 
> > of that, of course.
> >
> > ... OK, just saw Guido's "wait for new SC" comment, which I suppose applies 
> > to this too :-).
> >
> > One idea that I cannot recall seeing, but that seems to make sense to me 
> > and fit with Python's feel is using a WORD to distinguish between a 
> > variable value and a binding target.  That is, instead of a special symbol 
> > prefixing or suffixing a name, either to indicate it is or is not a binding 
> > target.  Of course, whether the extra word would be used for binding or for 
> > NOT binding is a question still.
> 
> If someone was prepared to pursue this to the level of writing a 3rd
> competing PEP, the variant I would personally like to see written up
> is the one where capture patterns are all prefixed with the keyword
> `as`.
> 
> PEP 634 already uses the `PATTERN as NAME` syntax to combine other
> match patterns with a capture pattern, and I'm going to be amending
> PEP 642 to propose using `as` when embedding capture patterns inside
> class patterns (`ATTR as NAME`) and mapping patterns (`KEY as NAME`).
> From there, it's an entirely plausible step to also require the `as`
> prefix on capture patterns in sequence patterns and as top level
> standalone patterns.
> 
> I personally don't think that extra step would be a good idea due to
> the inconsistency with name binding and iterable unpacking in regular
> assignment statements (if I liked the idea, I'd have already included
> it in PEP 642), but I think "anchor match patterns in normal
> expressions rather than assignment target syntax" is a credible enough
> idea that the overall design process would benefit from having a
> champion write it up.
> 
> > To me these read better than the punctuation characters.  But I guess some 
> > folks have suggested enlisting 'as', which is a word, of course.
> 
> Indeed, and one that doesn't look too bad for top level patterns:
> 
>     NOT_FOUND = 404
>     match http_code:
>       case 200:
>           print("OK document")
>       case NOT_FOUND:  # use the variable value
>           print("Document not found")
>       case as other_code:  # bind this name
>           print("Other HTTP code")

It doesn't look too bad because it looks like a switch statement, with 
only one lonely capture pattern, and an especially simple one at that. 
(The bound name isn't even used, which strongly suggests that it should 
be written as the wildcard pattern.)

Here is a more representative example, borrowed from here:

https://gvanrossum.github.io//docs/PyPatternMatching.pdf


    match node:
        case BinOp(Num(left), '+', Num(right)):
            return Num(left + right)
        case BinOp(left, '+' | '-', Num(0)):
            return simplify(left)
        case UnaryOp('-', UnaryOp('-', item)):
            return simplify(item)
        case _:
            return node


which becomes this with the "as" proposal:


    match node:
        case BinOp(Num(as left), '+', Num(as right)):
            return Num(left + right)
        case BinOp(as left, '+' | '-', Num(0)):
            return simplify(left)
        case UnaryOp('-', UnaryOp('-', as item)):
            return simplify(item)
        case _:
            return node


Here's another example from the same paper:


    def create_rectangle(*args, **kwargs):
        match (args, kwargs):
            case ([x1, y1, x2, y2], {}) if x2-x1 == y2-y1:
                return Square(x1, y1, x2-x1)
            case ([x1, y1, x2, y2], {}):
                return Rect(x1, y1, x2, y2)
            case ([(x1, y1), (x2, y2)], {}):
                return Rect(x1, y1, x2, y2)
            case ([x, y], {'width': wd, 'height': ht}):
                return Rect(x, y, x+wd, y+ht)


which would become:


    def create_rectangle(*args, **kwargs):
        match (args, kwargs):
            case ([as x1, as y1, as x2, as y2], {}) if x2-x1 == y2-y1:
                return Square(x1, y1, x2-x1)
            case ([as x1, as y1, as x2, as y2], {}):
                return Rect(x1, y1, x2, y2)
            case ([(as x1, as y1), (as x2, as y2)], {}):
                return Rect(x1, y1, x2, y2)
            case ([as x, as y], {'width': as wd, 'height': as ht}):
                return Rect(x, y, x+wd, y+ht)



-- 
Steve
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/25NAC56DIYID5L7XGMVQDM2RM6Z5FSNQ/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to