[Python-Dev] Re: PEP 622 (Structural Pattern Matching) questions

2020-08-06 Thread Guido van Rossum
On Thu, Aug 6, 2020 at 04:31 Mark Shannon  wrote:

> Hi,
>
> I have two questions about PEP 622, as it stands.
>
> 1. Is the current version the final version?


That is up to the Steering Council.


> 2. Is the difference in semantics between the Django example and the
> proposed replacement deliberate or accidental?
>(The difference being the change in behaviour for sequences other
> than list or tuple).
>
> Cheers,
> Mark.
> ___
> 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/NQBL4S6WTM5647J2YKJNWM446WX3ELHO/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
-- 
--Guido (mobile)
___
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/PLD6HF6U6I6QQMCTZRKM646GHCLF3GDN/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622 (Structural Pattern Matching) questions

2020-08-06 Thread Mark Shannon

Hi Daniel,

On 06/08/2020 1:11 pm, Daniel Moisset wrote:

Hi Mark,

As the specific author of that example (and the author of the big it had 
on a previous version) let me clarify:


The change in semantics is intentional. I could be more explicit, and 
preserve semantics, but I actually find very likely that the original 
code does not support other sequences because it would make their code 
more complicated (so it's a matter of opinion but for me it's a feature, 
not a bug)


Are you going to mention in the PEP that the two pieces of code are not 
equivalent, or show an equivalent version?


I don't know whether the original author intended to accept 
`array.array("u", "hi")` as a legal value, but I suspect that they did not.



Cheers,
Mark.



As for the previous fixed bug, of like to mentioned that I misread the 
original code (I tend to use >= rather than > for those comparisons) so 
I read "at least one element" rather than "more than one". Again, it may 
be subjective taste but I find our version more readable in that respect 
and less likely to be misinterpreted (making the bug easier to spot there)


Best,

Daniel



On Thu, 6 Aug 2020, 12:32 Mark Shannon, > wrote:


Hi,

I have two questions about PEP 622, as it stands.

1. Is the current version the final version?

2. Is the difference in semantics between the Django example and the
proposed replacement deliberate or accidental?
    (The difference being the change in behaviour for sequences other
than list or tuple).

Cheers,
Mark.
___
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/NQBL4S6WTM5647J2YKJNWM446WX3ELHO/
Code of Conduct: http://python.org/psf/codeofconduct/


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


[Python-Dev] Re: PEP 622 (Structural Pattern Matching) questions

2020-08-06 Thread Daniel Moisset
Hi Mark,

As the specific author of that example (and the author of the big it had on
a previous version) let me clarify:

The change in semantics is intentional. I could be more explicit, and
preserve semantics, but I actually find very likely that the original code
does not support other sequences because it would make their code more
complicated (so it's a matter of opinion but for me it's a feature, not a
bug)

As for the previous fixed bug, of like to mentioned that I misread the
original code (I tend to use >= rather than > for those comparisons) so I
read "at least one element" rather than "more than one". Again, it may be
subjective taste but I find our version more readable in that respect and
less likely to be misinterpreted (making the bug easier to spot there)

Best,

Daniel



On Thu, 6 Aug 2020, 12:32 Mark Shannon,  wrote:

> Hi,
>
> I have two questions about PEP 622, as it stands.
>
> 1. Is the current version the final version?
>
> 2. Is the difference in semantics between the Django example and the
> proposed replacement deliberate or accidental?
>(The difference being the change in behaviour for sequences other
> than list or tuple).
>
> Cheers,
> Mark.
> ___
> 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/NQBL4S6WTM5647J2YKJNWM446WX3ELHO/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
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/WA6HJBW4HQWL3ESYKH3PUWVE47TPJOXZ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-07-26 Thread Rob Cliffe via Python-Dev

I think we are storing up trouble unless we
    1) Allow arbitrary expressions after `case`, interpreted *as now*
    2) Use *different* syntaxes, not legal in expressions, for
            alternative matching values (i.e. not `|` or `or`) (NB 
simply stacking with multiple `case` lines is one possibility)

            templates such as `Point(x, 0)`
            anything else particular to `match`
I am reminded of the special restrictions for decorator syntax, which 
were eventually removed.


On 24/06/2020 20:38, Guido van Rossum wrote:

Everyone,

If you've commented and you're worried you haven't been heard, please 
add your issue *concisely* to this new thread. Note that the following 
issues are already open and will be responded to separately; please 
don't bother commenting on these until we've done so:


- Alternative spellings for '|'
- Whether to add an 'else' clause (and how to indent it)
- A different token for wildcards instead of '_'
- What to do about the footgun of 'case foo' vs. 'case .foo'

(Note that the last two could be combined, e.g. '?foo' or 'foo?' to 
mark a variable binding and '?' for a wildcard.)


--
--Guido van Rossum (python.org/~guido )
/Pronouns: he/him //(why is my pronoun here?)/ 



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


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


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-07-26 Thread Tobias Kohn

 Hi Rob,

 You are right: the grammar should probably read `suite` rather
than `block` (i.e. the `pass` is necessary).  Thanks for catching
this!

 As for the second question, I assume there might be a slight
oversight on your part.  The last line in the example replaces the
string `"_"` rather than the variable `_`.  The not-binding of `_`
thus has no influence on the last line.

 I think I will leave it for Mark himself to name the two bugs rather
than start a guessing game.  However, in an earlier version we had
left out the `if value` for the first case, accidentally translating
the `len(value) > 1` as a `len(value) >= 1` instead.

 Kind regards,
Tobias

Quoting Rob Cliffe via Python-Dev :


[...]

_First question_: Sometimes no action is needed after a case  
clause.  If the Django example had been written
if ( isinstance(value, (list, tuple)) and len(value) > 1 and  
isinstance(value[-1], (Promise, str)) ): *value, label =  
value else: label = key.replace('_', ' ').title()  the  
replacement code would/could be  match value: case [*value,  
label := (Promise() | str())] if value: pass case _:  
label = key.replace('_', ' ').title()  AFAICS the PEP does not  
*explicitly* state that the 'pass' line is necessary (is it?), i.e.  
that the block following `case` cannot (or can?) be empty. The term  
`block` is not defined in the PEP, or in  
https://docs.python.org/3/reference/grammar.html. But an empty block  
following a line ending in `:` would AFAIK be unprecedented in  
Python.  I think it is worth clarifiying this.  _Second question_:  
in the above example replacement, if `case _:` does not bind to `_`,  
does that mean that the following line will not work? Is this one of  
the "two bugs" that Mark Shannon alluded to?  (I have read every  
message in the threads and I don't remember them being spelt out.)  
And I'm curious what the other one is (is it binding to a variable  
`v`?).  Best wishes Rob Cliffe
___
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/4MNGTBKIXNMMVAIFOLR2W62SLK637OY5/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-07-26 Thread Rob Cliffe via Python-Dev



On 24/06/2020 20:38, Guido van Rossum wrote:

Everyone,

If you've commented and you're worried you haven't been heard, please 
add your issue *concisely* to this new thread. Note that the following 
issues are already open and will be responded to separately; please 
don't bother commenting on these until we've done so:


- Alternative spellings for '|'
- Whether to add an 'else' clause (and how to indent it)
- A different token for wildcards instead of '_'
- What to do about the footgun of 'case foo' vs. 'case .foo'

(Note that the last two could be combined, e.g. '?foo' or 'foo?' to 
mark a variable binding and '?' for a wildcard.)


(Prefatory remarks:  I am sure you get a lot of questions to which the 
answer is basically "Read the PEP".  I myself have been guilty in this 
regard.  But I fear this is inevitable when the PEP is so long and there 
is so much new stuff to absorb.  Apologies if this is yet another one.)


_First question_: Sometimes no action is needed after a case clause.  If 
the Django example had been written


if (
isinstance(value, (list, tuple)) and
len(value) > 1 and
isinstance(value[-1], (Promise, str))
):
*value, label = value
else:
label = key.replace('_', ' ').title()

the replacement code would/could be

match value:
case [*value, label := (Promise() | str())] if value:
pass
case _:
label = key.replace('_', ' ').title()

AFAICS the PEP does not *explicitly* state that the 'pass' line is necessary 
(is it?), i.e. that the block following `case` cannot (or can?) be empty.
The term `block` is not defined in the PEP, or in 
https://docs.python.org/3/reference/grammar.html.
But an empty block following a line ending in `:` would AFAIK be unprecedented 
in Python.  I think it is worth clarifiying this.

_Second question_: in the above example replacement, if `case _:` does not bind 
to `_`, does that mean that the following line will not work?
Is this one of the "two bugs" that Mark Shannon alluded to?  (I have read every 
message in the threads and I don't remember them being spelt out.)
And I'm curious what the other one is (is it binding to a variable `v`?).

Best wishes
Rob Cliffe

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


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-07-25 Thread Rob Cliffe via Python-Dev
Without arguing for or against allowing a capture variable, IMO rather 
than syntax like

    match  into :
it would be far better (and not require a new keyword) to write this as
    with  as match :
Rob Cliffe

On 24/06/2020 20:38, Guido van Rossum wrote:

Everyone,

If you've commented and you're worried you haven't been heard, please 
add your issue *concisely* to this new thread. Note that the following 
issues are already open and will be responded to separately; please 
don't bother commenting on these until we've done so:


- Alternative spellings for '|'
- Whether to add an 'else' clause (and how to indent it)
- A different token for wildcards instead of '_'
- What to do about the footgun of 'case foo' vs. 'case .foo'

(Note that the last two could be combined, e.g. '?foo' or 'foo?' to 
mark a variable binding and '?' for a wildcard.)


--
--Guido van Rossum (python.org/~guido )
/Pronouns: he/him //(why is my pronoun here?)/ 



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


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


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-07-19 Thread Rob Cliffe via Python-Dev



On 08/07/2020 16:15, MRAB wrote:

On 2020-07-08 03:08, Rob Cliffe via Python-Dev wrote:

Why not use '=' to distinguish binding from equality testing:
      case Point(x, =y): # matches a Point() with 2nd parameter equal to
y; if it does, binds to x.

This would allow a future (or present!) extension to other relative
operators:
      case Point(x, >y):
(although the syntax doesn't AFAICS naturally extend to specifying a
range, i.e. an upper and lower bound, which might be a desirable thing
to do.
Perhaps someone can think of a way of doing it).

Whether
      case =42:
      case 42:
would both be allowed would be one issue to be decided.

In Python, '=' is assignment and '==' is equality. Using '=' for 
equality could lead to confusion.

Fair enough.  In that case use `==` instead:
    case Point(x, ==y): # if matches a Point with the given y-value, 
bind to x


___
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/KYUZQRZNDOVFEOC5XBYOFXKTPK7LAZI4/

Code of Conduct: http://python.org/psf/codeofconduct/

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


[Python-Dev] Re: PEP 622: Structural Pattern Matching (version 2)

2020-07-17 Thread Jim J. Jewett
Mark Shannon wrote:

> In future, could you avoid editing emails when replying to them?
> A lot of context can get lost.

I'll add another voice to Ethan's saying that I appreciate having as much as 
possible trimmed.  

As long as people are arguing in good faith (and I assume that they are here), 
the loss of context is usually pretty small, and outweighed by being able to 
find the newly important part more quickly.  (I say this as someone reading and 
replying through the archives, in a way that seems to mangle quoted portions -- 
but they are usually still good enough to be useful.)

> ... Yes, the pattern matching syntax is more concise in some 
> circumstances, but there still needs to be justification why a 
> combination of simpler language changes is insufficient.

Code that fits on a single small (24x80) screen (without getting too dense) is 
much easier to understand, because I can see it all at once, instead of needing 
to remember things while I flip back and forth.  A combination of simpler 
changes might be fine, but shorter really is very valuable, all by itself.

> Saves two lines of code, but introduces two bugs!
> (Assuming that the original behavior should be preserved)

That is a pretty big assumption.  I'm guessing that at least one of the "bugs" 
is that sequences other than the built-in list and tuple are now also accepted. 
 Maybe there are good reasons to exclude other sequences, but ... in my 
experience, the reason is usually that someone didn't think of it, and no one 
felt strongly enough to fix it yet.  That would mean pattern matching led to a 
bug *fix*.  Closed source code tends to be even more fragile, though it also 
tends to not see as many surprising input types in the first place.

> If you don't have access to the original source, then it can be made a 
> function, not a method.

Even when I have read access, I may not have write access.  Creating and naming 
a separate match function every place I need to match isn't quite boilerplate, 
but it adds enough code to feel that way.  Trying to use a single match 
function with parameters gets ugly in a different way.

I'm not quite convinced that this PEP has found the magic solution, but the 
goal is clearly worthy.

> On 14/07/2020 5:25 pm, Tobias Kohn wrote:

> > match response.status:
> >      case HTTP_RESPONSE.UPGRADE_REQUIRED:

> Are you suggesting that all constants live in a separate module?

The limit to dotted names is a possibly temporary wart.  But even with that 
restriction, there is no reason you can't gather constants on an object first, 
and use its attributes.

> For a PEP to succeed it needs to show ...
> That the proposed change is the best known solution for the 
> problem being addressed.

I think the bigger barrier is "although never is often better than right now," 
and hope that a better solution will be found later, and fear that backwards 
compatibility with this would block that better solution.  (To be very 
explicit, I personally abstain on this, because I am not sure whether this is 
"good enough", nor am I confident a better solution can ever be found.)

> I worry that the PEP is treating pattern matching as an ideal which we 
> should be striving towards. That is a bad thing, IMO.

Fair.  Like annotations as a typing system, you can personally ignore it if it 
isn't helpful, but there is still some ecosystem cost.  I would like to see 
more old/new comparisons to judge how intrusive this will be, but eventually 
there will be (or not be) a leap of faith.  In the past, most of those have 
worked out.
 
> Pattern matching is well suited to statically typed functional languages.

and statically typed data domains and communications protocols

-jJ
___
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/4S75QY4FVVXW7YGTSFRHEXBK5OXXJM6Y/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching (version 2)

2020-07-14 Thread Ethan Furman

On 07/14/2020 11:05 AM, Mark Shannon wrote:

On 14/07/2020 5:25 pm, Tobias Kohn wrote:

On 07/14/2020, Mark Shannon wrote:



In future, could you avoid editing emails when replying to them?
A lot of context can get lost.


I appreciate posters who take the time to trim the parts of an email that they 
are not replying to.


Why the use of "shape" in "scare quotes"?


Because the `shape' of an object is not something that is a well-defined term, 
but rather addresses the intuitive understanding to explain what we are talking 
about.  It is usually the intention of the abstract to give a rough overview, 
before delving into the details and more formal descriptions.


You ignore my point about explaining PEP 622 directly. Sure, the abstract must 
give a high level overview, but it should be able to do that without so much 
hand waving.


I find the PEP abstract concrete enough.  Perhaps you could write a replacement 
that you think does a better job?


Actually, no.  Pattern matching is not about _avoiding_ anything, it is about a 
more concise syntax.  The suggestion that we wanted to avoid calls to `len` or 
`isinstance` is similar to the idea of using a lambda to avoid a function.  The 
objective of pattern matching is to introduce a more succinct and readable way 
to express structure.  It's all still there but we want to focus on the 
structure rather than `isinstance` calls.


I should have been clearer. Avoiding *explicit* calls to `len` and 
`isinstance`. Yes, the pattern matching syntax is more concise in some 
circumstances, but there still needs to be justification why a combination of 
simpler language changes is insufficient.


My apologies if I missed it, but do you have some ideas of these simpler 
language changes that would do the job?


Pattern matching already exists in some limited way in Python.  Even today you 
can write:
   `a, b = value`


I think most of us are aware of unpacking in Python ;)


Yes, but not everyone recognizes that unpacking is a form of pattern matching.




instead of:
   `a = value[0]
    b = value[1]`

The idea of this is, of course, not so much about avoiding item access, but 
about having a more concise syntax for it.  Moreover, saying this only saves a 
single line and is therefore rather useless is quite beside the point.  It is 
about a better representation of what the code is supposed to do and not about 
saving lines.


How do you quantify "better representation" then?


You mean, without large study groups and lots of money and/or time?  Not easily.

I can tell you that

   a, b = value

is much more informative, and easier to read and process, than the alternative 
of using item assignment.


Saves two lines of code, but introduces two bugs!
(Assuming that the original behavior should be preserved)


Thank you for pointing out the bug in our example.  This highlights, however, 
rather the difficulty of refactoring (did I already mention the issue of the 
'context' that real code is embedded in?), than any shortcoming of pattern 
matching as a tool.  And by the way: constructive critisism would perhaps 
include explicitly naming the two bugs.


I'm not sure it would be more constructive, this is not a bug report or code 
review after all.


It should be.  If the PEP is to be decided on it should be as correct as 
possible.


The point I am making is this:
It is far too easy to make mistakes using the constructs proposed in PEP 622.


You're point is false.  They weren't crafting new code, they were refactoring.


For example, by adding a simple "matches" method to Node and Leaf, `is_tuple` 
can be rewritten as something like:


This assumes that you have full control over the entire code.  But if you are using some 
third-party library, you cannot "simply add a `matches` method" (without some 
substantial trickery).  Moreover, there is quite some work needed to define such a 
`matches` function as you propose it (including support for the ellipsis as wildcard).  
In effect, you would have to implement large parts of the pattern matching for just this 
simple example.  Whereas we believe that it has merit enough to have the compiler do it 
for a wide range of possible use cases.


You wouldn't have to implement large parts of the pattern matching,
because this would be specific to one class. There are only two or three cases 
to deal with.
If you don't have access to the original source, then it can be made a 
function, not a method.


So, a few lines for that example, another few for a different example, some 
more for that example over there -- how many times do we have to write similar 
code before we let Python do the grunt work for us?


Preventing the use of symbolic constants or other complex rvalues is a 
impairment to usability.


First, let me quote what the PEP has to say on that exact example:


Although this will work, it's not necessarily what the proposal is focused on.


So why does the PEP include it as one of just three examples?


To 

[Python-Dev] Re: PEP 622: Structural Pattern Matching (version 2)

2020-07-14 Thread Mark Shannon

Hi Tobias,

In future, could you avoid editing emails when replying to them?
A lot of context can get lost.

On 14/07/2020 5:25 pm, Tobias Kohn wrote:

Hi Mark,

Thank you for your message.  I might be able to answer some of the 
questions and also address some issues with the underlying assumptions 
in your email---after all, we would most certainly want to avoid 
discussing and reasoning about straw men, as you yourself have 
repeatedly pointed out.



 > Why the use of "shape" in "scare quotes"?

Because the `shape' of an object is not something that is a well-defined 
term, but rather addresses the intuitive understanding to explain what 
we are talking about.  It is usually the intention of the abstract to 
give a rough overview, before delving into the details and more formal 
descriptions.


You ignore my point about explaining PEP 622 directly. Sure, the 
abstract must give a high level overview, but it should be able to do 
that without so much hand waving.





 > Using a contrived example like this seems like a straw man.  It feels 
like it is constructed to favour the PEP, whilst being unlike any real code.


It is a trait of many (good) tutorials to present a new structure with 
an example that highlights its feature in an approachable way rather 
than coming up with `real code'---particularly given that real code is 
always surrounded by a larger context, which rather clouds any 
understanding.  And it would only be a straw man had we constructed a 
contrived example of unrealistic code that we then showed to be 
simplified by pattern matching.  That's not the case: it really is just 
a simple educational example to present the idea.


The example given in the PEP does seems like a "contrived example of 
unrealistic code", as you put it. Is there real code like this?




BTW: as a matter of course, it is constructed in favour of the PEP!


 > There seem to be three things you want to enhance here:
 > Unpacking; to avoid calls to `len`
 > Type checking; to avoid calls to `isinstance`.
 > To avoiding nesting by using complex lvalues.

Actually, no.  Pattern matching is not about _avoiding_ anything, it is 
about a more concise syntax.  The suggestion that we wanted to avoid 
calls to `len` or `isinstance` is similar to the idea of using a lambda 
to avoid a function.  The objective of pattern matching is to introduce 
a more succinct and readable way to express structure.  It's all still 
there but we want to focus on the structure rather than `isinstance` calls.


I should have been clearer. Avoiding *explicit* calls to `len` and 
`isinstance`. Yes, the pattern matching syntax is more concise in some 
circumstances, but there still needs to be justification why a 
combination of simpler language changes is insufficient.




Pattern matching already exists in some limited way in Python.  Even 
today you can write:

   `a, b = value`


I think most of us are aware of unpacking in Python ;)



instead of:
   `a = value[0]
    b = value[1]`

The idea of this is, of course, not so much about avoiding item access, 
but about having a more concise syntax for it.  Moreover, saying this 
only saves a single line and is therefore rather useless is quite beside 
the point.  It is about a better representation of what the code is 
supposed to do and not about saving lines.


How do you quantify "better representation" then?




 > Saves two lines of code, but introduces two bugs!
 > (Assuming that the original behavior should be preserved)

Thank you for pointing out the bug in our example.  This highlights, 
however, rather the difficulty of refactoring (did I already mention the 
issue of the 'context' that real code is embedded in?), than any 
shortcoming of pattern matching as a tool.  And by the way: constructive 
critisism would perhaps include explicitly naming the two bugs.


I'm not sure it would be more constructive, this is not a bug report or 
code review after all.

The point I am making is this:
It is far too easy to make mistakes using the constructs proposed in PEP 
622.





 > For example, by adding a simple "matches" method to Node and Leaf, 
`is_tuple` can be rewritten as something like:


This assumes that you have full control over the entire code.  But if 
you are using some third-party library, you cannot "simply add a 
`matches` method" (without some substantial trickery).  Moreover, there 
is quite some work needed to define such a `matches` function as you 
propose it (including support for the ellipsis as wildcard).  In effect, 
you would have to implement large parts of the pattern matching for just 
this simple example.  Whereas we believe that it has merit enough to 
have the compiler do it for a wide range of possible use cases.


You wouldn't have to implement large parts of the pattern matching,
because this would be specific to one class. There are only two or three 
cases to deal with.
If you don't have access to the original source, then it can be made a 
function, 

[Python-Dev] Re: PEP 622: Structural Pattern Matching (version 2)

2020-07-14 Thread Tobias Kohn

Hi Mark,

Thank you for your message.  I might be able to answer some of the  
questions and also address some issues with the underlying assumptions  
in your email---after all, we would most certainly want to avoid  
discussing and reasoning about straw men, as you yourself have  
repeatedly pointed out.



Why the use of "shape" in "scare quotes"?


Because the `shape' of an object is not something that is a  
well-defined term, but rather addresses the intuitive understanding to  
explain what we are talking about.  It is usually the intention of the  
abstract to give a rough overview, before delving into the details and  
more formal descriptions.


Using a contrived example like this seems like a straw man.  It  
feels like it is constructed to favour the PEP, whilst being unlike  
any real code.


It is a trait of many (good) tutorials to present a new structure with  
an example that highlights its feature in an approachable way rather  
than coming up with `real code'---particularly given that real code is  
always surrounded by a larger context, which rather clouds any  
understanding.  And it would only be a straw man had we constructed a  
contrived example of unrealistic code that we then showed to be  
simplified by pattern matching.  That's not the case: it really is  
just a simple educational example to present the idea.


BTW: as a matter of course, it is constructed in favour of the PEP!


There seem to be three things you want to enhance here:
Unpacking; to avoid calls to `len`
Type checking; to avoid calls to `isinstance`.
To avoiding nesting by using complex lvalues.


Actually, no.  Pattern matching is not about _avoiding_ anything, it  
is about a more concise syntax.  The suggestion that we wanted to  
avoid calls to `len` or `isinstance` is similar to the idea of using a  
lambda to avoid a function.  The objective of pattern matching is to  
introduce a more succinct and readable way to express structure.  It's  
all still there but we want to focus on the structure rather than  
`isinstance` calls.


Pattern matching already exists in some limited way in Python.  Even  
today you can write:

  `a, b = value`

instead of:
  `a = value[0]
   b = value[1]`
   
The idea of this is, of course, not so much about avoiding item  
access, but about having a more concise syntax for it.  Moreover,  
saying this only saves a single line and is therefore rather useless  
is quite beside the point.  It is about a better representation of  
what the code is supposed to do and not about saving lines.



Saves two lines of code, but introduces two bugs!
(Assuming that the original behavior should be preserved)


Thank you for pointing out the bug in our example.  This highlights,  
however, rather the difficulty of refactoring (did I already mention  
the issue of the 'context' that real code is embedded in?), than any  
shortcoming of pattern matching as a tool.  And by the way:  
constructive critisism would perhaps include explicitly naming the two  
bugs.


For example, by adding a simple "matches" method to Node and Leaf,  
`is_tuple` can be rewritten as something like:


This assumes that you have full control over the entire code.  But if  
you are using some third-party library, you cannot "simply add a  
`matches` method" (without some substantial trickery).  Moreover,  
there is quite some work needed to define such a `matches` function as  
you propose it (including support for the ellipsis as wildcard).  In  
effect, you would have to implement large parts of the pattern  
matching for just this simple example.  Whereas we believe that it has  
merit enough to have the compiler do it for a wide range of possible  
use cases.



I really don't see you how you can claim that
`case 406:`
is more readable than
`elif response == HTTP_UPGRADE_REQUIRED:`
?
Preventing the use of symbolic constants or other complex rvalues is  
a impairment to usability.


First, let me quote what the PEP has to say on that exact example:

Although this will work, it's not necessarily what the proposal is  
focused on.


Moreover, it is usually a good idea to put constants into a separate  
namespace that further describes their meaning and intended use.  And  
that is fully supported by the syntax as proposed in the PEP.

```
match response.status:
    case HTTP_RESPONSE.UPGRADE_REQUIRED:
    ...
```


For a PEP to succeed it needs to show two things.

1. Exactly what problem is being solved, or need is to be fulfilled,  
and that is a sufficiently large problem, or need, to merit the  
proposed change.


2. That the proposed change is the best known solution for the  
problem being addressed.


IMO, PEP 622 fails on both counts.


This seems fair enough as far as the two issues are concerned.  It  
might seem indeed as if pattern matching does not add anything that  
could not be done already in Python.  Part of the problem is that  
pattern matching starts to really shine when the objects and data 

[Python-Dev] Re: PEP 622: Structural Pattern Matching (version 2)

2020-07-14 Thread Mark Shannon


Hi,

As I wrote in an earlier email:


For a PEP to succeed it needs to show two things.

1. Exactly what problem is being solved, or need is to be fulfilled, and that 
is a sufficiently large problem, or need, to merit the proposed change.

2. That the proposed change is the best known solution for the problem being 
addressed.

IMO, PEP 622 fails on both counts.



This email addresses point 1 (for version 2).

Abstract


Why the use of "shape" in "scare quotes"?
It worries me that the abstract can't explain what PEP 622 does directly.

Could you use a real example in the abstract?
Using a contrived example like this seems like a straw man.
It feels like it is constructed to favour the PEP, whilst being unlike 
any real code.


Rationale and Goals
---

Python programs frequently need to handle data which varies in type, presence of attributes/keys, or number of elements. Typical examples are operating on nodes of a mixed structure like an AST, handling UI events of different types, processing structured input (like structured files or network messages), or “parsing” arguments for a function that can accept different combinations of types and numbers of parameters. 


AST, and UI objects usually (pretty much always) form a class hierarchy, 
making is easy to add utility matching methods to the base class.
Where matching *might* have some value is when unrelated types are 
involved, but you need to show that enhanced destructuring would be 
insufficient.



In fact, the classic 'visitor' pattern is an example of this, done in an OOP 
style -- but matching makes it much less tedious to write.


This might be true of the "classic" visitor pattern, but that's a straw man.
The Python visitor pattern is a joy to use.
Each case gets its own self contained method, clearly named, which is 
much better than a giant `match` statement.



Much of the code to do so tends to consist of complex chains of nested if/elif 
statements, including multiple calls to len(), isinstance() and 
index/key/attribute access. Inside those branches users sometimes need to 
destructure the data further to extract the required component values, which 
may be nested several objects deep.


There seem to be three things you want to enhance here:
Unpacking; to avoid calls to `len`
Type checking; to avoid calls to `isinstance`.
To avoiding nesting by using complex lvalues.

You fail to justify why the first two cannot be handled separately with 
much simpler extensions to the language and why complex lvalues are 
better than nesting.


The examples


There are only three examples, none of which are compelling.
In fact, two of them serve as a warning against the additional 
complexity this PEP entails.


Django example:
'''

Saves two lines of code, but introduces two bugs!
(Assuming that the original behavior should be preserved)

If the authors of the PEP cannot use this feature correctly in the first 
example they give, what chance do the rest of us have?



is_tuple example:
'

(Repeating my earlier email)
Python's support for OOP provides an alternative to ADTs.
For example, by adding a simple "matches" method to Node and Leaf, 
`is_tuple` can be rewritten as something like:


def is_tuple(node):
if not isinstance(node, Node):
return False
return node.matches("(", ")") or node.matches("(", ..., ")")


The "switch on http response codes" example.


This clearly demonstrates the value of symbolic constants for 
readability and the serious flaw in the PEP that I cannot use them.


I really don't see you how you can claim that
`case 406:`
is more readable than
`elif response == HTTP_UPGRADE_REQUIRED:`
?

Preventing the use of symbolic constants or other complex rvalues is a 
impairment to usability.

Silently failing when symbolic constants are used is terrible.

I do see the value of a `switch` statement for repeated tests against 
the same value; its intent is clearer than repeated `elif`s. But there 
is no need for it to be so hard to use.



Cheers,
Mark.


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


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-07-08 Thread Greg Ewing

On 9/07/20 3:26 am, Brandt Bucher wrote:

match :
 case  | : ...
 case  |  if : ...
 case  | : ...
```

It's safe to use the same decision tree for  through , but it must be rebuilt for 
 and , since  could have done literally *anything*.


I think you're being overly cautious here. To my mind, the guards
should be regarded as part of the pattern matching process, and so
people shouldn't be writing code that depends on them having side
effects.

As a nice consequence of adopting that rule, we would be able
to say that these are equivalent:

case C(a.b): ...

case C(x) if x == a.b: ...

--
Greg
___
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/NRTKPMUUOVJIAO3CTPGXW4JAI3DU2ZOY/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-07-08 Thread Brandt Bucher
Inada Naoki wrote:
> Since this is very new system, can we have some restriction to allow 
> aggressive optimization than regular Python code?

The authors were just discussing a related question yesterday (more 
specifically, can the compiler fold `C() | C()` -> `C( | )`). 
The answer we arrived at is "yes"; in general patterns may take reasonable 
shortcuts, and should not be expected to follow all the same rules as 
expressions. This means that users should never count on 
`__contains__`/`__getitem__`/`__instancecheck__`/`__len__`/`__match_args__` or 
other attributes being looked up or called more than once with the same 
arguments, and that name lookups *may* be "frozen", in a sense. We don't feel a 
need to cater to code that relies on these side-effecty behaviors (or doing 
even nastier things like changing local/global name bindings); in the eyes of 
the authors, code like that is buggy.

However, these rules only apply as long as we are still in "pattern-land", 
meaning all of our knowledge about the world is invalidated as soon as we hit a 
guard or stop matching.

In practice, I am currently experimenting with building decision-trees at 
compile-time. Given a match block of the following form:

```
match :
case  | : ...
case  |  if : ...
case  | : ...
```

It's safe to use the same decision tree for  through , but it must be 
rebuilt for  and , since  could have done literally *anything*.
___
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/XY3FXVB7HDYJIVKSOOBHW5BV2UB522FL/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-07-08 Thread MRAB

On 2020-07-08 03:08, Rob Cliffe via Python-Dev wrote:

Why not use '=' to distinguish binding from equality testing:
      case Point(x, =y): # matches a Point() with 2nd parameter equal to
y; if it does, binds to x.

This would allow a future (or present!) extension to other relative
operators:
      case Point(x, >y):
(although the syntax doesn't AFAICS naturally extend to specifying a
range, i.e. an upper and lower bound, which might be a desirable thing
to do.
Perhaps someone can think of a way of doing it).

Whether
      case =42:
      case 42:
would both be allowed would be one issue to be decided.

In Python, '=' is assignment and '==' is equality. Using '=' for 
equality could lead to confusion.

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


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-07-08 Thread Richard Damon
On 7/7/20 10:08 PM, Rob Cliffe via Python-Dev wrote:
> Why not use '=' to distinguish binding from equality testing:
>     case Point(x, =y): # matches a Point() with 2nd parameter equal to
> y; if it does, binds to x.
>
> This would allow a future (or present!) extension to other relative
> operators:
>     case Point(x, >y):
> (although the syntax doesn't AFAICS naturally extend to specifying a
> range, i.e. an upper and lower bound, which might be a desirable thing
> to do.
> Perhaps someone can think of a way of doing it).
>
> Whether
>     case =42:
>     case 42:
> would both be allowed would be one issue to be decided.
> Rob Cliffe 
My preference would be that we mark where to bind as opposed to what is
a constant. Forgetting to mark a constant that has been bound to a name
runs the risk of changing that 'constant' (since Python doesn't support
marking a name as a constant). Forgetting to mark a name to bind may
likely cause a run time error if it hasn't been bound yet, or at the
very least probably fails in a 'safer' way. I think forgetting to add a
special mark is a much more likely error than adding a mark by mistake
(unless the mark is just havig a dot in the name).

-- 
Richard Damon
___
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/NMFVBR433E6UEGEEJAS6I6NNXPK7W4OM/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-07-08 Thread Chris Angelico
On Wed, Jul 8, 2020 at 8:56 PM Inada Naoki  wrote:
>
> On Wed, Jul 8, 2020 at 6:14 PM Chris Angelico  wrote:
> >
> >
> > These two I would be less averse to, but the trouble is that they make
> > the semantics a bit harder to explain. "Dotted names are looked up if
> > not already looked up, otherwise they use the same object from the
> > previous lookup". If you have (say) "case
> > socket.AddressFamily.AF_INET", does it cache "socket",
> > "socket.AddressFamily", or both?
> >
>
> I meant "It is implementation detail" and "User must not rely on side effects
> of attribute access."
>

Fair enough. I wouldn't mind that, it seems like a nice optimization
that would only harm code that would be extremely confusing to read
anyway. But only within one matching - caching beyond that seems more
dangerous.

ChrisA
___
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/XORPYNPF2ZNS6YX6AHXXBHMC6VQEYD5V/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-07-08 Thread Inada Naoki
On Wed, Jul 8, 2020 at 6:14 PM Chris Angelico  wrote:
>
>
> These two I would be less averse to, but the trouble is that they make
> the semantics a bit harder to explain. "Dotted names are looked up if
> not already looked up, otherwise they use the same object from the
> previous lookup". If you have (say) "case
> socket.AddressFamily.AF_INET", does it cache "socket",
> "socket.AddressFamily", or both?
>

I meant "It is implementation detail" and "User must not rely on side effects
of attribute access."


-- 
Inada Naoki  
___
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/QN6EG4332J2RO27DJYMBLGD7KLQCUZ5A/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-07-08 Thread Rhodri James

On 08/07/2020 11:05, Federico Salerno wrote:
What I don't like is the use of _ as catch-all, which is different and 
not interdependent with its use as throwaway.


Any name used as a pattern is a catch-all.  The only difference between 
"case dummy:" and "case _:" is that "_" doesn't bind to the thing being 
matched, but "dummy" does bind to it.


--
Rhodri James *-* Kynesim Ltd
___
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/ZU6MJDE4CMMQDYYAJLKWTA2FOAIR5IPG/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-07-08 Thread Federico Salerno

On 07/07/2020 16:31, Henk-Jaap Wagenaar wrote:
I used to be in this "camp", however, a (I think valid) point was 
raised that "else:" is not a (full) alternative. Due to the 
restriction on repeated names (e.g. Point(x, x) is illegal), if you 
want to "throw away" intermediate matches, you will have to either 
have to come up with new names (Point(unused_1, unused_2)) or use the 
"_" as currently instituted (Point(_, _)) and "else:" does not cover 
that insofar as I can tell.


Personally I think using _ as throwaway name is perfectly fine, as it is 
in the rest of Python. The only exception would then be that _ is 
allowed to be repeated, whereas other identifiers aren't. I'd be ok with 
that.


What I don't like is the use of _ as catch-all, which is different and 
not interdependent with its use as throwaway.


On 08/07/2020 07:26, Steven Barker wrote:

To sum up, I feel like using constructor and keyword-argument syntax 
to access attributes is an abuse of notation. I'd much prefer a new 
syntax for matching classes and their attributes that was not so 
likely to be confusing due to imperfect parallels with class construction.

+1

Ideally something like Datetime.year=x would be in my opinion clear at a 
glance (and reference vs. assignment could be accomplished simply by 
having == for reference and = for assignment), but it's problematic when 
it comes to mentioning multiple attributes.

A couple ideas:

1. Datetime[year=x, months==3, days==SOME_CONST]

2. (Datetime.year=x, months==3, days==SOME_CONST)

3. Datetime.year=x .months==3 .days==SOME_CONST

4. Datetime.year=x, .months==3, .days==SOME_CONST

With no class, this would perhaps favour usage of = and/or == before 
names to resolve the reference vs. assignment dispute.


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


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-07-08 Thread Chris Angelico
On Wed, Jul 8, 2020 at 6:17 PM Inada Naoki  wrote:
>
> Since this is very new system, can we have some restriction
> to allow aggressive optimization than regular Python code?
>
> # Class Pattern
>
> Example:
>
> match val:
> case Point(0, y): ...
> case Point(x, 0): ...
> case Point(x, y): ...
>
> * Can VM cache the "Point" at first execution, and never lookup in
> next time? (e.g. function executed many times)

I'd prefer not - that seems very confusing.

> # Constant value pattern
>
> Example:
>
> match val:
> case Sides.SPAM: ...
> case Sides.EGGS: ...
>
> * Can VM cache the value of "Sides.SPAM" and "Sides.EGGS" for next execution?
>

Similar, but with the additional consideration that you can create a
"pre-baked pattern" by using a dict, so if you're worried about
performance, use the slightly uglier notation (assuming that
Sides.SPAM and Sides.EGGS are both hashable - and if they're not, the
risk of prebaking is way too high).

> * Can VM lookup "Point" only once per executing `match`, instead three times?
> * Can VM lookup "Sides" only once, instead of two?

These two I would be less averse to, but the trouble is that they make
the semantics a bit harder to explain. "Dotted names are looked up if
not already looked up, otherwise they use the same object from the
previous lookup". If you have (say) "case
socket.AddressFamily.AF_INET", does it cache "socket",
"socket.AddressFamily", or both?

ChrisA
___
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/IR5UUBLXBAZDT45MGYD2CX42K2R7Z5LB/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-07-08 Thread Inada Naoki
Since this is very new system, can we have some restriction
to allow aggressive optimization than regular Python code?

# Class Pattern

Example:

match val:
case Point(0, y): ...
case Point(x, 0): ...
case Point(x, y): ...

* Can VM lookup "Point" only once per executing `match`, instead three times?
* Can VM cache the "Point" at first execution, and never lookup in
next time? (e.g. function executed many times)


# Constant value pattern

Example:

match val:
case Sides.SPAM: ...
case Sides.EGGS: ...

* Can VM lookup "Sides" only once, instead of two?
* Can VM cache the value of "Sides.SPAM" and "Sides.EGGS" for next execution?

Regards,

-- 
Inada Naoki  
___
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/GUFY4MNHTF2F75X5YI574LVP6QAZQ5KI/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-07-07 Thread Steven Barker
On Sun, Jun 28, 2020 at 8:44 AM Jim J. Jewett  wrote:

> I actually like that it looks like instantiation; it seems to be saying
> "Do we have the sort of object we would get from this instantiation?"
>
> Unfortunately, this does aggravate the confusion over whether a variable
> is being used as a filter, vs binding to something from the matched object.
>

The constructor-like syntax for class patterns is the part I like least
about this proposal. It seems to expect that there is a one-to-one
correspondence between constructor arguments and instance attributes. While
that might be common, especially for DataClass-like types, it's certainly
not always the case. Some attributes might be computed from multiple
arguments (or looked up elsewhere), and some arguments may never be saved
in their original form. I fear it will be extremely confusing if an
attribute being matched by a class pattern doesn't correspond at all to an
argument in a valid constructor call. For example, this class would make
things very confusing:

class Foo:
def __init__(self, a, b):
self.c = a + b

You could match an instance of the class with `case Foo(c=x)` and it would
work, but that might come as a surprise to anyone familiar with the class
constructor's argument names.

Even when attributes and constructor arguments do line up, the class
pattern syntax also seems a bit awkward when you are not required to match
against all of the non-optional constructor arguments. I imagine `case
datetime.datetime(year=2020):` would be a valid (and even useful!) class
pattern, but you can't construct a datetime instance in that way since the
class has three required arguments.

To sum up, I feel like using constructor and keyword-argument syntax to
access attributes is an abuse of notation. I'd much prefer a new syntax for
matching classes and their attributes that was not so likely to be
confusing due to imperfect parallels with class construction.
___
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/7LXFWX5LPLJBRVUK7OEPB3KGJQNB3AO6/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-07-07 Thread Rob Cliffe via Python-Dev

Why not use '=' to distinguish binding from equality testing:
    case Point(x, =y): # matches a Point() with 2nd parameter equal to 
y; if it does, binds to x.


This would allow a future (or present!) extension to other relative 
operators:

    case Point(x, >y):
(although the syntax doesn't AFAICS naturally extend to specifying a 
range, i.e. an upper and lower bound, which might be a desirable thing 
to do.

Perhaps someone can think of a way of doing it).

Whether
    case =42:
    case 42:
would both be allowed would be one issue to be decided.
Rob Cliffe
___
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/MENII4GJ66JHWBKNTNJSJOYCMSMLSIRO/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching [was: PEP 622 railroaded through?]

2020-07-07 Thread Guido van Rossum
Please move this subtopic to a subject that doesn’t have “PEP 622” in its
topic.

On Tue, Jul 7, 2020 at 17:54 Greg Ewing  wrote:

> On 8/07/20 5:30 am, Paul Sokolovsky wrote:
> > from __future__ import const
> >
> > FOO: const = 1
> >
> > match val:
> >  case FOO:  # obviously matches by constant's value
>
> This would make it *more* difficult to distinguish constants from
> assignment targets when looking at the match statement, unless you
> choose names which "look constant-like" somehow.
>
> It also has the general problem of const-declarations in Python.
> Currently the compiler only has to analyse one module at a time;
> this would require it to also look inside imported modules to
> determine whether things were declared const.
>
> --
> Greg
> ___
> 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/ACJJV65BQNZ2LMNUBGJJLBR7AI3EO4SU/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
-- 
--Guido (mobile)
___
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/GFMOZ6XFIJKQ4ST7TFTCMRUGICZASE5G/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching [was: PEP 622 railroaded through?]

2020-07-07 Thread Greg Ewing

On 8/07/20 5:30 am, Paul Sokolovsky wrote:

from __future__ import const

FOO: const = 1

match val:
 case FOO:  # obviously matches by constant's value


This would make it *more* difficult to distinguish constants from
assignment targets when looking at the match statement, unless you
choose names which "look constant-like" somehow.

It also has the general problem of const-declarations in Python.
Currently the compiler only has to analyse one module at a time;
this would require it to also look inside imported modules to
determine whether things were declared const.

--
Greg
___
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/ACJJV65BQNZ2LMNUBGJJLBR7AI3EO4SU/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching [was: PEP 622 railroaded through?]

2020-07-07 Thread Greg Ewing

On 8/07/20 2:31 am, Henk-Jaap Wagenaar wrote:
Would it be possible here to use a syntax/symbol that is illegal instead 
of _? I think this has been mooted but my favourite (so far) would be 
"?" so you have "case ?:" and "Point(?, ?)".


Would ?name then work instead of ".name" as well?


It would work better if ? were used to mark assigned names instead
of values. Then '?' on its own would be a special case of '?name'
where you leave out the name.

--
Greg
___
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/6W2CI6ST7AFCXWXPGP7VJN35I3WGZJV3/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching [was: PEP 622 railroaded through?]

2020-07-07 Thread Paul Moore
On Tue, 7 Jul 2020 at 18:35, Guido van Rossum  wrote:
>
> On Tue, Jul 7, 2020 at 9:09 AM Paul Moore  wrote:
>>
>> Hopefully the PEP authors intend to post an updated version
>> (preferably with a summary of changes, for people struggling to keep
>> up with the traffic here!) sometime soon.
>
>
> Please consider that the PEP authors also are struggling with the traffic 
> here.

Sorry! I didn't intend to imply otherwise. Mostly I was just hoping
you'd be more aware of what you'd changed and could offer a "these are
the high spots of what's changed" overview when you post the new
version. But absolutely don't feel that I'm suggesting you're obliged
to do so!

Paul
___
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/3KOI5PVB2EH6LA4TS2INEPCBXS6GWIQM/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching [was: PEP 622 railroaded through?]

2020-07-07 Thread Guido van Rossum
On Tue, Jul 7, 2020 at 9:09 AM Paul Moore  wrote:

> Hopefully the PEP authors intend to post an updated version
> (preferably with a summary of changes, for people struggling to keep
> up with the traffic here!) sometime soon.
>

Please consider that the PEP authors also are struggling with the traffic
here.

-- 
--Guido van Rossum (python.org/~guido)
*Pronouns: he/him **(why is my pronoun here?)*

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


[Python-Dev] Re: PEP 622: Structural Pattern Matching [was: PEP 622 railroaded through?]

2020-07-07 Thread Paul Sokolovsky
Hello,

On Tue, 7 Jul 2020 17:22:28 +0100
Henk-Jaap Wagenaar  wrote:

[]

> > >>  I don't like the .name syntax (grit on Tim's monitor; does

[]

> "PEP 622: Ditch leading dots for name loads": this is now an
> ex-syntax, it is bereft of life (for this, draft, of the PEP, might
> come back later!):
> https://github.com/python/peps/commit/f1de4f169d762cbb46fbfe94d2c01839db9b2f07
> 
> In there, it makes a good point that namespaced constants are good,
> especially for this kind of thing (you probably want to e.g. match
> over a bunch of possible constants which you can then put in an enum
> or some other namespace).

That's probably a nice move, but requiring constants to be
extra-namespaced seems like a pretty arbitrary and limiting "rule"
either.

This touches on the sentiment which I was too shy to share for a long
time even on python-ideas, but would like to take a chance to bring up
here now:

With the advent of Lua 5.4, Python appears to be **the only** of the
popular VHLL/scripting languages which doesn't support defining of
constants in the core language:

JavaScript has "const foo = 1;"
PHP has "const foo = 1;"
Perl has "use constant foo => 1;"
Lua has "local foo  = 1"


The closest Python has is:

---
from typing import Final
foo: Final = 1
--- 

which is done on the level of an arbitrary external module, and doesn't
enforce or employ const'ness on the language core level (unlike other
languages above).

If there were constants on the level of the core language, it would
*also* allow to elegantly resolve issue with the usage in match patterns
(in addition to baseline benefits of allowing programmers to express
programs more clearly and perform low-hanging optimizations). E.g.:

---
from __future__ import const

FOO: const = 1

match val:
case FOO:  # obviously matches by constant's value
---


-- 
Best regards,
 Paul  mailto:pmis...@gmail.com
___
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/YPP2TWYONFL4BOR3MJHGTHWSPMQNP7J7/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching [was: PEP 622 railroaded through?]

2020-07-07 Thread Eric Fahlgren
On Tue, 7 Jul 2020 at 15:04, Rob Cliffe via Python-Dev <
python-dev@python.org> wrote:

>  I don't like the .name syntax (grit on Tim's monitor; does not
>> suggest the meaning). [...] But I don't know what syntax (where
>> necessary) to suggest.
>
>
https://photos.app.goo.gl/xN68s3QMMBTPTLD47   Look about two character
spaces left of "I don't like..."

As I read this part of Rob's post this morning, I thought he was
surreptitiously making a point about grit on the screen, when I noticed it
was *literally grit on the screen*.  I cannot convey how long it took me to
recover.
___
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/XRHUZGM7HP6S6Z7UQTYTIE7GO64S7LIP/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching [was: PEP 622 railroaded through?]

2020-07-07 Thread Henk-Jaap Wagenaar
On Tue, 7 Jul 2020 at 17:09, Paul Moore  wrote:

> On Tue, 7 Jul 2020 at 15:40, Henk-Jaap Wagenaar
>  wrote:
> >
> > On Tue, 7 Jul 2020 at 15:04, Rob Cliffe via Python-Dev <
> python-dev@python.org> wrote:
> >>
> >>  I don't like the .name syntax (grit on Tim's monitor; does not
> >> suggest the meaning). [...] But I don't know what syntax (where
> necessary) to suggest.
> >
> >
> > +1(000)
>
> There's been traffic on the PEP repository which suggests that there
> is a new version of the PEP incoming which responds to these types of
> concern. I'm not willing to read raw rst diffs, so I haven't checked
> any of the details.
>

"PEP 622: Ditch leading dots for name loads": this is now an ex-syntax, it
is bereft of life (for this, draft, of the PEP, might come back later!):
https://github.com/python/peps/commit/f1de4f169d762cbb46fbfe94d2c01839db9b2f07

In there, it makes a good point that namespaced constants are good,
especially for this kind of thing (you probably want to e.g. match over a
bunch of possible constants which you can then put in an enum or some other
namespace).
___
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/2AP7CECCWKAGXBL27T6MNTRKPS4PS2OH/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching [was: PEP 622 railroaded through?]

2020-07-07 Thread Emily Bowman
On Tue, Jul 7, 2020 at 8:37 AM Rhodri James  wrote:

> I'm not quite convinced about making "_" non-binding, mostly because of
> the knock-on effects in the PEP for other types of patterns.  It seems
> to breed more special cases, and I can't help but feel that's a bad sign.
>

After spending some time with it in my head and in the actual testbed, it
seems like a reasonable compromise. case Point(x,x): being illegal while
x,x=(1,2) is perfectly legal is a bit of contention, but grammar also
doesn't need to be perfectly consistent in order to learn to speak a
language, it just needs to minimize the context-switching. It'd be so
simple if we could use case *:, but alas.
___
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/GD4XNSAW463J2U3P546UO6NFFENC3RUW/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching [was: PEP 622 railroaded through?]

2020-07-07 Thread Paul Moore
On Tue, 7 Jul 2020 at 15:40, Henk-Jaap Wagenaar
 wrote:
>
> On Tue, 7 Jul 2020 at 15:04, Rob Cliffe via Python-Dev 
>  wrote:
>>
>>  I don't like the .name syntax (grit on Tim's monitor; does not
>> suggest the meaning). [...] But I don't know what syntax (where necessary) 
>> to suggest.
>
>
> +1(000)

There's been traffic on the PEP repository which suggests that there
is a new version of the PEP incoming which responds to these types of
concern. I'm not willing to read raw rst diffs, so I haven't checked
any of the details.

Hopefully the PEP authors intend to post an updated version
(preferably with a summary of changes, for people struggling to keep
up with the traffic here!) sometime soon.

Paul
___
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/7TGKN3QQVNEJQWZSJO6SAYHROXR3HLFT/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching [was: PEP 622 railroaded through?]

2020-07-07 Thread Rhodri James

On 07/07/2020 15:31, Henk-Jaap Wagenaar wrote:

On Tue, 7 Jul 2020 at 15:04, Rob Cliffe via Python-Dev <
python-dev@python.org> wrote:

  I'm not keen on special treatment of the '_' variable, and would
prefer to be able to use 'else:' after 'match'.



I used to be in this "camp", however, a (I think valid) point was raised
that "else:" is not a (full) alternative. Due to the restriction on
repeated names (e.g. Point(x, x) is illegal), if you want to "throw away"
intermediate matches, you will have to either have to come up with new
names (Point(unused_1, unused_2)) or use the "_" as currently instituted
(Point(_, _)) and "else:" does not cover that insofar as I can tell.


There are two things here, the specialness of "_" and using "else:" as 
the catch-all clause.


I'm not quite convinced about making "_" non-binding, mostly because of 
the knock-on effects in the PEP for other types of patterns.  It seems 
to breed more special cases, and I can't help but feel that's a bad sign.


On the other hand "else:" would have exactly the effect of "case _:", so 
we're into arguments about there preferably being only one obvious way 
to do things.  I'd maintain that "else:" is obvious :-)


--
Rhodri James *-* Kynesim Ltd
___
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/EIBEIZ7QLBO3RBH253D7ZK5WTRNKHSYD/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching [was: PEP 622 railroaded through?]

2020-07-07 Thread Henk-Jaap Wagenaar
On Tue, 7 Jul 2020 at 15:04, Rob Cliffe via Python-Dev <
python-dev@python.org> wrote:

>  I don't like the .name syntax (grit on Tim's monitor; does not
> suggest the meaning). [...] But I don't know what syntax (where necessary)
> to suggest.


+1(000)


>  I'm not keen on special treatment of the '_' variable, and would
> prefer to be able to use 'else:' after 'match'.
>

I used to be in this "camp", however, a (I think valid) point was raised
that "else:" is not a (full) alternative. Due to the restriction on
repeated names (e.g. Point(x, x) is illegal), if you want to "throw away"
intermediate matches, you will have to either have to come up with new
names (Point(unused_1, unused_2)) or use the "_" as currently instituted
(Point(_, _)) and "else:" does not cover that insofar as I can tell.

Would it be possible here to use a syntax/symbol that is illegal instead of
_? I think this has been mooted but my favourite (so far) would be "?" so
you have "case ?:" and "Point(?, ?)".

Would ?name then work instead of ".name" as well? Not sure that makes its
use more/less/equal consistent with the previous suggestion.

Apologies if this has been discussed, I have followed the thread(s) but I
might well have forgotten or missed something!
___
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/XRG7DTFZKBY6E373QKB3TBEBB7D6FWWF/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-07-04 Thread Shantanu Jain
Caveats:
- Any expression (unless you allow reference to variables previously bound
by the match statement) can just be aliased (as long as you don’t need
short circuiting), so it’s not a critical feature. Constant value patterns
are the most easily replaceable by if/elif part of PEP 622.
- I’m sure the PEP authors have a better understanding than I of what use
cases come up in practice; the fact that they didn’t address this is maybe
revealing.
- A discussion of allowing expressions in constant value patterns is a
slight digression from alternative syntax for constant value patterns and I
don’t want to go too deep down the rabbit hole and lose sight of the
original question.

I think it could be very reasonable to want to use dictionary lookups,
especially since a lot of older code / libraries use dicts for enum-like
use cases.

And arithmetic expressions (outside of powers of 2 and 10):
```
match unit_value:
case %(7 * 24 * 60 * 60): return “week”
...
```
And function calls:
```
match hsv_color:
case %(hsv(“black”)): ...
case %(hsv(“cyan”)): ...
case (_, 0, _): return “some sort of grey”

match git_bisect_action:
case %(config.get_old_term()): ...
case %(config.get_new_term()): ...

match conn:
case %(get_current_conn()): ...
case Connection(host, port): ...
```

The caveats above apply, and even if you find the above examples
compelling, this would probably fall in the 10 bucket of 90/10 usage. But
if our syntax for constant value patterns made it natural / easy to
support, it’s something to consider, either now or later a la PEP 614.

On Sat, 4 Jul 2020 at 19:15, Chris Angelico  wrote:

> On Sun, Jul 5, 2020 at 12:03 PM Shantanu Jain 
> wrote:
> > - Finally, I did mention increasing the scope of constant value patterns
> to accommodate expressions (as opposed to just dotted names). If we were to
> do this, it’s a reason to prefer some syntaxes for constant value patterns
> over others.
> >
>
> I'm kinda theoretically in favour of expressions, but only the sort
> that logically "feel" like constants. Unary minus and the addition of
> real and imaginary parts are already supported, so what's still of
> value? IMO exponentiation of 2 is usually better spelled in hex
> (instead of 2**10, use 0x400, unless there's good reason), and since
> you can have underscores to break up an integer, that handles powers
> of 10 as well. What notations would you want to use?
>
> ChrisA
> ___
> 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/T24W2FZ6UY36CI2GP4LKGBSLSHBYH4K3/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
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/YFGOGWIKXWT3REL335WOR4ZTQMJC7SXL/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-07-04 Thread Chris Angelico
On Sun, Jul 5, 2020 at 12:03 PM Shantanu Jain  wrote:
> - Finally, I did mention increasing the scope of constant value patterns to 
> accommodate expressions (as opposed to just dotted names). If we were to do 
> this, it’s a reason to prefer some syntaxes for constant value patterns over 
> others.
>

I'm kinda theoretically in favour of expressions, but only the sort
that logically "feel" like constants. Unary minus and the addition of
real and imaginary parts are already supported, so what's still of
value? IMO exponentiation of 2 is usually better spelled in hex
(instead of 2**10, use 0x400, unless there's good reason), and since
you can have underscores to break up an integer, that handles powers
of 10 as well. What notations would you want to use?

ChrisA
___
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/T24W2FZ6UY36CI2GP4LKGBSLSHBYH4K3/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-07-04 Thread Shantanu Jain
Apologies if I misunderstand anything, but my suggestion was just an
alternative to the dot syntax for constant value patterns (which along with
literal patterns are how PEP 622’s proposes to to cover the “more flexible
switch” use case).

This syntax is more verbose than PEP 622’s dot syntax for identifying
constant value patterns, but that’s the intention. A number of messages in
the thread point out that the difference between `case FOO: …` and `case
.FOO: …` is very easy to miss.

There are a couple other proposals for how to identify constant value
patterns (and proposals for having constant value patterns be the default
and capture patterns be the ones explicitly demarcated).
The one suggested the most is `case $FOO: …`. This is less verbose than my
suggestion, but a) it requires introducing a new symbol to Python, b) it
doesn’t correspond to any existing Python syntax, whereas syntax that’s
reminiscent of format strings might build on a shared substitution metaphor
in users’ minds.

The last two lines of my suggestion were just pointing out another
potential reason to prefer this bikeshed over dot syntax (and others
proposed at
https://github.com/python/peps/blob/master/pep-0622.rst#alternatives-for-constant-value-pattern
): if we wanted to extend constant value patterns to match constant
expressions (as opposed to just dotted names), having syntax that uses
delimiters might be more readable than a dot or dollar prefix — at least to
me it’s easier to parse a delimited region to see what part of a pattern
would be matched against literally.

tldr;
- My suggestion was explicitly just bikeshedding syntax for constant value
patterns (the “slightly more flexible switch” part of PEP 622).
- The relative verbosity as compared to dot prefix syntax is meant as a
feature, since it’s very easy to miss the dot
- If you’re a proponent of dot syntax, you won’t see any value in this
suggestion. Given that dot syntax seemed to come up in the thread a fair
amount, and that the PEP calls it the “trickiest item”, I thought it might
be worth suggesting some other options.
- Finally, I did mention increasing the scope of constant value patterns to
accommodate expressions (as opposed to just dotted names). If we were to do
this, it’s a reason to prefer some syntaxes for constant value patterns
over others.

On Sat, 4 Jul 2020 at 16:51, Emily Bowman  wrote:

> I don't see how this extrapolates to arbitrary, extended match
> expressions? You're proposing a slightly more flexible switch, which match
> is only intended to be as the most basic case. Even if you purely swapped
> it out with any the various proposals for identifying a constant vs a
> target, it's still far more verbose than any of them.
>
> On Sat, Jul 4, 2020 at 4:31 PM Shantanu Jain 
> wrote:
>
>> Thank you for this PEP! Pattern matching is really exciting.
>>
>> As the PEP mentions and the thread evidences, the current dot syntax for
>> the “constant value pattern” is a tricky point. Given this, I thought I’d
>> throw another suggestion into the bikeshed.
>>
>> Use percent placeholder to indicate lookup (or even eval) semantics for a
>> given name. For example:
>> ```
>> FOO = 1
>> value = 0
>>
>> match value:
>> case %(FOO):  # This would not be matched
>> ...
>> case BAR:# This would be matched
>> ...
>> ```
>> I like this syntax because it’s reminiscent of named substitution in
>> percent formatted strings. It suggests a substitution / placeholder
>> metaphor that is quite fitting. It has the benefit of not introducing a new
>> symbol into Python and being explicit and hard to miss, including in nested
>> contexts.
>>
>> Note, it seems like it would also be technically possible to use curly
>> braces (the more idiomatic means of named substitution in Python 3):
>> ```
>> case {FOO}: …
>> ```
>> The main downside of this is that it could look like some sort of
>> singleton “set pattern” (note that the PEP only supports “sequence
>> patterns” and “mapping patterns”).
>> (But set patterns maybe don’t quite make sense + if your set pattern had
>> multiple elements you’d still get a SyntaxError. For other examples where
>> something in Python looks like a set literal but isn’t, refer to `{}` and
>> f-strings, so it’s maybe not the biggest stretch)
>>
>> Both of these suggestions could also allow us more flexibility for
>> constant value patterns, since currently there isn't a good way to match
>> against a constant expression. For example, we could extend this syntax to
>> allow us to express:
>> ```
>> case %(2 ** 10): ...
>> ```
>> ___
>> 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/YQUCFREQ2P7NENOTPBE277I3BZ6DGXSR/
>> Code of Conduct: 

[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-07-04 Thread Emily Bowman
 I don't see how this extrapolates to arbitrary, extended match
expressions? You're proposing a slightly more flexible switch, which match
is only intended to be as the most basic case. Even if you purely swapped
it out with any the various proposals for identifying a constant vs a
target, it's still far more verbose than any of them.

On Sat, Jul 4, 2020 at 4:31 PM Shantanu Jain  wrote:

> Thank you for this PEP! Pattern matching is really exciting.
>
> As the PEP mentions and the thread evidences, the current dot syntax for
> the “constant value pattern” is a tricky point. Given this, I thought I’d
> throw another suggestion into the bikeshed.
>
> Use percent placeholder to indicate lookup (or even eval) semantics for a
> given name. For example:
> ```
> FOO = 1
> value = 0
>
> match value:
> case %(FOO):  # This would not be matched
> ...
> case BAR:# This would be matched
> ...
> ```
> I like this syntax because it’s reminiscent of named substitution in
> percent formatted strings. It suggests a substitution / placeholder
> metaphor that is quite fitting. It has the benefit of not introducing a new
> symbol into Python and being explicit and hard to miss, including in nested
> contexts.
>
> Note, it seems like it would also be technically possible to use curly
> braces (the more idiomatic means of named substitution in Python 3):
> ```
> case {FOO}: …
> ```
> The main downside of this is that it could look like some sort of
> singleton “set pattern” (note that the PEP only supports “sequence
> patterns” and “mapping patterns”).
> (But set patterns maybe don’t quite make sense + if your set pattern had
> multiple elements you’d still get a SyntaxError. For other examples where
> something in Python looks like a set literal but isn’t, refer to `{}` and
> f-strings, so it’s maybe not the biggest stretch)
>
> Both of these suggestions could also allow us more flexibility for
> constant value patterns, since currently there isn't a good way to match
> against a constant expression. For example, we could extend this syntax to
> allow us to express:
> ```
> case %(2 ** 10): ...
> ```
> ___
> 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/YQUCFREQ2P7NENOTPBE277I3BZ6DGXSR/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
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/WTUD5LSX7QZVSJM4UZLAVLW5OV4PNWS2/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-07-04 Thread Shantanu Jain
Thank you for this PEP! Pattern matching is really exciting.

As the PEP mentions and the thread evidences, the current dot syntax for
the “constant value pattern” is a tricky point. Given this, I thought I’d
throw another suggestion into the bikeshed.

Use percent placeholder to indicate lookup (or even eval) semantics for a
given name. For example:
```
FOO = 1
value = 0

match value:
case %(FOO):  # This would not be matched
...
case BAR:# This would be matched
...
```
I like this syntax because it’s reminiscent of named substitution in
percent formatted strings. It suggests a substitution / placeholder
metaphor that is quite fitting. It has the benefit of not introducing a new
symbol into Python and being explicit and hard to miss, including in nested
contexts.

Note, it seems like it would also be technically possible to use curly
braces (the more idiomatic means of named substitution in Python 3):
```
case {FOO}: …
```
The main downside of this is that it could look like some sort of singleton
“set pattern” (note that the PEP only supports “sequence patterns” and
“mapping patterns”).
(But set patterns maybe don’t quite make sense + if your set pattern had
multiple elements you’d still get a SyntaxError. For other examples where
something in Python looks like a set literal but isn’t, refer to `{}` and
f-strings, so it’s maybe not the biggest stretch)

Both of these suggestions could also allow us more flexibility for constant
value patterns, since currently there isn't a good way to match against a
constant expression. For example, we could extend this syntax to allow us
to express:
```
case %(2 ** 10): ...
# or
case {get_default()}: ...
```
___
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/Y4I4PO3VFRYAJUAW2JXA4IYVN7NZMTDQ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-07-04 Thread Shantanu Jain
Thank you for this PEP! Pattern matching is really exciting.

As the PEP mentions and the thread evidences, the current dot syntax for
the “constant value pattern” is a tricky point. Given this, I thought I’d
throw another suggestion into the bikeshed.

Use percent placeholder to indicate lookup (or even eval) semantics for a
given name. For example:
```
FOO = 1
value = 0

match value:
case %(FOO):  # This would not be matched
...
case BAR:# This would be matched
...
```
I like this syntax because it’s reminiscent of named substitution in
percent formatted strings. It suggests a substitution / placeholder
metaphor that is quite fitting. It has the benefit of not introducing a new
symbol into Python and being explicit and hard to miss, including in nested
contexts.

Note, it seems like it would also be technically possible to use curly
braces (the more idiomatic means of named substitution in Python 3):
```
case {FOO}: …
```
The main downside of this is that it could look like some sort of singleton
“set pattern” (note that the PEP only supports “sequence patterns” and
“mapping patterns”).
(But set patterns maybe don’t quite make sense + if your set pattern had
multiple elements you’d still get a SyntaxError. For other examples where
something in Python looks like a set literal but isn’t, refer to `{}` and
f-strings, so it’s maybe not the biggest stretch)

Both of these suggestions could also allow us more flexibility for constant
value patterns, since currently there isn't a good way to match against a
constant expression. For example, we could extend this syntax to allow us
to express:
```
case %(2 ** 10): ...
```
___
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/YQUCFREQ2P7NENOTPBE277I3BZ6DGXSR/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-30 Thread Daniel Moisset
Hi, thank you for the comments

On Tue, 30 Jun 2020 at 07:18, Greg Ewing 
wrote:

> On 29/06/20 8:47 am, Daniel Moisset wrote:
> > <
> https://github.com/dmoisset/notebook/blob/811bf66/python/pep622/understanding-pep-622.md>
>  .
>
>
> You seem to be trying to shoehorn all Python data structures into
> looking like alebraic types, for the sole purpose of being able to
> claim that PEP 622 is really about algebraic types rather than
> pattern matching.
>

There may be a bit of this, I like "unifying concepts". But if I have a
bias, I was heavily pushed by the writing on the PEP. Their inspirations
are explicitly Rust and Scala (which have a very strong "algebraic type"
core),, and in discussions I've seen the authors discuss F# and Haskell
(again with a strong algebraic type influence). If they started on "we were
inspired by C's and Javascript's switch statement and then added some extra
features" I would have a different vision that the focus is
multiple-choice-conditional and the rest are extras. If they mentioned
Javascript destructuring operations as inspiration I would think instead
that the focus is decomposing builtin types and the rest are extras. The
motivation starts discussing about isinstance() checks and extracting
attributes which sounds more like "we added this to have algebraic data
types and hey, now that we're here we can also include some unpacking and
have a switch statement too".

The goal of my notes was to read the PEP between lines, so there's some
personal guess and bias, but it's not out of the blue :)

I don't think that's a helpful way of looking at things. Pattern
> matching with destructuring is a more general concept. Algebraic
> types is just one of its applications.
>

I agree on this statement (except the first sentence :) )... what I'm
trying to say is that the PEP has some underlying algebraic type style and
making it explicit is a way to understand it with different eyes.


> I think your viewpoint is coloured by languages in which algebraic
> types play a much more central role than they do in Python. For
> example, in Haskell, the usual notation for lists is syntactic
> sugar for an algebraic type representing a linked list.
>

Haskell also does some shoe-horning... integers in haskell are supposed to
be an algebraic type made by the union of infinite constructors named "1",
"2", "3", ... :) Even if the implementation is nothing like that, this kind
of shoe-horning is useful allows you to have a coherent story and design,
so I'm looking for somehting close to that in Python.


> But Python lists are not linked lists, they're flexible-sized
> arrays, and you have to squint very hard indeed to see them as
> being fundamentally an algebraic type. Yet pattern matching on
> them makes perfectly good sense.
>

True.  And python has already had that for ages. I'm *guessing* intent here
again, but I believe that was included into the PEP because it was easy,
not because it was the main concern to address.

> returning by default an object __dict__ or some sort of mapping view
> > on the attributes could still be fine. It's not clear to me why the
> > "keys" of this structure are placed separately.
>
> I think the PEP explains the rationale behind the design of the
> matching protocol quite well. The goal is to make it as simple as
> possible to implement in the most common cases.
>

I have improved my understanding of this. I still find the protocol weak
(but mostly the match, not the matched_args) even for the cases that are
desired to be covered, but I'm already discussing those directly with the
authors.

> For me, there should be an instance method in object (that
> > subclasses  can override) that returns the algebraic structure of the
> value.
> > The PEP as-is creates different destructuring views depending on
> > which matching class you use (whicch I think relates to something
> > that was mentioned but not discussed a lot in the python-dev list
> > about Liskov sustitability).
> I think the PEP has this right. Liskov substitutability doesn't apply
> to constructors -- they're not methods, and the constructor of a
> subclass doesn't have to accept the same arguments as that of its
> base class. The same thing applies to deconstructors, since they have
> to mirror the signature of their corresponding constructors. (...)


You're right, it was not Liskov related, but the single argument default
behaviour. I was wrong about this.
___
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/ONVWLWDJZWW2KGCRZPFZ3XXVKTB2JTT7/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-30 Thread Greg Ewing

On 29/06/20 8:47 am, Daniel Moisset wrote:
 . 


You seem to be trying to shoehorn all Python data structures into
looking like alebraic types, for the sole purpose of being able to
claim that PEP 622 is really about algebraic types rather than
pattern matching.

I don't think that's a helpful way of looking at things. Pattern
matching with destructuring is a more general concept. Algebraic
types is just one of its applications.

I think your viewpoint is coloured by languages in which algebraic
types play a much more central role than they do in Python. For
example, in Haskell, the usual notation for lists is syntactic
sugar for an algebraic type representing a linked list.

But Python lists are not linked lists, they're flexible-sized
arrays, and you have to squint very hard indeed to see them as
being fundamentally an algebraic type. Yet pattern matching on
them makes perfectly good sense.


returning by default an object __dict__ or some sort of mapping view
on the attributes could still be fine. It's not clear to me why the
"keys" of this structure are placed separately.


I think the PEP explains the rationale behind the design of the
matching protocol quite well. The goal is to make it as simple as
possible to implement in the most common cases.


For me, there should be an instance method in object (that
subclasses  can override) that returns the algebraic structure of the value.
The PEP as-is creates different destructuring views depending on
which matching class you use (whicch I think relates to something
that was mentioned but not discussed a lot in the python-dev list
about Liskov sustitability).

I think the PEP has this right. Liskov substitutability doesn't apply
to constructors -- they're not methods, and the constructor of a
subclass doesn't have to accept the same arguments as that of its
base class. The same thing applies to deconstructors, since they have
to mirror the signature of their corresponding constructors. For
example, consider

   class Oval:
  def __init__(self, centre, width, height):
 ...

   class Circle(Oval):
  def __init__(self, centre, radius):
 ...

   match shape:
  case Oval(c, w, h):
 ...

If shape happens to be a Circle, you still want to deconstruct it as
an Oval and get centre, width, height, not centre, radius. There's
no way that can happen if the object itself is responsible for its
deconstruction.

(Incidentally, I do think the post that mentioned Liskov
substitutability has a point, but it's a different one --
the default single-positional-argument deconstruction is probably
a bad idea, because it will be wrong for a large number of
existing classes.)

--
Greg
___
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/IIRJGVB3FE4BQRIEX7RYUH4SZVYLKLUH/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-29 Thread Stephen J. Turnbull
Rhodri James writes:

 > That's the clearest explanation of why "_" needs to be treated 
 > carefully, but I don't think it argues for the PEP's special treatment. 

That depends on whether you care about taking advantage of the
convention that "_" is a dummy.  In fact, _ = gettext partakes of that
convention: all the programmer need know about internationalization is
that non-English speakers might like to read the string in their own
language.  From her point of view, _() is a no-op aka dummy.

 > Those people like me who just write for ourselves and don't care about 
 > internationalisation use "_" like any other variable with a strong 
 > implication that it's a dummy, so don't really care.  Those people like 
 > you who care about internationalisation presumably avoid using "_" 
 > anyway, so the PEP's usage goes against your current instincts.

I can't speak for others, but I use "_" as a dummy all the time.  Of
course that means I need to take care to use a different convention in
code that assumes _ == gettext, but it's rarely needed in my
experience.

But if the use of _ as a dummy in "case _" becomes syntax, I can't use
a different dummy, can I?  Or can I use a different dummy (such as
"xx" or "__") at the expense of binding it?

With the non-binding treatment of "case _", I don't have to worry
about it.

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


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-29 Thread Rhodri James

On 27/06/2020 10:36, Stephen J. Turnbull wrote:

Richard Damon writes:
  > As long as the bindings in match also make the symbol a local
  > (which seems reasonable) then you would get a similar restriction.

It's quite different.  First, it surely won't make other symbols
match-local.  Of course there will be times when you do all the work
inside the match statement.  But often you'll want to do bindings in a
match statement, then use those outside.  The second problem is that
this use of '_' isn't optional.  It's part of the syntax.  That means
that you can't use the traditional marking of a translateable string
(and it's not just tradition; there is a lot of external software that
expects it) in that scope.

So it's practically important, if not theoretically necessary, that
'case _' not bind '_'.


That's the clearest explanation of why "_" needs to be treated 
carefully, but I don't think it argues for the PEP's special treatment. 
Those people like me who just write for ourselves and don't care about 
internationalisation use "_" like any other variable with a strong 
implication that it's a dummy, so don't really care.  Those people like 
you who care about internationalisation presumably avoid using "_" 
anyway, so the PEP's usage goes against your current instincts.


--
Rhodri James *-* Kynesim Ltd
___
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/RXUG2UJCSINOMBHSWWIPIUAGLVRTEMNH/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-29 Thread Rhodri James

On 28/06/2020 21:47, Daniel Moisset wrote:

I've been going over the PEP this weekend, trying to get a
deeper understanding of what are its main ideas and consequences, and wrote
some notes. I'm not posting the notes directly to this list because it's a
bit of a long read, but I also tried to make it helpful as an analysis for
people involved in the discussion. So here's a link:
https://github.com/dmoisset/notebook/blob/811side
of thingsbf66/python/pep622/understanding-pep-622.md

.
I may update this in master, but for clarity I'm permalinking the current
version.

I'll soon switch to "proposing solutions" mode (rather than "analysis mode"
as this text is) soon, but needed to do this first, and hopefully this
helps someone else in this list organise ideas.


Thank you for that, Daniel.  That's a very nice analysis that makes my 
own misgivings clearer and put some of them to rest.  I think you are 
right that generalised destructuring is probably the thing to 
concentrate on; once we have something cohesive there, pattern syntax 
should become a lot more obvious.


--
Rhodri James *-* Kynesim Ltd
___
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/U5OB7BCVQZ7G7LR36DXQIFAC3G2H3RYV/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-29 Thread Stephen J. Turnbull
Daniel. writes:

 > IMHO, the most obvious solution is that the bind should be available only
 > inside case block and if you need to change a global or a nonlocal you do
 > this explicitly inside the case block,

Do you mean

case x:
x = x

?

 > if this is the case you can pickup a bind name that doesn't shadow
 > the desired variable.

But you can already do that in the case clause itself.

 > This way the intention to overwrite a global/nonlocal is clear in
 > code

But you can't "overwrite" a global or nonlocal without a declaration.
You can only shadow it, and as I wrote above, if you want to avoid
shadowing that global or nonlocal you choose a different name in the
case clause.

Regarding the proposal itself, it's a major change, because that's not
the way binding works anywhere else in Python.  There are two
differences.  The first is that there are no statements besides class
and def that create scopes, and the other two scopes that I know of
are module and comprehension (I seem to recall that comprehension
scope is based on the idea that the code inside the brackets is
actually syntactic sugar for a generator def, so that special case
would be derivative of function scope).

The second difference is that you can't change the binding of a name
in an outer local scope without a nonlocal declaration.  That means if
case scope follows that rule and you want to have a binding inside the
case scope that persists outside it, you'd need to declare it.
Probably you don't want to have to declare those "external" names, so
the names bound by the case clause would be very special.  I haven't
thought carefully about it, but it seems to me this could be a bug
magnet.

So, you could do this, but it would make scoping much more complex
than it currently is, and require a lot of redundancy (every binding
you want to preserve for later use would need to be made twice, once
in the case clause and again in the case body).  And I don't think
it's that useful.  It doesn't help with the I18N problem, since you
might want to use a marked string in the "case _" suite.  And the main
complexity from the current scoping rules comes from the fact that it
seems likely that different arms of the match will bind different sets
of names, so NameErrors become more likely in the following code.  But
your proposal doesn't help with that, and may make it more likely by
proliferating names.

Regards,
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/YDEORTNVLYXHX72FJ6CWXGZZ7C32ECKV/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-29 Thread Stephen J. Turnbull
Richard Damon writes:

 > I wasn't imply local to the match statement, but if the match is used
 > inside a function, where using the binding operatior = will create a
 > local name, even if there is a corresponding global name that matches
 > (unless you use the global statement), will a match statement that binds
 > to a name that hasn't bee made a local name by having an explicit
 > assignment to it, actually bind to a global that might be present, or
 > will it create a local?

All names are global, in some relevent sense.  It's the bindings to
objects that are scoped, and a binding in an inner scope shadows that
of an outer scope.  This just works, as I'm sure you've experienced.
In this case, the match statement will create a binding in the current
scope (in the case you present, local scope for that function).  The
problem for internationalization is not your example:

 >     match baz:
 > 
 >     case 1: print('baz was one')
 > 
 >     case foo: print('baz was ', foo)

but this kind of situation:

match baz:
case 1: print(_('baz was one'))
case _: print(_('baz was '), _(foo))

where _() marks a string that should be translated to another
language, and also implements the lookup at runtime.  If "case _"
binds "_", the _() in the print statement in that arm of the match
will very likely raise, and later _() will as well, until the end of
the scope.  It's very unlikely it will do what's desired!

Do translatable strings have to be marked with _()?  In theory, no, in
fact "_" is an alias for the gettext function, which could also be
used.  But in practice the marking aspect is used by a wide variety of
translation support software searching for strings to translate, and
it's also important to the readability of strings in the source that
the mark be as lightweight as possible.  So for internationalization
it's useful that "case _" does not bind an object to the name "_".

It's a very special case, and it's fortunate that it works out this
way that there's no conflict between the two uses of "_".  Or maybe
Lady Fortune is Dutch. :-)

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


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-28 Thread Daniel Moisset
I've been going over the PEP this weekend, trying to get a
deeper understanding of what are its main ideas and consequences, and wrote
some notes. I'm not posting the notes directly to this list because it's a
bit of a long read, but I also tried to make it helpful as an analysis for
people involved in the discussion. So here's a link:
https://github.com/dmoisset/notebook/blob/811side
of thingsbf66/python/pep622/understanding-pep-622.md

.
I may update this in master, but for clarity I'm permalinking the current
version.

I'll soon switch to "proposing solutions" mode (rather than "analysis mode"
as this text is) soon, but needed to do this first, and hopefully this
helps someone else in this list organise ideas.

Best,

D.


On Tue, 23 Jun 2020 at 17:04, Guido van Rossum  wrote:

> I'm happy to present a new PEP for the python-dev community to review.
> This is joint work with Brandt Bucher, Tobias Kohn, Ivan Levkivskyi and
> Talin.
>
> Many people have thought about extending Python with a form of pattern
> matching similar to that found in Scala, Rust, F#, Haskell and other
> languages with a functional flavor. The topic has come up regularly on
> python-ideas (most recently yesterday :-).
>
> I'll mostly let the PEP speak for itself:
> - Published: https://www.python.org/dev/peps/pep-0622/ (*)
> - Source: https://github.com/python/peps/blob/master/pep-0622.rst
>
> (*) The published version will hopefully be available soon.
>
> I want to clarify that the design space for such a match statement is
> enormous. For many key decisions the authors have clashed, in some cases we
> have gone back and forth several times, and a few uncomfortable compromises
> were struck. It is quite possible that some major design decisions will
> have to be revisited before this PEP can be accepted. Nevertheless, we're
> happy with the current proposal, and we have provided ample discussion in
> the PEP under the headings of Rejected Ideas and Deferred Ideas. Please
> read those before proposing changes!
>
> I'd like to end with the contents of the README of the repo where we've
> worked on the draft, which is shorter and gives a gentler introduction than
> the PEP itself:
>
>
> # Pattern Matching
>
> This repo contains a draft PEP proposing a `match` statement.
>
> Origins
> ---
>
> The work has several origins:
>
> - Many statically compiled languages (especially functional ones) have
>   a `match` expression, for example
>   [Scala](
> http://www.scala-lang.org/files/archive/spec/2.11/08-pattern-matching.html
> ),
>   [Rust](https://doc.rust-lang.org/reference/expressions/match-expr.html),
>   [F#](
> https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/pattern-matching
> );
> - Several extensive discussions on python-ideas, culminating in a
>   summarizing
>   [blog post](
> https://tobiaskohn.ch/index.php/2018/09/18/pattern-matching-syntax-in-python/
> )
>   by Tobias Kohn;
> - An independently developed [draft
>   PEP](
> https://github.com/ilevkivskyi/peps/blob/pattern-matching/pep-.rst)
>   by Ivan Levkivskyi.
>
> Implementation
> --
>
> A full reference implementation written by Brandt Bucher is available
> as a [fork]((https://github.com/brandtbucher/cpython/tree/patma)) of
> the CPython repo.  This is readily converted to a [pull
> request](https://github.com/brandtbucher/cpython/pull/2)).
>
> Examples
> 
>
> Some [example code](
> https://github.com/gvanrossum/patma/tree/master/examples/) is available
> from this repo.
>
> Tutorial
> 
>
> A `match` statement takes an expression and compares it to successive
> patterns given as one or more `case` blocks.  This is superficially
> similar to a `switch` statement in C, Java or JavaScript (an many
> other languages), but much more powerful.
>
> The simplest form compares a target value against one or more literals:
>
> ```py
> def http_error(status):
> match status:
> case 400:
> return "Bad request"
> case 401:
> return "Unauthorized"
> case 403:
> return "Forbidden"
> case 404:
> return "Not found"
> case 418:
> return "I'm a teapot"
> case _:
> return "Something else"
> ```
>
> Note the last block: the "variable name" `_` acts as a *wildcard* and
> never fails to match.
>
> You can combine several literals in a single pattern using `|` ("or"):
>
> ```py
> case 401|403|404:
> return "Not allowed"
> ```
>
> Patterns can look like unpacking assignments, and can be used to bind
> variables:
>
> ```py
> # The target is an (x, y) tuple
> match point:
> case (0, 0):
> print("Origin")
> case (0, y):
> print(f"Y={y}")
> case (x, 0):
> print(f"X={x}")
> case (x, y):
> print(f"X={x}, Y={y}")
> case _:
> raise ValueError("Not a point")
> 

[Python-Dev] Re: PEP 622: Structural Pattern Matching - followup

2020-06-28 Thread Eric Nieuwland
I wrote:
> 
> Guido van Rossum wrote:
> 
>> Eric Nieuwland wrote:
>> 
>>> I have some doubt about the keyword: ‘match' seems to be at odds with
>>> 'for', 'while', 'with', 'if' as it is more of an action.
>>> It's more like 'try' but that statement has a completely different
>>> structure.
>> 
>> Well, 'try' is also an action. :-) Many people have tried to come up with a
>> different keyword here, but nothing has been found that comes even close to
>> the simplicity of match. Plus, several other languages (Scala, Rust) use it
>> too (which is further evidence that it's a natural fit).
> 
> It may also be evidence for not being able to come up with a more accurate 
> keyword.
> 
> Reading through the PEP once more I noticed I was understanding
> 
>   match X:
>   case Y:
>   Z
> 
> as
> 
>   when X:
>   matches Y:
>   Z
> 
> which also to me seems to reflect the close relation to an if-elif-elif… 
> construction.
> 
> This would almost naturally imply the possibility of:
> 
>   when X:
>   matches Y:
>   Z
>   ...
>   else:
>   Q
> 
> And maybe also an additional operator:
> 
>   if X matches Y:
>   Z
> 
> 
>>> Not a native speaker I don't have a reasonable alternative, though.
>> 
>> Me neither, but I speak it quite fluently now, and 'match' really feels
>> like it fits well here.
> 
> Trying ;-)


Thinking of this over the weekend, I think the following might be even more 
flexible and powerful:


when X:
 Y1:
Z1
 Y2:
Z2
…
else:
Q

which would be the same as:

if X  Y1:
Z1
elif X  Y2:
Z2
…
else:
Q

Furthermore

when X:
 Y1 if C1:
Z1
 Y2 if C2:
Z2
…
else:
Q

would be the same as:

if X  Y1 and C1:
Z1
elif X  Y2 and C2:
Z2
…
else:
Q

and so the PEP would need to define:
- the 'when’ keyword
- the 'matches' comparison


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


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-06-28 Thread Jim J. Jewett
I actually like that it looks like instantiation; it seems to be saying "Do we 
have the sort of object we would get from this instantiation?"  

Unfortunately, this does aggravate the confusion over whether a variable is 
being used as a filter, vs binding to something from the matched object.
___
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/CBFTL4NGOC5FWZTMALWUWI42DC63A4IY/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-06-28 Thread salernof11
What about `case for Point(x, 0):`? It reads very naturally, the presence of 
"for" hints against Point() being a call to the class, and "for" is an existing 
keyword that would make no other sense in that position.
Examples with other formats such as `case for [x, 0]:` seem to work just as 
well.
___
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/RAKL3WGR3CJLRVNGZQUAWSJAR3TT4VDE/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-06-27 Thread Nick Coghlan
On Thu., 25 Jun. 2020, 5:41 am Guido van Rossum,  wrote:

> Everyone,
>
> If you've commented and you're worried you haven't been heard, please add
> your issue *concisely* to this new thread. Note that the following issues
> are already open and will be responded to separately; please don't bother
> commenting on these until we've done so:
>
> - Alternative spellings for '|'
> - Whether to add an 'else' clause (and how to indent it)
> - A different token for wildcards instead of '_'
> - What to do about the footgun of 'case foo' vs. 'case .foo'
>
> (Note that the last two could be combined, e.g. '?foo' or 'foo?' to mark a
> variable binding and '?' for a wildcard.)
>

I'm not sure if it's a separate point or not, but something I would like to
see the PEP take into account is whether or not the destructuring syntax
(especially for mappings) could become the basis for a future proposed
enhancement to assignment statements that effectively allowed an assignment
statement to be a shorthand for:

match RHS:
case LHS:
   pass # Just doing a destructuring assignment
else:
raise ValueError("Could not match RHS to LHS")


In "y, x = x, y" the fact the names are being used as both lvalues and
rvalues is indicated solely by their appearing on both sides of the
assignment statement.

This is the strongest existing precedent for all names in case expressions
being lvalues by default and having a separate marker for rvalues.

However, I believe it's also a reasonably strong argument *against* using
"." as that rvalue marker, as in "obj.x, obj.y = x, y" the dotted
references remain lvalues, they don't implicitly turn into rvalues.

Interestingly though, what those points suggest is that to be forward
compatible with a possible extension to assignment statements, the PEP is
correct that any syntactic marker would need to be on the *rvalues* that
are constraining the match, putting any chosen symbol (e.g. "?") squarely
in the wildcard role rather than the "lvalue marker" role.

y,? = returns_2_tuple()
y,?None = returns_2_tuple() # Exception if 2nd element is not == None
y,?sentinel = returns_2_tuple() # Exception if 2nd element is not ==
sentinel
y,*? = returns_iterable()

The main mindset shift this approach would require relative to the PEP as
currently written is in explicitly treating the case expression syntax as
an evolution of the existing lvalue syntax in assignment statements rather
than treating it as the introduction of a third independent kind of
expression syntax.

Cheers,
Nick.


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


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-27 Thread Daniel.
Em sáb., 27 de jun. de 2020 às 11:12, Richard Damon <
rich...@damon-family.org> escreveu:

> On 6/27/20 5:36 AM, Stephen J. Turnbull wrote:
> > Richard Damon writes:
> >
> >  > I thought _ was also commonly used as:
> >  >
> >  > first, -, last = (1, 2, 3)
> >  >
> >  > as a generic don't care about assignment.
> >
> > It is.  But there are other options (eg, 'ignored') if '_' is used for
> > translation in the same scope.
> >
> >  > I guess since the above will create a local, so not overwrite a
> >  > 'global' function _ for translations, so the above usage works as
> >  > long as that function (or whatever namespace you are in) doesn't
> >  > use _ for translations.
> >
> > Exactly.
> >
> >  > As long as the bindings in match also make the symbol a local
> >  > (which seems reasonable) then you would get a similar restriction.
> >
> > It's quite different.  First, it surely won't make other symbols
> > match-local.  Of course there will be times when you do all the work
> > inside the match statement.  But often you'll want to do bindings in a
> > match statement, then use those outside.  The second problem is that
> > this use of '_' isn't optional.  It's part of the syntax.  That means
> > that you can't use the traditional marking of a translateable string
> > (and it's not just tradition; there is a lot of external software that
> > expects it) in that scope.
> >
> > So it's practically important, if not theoretically necessary, that
> > 'case _' not bind '_'.
> >
> > Steve
>
> I wasn't imply local to the match statement, but if the match is used
> inside a function, where using the binding operatior = will create a
> local name, even if there is a corresponding global name that matches
> (unless you use the global statement), will a match statement that binds
> to a name that hasn't bee made a local name by having an explicit
> assignment to it, actually bind to a global that might be present, or
> will it create a local? My first feeling is that binding to the global
> would be surprising.
>
> i.e.
>
> foo = 1
>
> def bar(baz):
>
> match baz:
>
> case 1: print('baz was one')
>
> case foo: print('baz was ', foo)
>
> bar(2)
>
> print(foo)
>
>
> will this script create a new foo name inside bar, so that when we
> return, the module global foo is still 1, or did be bind to the global
> and change it?
>
> Rebinding a global without a global statement would be unexpected
> (normally we can mutate the global, but not rebind it)
>
> --
> Richard Damon
> ___
> 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/A2YKBTEHILHRNLN62LIPNAXCDG73ACD6/
> Code of Conduct: http://python.org/psf/codeofconduct/
>

I think that global binding make no sense, it will break a lot of code
silently, think about this

def bar(baz):
match baz:
case bar: pass


IMHO, the most obvious solution is that the bind should be available only
inside case block and if you need to change a global or a nonlocal you do
this explicitly inside the case block, if this is the case you can pickup a
bind name that doesn't shadow the desired variable. This way the intention
to overwrite a global/nonlocal is clear in code


-- 
“If you're going to try, go all the way. Otherwise, don't even start. ..."
  Charles Bukowski
___
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/SE5LVGEEIP7OI2KRREOAWJDLMMCKF6HR/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-27 Thread Richard Damon
On 6/27/20 5:36 AM, Stephen J. Turnbull wrote:
> Richard Damon writes:
>
>  > I thought _ was also commonly used as:
>  > 
>  > first, -, last = (1, 2, 3)
>  > 
>  > as a generic don't care about assignment.
>
> It is.  But there are other options (eg, 'ignored') if '_' is used for
> translation in the same scope.
>
>  > I guess since the above will create a local, so not overwrite a
>  > 'global' function _ for translations, so the above usage works as
>  > long as that function (or whatever namespace you are in) doesn't
>  > use _ for translations.
>
> Exactly.
>
>  > As long as the bindings in match also make the symbol a local
>  > (which seems reasonable) then you would get a similar restriction.
>
> It's quite different.  First, it surely won't make other symbols
> match-local.  Of course there will be times when you do all the work
> inside the match statement.  But often you'll want to do bindings in a
> match statement, then use those outside.  The second problem is that
> this use of '_' isn't optional.  It's part of the syntax.  That means
> that you can't use the traditional marking of a translateable string
> (and it's not just tradition; there is a lot of external software that
> expects it) in that scope.
>
> So it's practically important, if not theoretically necessary, that
> 'case _' not bind '_'.
>
> Steve

I wasn't imply local to the match statement, but if the match is used
inside a function, where using the binding operatior = will create a
local name, even if there is a corresponding global name that matches
(unless you use the global statement), will a match statement that binds
to a name that hasn't bee made a local name by having an explicit
assignment to it, actually bind to a global that might be present, or
will it create a local? My first feeling is that binding to the global
would be surprising.

i.e.

foo = 1

def bar(baz):

    match baz:

    case 1: print('baz was one')

    case foo: print('baz was ', foo)

bar(2)

print(foo)


will this script create a new foo name inside bar, so that when we
return, the module global foo is still 1, or did be bind to the global
and change it?

Rebinding a global without a global statement would be unexpected
(normally we can mutate the global, but not rebind it)

-- 
Richard Damon
___
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/A2YKBTEHILHRNLN62LIPNAXCDG73ACD6/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-27 Thread Stephen J. Turnbull
Richard Damon writes:

 > I thought _ was also commonly used as:
 > 
 > first, -, last = (1, 2, 3)
 > 
 > as a generic don't care about assignment.

It is.  But there are other options (eg, 'ignored') if '_' is used for
translation in the same scope.

 > I guess since the above will create a local, so not overwrite a
 > 'global' function _ for translations, so the above usage works as
 > long as that function (or whatever namespace you are in) doesn't
 > use _ for translations.

Exactly.

 > As long as the bindings in match also make the symbol a local
 > (which seems reasonable) then you would get a similar restriction.

It's quite different.  First, it surely won't make other symbols
match-local.  Of course there will be times when you do all the work
inside the match statement.  But often you'll want to do bindings in a
match statement, then use those outside.  The second problem is that
this use of '_' isn't optional.  It's part of the syntax.  That means
that you can't use the traditional marking of a translateable string
(and it's not just tradition; there is a lot of external software that
expects it) in that scope.

So it's practically important, if not theoretically necessary, that
'case _' not bind '_'.

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


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-26 Thread Gregory P. Smith
On Fri, Jun 26, 2020 at 6:42 AM Mark Shannon  wrote:

>
> > Let us start from some anecdotal evidence: isinstance() is one of the
> most called functions in large scale Python code-bases (by static call
> count). In particular, when analyzing some multi-million line production
> code base, it was discovered that isinstance() is the second most called
> builtin function (after len()). Even taking into account builtin classes,
> it is still in the top ten. Most of such calls are followed by specific
> attribute access.
>
> Why use anecdotal evidence? I don't doubt the numbers, but it would be
> better to use the standard library, or the top N most popular packages
> from GitHub.
>

Agreed.  This anecdote felt off to me and made for a bad introductory
feeling.  I know enough of who is involved to read it as likely "within the
internal Dropbox code base we found isinstance() to be the second most
called built-in by static call counts".  It'd be better worded as such
instead of left opaque if you are going to use this example at all.  [but
read on below, i'm not sure the anecdotal evidence is even relevant to
state]

Also if using this, please include text explaining what "static call count
means".  Was that "number of grep 'isinstance[(]' matches in all .py files
which we reasonably assume are calls"?  Or was that "measuring a running
application and counting cumulative calls of every built-in for the
lifetime of the large application"?  Include a footnote of if you have you
removed all use of six and py2->py3-isms?  Both six and manual py2->3
porting often wound up adding isinstance in places where they'll rightfully
be refactored out when cleaning up the py2 dead code legacy becomes anyones
priority.

A very rough grep of our much larger Python codebase within Google shows
isinstance *call site counts* to likely be lower than int or len and
similar to print.  With a notable percentage of isinstance usage clearly
related to py2 -> py3 compatibility, suggesting many can now go away.  I'm
not going to spend much time looking further as I don't think actual
numbers matter:  *Confirmed, isinstance gets used a lot.*  We can simply
state that as a truth and move on without needing a lot of justification.

>
> > There are two possible conclusions that can be drawn from this
> information:
> >
> > Handling of heterogeneous data (i.e. situations where a variable can
> take values of multiple types) is common in real world code.
> > Python doesn't have expressive ways of destructuring object data
> (i.e. separating the content of an object into multiple variables).
>
> I don't see how the second conclusion can be drawn.
> How does the prevalence of `isinstance()` suggest that Python doesn't
> have expressive ways of destructuring object data?

...

> >
> > We believe this will improve both readability and reliability of
> relevant code. To illustrate the readability improvement, let us consider
> an actual example from the Python standard library:
> >
> > def is_tuple(node):
> > if isinstance(node, Node) and node.children == [LParen(), RParen()]:
> > return True
> > return (isinstance(node, Node)
> > and len(node.children) == 3
> > and isinstance(node.children[0], Leaf)
> > and isinstance(node.children[1], Node)
> > and isinstance(node.children[2], Leaf)
> > and node.children[0].value == "("
> > and node.children[2].value == ")")
> >
>
> Just one example?
> The PEP needs to show that this sort of pattern is widespread.
>

Agreed.  I don't find application code following this pattern to be
common.  Yes it exists, but I would not expect to encounter it frequently
if I were doing random people's Python code reviews.

The supplied "stdlib" code example is lib2to3.fixer_util.is_tuple.  Using
that as an example of code "in the standard library" is *technically*
correct. But lib2to3 is an undocumented deprecated library that we have
slated for removal.  That makes it a bit weak to cite.

Better practical examples don't have to be within the stdlib.

Randomly perusing some projects I know that I expect to have such
constructs, here's a possible example:
https://github.com/PyCQA/pylint/blob/master/pylint/checkers/logging.py#L231.

There are also code patterns in pytype such as
https://github.com/google/pytype/blob/master/pytype/vm.py#L480  and
https://github.com/google/pytype/blob/master/pytype/vm.py#L1088 that might
make sense.

Though I realize you were probably in search of a simple one for the PEP in
order to write a before and after example.

-gps
___
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/X7XWT4YZFRFJJYJFHZY6X5LYLBZ7LH52/
Code of Conduct: 

[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-26 Thread Petr Viktorin

On 2020-06-26 16:54, Stéfane Fermigier wrote:
[...]



Here's one example:

https://github.com/clojure/core.match (in particular: 
https://github.com/clojure/core.match/wiki/Understanding-the-algorithm ).


Alson some insights from 
https://softwareengineering.stackexchange.com/questions/237023/pattern-matching-in-clojure-vs-scala



In this video  I
watched recently, Rich Hickey comments that he likes the
destructuring part of languages like Scala, but not so much the
pattern matching part, and he designed Clojure accordingly. That
probably explains why the pattern matching is in a library and not
as robust, although the kind of problems seen in the post you
mentioned are clearly bugs.

What Rich Hickey mentions as an alternative to pattern matching is
multimethods . Most languages let
you do polymorphic dispatch based on type. Some languages let you
also do it based on a value. Using multimethods, Clojure lets you do
it based on any arbitrary function. That's a pretty powerful concept.

It comes down to the principle that programmers using a language
should use the language's own best idioms. Trying to write
Scala-like code in Clojure is going to have its difficulties, and
vice versa.


It does look like the PEP tries to do two different things: "switch" 
instead of if/elif, and destructuring.


Would it be useful to introduce an operator for "isinstance", if it's so 
commonly used? Are the calls to it (in the relevant codebase) actually 
used in complex code that needs destructuring, or could we live with 
this (IS_A being a placeholder for bikeshedding, of course):


if shape IS_A Point:
x, y = shape
...
elif shape IS_A Rectangle:
x, y, w, h = shape
...
elif shape IS_A Line:
x, y = line.start
if line.start == line.end:
print(f"Zero length line at {x}, {y}")

or:

queue: Union[Queue[int], Queue[str]]
if queue IS_A IntQueue:
# Type-checker detects unreachable code
...


There aren't many convincing examples for destructuring in the PEP, IMO.

The "mapping pattern" one could be rewritten as:

if route := config.get('route'):
process_route(route)
if subconfig := config.pop(constants.DEFAULT_PORT):
process_config(sub_config, config)

Sequence destructuring examples ([_] for "short sequence") don't seem 
too useful. Would they actually improve lots of existing code?


Complex object /tree destructuring (like the is_tuple) is painful in 
Python, but then again, the new syntax also becomes quite inscrutable 
for complex cases.

Is code like the is_tuple example in the Rationale actually common?

The "Sealed classes as algebraic data types" example looks like a good 
candidate for a dump() method or PEP 443 single dispatch, both of which 
should be amenable to static analysis.

___
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/57RTPCDQX56WZKQC42KXYS2EHQWLALCN/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-26 Thread Stéfane Fermigier
On Fri, Jun 26, 2020 at 3:38 PM Mark Shannon  wrote:

>
> What does "static and dynamic specifications" mean? Surely, there are
> just specifications.
>

There are specifications for both the runtime and the static aspects of the
Python programming language.


> Python does not have a static checking phase,


The (C)Python *interpreter* doesn't. Other Python implementations (existing
or hypothetical) may or may not have a static checking phase.

But static tools need specifications beyond (ie. additionally to) runtime
specifications, which are defined in PEP 483, 484, 585 and others.

> Let us start from some anecdotal evidence: isinstance() is one of the
> most called functions in large scale Python code-bases (by static call
> count). In particular, when analyzing some multi-million line production
> code base, it was discovered that isinstance() is the second most called
> builtin function (after len()). Even taking into account builtin classes,
> it is still in the top ten. Most of such calls are followed by specific
> attribute access.
>
> Why use anecdotal evidence? I don't doubt the numbers, but it would be
> better to use the standard library, or the top N most popular packages
> from GitHub.
>

Maybe a scientific paper could be written on this subject. I'm guessing
the "multi-million line production code base" in question is the Dropbox
code base, and maybe Dropbox has an idiomatic way of writing Python with
lots of "isinstance()"s.

> In general, we believe that pattern matching has been proved to be a
> useful and expressive tool in various modern languages. In particular, many
> aspects of this PEP were inspired by how pattern matching works in Rust [3]
> and Scala [4].
>
> Both those languages are statically typed, which allows the compiler to
> perform the much of the pattern matching at compile time.
>
> You should give examples from dynamic typed languages instead, e.g.
> clojure.
>

Here's one example:

https://github.com/clojure/core.match (in particular:
https://github.com/clojure/core.match/wiki/Understanding-the-algorithm ).

Alson some insights from
https://softwareengineering.stackexchange.com/questions/237023/pattern-matching-in-clojure-vs-scala


In this video  I watched
recently, Rich Hickey comments that he likes the destructuring part of
languages like Scala, but not so much the pattern matching part, and he
designed Clojure accordingly. That probably explains why the pattern
matching is in a library and not as robust, although the kind of problems
seen in the post you mentioned are clearly bugs.

What Rich Hickey mentions as an alternative to pattern matching is
multimethods . Most languages let you do
polymorphic dispatch based on type. Some languages let you also do it based
on a value. Using multimethods, Clojure lets you do it based on any
arbitrary function. That's a pretty powerful concept.

It comes down to the principle that programmers using a language should use
the language's own best idioms. Trying to write Scala-like code in Clojure
is going to have its difficulties, and vice versa.


  S.

-- 
Stefane Fermigier - http://fermigier.com/ - http://twitter.com/sfermigier -
http://linkedin.com/in/sfermigier
Founder & CEO, Abilian - Enterprise Social Software -
http://www.abilian.com/
Chairman, National Council for Free & Open Source Software (CNLL) -
http://cnll.fr/
Founder & Organiser, PyParis & PyData Paris - http://pyparis.org/ &
http://pydata.fr/
___
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/JWBAB4EC57NCTYREKPF63K6J347TCQXJ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-26 Thread Arthur Darcet
On Fri, 26 Jun 2020 at 09:07, Greg Ewing 
wrote:

> On 26/06/20 2:10 pm, Gregory P. Smith wrote:
> > match get_shape() as shape:
> >case start, end := Line@(shape):
>
> This looks just as inscrutable to me in its own way.
>

Absolutely, but that's kind of the point I think: no possible way to
understand it for something else that what it means.


Arthur
___
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/5AN52CT5BYARJHO3BL3OMXI4A27DHJCH/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-26 Thread Rob Cliffe via Python-Dev

Yes, my brain went through the same path.
Another minor nitpick: It would be kinda nice if the various types of 
pattern were listed in the grammar in the same order as the 
corresponding paragraphs subsequently appear.


On 26/06/2020 11:53, Daniel Moisset wrote:

Just a minor editorial thing on the PEP text:

The section 
https://www.python.org/dev/peps/pep-0622/#case-clauses presents a 
simplified syntax. That one mentions "group_pattern", but the document 
never mentions (in prose) what a group pattern is. It confused me 
until I found the definition in the full grammar, which seems to refer 
to those sequence patterns using () rather than []. Probably it makes 
more sense for a quick read to remove the "| group_pattern" from the 
simplified grammar, it looks more like an intermediate construct.



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


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-26 Thread Mark Shannon

Hi,

For a PEP to succeed it needs to show two things.

1. Exactly what problem is being solved, or need is to be fulfilled, and 
that is a sufficiently large problem, or need, to merit the proposed change.


2. That the proposed change is the best known solution for the problem 
being addressed.


IMO, PEP 622 fails on both counts.

This email addresses point 1.

Given the positive response to the PEP, it may well be that it does 
address a need. However, the PEP itself fails to show that.



Abstract



This PEP proposes adding pattern matching statements [1] to Python in order to 
create more expressive ways of handling structured heterogeneous data. The 
authors take a holistic approach, providing both static and runtime 
specifications.


What does "static and dynamic specifications" mean? Surely, there are 
just specifications.
Python does not have a static checking phase, so static analysis tools 
need to understand the dynamic behaviour of the program, not have their 
own alternate semantics. There is no "static specification" of 
`isinstance()`, yet static analysis tools understand it.




PEP 275 and PEP 3103 previously proposed similar constructs, and were rejected. 
Instead of targeting the optimization of if ... elif ... else statements (as 
those PEPs did), this design focuses on generalizing sequence, mapping, and 
object destructuring. It uses syntactic features made possible by PEP 617, 
which introduced a more powerful method of parsing Python source code.


Why couple the choice part (a sort of enhanced elif) with destructing (a 
sort of enhanced unpacking)?
We could have a "switch" statement that chooses according to value, and 
we could have "destructuring" that pulls values apart. Why do they need 
to be coupled?


Rationale and Goals
---


Let us start from some anecdotal evidence: isinstance() is one of the most 
called functions in large scale Python code-bases (by static call count). In 
particular, when analyzing some multi-million line production code base, it was 
discovered that isinstance() is the second most called builtin function (after 
len()). Even taking into account builtin classes, it is still in the top ten. 
Most of such calls are followed by specific attribute access.


Why use anecdotal evidence? I don't doubt the numbers, but it would be 
better to use the standard library, or the top N most popular packages 
from GitHub.




There are two possible conclusions that can be drawn from this information:

Handling of heterogeneous data (i.e. situations where a variable can take 
values of multiple types) is common in real world code.
Python doesn't have expressive ways of destructuring object data (i.e. 
separating the content of an object into multiple variables).


I don't see how the second conclusion can be drawn.
How does the prevalence of `isinstance()` suggest that Python doesn't 
have expressive ways of destructuring object data?


That `len()` is also common, does suggests that some more expressive 
unpacking syntax might be useful. However, since `len()` only applies to 
sequences, it suggests to me that unpacking of non-sequences isn't 
generally useful.




This is in contrast with the opposite sides of both aspects:


This sentence makes no sense. What is "this"? Both aspects of what?



Its success in the numeric world indicates that Python is good when working 
with homogeneous data. It also has builtin support for homogeneous data 
structures such as e.g. lists and arrays, and semantic constructs such as 
iterators and generators.
Python is expressive and flexible at constructing objects. It has syntactic 
support for collection literals and comprehensions. Custom objects can be 
created using positional and keyword calls that are customized by special 
__init__() method.

This PEP aims at improving the support for destructuring heterogeneous data by 
adding a dedicated syntactic support for it in the form of pattern matching. On 
a very high level it is similar to regular expressions, but instead of matching 
strings, it will be possible to match arbitrary Python objects.


An explanation is needed of why "destructuring" needs to be so tightly 
coupled with matching by class or value.




We believe this will improve both readability and reliability of relevant code. 
To illustrate the readability improvement, let us consider an actual example 
from the Python standard library:

def is_tuple(node):
if isinstance(node, Node) and node.children == [LParen(), RParen()]:
return True
return (isinstance(node, Node)
and len(node.children) == 3
and isinstance(node.children[0], Leaf)
and isinstance(node.children[1], Node)
and isinstance(node.children[2], Leaf)
and node.children[0].value == "("
and node.children[2].value == ")")



Just one example?
The PEP needs to show that this sort of pattern is widespread.


With the syntax 

[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-26 Thread Rob Cliffe via Python-Dev



On 23/06/2020 20:35, Chris Angelico wrote:

On Wed, Jun 24, 2020 at 5:30 AM Rob Cliffe via Python-Dev
 wrote:

The PEP is great, but this strikes me as horribly confusing, given that 
401|403|404 is already legal syntax.
IIUC any legal expression can come between `case` and `:`, but expressions that 
contain `|` at their outermost level are interpreted differently than from in 
other contexts.
Presumably adding parentheses:
 case (401|403|404):
would make it equivalent to
 case 407:

Is a separator (other than whitespace) actually needed?  Can the parser cope 
with
 case 401 403 404:

Failing that IMO preferable, albeit not ideal, possibilities would be
   1) Use colon as the separator.
   2) Use comma as the separator - this is already legal syntax too, but IMO it 
reads more naturally.
   (And IIRC there are already contexts where brackets are necessary to 
indicate a tuple.)
Perhaps someone can think of something better.

I also (with others) prefer `else:` or perhaps `case else:` to using the`_` 
variable.
The latter is obscure, and woudn't sit well with code that already uses that 
variable for its own purposes.


It's not really arbitrary expressions, though. It's more like an
assignment target list, but with some handling of constants.

case (x, y):

is very similar to

(x, y) = ...



If arbitrary expressions are not allowed
    - the power of this new feature is reduced
    - we have to remember another set of  rules about what is allowed 
and what isn't.  Just as we did with decorator syntax - until that 
restriction was done away with.

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


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-06-26 Thread Daniel Moisset
This one is new but I think unrelated and unmentioned:

Why is the mapping match semantics non-strict about keys? Besides the
"asymmetry" with sequence matches, I think a strict match should be useful
sometimes (quickly deconstructing JSON data comes to my mind, where I want
to know that I didn't get unexpected keys). I cannot get that behaviour
with the current pep. But if we make key strictness the default, I can
always add **_ to my mapping pattern and make it non strict (that's
currently forbidden but the restriction can be lifted). Is there an
assumption (or even better, data evidence) that non-strict checks are much
much more common?

A similar but weaker argument can be made for class patterns (although I
can imagine non-strict matches *are* more common in that case).

Mostly but not completely unrelated to the above, and purely syntactic
sugar bikeshedding, but I think having "..." as an alias for "*_" or "**_"
(depending on context, and I'd say it's *both* inside a class pattern)
could make these patterns slightly more readable.

Best,
D.

On Wed, 24 Jun 2020 at 20:44, Guido van Rossum  wrote:

> Everyone,
>
> If you've commented and you're worried you haven't been heard, please add
> your issue *concisely* to this new thread. Note that the following issues
> are already open and will be responded to separately; please don't bother
> commenting on these until we've done so:
>
> - Alternative spellings for '|'
> - Whether to add an 'else' clause (and how to indent it)
> - A different token for wildcards instead of '_'
> - What to do about the footgun of 'case foo' vs. 'case .foo'
>
> (Note that the last two could be combined, e.g. '?foo' or 'foo?' to mark a
> variable binding and '?' for a wildcard.)
>
> --
> --Guido van Rossum (python.org/~guido)
> *Pronouns: he/him **(why is my pronoun here?)*
> 
> ___
> 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/STJSSAETMTUY7FK5AE53IM73Z2WORNYN/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
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/DS26FCVJ2FCQBRK6OQEBIKYBZPXIIY5P/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-26 Thread Rhodri James

On 25/06/2020 23:20, Emily Bowman wrote:

On my personal "potentially inscrutable uses of a tool" this still rates
well below list comprehensions, so there's that; the biggest pet peeve I


Clearly YMMV.  To me list comprehensions like "[f(x) for x in l]" were 
obviously related to the "f(x) ∀ x ∊ l" familiar from my maths degree.




have anymore is understanding at a glance what is and isn't an assignment.


Yes, this does seem to be a lot of people's problem.  My point is we get 
to that position one step at a time, so maybe we should be examining the 
first steps in that chain and re-evaluating whether they were in fact 
the right ones, given where we end up.  I accept the PEP's general point 
that name patterns will be common, but I don't think something like 
"case int as x:" is hard to write and it brings in the idea that we are 
talking about types right at the start.




--
Rhodri James *-* Kynesim Ltd
___
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/UV6P5TV4WAQHTB47WJBLCPV4JDZO24AR/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-06-26 Thread Emily Bowman
On Fri, Jun 26, 2020 at 3:47 AM Paul Moore  wrote:

> For me, this prompts the question (which I appreciate is more about
> implementation than design) - would there be any (significant)
> performance difference between [...]


> In C, the switch statement was explicitly intended to be faster by
> means of doing a computed branch. In a higher level language, I can
> see the added features of match meaning that it's *slower* than a
> series of if tests for simple cases. But I have no intuition about the
> performance of this proposal. I'd like to believe that the choice
> between the 2 alternatives above is purely a matter of preferred
> style, but I don't know. If match is significantly slower, that could
> make it a bit of an attractive nuisance.
>

Each case essentially compiles down to an equivalent if structure, already.
There's no penalty that I'm seeing. There's actually much more room for
optimizing eventually, since the test is bound to a single element instead
of any arbitrary if expression, and a Cython or PyPy could work some magic
to detect a small set of primitive types and optimize for that.
___
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/7U7VAG2NVWZFBIOH36KVEJC5PCSHZ2R7/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-26 Thread Daniel Moisset
Just a minor editorial thing on the PEP text:

The section https://www.python.org/dev/peps/pep-0622/#case-clauses presents
a simplified syntax. That one mentions "group_pattern", but the document
never mentions (in prose) what a group pattern is. It confused me until I
found the definition in the full grammar, which seems to refer to those
sequence patterns using () rather than []. Probably it makes more sense for
a quick read to remove the "| group_pattern" from the simplified grammar,
it looks more like an intermediate construct.

On Tue, 23 Jun 2020 at 17:04, Guido van Rossum  wrote:

> I'm happy to present a new PEP for the python-dev community to review.
> This is joint work with Brandt Bucher, Tobias Kohn, Ivan Levkivskyi and
> Talin.
>
> Many people have thought about extending Python with a form of pattern
> matching similar to that found in Scala, Rust, F#, Haskell and other
> languages with a functional flavor. The topic has come up regularly on
> python-ideas (most recently yesterday :-).
>
> I'll mostly let the PEP speak for itself:
> - Published: https://www.python.org/dev/peps/pep-0622/ (*)
> - Source: https://github.com/python/peps/blob/master/pep-0622.rst
>
> (*) The published version will hopefully be available soon.
>
> I want to clarify that the design space for such a match statement is
> enormous. For many key decisions the authors have clashed, in some cases we
> have gone back and forth several times, and a few uncomfortable compromises
> were struck. It is quite possible that some major design decisions will
> have to be revisited before this PEP can be accepted. Nevertheless, we're
> happy with the current proposal, and we have provided ample discussion in
> the PEP under the headings of Rejected Ideas and Deferred Ideas. Please
> read those before proposing changes!
>
> I'd like to end with the contents of the README of the repo where we've
> worked on the draft, which is shorter and gives a gentler introduction than
> the PEP itself:
>
>
> # Pattern Matching
>
> This repo contains a draft PEP proposing a `match` statement.
>
> Origins
> ---
>
> The work has several origins:
>
> - Many statically compiled languages (especially functional ones) have
>   a `match` expression, for example
>   [Scala](
> http://www.scala-lang.org/files/archive/spec/2.11/08-pattern-matching.html
> ),
>   [Rust](https://doc.rust-lang.org/reference/expressions/match-expr.html),
>   [F#](
> https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/pattern-matching
> );
> - Several extensive discussions on python-ideas, culminating in a
>   summarizing
>   [blog post](
> https://tobiaskohn.ch/index.php/2018/09/18/pattern-matching-syntax-in-python/
> )
>   by Tobias Kohn;
> - An independently developed [draft
>   PEP](
> https://github.com/ilevkivskyi/peps/blob/pattern-matching/pep-.rst)
>   by Ivan Levkivskyi.
>
> Implementation
> --
>
> A full reference implementation written by Brandt Bucher is available
> as a [fork]((https://github.com/brandtbucher/cpython/tree/patma)) of
> the CPython repo.  This is readily converted to a [pull
> request](https://github.com/brandtbucher/cpython/pull/2)).
>
> Examples
> 
>
> Some [example code](
> https://github.com/gvanrossum/patma/tree/master/examples/) is available
> from this repo.
>
> Tutorial
> 
>
> A `match` statement takes an expression and compares it to successive
> patterns given as one or more `case` blocks.  This is superficially
> similar to a `switch` statement in C, Java or JavaScript (an many
> other languages), but much more powerful.
>
> The simplest form compares a target value against one or more literals:
>
> ```py
> def http_error(status):
> match status:
> case 400:
> return "Bad request"
> case 401:
> return "Unauthorized"
> case 403:
> return "Forbidden"
> case 404:
> return "Not found"
> case 418:
> return "I'm a teapot"
> case _:
> return "Something else"
> ```
>
> Note the last block: the "variable name" `_` acts as a *wildcard* and
> never fails to match.
>
> You can combine several literals in a single pattern using `|` ("or"):
>
> ```py
> case 401|403|404:
> return "Not allowed"
> ```
>
> Patterns can look like unpacking assignments, and can be used to bind
> variables:
>
> ```py
> # The target is an (x, y) tuple
> match point:
> case (0, 0):
> print("Origin")
> case (0, y):
> print(f"Y={y}")
> case (x, 0):
> print(f"X={x}")
> case (x, y):
> print(f"X={x}, Y={y}")
> case _:
> raise ValueError("Not a point")
> ```
>
> Study that one carefully!  The first pattern has two literals, and can
> be thought of as an extension of the literal pattern shown above.  But
> the next two patterns combine a literal and a variable, and the
> variable is *extracted* from the target value (`point`).  The fourth

[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-06-26 Thread Paul Moore
On Fri, 26 Jun 2020 at 11:29, Daniel Moisset  wrote:
>
> I think roughly half of the uses will actually be for "the switch statement 
> we never had", where all branches would be constants. I've been writing a lot 
> of code like that these last couple of weeks, so I may be biased (although 
> the PEP authors may have been writing AST visitors this last week and may be 
> biased the other way ;-) )
>
> As a sub point, I can understand if the PEP authors argue "match is not for 
> that, use if/elif/dicts of functions in that case like you did before and 
> ignore this PEP", but if that's the case, that should be explicit in the PEP.

For me, this prompts the question (which I appreciate is more about
implementation than design) - would there be any (significant)
performance difference between

match var:
case 1:
print("Got 1")
case 2:
print("Got 2")
case _:
print("Got another value")

and

if var == 1:
print("Got 1")
elif var == 2:
print("Got 2")
else:
print("Got another value")

?

In C, the switch statement was explicitly intended to be faster by
means of doing a computed branch. In a higher level language, I can
see the added features of match meaning that it's *slower* than a
series of if tests for simple cases. But I have no intuition about the
performance of this proposal. I'd like to believe that the choice
between the 2 alternatives above is purely a matter of preferred
style, but I don't know. If match is significantly slower, that could
make it a bit of an attractive nuisance.

Paul
___
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/GNTYPDKJFJDHHFAAA5ATI7RFVNEPOHQ3/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-06-26 Thread Daniel Moisset
[apologies for the duplicate to Guido, used reply instead of reply to all]

To summarize my previous unanswered post, I posted a +1 to the "defaulting
to binding vs interpreting NAME as a constant" is a dangerous default. And
I submitted a couple of alternate syntactic ways to denote "capture is
desired" (the angle brackets, and the capture object). I think both are
reasonably readable, and one of them doesn't even add any unusual syntax
(not even the "dot prefix")

As an elaboration on that, after reading the discussion and trying to not
repeat what has previously been said:


   - I think there's a mismatch between an assumption made by the authors
   vs what many of us are posting here, which is explicitly stated in "
   
https://www.python.org/dev/peps/pep-0622/#alternatives-for-constant-value-pattern;
   : Quoting the PEP: «the name patterns are more common in typical code, so
   having special syntax for common case would be weird». Even if I think a
   popular use case would be analysing and deconstructing complex nested
   structures (like ASTs), I think roughly half of the uses will actually be
   for "the switch statement we never had", where all branches would be
   constants. I've been writing a lot of code like that these last couple of
   weeks, so I may be biased (although the PEP authors may have been writing
   AST visitors this last week and may be biased the other way ;-) )
  - As a sub point, I can understand if the PEP authors argue "match is
  not for that, use if/elif/dicts of functions in that case like you did
  before and ignore this PEP", but if that's the case, that should be
  explicit in the PEP.
   - I am fairly sure (as much as one can be of the future in these things)
   that with this PEP approved as is, linters will add new rules like "you
   have more than a top level name pattern, only the first one will match.
   Perhaps you wanted constant patterns?" and "your pattern captures shadow an
   existing name" and "a name you bound in a pattern isn't used inside the
   pattern". These will definitely help, but for me "how many new linter rules
   will be needed if this language change is introduced" is a good measure of
   how unelegant it is.
  - Perhaps arguing against myself, I know that, thanks to my regular
  usage of linters, I personally won't suffer much from this problem (once
  they get updated). But I also teach Python to people, and I feel that I'd
  have to add this to the list of "gotchas to avoid" if the PEP
passes as is.


Again, I can't write this email without saying that this feature is great,
that the effort put in this PEP is really palpable, that I'd love to find
the way to get it accepted, and that even if I'm normally conservative
upgrading python versions and waiting my environment to support it fully,
this will likely be the first time that I upgrade just for a language
feature :)


On Wed, 24 Jun 2020 at 20:44, Guido van Rossum  wrote:

> Everyone,
>
> If you've commented and you're worried you haven't been heard, please add
> your issue *concisely* to this new thread. Note that the following issues
> are already open and will be responded to separately; please don't bother
> commenting on these until we've done so:
>
> - Alternative spellings for '|'
> - Whether to add an 'else' clause (and how to indent it)
> - A different token for wildcards instead of '_'
> - What to do about the footgun of 'case foo' vs. 'case .foo'
>
> (Note that the last two could be combined, e.g. '?foo' or 'foo?' to mark a
> variable binding and '?' for a wildcard.)
>
> --
> --Guido van Rossum (python.org/~guido)
> *Pronouns: he/him **(why is my pronoun here?)*
> 
> ___
> 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/STJSSAETMTUY7FK5AE53IM73Z2WORNYN/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
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/NZAQQOXM4K2G4ID4FNWZ6KRDEWFSWDMJ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-26 Thread Paul Moore
On Fri, 26 Jun 2020 at 03:37, Gregory P. Smith  wrote:
>
> Litmus test: Give someone who does not know Python this code example from the 
> PEP and ask them what it does and why it does what it does:
>
> match get_shape():
> case Line(start := Point(x, y), end) if start == end:
> print(f"Zero length line at {x}, {y}")
>
> I expect confusion to be the result.  If they don't blindly assume the 
> variables come from somewhere not shown to stop their anguish.
>
> With Python experience, my own reading is:

With Python experience *and limited use of other languages with match
constructs*, this reads naturally to me and makes instant sense.
Clearly it's unreasonable to expect all users to have multi-language
experience, but I'd argue that my experience demonstrates that
"limited use of constructs like this" is enough to understand the
proposed syntax. And therefore, that once it's added to Python, it
won't take long for people to become sufficiently familiar with it to
handle fairly complex examples.

Paul
___
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/3SZXT3GULG6NX55T4HAQM3TBURGR3PUZ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-26 Thread Emily Bowman
On Fri, Jun 26, 2020 at 12:42 AM Rob Cliffe via Python-Dev <
python-dev@python.org> wrote:

> 1) In the beginning of the "Mapping Pattern" section:
>  "{" (pattern ":" pattern)+ "}"
> This is spelt inconsistently: there is a `+` before the closing `}`
> but not after the opening `{`.
>

That grammar is more like a regex: + means "accept one or more of the
previous" here.

Maybe grammar inserts should be their own subsections to avoid confusion,
or at least highlighted, instead of mixing into the text.
___
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/G2HL7KKWSZRQQ5TL5ZD5M3K2BPEUMLJK/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-26 Thread Rob Cliffe via Python-Dev

Some proof-reading of the PEP.  I apologise if this is out of date.

1) In the beginning of the "Mapping Pattern" section:
         "{" (pattern ":" pattern)+ "}"
    This is spelt inconsistently: there is a `+` before the closing `}` 
but not after the opening `{`.


2) The second code snippet in the "Guards" section:

values = [0]

match value:
case [x] if x:
...  # This is not executed
case _:
...
print(x)  # This will print "0"

   Inconsistent spelling: `values` and `value`

3) At the end of the "Named sub-patterns" section:
"PEP 572"
   It would be more helpful to say "PEP 572 (Assignment Expressions)"

Rob Cliffe

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


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-06-26 Thread Greg Ewing

On 26/06/20 6:21 am, Pablo Galindo Salgado wrote:
Which means that users can do a positional match against the proxy with 
a name pattern:


match input:
     case datetime.date(dt):
         print(f"The date {dt.isoformat()}"


I think that would be an incorrect way for matching on datetime
to behave. Since datetime has a constructor that takes positional
arguments, it should have a __match__ and/or __match_args__
that agrees.

This suggests that there will be a burden on many existing types
to ensure they implement appropriate matching behaviour, as the
default behaviour provided by object will be wrong for them.

I'm wondering whether the default "single positional match"
behaviour is a bad idea. I.e. the only thing that should work
by default is

   case someclass():

and not

   case someclass(instance):

Classes such as int with constructors that can take a single
argument should be required to implement the corresponding
match behaviour explicitly.

--
Greg
___
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/TWLPWBFQHYPRORJYN5YPV3WNYMYSJXMS/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-26 Thread Greg Ewing

On 26/06/20 5:45 pm, Ned Deily wrote:

Hasn't "|" been used in a similar way for decades in Unix/POSIX shell patterns, 
including with the shell case statement?


Yes, but I regard Unix shell syntaxes as just plain weird
and not a good model for designing a language on.

--
Greg
___
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/C4INFHUOJDPG3D34QDWXFCUXOGXS4AJ2/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-26 Thread Greg Ewing

On 26/06/20 2:10 pm, Gregory P. Smith wrote:

match get_shape() as shape:
   case start, end := Line@(shape):


This looks just as inscrutable to me in its own way.

--
Greg
___
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/DIBSDVYS2JURMXSGL3EXWSIDCGJFQTYN/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-26 Thread Greg Ewing

On 26/06/20 1:08 pm, Paul Svensson wrote:

We already allow (x, x) = (1, 2)
So, why do we need to disallow binding several values to the same name ?


I think it was done because people might expect that to match
only if the *same* value appears in both places. Some other
languages have pattern matching that works that way. I think
the intention is to leave open the possibility of implementing
it in the future.

--
Greg
___
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/RFBU4JCJACOZSJI6AVDUAIM7ACVQNOV7/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-06-26 Thread Greg Ewing

On 26/06/20 12:31 pm, Brandt Bucher wrote:

I'd imagine that we either find some straightforward way of > opting-in to the 
current default behavior


Maybe special-case 'self' in __match_args__ to mean the
object being matched?

--
Greg
___
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/RNJ4UAU46AVM5CKWIMLAORJAXPVOIKWJ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-26 Thread Ned Deily
On Jun 25, 2020, at 21:33, Gregory P. Smith  wrote:
> I prefer "or" to "|" as a combining token as there is nothing bitwise going 
> on here.  "or" reads better.   Which is why Python used it for logic 
> operations in the first place.  It is simple English.  "|" does not read like 
> or to anyone but a C based language programmer.  Something Python users 
> should never need to know.

Hasn't "|" been used in a similar way for decades in Unix/POSIX shell patterns, 
including with the shell case statement?

>From IEE Std 1003.1 -> Shell Command Language:
"The conditional construct case shall execute the compound-list corresponding 
to the first one of several patterns (see Pattern Matching Notation) that is 
matched by the string resulting from the tilde expansion, parameter expansion, 
command substitution, arithmetic expansion, and quote removal of the given 
word. The reserved word in shall denote the beginning of the patterns to be 
matched. Multiple patterns with the same compound-list shall be delimited by 
the '|' symbol. The control operator ')' terminates a list of patterns 
corresponding to a given action. The compound-list for each list of patterns, 
with the possible exception of the last, shall be terminated with ";;". The 
case construct terminates with the reserved word esac (case reversed).

The format for the case construct is as follows:

case word 
in
   
 [(] pattern1 ) compound-list 
;;
   
 [[(] pattern[ | pattern] ... ) compound-list ;;] 
...
   
 [[(] pattern[ | pattern] ... ) compound-list]

esac
"

case ${branch} in
37|3.7) pushd "$HOME/dev/37/source" ;;
38|3.8) pushd "$HOME/dev/38/source" ;;
39|3.9) pushd "$HOME/dev/39/source" ;;
3x|3.x|master) pushd "$HOME/dev/3x/source" ;;
*) echo "unknown branch ${branch}" ;;
esac

   
--
  Ned Deily
  n...@python.org -- []
___
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/URONXXII7H3AIP735HT5KVWZBILGLQG5/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-26 Thread Emily Bowman
Whoops, meant to reply to Gregory on that one, sorry Richard.


On Thu, Jun 25, 2020 at 7:15 PM Gregory P. Smith  wrote:

>
> Can I use an i18n'd _("string") within a case without jumping through
> hoops to assign it to a name before the match:?
>


The PEP currently says:
>
> "The named class must inherit from type. It may be a single name or a
> dotted name (e.g. some_mod.SomeClass or mod.pkg.Class). The leading name
> must not be _, so e.g. _(...) and _.C(...) are invalid. Use object(foo=_)
> to check whether the matched object has an attribute foo."
>
___
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/KC6KLMBJZY3VKIDY2TT2QUQ36AILYUW2/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-25 Thread Emily Bowman
On Thu, Jun 25, 2020 at 8:31 PM Richard Damon 
wrote:

>
> I thought _ was also commonly used as:
>
> first, -, last = (1, 2, 3)
>
> as a generic don't care about assignment. I guess since the above will
> create a local, so not overwrite a 'global' function _ for translations,
> so the above usage works as long as that function (or whatever namespace
> you are in) doesn't use _ for translations. As long as the bindings in
> match also make the symbol a local (which seems reasonable) then you
> would get a similar restriction.
>

The PEP currently says:

"The named class must inherit from type. It may be a single name or a
dotted name (e.g. some_mod.SomeClass or mod.pkg.Class). The leading name
must not be _, so e.g. _(...) and _.C(...) are invalid. Use object(foo=_)
to check whether the matched object has an attribute foo."
___
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/EAMFUFSEPZFABBMD3EWASUS5YQOA26YQ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-25 Thread Richard Damon
On 6/25/20 6:48 PM, Emily Bowman wrote:
> On Thu, Jun 25, 2020 at 3:41 PM Richard Damon
> mailto:rich...@damon-family.org>> wrote:
> > Actually, you could make _ less special by still binding the value to
>
> it, just make it special in that you allow several values to be bound,
> and maybe just define that the result will be just one of the values,
> maybe even specify which if you want.
>
>
> Like Guido said above, the problem is that _ is already effectively
> reserved for translated text. Combining the two would feel a bit
> weird, but should still be possible.

I thought _ was also commonly used as:

first, -, last = (1, 2, 3)

as a generic don't care about assignment. I guess since the above will
create a local, so not overwrite a 'global' function _ for translations,
so the above usage works as long as that function (or whatever namespace
you are in) doesn't use _ for translations. As long as the bindings in
match also make the symbol a local (which seems reasonable) then you
would get a similar restriction.

-- 
Richard Damon
___
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/M5HWPDG43KGHKM6JVH7ZAGK6YT7OYVJR/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-25 Thread Gregory P. Smith
Litmus test: Give someone who does not know Python this code example from
the PEP and ask them what it does and why it does what it does:

match get_shape():
case Line(start := Point(x, y), end) if start == end:
print(f"Zero length line at {x}, {y}")

I expect confusion to be the result.  If they don't blindly assume the
variables come from somewhere not shown to stop their anguish.

With Python experience, my own reading is:
 * I see start actually being assigned.
 * I see nothing giving values to end, x, or y.
 * Line and Point are things being called, probably class constructions due
to being Capitalized.
 * But where did the parameter values come from and why and how can end be
referred to in a conditional when it doesn't exist yet?
   They appear to be magic!

Did get_shape() return these? (i think not).  Something magic and *implicit
rather than explicit* happens in later lines.  The opposite of what Python
is known for.

Where's the pseudo-code describing *exactly* what the above looks like
logically speaking? (there's a TODO in the PEP for the __match__ protocol
code so I assume it will come, thanks!).  I can guess _only_ after reading
a bunch of these discussions and bits of the PEP.  Is it this?  I can't
tell.

shape = get_shape()
values_or_none = Line.__match__(shape)
if values_or_none:
  start, end = values_or_none
  if start == end:
if x, y := Point.__match__(shape):
  print(...)
  del x, y
  else:
print(...)
  del start, end
else:
  # ... onto the next case: ?

Someone unfamiliar with Python wouldn't even have a chance of seeing that.
I had to rewrite the above many times, I'm probably still wrong.

That sample is very confusing code.  It makes me lean -1 on the PEP overall
today.

This syntax does not lead to readable logically understandable code.  I
wouldn't encourage anyone to write code that way because it is not
understandable to others.  We must never assume others are experts in the
language they are working on code in if we want it to be maintainable.  I
wouldn't approve a code review containing that example.

It would help *in part* if ()s were not used to invoke the __match__
protocol.  I think a couple others also mentioned this earlier.  Don't make
it look like a call.  Use different tokens than ().  Point{x, y} for
example.  Or some way to use another token unused in that context in our
toolbook such as @ to signify "get a matcher for this class" instead of
"construct this class".  for example ClassName@() as our match protocol
indicator, shown here with explicit assignments for clarity:

match get_shape() as shape:
  case start, end := Line@(shape):

no implicit assignments, it is clear where everything comes from.  it is
clear it isn't a constructor call.

downside?  possibly a painful bug when someone forgets to type the @.  but
the point of it not being construction needs to be made.  not using ()s but
instead using ClassName@{} or just ClassName{} would prevent that.

The more nested things get with sub-patterns, the worse the confusion
becomes.  The nesting sounds powerful but is frankly something I'd want to
forbid anyone from using when the assignment consequences are implicit.  So
why implement sub-patterns at all?  All I see right now is pain.

-gps
___
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/B4OXI6CZTSNC6LHWRAKT4XVFFDIUR4K3/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-25 Thread Gregory P. Smith
On Wed, Jun 24, 2020 at 7:58 PM Stephen J. Turnbull <
turnbull.stephen...@u.tsukuba.ac.jp> wrote:

> Ethan Furman writes:
>
>  > _ does not bind to anything, but of what practical importance is that?
>
> *sigh* English speakers ... mutter ... mutter ... *long sigh*
>
> It's absolutely essential to the use of the identifier "_", otherwise
> the I18N community would riot in the streets of Pittsburgh.  Not good
> TV for Python (and if Python isn't the best TV, what good is it? ;-)
>
>
Can I use an i18n'd _("string") within a case without jumping through hoops
to assign it to a name before the match:?


> 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/ENUPVNZEW7DFJKVCKK5XQ4NLV3KOW36C/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
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/WPPCVM6YPAYSGA7AJ5YOKGLQQNGXFLF4/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-25 Thread Gregory P. Smith
On Wed, Jun 24, 2020 at 7:34 PM Taine Zhao  wrote:

> > e.g., "or", and then I wonder "what does short-circuiting have to do
> > with it?". All reuse of symbols carries baggage.
>
> "or" brings an intuition of the execution order of pattern matching, just
> like how people already know about "short-circuiting".
>
> "or" 's operator precedence also suggests the syntax of OR patterns.
>
> As we have "|"  as an existing operator, it seems that there might be
> cases that the precedence of "|" is not consistent with it in an
> expression. This will mislead users.
>

I prefer "or" to "|" as a combining token as there is nothing bitwise going
on here.  "or" reads better.   Which is why Python used it for logic
operations in the first place.  It is simple English.  "|" does not read
like or to anyone but a C based language programmer.  Something Python
users should never need to know.

There is no existing pythonic way to write "evaluate all of these things at
once in no specific order".

And in reality, there will be an order. It'll be sequential, and if it
isn't the left to right order that things are written with the "|" between
them, it will break someones assumptions and make optimization harder.
Some too-clever-for-the-worlds-own-good author is going to implement
__match__ classmethods that have side effects and make state changes that
impact the behavior of later matcher calls (no sympathy for them). Someone
else is going to order them most likely to least likely for performance (we
should have sympathy for that).

Given we only propose to allow a single trailing guard if per case, using
"or" instead of "|" won't be confused with an if's guard condition.

-gps
___
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/2C2S4EDIFGYI6AW3K6VVU2QKEPLASZJT/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-25 Thread Paul Svensson

On Thu, 25 Jun 2020, Richard Damon wrote:


On 6/25/20 10:42 AM, Greg Ewing wrote:

On 26/06/20 1:18 am, Rhodri James wrote:

I will quickly and regularly forget that in this one place, "_" is
special.


You don't have to remember that it's special to understand what
'case _' does. Even if it were treated as an ordinary name, it
would still have the effect of matching anything.


Actually, you could make _ less special by still binding the value to
it, just make it special in that you allow several values to be bound,
and maybe just define that the result will be just one of the values,
maybe even specify which if you want.


We already allow (x, x) = (1, 2)
So, why do we need to disallow binding several values to the same name ?
Without the restriction, there's no need for _ to be special,
and anyone using _ for something else, can use some other dummy for matching.

/Paul
___
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/IWEBLCNUPONLTVXXENX4MU2JHX6LP2EZ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-25 Thread Greg Ewing

On 26/06/20 5:07 am, MRAB wrote:
How do you indicate that you want it to match anything and don't care 
about the value?


   case Spam(-> _):

Or if that's considered too verbose and we're willing to make
_ even more special, it could be just

   case Spam(_):

In that case we would be regarding _ as a "value that matches
anything" rather than a "name that doesn't get assigned to".

--
Greg
___
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/3YJCAGV56FNCGT3VLTJUOHIIIROZR3IY/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-06-25 Thread Brandt Bucher
Ethan Furman wrote:
> Ouch.  That seems like a pretty serious drawback.  Will this issue be 
> resolved?

It's currently being revisited.

Realistically, I'd imagine that we either find some straightforward way of 
opting-in to the current default behavior (allowing one arg to be positionally 
matched against the proxy), or lose the nice behavior altogether. Obviously the 
former is preferable, since it's not trivial to reimplement yourself.
___
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/UZ77WPWH4DK3IK3ANKQYOCXKVW4AERIE/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-25 Thread Ethan Furman

In this example code from the PEP:

match shape:
case Point(x, y):
...
case Rectangle(x0, y0, x1, y1, painted=True):

What is the "painted=True" portion doing?  Is it requiring that the painted 
attribute of the shape object be True in order to match?

--
~Ethan~
___
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/G2TQXL5WZBTDKA2OLZ2WYLDN5F5AK2G5/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-06-25 Thread Ethan Furman

On 06/25/2020 04:07 PM, Brandt Bucher wrote:

Pablo Galindo Salgado wrote:

...users can do a positional match against the proxy with a name pattern:

match input:
 case datetime.date(dt):
 print(f"The date {dt.isoformat()}"

...if 'datetime.date' were updated to implement a non-default __match_args__, 
allowing individual fields to be pulled out of it like this, then the first 
block would be valid, correct code before the change, but would raise an 
ImpossibleMatch after the change because 'dt' is not a field in __match_args__. 
Is this argument misinterpreting something about the PEP or is missing some 
important detail?


Well yeah, it's actually a fair bit worse than you describe. Since dt is matched 
positionally, it wouldn't raise during matching - it would just succeed as before, but 
instead binding the year attribute (not the whole object) to the name "dt". So 
it wouldn't fail until later, when your method call raises a TypeError.


Ouch.  That seems like a pretty serious drawback.  Will this issue be resolved?

--
~Ethan~
___
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/SD44QMJPUFXQGJW2VSB23RNQGKKYZDOO/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-06-25 Thread Brandt Bucher
Pablo Galindo Salgado wrote:
> ...users can do a positional match against the proxy with a name pattern:
>
> match input:
> case datetime.date(dt):
> print(f"The date {dt.isoformat()}"
>
> ...if 'datetime.date' were updated to implement a non-default __match_args__, 
> allowing individual fields to be pulled out of it like this, then the first 
> block would be valid, correct code before the change, but would raise an 
> ImpossibleMatch after the change because 'dt' is not a field in 
> __match_args__. Is this argument misinterpreting something about the PEP or 
> is missing some important detail?

Well yeah, it's actually a fair bit worse than you describe. Since dt is 
matched positionally, it wouldn't raise during matching - it would just succeed 
as before, but instead binding the year attribute (not the whole object) to the 
name "dt". So it wouldn't fail until later, when your method call raises a 
TypeError.
___
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/Y7DJJA2ONIRJSMMA6PYKAYCZSYIECY4D/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-25 Thread Emily Bowman
On Thu, Jun 25, 2020 at 3:41 PM Richard Damon 
wrote:
> Actually, you could make _ less special by still binding the value to

> it, just make it special in that you allow several values to be bound,
> and maybe just define that the result will be just one of the values,
> maybe even specify which if you want.
>

Like Guido said above, the problem is that _ is already effectively
reserved for translated text. Combining the two would feel a bit weird, but
should still be possible.
___
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/KJMYK6AP3CPA2LJUFSAKKO3JSHZJYZCP/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-06-25 Thread Emily Bowman
On Wed, Jun 24, 2020 at 12:46 PM Guido van Rossum  wrote:

> Everyone,
>
> If you've commented and you're worried you haven't been heard, please add
> your issue *concisely* to this new thread. Note that the following issues
> are already open and will be responded to separately; please don't bother
> commenting on these until we've done so:
>
> - Alternative spellings for '|'
> - Whether to add an 'else' clause (and how to indent it)
> - A different token for wildcards instead of '_'
> - What to do about the footgun of 'case foo' vs. 'case .foo'
>
> (Note that the last two could be combined, e.g. '?foo' or 'foo?' to mark a
> variable binding and '?' for a wildcard.)
>

I don't think combining assignment and wildcard will help. '_' is fine for
that. I could get used to '?' as an assignment or a wildcard, but it would
always be a double-take if it was both.

I've seen languages that use '>foo' to indicate assignment, but I can't for
the life of me remember which now, aside from shell redirection. '=foo'
might be more obvious. In the end I think it's only important that there's
some assignment operator, and we'll all get used to whatever you choose.
___
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/QSJRX2QAPA45KMJOZHW2WYPJWRPRFL65/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-25 Thread Richard Damon
On 6/25/20 10:42 AM, Greg Ewing wrote:
> On 26/06/20 1:18 am, Rhodri James wrote:
>> I will quickly and regularly forget that in this one place, "_" is
>> special.
>
> You don't have to remember that it's special to understand what
> 'case _' does. Even if it were treated as an ordinary name, it
> would still have the effect of matching anything.
>
Actually, you could make _ less special by still binding the value to
it, just make it special in that you allow several values to be bound,
and maybe just define that the result will be just one of the values,
maybe even specify which if you want.

-- 
Richard Damon
___
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/EIPWQ6W3CGNV5GGRDCCQ3M63CQFMYDM5/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-25 Thread Emily Bowman
On Thu, Jun 25, 2020 at 9:21 AM Rhodri James  wrote:

> Well, now is the time for expressing surprise :-p
>
> As I've said before, one of my main problems with the PEP is as you go
> through it, more and more special cases and surprises appear, and the
> consequences of earlier surprises generate more special cases and
> surprises.  You claim not unreasonably that it's easy to remember that
> "_" is special in matches.  Maybe you're right, but that decision has
> consequences spelled out later in the PEP that are less easy to
> remember.  Another example: I had not previously thought the definition
> of name patterns to be surprising, but apparently they are (it just
> surprised me, at any rate).  That consequently makes the definition of
> constant value patterns, which I was already iffy about, really quite
> surprising.
>
> Each individual learning curve might be small, but cumulative total by
> the time you reach the end of the PEP is large.  Simple match statements
> will, with adequate squinting, look recognisably like other areas of
> Python.  Complex match statements won't.  And that's a problem for
> anyone who wants to be able to read someone else's code.
>
> Bear in mind I am predominantly a C programmer who uses Python from time
> to time for tools and glue.  If I have to put in effort to learn new
> special-case rules in Python, that's an active discouragement; I'm
> frankly unlikely to bother, and more likely to write those tools and
> glue in C instead.  I'm certainly much less likely to use someone else's
> tools and glue if I have to re-read the spec to remind myself what all
> the gotchas are.
>

On my personal "potentially inscrutable uses of a tool" this still rates
well below list comprehensions, so there's that; the biggest pet peeve I
have anymore is understanding at a glance what is and isn't an assignment.
This is a draft PEP and a lot of discussion around making assignment vs
matched classes more explicit, so it's not like this is going to be set in
stone, and I doubt that most will ever use the more esoteric parts of the
syntax. One way or another, this is going to be a far more capable, and
thus complex, tool than a switch statement, so there's only so much
obviousness you can ask for coming in blind.
___
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/FIPQMOHWVYOPBFLH2MZN66Z2DM7TBWL7/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-25 Thread Brett Cannon
On Thu, Jun 25, 2020 at 3:17 AM Greg Ewing 
wrote:

> On 25/06/20 7:50 pm, Anders Munch wrote:
> > Pascal is a precedent for this placement of 'case',
>
> Yes, but it doesn't use it with "match". In fact it doesn't have
> any keyword in front of the values to be matched; it goes like
>
> case n of
>1: ...;
>2: ...;
>3: ...;
> end
>
> If we did that in Python it would look like this:
>
> case shape:
>Point(x, y):
>   ...
>Line(x1, y1, x2, y2):
>   ...
>Circle(cx, cy, r):
>   ...
>
> What think folks of this?
>

It feels like it would be the only bit of syntax in Python that requires a
`:` and yet has no keyword to go with it for clarification of what the
block is meant for. That makes me not like this.
___
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/BUGY5NJEZR5BWGHE2LXNB4UJ5C2TJY5O/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-25 Thread Ethan Furman

On 06/25/2020 03:00 AM, Greg Ewing wrote:

On 25/06/20 7:50 pm, Anders Munch wrote:



Pascal is a precedent for this placement of 'case',


Yes, but it doesn't use it with "match". In fact it doesn't have
any keyword in front of the values to be matched; it goes like

    case n of
   1: ...;
   2: ...;
   3: ...;
    end

If we did that in Python it would look like this:

    case shape:
   Point(x, y):
  ...
   Line(x1, y1, x2, y2):
  ...
   Circle(cx, cy, r):
  ...


I strongly prefer "match expression: case ...:"

--
~Ethan~
___
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/OZ6GSBPCDOJW73DAPXTGVW2L6OQLRIGH/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-06-25 Thread Pablo Galindo Salgado
I was talking with a colleague today about the PEP and he raised a couple
of question regarding the match protocol and the proxy result.

One question is that taking into account that 'case object(x)' is valid for
every object, but it does (could do) something different for objects
that have a non-None __match_args__ it seems that implementing
__match_args__ will break Liskov substitutability as you could not
substitute
the child in a context where you expect a parent.

Even if you don't care about Liskov substitutability seems that introducing
a __match_args__ for a class will almost always be backwards
incompatible. For example, let's say that 'datetime.date' doesn't have a
custom matching defined, so it inherits the default object.__match__,
 which does:

class object:
@classmethod
def __match__(cls, instance):
if isinstance(instance, cls):
return instance

The PEP notes that:
> The above implementation means that by default only match-by-name and a
single positional match by value against the proxy will work

Which means that users can do a positional match against the proxy with a
name pattern:

match input:
case datetime.date(dt):
print(f"The date {dt.isoformat()}"

Imagine that later, someone notices that it would be reasonable to support
structural pattern matching for the fields of a 'datetime.date' so that
users could do:

match birthday:
case datetime.date(year) if year == 1970:
print("You were born in 1970")

But, if 'datetime.date' were updated to implement a non-default
__match_args__, allowing individual fields to be pulled out of it like
this, then the first block would be valid,
correct code before the change, but would raise an ImpossibleMatch after
the change because 'dt' is not a field in __match_args__.

Is this argument misinterpreting something about the PEP or is missing some
important detail?

On Wed, 24 Jun 2020 at 20:47, Guido van Rossum  wrote:

> Everyone,
>
> If you've commented and you're worried you haven't been heard, please add
> your issue *concisely* to this new thread. Note that the following issues
> are already open and will be responded to separately; please don't bother
> commenting on these until we've done so:
>
> - Alternative spellings for '|'
> - Whether to add an 'else' clause (and how to indent it)
> - A different token for wildcards instead of '_'
> - What to do about the footgun of 'case foo' vs. 'case .foo'
>
> (Note that the last two could be combined, e.g. '?foo' or 'foo?' to mark a
> variable binding and '?' for a wildcard.)
>
> --
> --Guido van Rossum (python.org/~guido)
> *Pronouns: he/him **(why is my pronoun here?)*
> 
> ___
> 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/STJSSAETMTUY7FK5AE53IM73Z2WORNYN/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
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/T32GEZA43AE6LDSAG35I3F2ITXJ5SPTJ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-25 Thread Gregory P. Smith
On Wed, Jun 24, 2020 at 1:38 PM Luciano Ramalho  wrote:

> Thank you Guido, Brandt Bucher, Tobias Kohn, Ivan Levkivskyi and Talin
> for this fun and very useful new feature.
>
> I do enjoy pattern matching a lot in Elixir—my favorite language these
> days, after Python.
>
> I don't want to start a discussion, but I just want to say that as an
> instructor I fear this core language addition may make the language
> less approachable to the non-IT professionals, researchers etc. who
> have saved Python from the decline that we can observe happening in
> Ruby—a language of similar age, with similar strengths and weaknesses,
> but never widely adopted outside of the IT profession.
>
> After I wrap up Fluent Python 2e (which is aimed at professional
> developers) I hope I can find the time to tackle the challenge of
> creating introductory Python content that manages to explain pattern
> matching and other recent developments in a way that is accessible to
> all.
>

Hold on a while.  This feature does not exist.  This PEP has not been
accepted.  Don't count your chickens.py before they hatch.

The last P in PEP stands for Proposal for a reason.  Rejection is a
perfectly valid option.  As is a significant reworking of the proposal so
that it doesn't turn into a nightmare.  This one needs a lot of work at a
minimum.  As proposed, it is extremely non-approachable and non-trivial.

-gps
___
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/GUQLG3H5REWRB5ZINAISX7ZCS3DJQOED/
Code of Conduct: http://python.org/psf/codeofconduct/


  1   2   3   >