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

2020-08-17 Thread Mark Shannon




On 15/08/2020 11:06 pm, Guido van Rossum wrote:
On Fri, Aug 14, 2020 at 11:42 PM Steven D'Aprano > wrote:


On Sat, Aug 15, 2020 at 12:36:25AM +1000, Chris Angelico wrote:

 > Do you have anything new to add to the discussion, or is this 2000
 > lines of rehash?

Having a summary of objections/critiques in one place is far better
than
expecting people to wade through multiple huge threads.


But Mark's repo doesn't replace any of the threads -- it just repeats 
Mark's own arguments, which are exclusively focused on the examples in 
the PEP (it's as if Mark read nothing *but* the examples).


I've read all the PEP. *All* of it. Several times.

I would encourage others to read it all carefully as well.
Anyone who just reads the abstract and introduction might well think 
that PEP 622 is a wonderful thing without any flaws. Reading the whole 
PEP and thinking about its application reveals its flaws.


By choosing examples of your choosing, I am making an effort to be as 
fair as possible. Probably more than fair, in this case.


Throughout the critique, I have attempted to be objective where possible
and fair where objectivity is impossible.
Please point out anywhere I have failed, I'd like the critique to be as 
fair as possible.


For examples where PEP 622 works poorly see the
"Irregularities and surprising behavior" section.

I would also bring you attention to my rigorous analysis of the possible 
application to PEP 622 the entirety of CPython.

If I have made any mistakes there, I'd be happy to correct them.

Cheers,
Mark.
___
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/HF7NYAN4J56OD7BYMTKVLOPWGLUWJNRV/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622 questions

2020-08-17 Thread Mark Shannon




On 16/08/2020 8:23 pm, Jean Abou Samra wrote:

Hi there,

As a poor user, I am extremely excited about the possibilities PEP 622 
(structural pattern matching) opens. I'd like to ask a few questions.


OOI, what possibilities?
I'm genuinely interested know what problems PEP 622 would solve for you.



I hope these were not already answered in other threads, which it is hard to 
follow given the amounts of information.

First, I'd like to know wether walrus patterns are encouraged as an expressive 
way to explain the code in addition to comments, for example:

match number:
   case exact := numbers.Rational():
   ...
   case inexact:
   ...

Here we rename number depending on the case clause that was taken. Would this 
be considered good practice? Maybe it'd be worth codifying in PEP 8 if PEP 622 
is accepted?

A nit: how is the keywords module going to integrate soft keywords? Perhaps not 
at all?

Also, I see potential for a caveat:

match number:
   case int: # missing parentheses!
   ...
   case float:
   ...
   case Fraction:
   ...

In this case, if I understand the specification correctly, the first case will 
always match, right? Maybe the interpreter could throw a SyntaxWarning when a 
bare capture pattern (without a guard) is used as a pattern in any case clause 
other than the last one? As far as I understand, this could possibly prevent 
many of the mistakes in load/store that people have been rightfully complaining 
about so far. It's merely a stronger measure than letting static checkers do 
the work (since we don't all use these tools).

Finally, was as-based syntax considered as an alternative to walrus patterns, that is, 
PATTERN as NAME instead of NAME := PATTERN, as we have in the try statement? Given the 
extensive discussion, I guess it might have been rejected, so it could deserve a place 
under "Rejected ideas" -- this holds for all the above too, which I'm sorry 
about if it's dumb.

Best regards,
Jean Abou Samra
___
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/2HDCJYULPKEDLHLMQH563VYZTG47ST3N/
Code of Conduct: http://python.org/psf/codeofconduct/


___
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/BG66UP2S3GNRJLQGWSFID6EDIEI772Y4/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622 questions

2020-08-17 Thread Mark Shannon



On 16/08/2020 9:41 pm, Guido van Rossum wrote:
On Sun, Aug 16, 2020 at 12:37 PM Jean Abou Samra > wrote:


Hi there,

As a poor user, I am extremely excited about the possibilities PEP
622 (structural pattern matching) opens. I'd like to ask a few
questions.

I hope these were not already answered in other threads, which it is
hard to follow given the amounts of information.


Most of the threads can hardly be considered information -- at best it's 
debate, arguments and opinions. :-)


First, I'd like to know wether walrus patterns are encouraged as an
expressive way to explain the code in addition to comments, for example:

match number:
   case exact := numbers.Rational():
       ...
   case inexact:
       ...

Here we rename number depending on the case clause that was taken.
Would this be considered good practice? Maybe it'd be worth
codifying in PEP 8 if PEP 622 is accepted?


I think we should wait a while to see what style develops before 
recommending specifics. Right now I'm not excited about it, mostly 
because the first case is a lot longer. Assuming the code blocks in the 
cases aren't very long, it doesn't seem hard to keep the context ("is 
the number exact or inexact here?") in mind without using the different 
variable names.


A nit: how is the keywords module going to integrate soft keywords?
Perhaps not at all?


Already taken care of -- it has a separate list `softkwlist` (currently 
empty) and corresponding function `issoftkeyword`. If any soft keywords 
appear in the grammar the code generation process will update keyword.py.


Also, I see potential for a caveat:

match number:
   case int: # missing parentheses!
       ...
   case float:
       ...
   case Fraction:
       ...

In this case, if I understand the specification correctly, the first
case will always match, right? Maybe the interpreter could throw a
SyntaxWarning when a bare capture pattern (without a guard) is used
as a pattern in any case clause other than the last one? As far as I
understand, this could possibly prevent many of the mistakes in
load/store that people have been rightfully complaining about so
far. It's merely a stronger measure than letting static checkers do
the work (since we don't all use these tools).


The reference implementation in fact does issue a SyntaxWarning for this 
case.


Shouldn't that detail be in the PEP?



Finally, was as-based syntax considered as an alternative to walrus
patterns, that is, PATTERN as NAME instead of NAME := PATTERN, as we
have in the try statement? Given the extensive discussion, I guess
it might have been rejected, so it could deserve a place under
"Rejected ideas" -- this holds for all the above too, which I'm
sorry about if it's dumb.


I don't recall it was discussed. A very early draft (that wasn't 
published) used `as` instead of `case`, and that draft used `:=` for 
this purpose. It's always made sense to use that, so I've never 
considered `as`. Do you think there are situations where `as` has a 
clear advantage over `:=`?


Anyway, unless someone digs up an actual thread where this was discussed 
I think it's not worth adding to Rejected ideas (we can't possibly 
review the entire design space).


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



___
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/NKM4QQNLKOH5J2DNS55LBKFGG2H2JGLY/
Code of Conduct: http://python.org/psf/codeofconduct/


___
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/UIYT3LCWYCFYYD27NQ6G3K4ZDRUNF2CP/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-08-17 Thread Mark Shannon

Hi Chris,

On 14/08/2020 3:36 pm, Chris Angelico wrote:

On Sat, Aug 15, 2020 at 12:32 AM Mark Shannon  wrote:


Hi all,

I've written up a critique of PEP 622.
Rather than dump a 2000 line email on you all, I've made a git repo.

https://github.com/markshannon/pep622-critique



I started reading it. You're saying the same things that everyone else
has said, so I stopped reading.


I've added an abstract and made the analysis of the standard library 
more prominent.
Would you take another look and let me know if it is more a compelling 
read now?




Do you have anything new to add to the discussion, or is this 2000
lines of rehash?


Do let me know whether you think it adds anything new, once you've read 
a bit more.


Cheers,
Mark.
___
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/JKWBMFCV56ZZTBPJFRF55OTWL6PYLNRL/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-08-17 Thread Henk-Jaap Wagenaar
On Mon, 17 Aug 2020 at 11:30, Mark Shannon  wrote:

>
> I would also bring you attention to my rigorous analysis of the possible
> application to PEP 622 the entirety of CPython.
> If I have made any mistakes there, I'd be happy to correct them.
>
>
You say "I've elided a lot of complex logic int cases, as it is not
relevant." in the plistlib._BinaryPlistWriter._write_object example, this
seems to be a prime example where guards could be used to simplify/unnest
the logic? Even if you disagree, I think it is highly relevant and worth
commenting on, one way or another!
___
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/CJSF5EZ5EN54ZAGBBRNG3PPR6H4DPKDR/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-08-17 Thread Mark Shannon



On 17/08/2020 1:13 pm, Henk-Jaap Wagenaar wrote:
On Mon, 17 Aug 2020 at 11:30, Mark Shannon > wrote:



I would also bring you attention to my rigorous analysis of the
possible
application to PEP 622 the entirety of CPython.
If I have made any mistakes there, I'd be happy to correct them.


You say "I've elided a lot of complex logic int cases, as it is not 
relevant." in the plistlib._BinaryPlistWriter._write_object example, 
this seems to be a prime example where guards could be used to 
simplify/unnest the logic? Even if you disagree, I think it is highly 
relevant and worth commenting on, one way or another!


Thanks for the feedback.

I've expanded the code in the `int` and `UID` cases, and made it clearer 
why the remaining code has been elided.



Cheers,
Mark.
___
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/WMLES4ER52GGJCXQTH2ULSF5EESCXVHY/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-08-17 Thread Henk-Jaap Wagenaar
Thanks for having a look! The example now looks like (looking at int case
only, same applies to UID):

case int():
if value < 0:
try:
self._fp.write(struct.pack('>Bq', 0x13, value))
except struct.error:
raise OverflowError(value) from None
elif value < 1 << 8:
self._fp.write(struct.pack('>BB', 0x10, value))
...
elif value < 1 << 64:
self._fp.write(b'\x14' + value.to_bytes(16, 'big',
signed=True))
else:
raise OverflowError(value)

I was more thinking it would read/look something like:

case int() if value < 0:
try:
self._fp.write(struct.pack('>Bq', 0x13, value))
except struct.error:
raise OverflowError(value) from None
case int() if value < 1 << 8:
self._fp.write(struct.pack('>BB', 0x10, value))
...
case int() if value < 1 << 64:
self._fp.write(b'\x14' + value.to_bytes(16, 'big',
signed=True))
case int():
raise OverflowError(value)

Which I think works as expected under the current PEP622?

On Mon, 17 Aug 2020 at 14:16, Mark Shannon  wrote:

>
>
> On 17/08/2020 1:13 pm, Henk-Jaap Wagenaar wrote:
> > On Mon, 17 Aug 2020 at 11:30, Mark Shannon  > > wrote:
> >
> >
> > I would also bring you attention to my rigorous analysis of the
> > possible
> > application to PEP 622 the entirety of CPython.
> > If I have made any mistakes there, I'd be happy to correct them.
> >
> >
> > You say "I've elided a lot of complex logic int cases, as it is not
> > relevant." in the plistlib._BinaryPlistWriter._write_object example,
> > this seems to be a prime example where guards could be used to
> > simplify/unnest the logic? Even if you disagree, I think it is highly
> > relevant and worth commenting on, one way or another!
>
> Thanks for the feedback.
>
> I've expanded the code in the `int` and `UID` cases, and made it clearer
> why the remaining code has been elided.
>
>
> Cheers,
> Mark.
>
___
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/PUENMFG7AFEGN446JHNBLSRUVCV52HHZ/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-08-17 Thread Marat Khalili

Hi all,


I started reading it. You're saying the same things that everyone else
has said, so I stopped reading.

Do you have anything new to add to the discussion, or is this 2000
lines of rehash?


I'm new to the subject, and I find the rehash of everything that has 
been said on the subject useful. Apart from the OP's gist I could find 
only one publication on subject 
 which 
actually spends more space discussing an alternative approach. If OP's 
gist is one-sided, I'd prefer to read more summaries from people who 
defend the PEP. The proposed changes are substantial, and the arguments 
collected by OP against it are quite compelling (the example with 
changing HTTP_OK value is downright horrifying).


To make my comment slightly less meta, I'd like to ask if the following 
aspect was already discussed. In some cases the problem that PEP 622 is 
intended to solve is solved by the "dict of lambdas" pattern (here 
 
is an example in the wild). Particularly, the HTTP example is handled 
easily this way (note that I handled more cases in the same number of 
lines):


RESPONSE_STATUS_REACTIONS = {    HTTP_OK: lambda: 
do_something(response.data),    HTTP_MOVED_PERMANENTLY: lambda: 
retry(response.location),    # no way to merge with the one above in 
current syntax    HTTP_FOUND: lambda: retry(response.location),    
HTTP_UNAUTHORIZED: lambda: retry(auth=get_credentials()),    
HTTP_UPGRADE: lambda: retry(delay=DELAY), # `retry` is pretty magical 
here    # `lambda: raise` does not work in current syntax    
HTTP_INTERNAL_SERVER_ERROR: lambda: raise_(RequestError("we couldn't get 
the data")),    # same problems with merging here    HTTP_BAD_GATEWAY: 
lambda: raise_(RequestError("we couldn't get the data")),    
HTTP_SERVICE_UNAVAILABLE: lambda: raise_(RequestError("we couldn't get 
the data")),}RESPONSE_STATUS_REACTIONS.get(response.status, lambda: 
raise_(RequestError(f"Unexpected response status {response.status}")))()


But of course dict only matches keys exactly, so the following won't 
work for subclasses of bool or int:


key = {    bool: lambda key: ('false', 'true')[key],    int: _intstr, # 
no idea what _intstr does, just rewording the gist example

}[type(key)](key)

I wonder if some better mapping class can be added to the standard 
library that would accept more flexible patterns and match them in 
correct order without assigning anything? Assignment or whatever side 
effects would then be performed explicitly and kept separate from matching.


With Best Regards,
Marat Khalili

___
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/BFXBYKXBSMWE5K6BXVVUMBNDZBV25DMX/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-08-17 Thread Mark Shannon



On 17/08/2020 3:08 pm, Henk-Jaap Wagenaar wrote:
Thanks for having a look! The example now looks like (looking at int 
case only, same applies to UID):


         case int():
             if value < 0:
                 try:
                     self._fp.write(struct.pack('>Bq', 0x13, value))
                 except struct.error:
                     raise OverflowError(value) from None
             elif value < 1 << 8:
                 self._fp.write(struct.pack('>BB', 0x10, value))
             ...
             elif value < 1 << 64:
                 self._fp.write(b'\x14' + value.to_bytes(16, 'big', 
signed=True))

             else:
                 raise OverflowError(value)

I was more thinking it would read/look something like:

         case int() if value < 0:
                 try:
                     self._fp.write(struct.pack('>Bq', 0x13, value))
                 except struct.error:
                     raise OverflowError(value) from None
         case int() if value < 1 << 8:
                 self._fp.write(struct.pack('>BB', 0x10, value))
         ...
         case int() if value < 1 << 64:
                 self._fp.write(b'\x14' + value.to_bytes(16, 'big', 
signed=True))

         case int():
             raise OverflowError(value)

Which I think works as expected under the current PEP622?


That would work, but would be slower for the reference implementation 
due to the repeated `isinstance(value, int)` checks.


I think the repeated `int()` cases do not help readability.
Which form do you think is more readable?



On Mon, 17 Aug 2020 at 14:16, Mark Shannon > wrote:




On 17/08/2020 1:13 pm, Henk-Jaap Wagenaar wrote:
 > On Mon, 17 Aug 2020 at 11:30, Mark Shannon mailto:[email protected]>
 > >> wrote:
 >
 >
 >     I would also bring you attention to my rigorous analysis of the
 >     possible
 >     application to PEP 622 the entirety of CPython.
 >     If I have made any mistakes there, I'd be happy to correct them.
 >
 >
 > You say "I've elided a lot of complex logic int cases, as it is not
 > relevant." in the plistlib._BinaryPlistWriter._write_object example,
 > this seems to be a prime example where guards could be used to
 > simplify/unnest the logic? Even if you disagree, I think it is
highly
 > relevant and worth commenting on, one way or another!

Thanks for the feedback.

I've expanded the code in the `int` and `UID` cases, and made it
clearer
why the remaining code has been elided.


Cheers,
Mark.


___
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/VYYCWOGEELVCSPWM4VJ2A63BHIPIL3LF/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-08-17 Thread Henk-Jaap Wagenaar
>
> That would work, but would be slower for the reference implementation
> due to the repeated `isinstance(value, int)` checks.
>

If you wanted to avoid that you could use match/case inside the "case
int()" instead, i.e.:

case int():
match value:
  case _ if value < 8:
// do things
  case _ if value < 1 << 8:
 // do things
  ...
  case _:
 // raise some kind of error

but that might be madness.


> I think the repeated `int()` cases do not help readability.
> Which form do you think is more readable?
>

I think the form I suggested is more readable and also I think it is more
PEP622-like and that it is easier to reason about/test/debug/maintain, but
that's just my opinion! Not sure how important the speed difference is to
this example.
___
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/VAKQAJ2BTATMXG2JUKKEO4BTMJDUWGQS/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-08-17 Thread Guido van Rossum
On Mon, Aug 17, 2020 at 8:11 AM Mark Shannon  wrote:

>
>
> On 17/08/2020 3:08 pm, Henk-Jaap Wagenaar wrote:
> > Thanks for having a look! The example now looks like (looking at int
> > case only, same applies to UID):
> >
> >  case int():
> >  if value < 0:
> >  try:
> >  self._fp.write(struct.pack('>Bq', 0x13, value))
> >  except struct.error:
> >  raise OverflowError(value) from None
> >  elif value < 1 << 8:
> >  self._fp.write(struct.pack('>BB', 0x10, value))
> >  ...
> >  elif value < 1 << 64:
> >  self._fp.write(b'\x14' + value.to_bytes(16, 'big',
> signed=True))
> >  else:
> >  raise OverflowError(value)
> >
> > I was more thinking it would read/look something like:
> >
> >  case int() if value < 0:
> >  try:
> >  self._fp.write(struct.pack('>Bq', 0x13, value))
> >  except struct.error:
> >  raise OverflowError(value) from None
> >  case int() if value < 1 << 8:
> >  self._fp.write(struct.pack('>BB', 0x10, value))
> >  ...
> >  case int() if value < 1 << 64:
> >  self._fp.write(b'\x14' + value.to_bytes(16, 'big',
> signed=True))
> >  case int():
> >  raise OverflowError(value)
> >
> > Which I think works as expected under the current PEP622?
>
> That would work, but would be slower for the reference implementation
> due to the repeated `isinstance(value, int)` checks.
>

The PEP allows the compiler to generate optimized code that only checks
once.


> I think the repeated `int()` cases do not help readability.
> Which form do you think is more readable?
>

I find Henk-Jaap's version better, because the case blocks show the
structure of the code better.

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

___
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/JNL6IRFMZU4H5IP3CKXCJ2JHROUENM2K/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-08-17 Thread Baptiste Carvello
Le 14/08/2020 à 16:24, Mark Shannon a écrit :
> 
> https://github.com/markshannon/pep622-critique

Hi all,

reading through this made me think of 3 ideas which I think are new [1].
2 of them are about the Value Pattern question, the last one is a small
nit about the Django example.

* the critique points the limitations to the use of pattern matching in
__init__ methods, because Capture Patterns can't assign to dotted names.

Thus the currently proposed dot-based rule is a limitation not just for
Value Patterns, as already heavily discussed, but also for Capture
Patterns. Moreover, this limitation cannot be lifted after the fact if
the __init__ method use-case proves important in the future.

* the critique points that Value Patterns with booleans would need
identity-, not equality-based comparison. This leads to the idea that,
if a special syntax if eventually used for Value Patterns, using the
comparison operator in it might be useful. Thus we could have:

>>> match int_or_boolean:  # ok, dubious design!
... case is True:  # same as "if int_or_boolean is True:"
... print("boolean true")
... case is False:
... print("boolean false")
... case == ONE:  # same as "if int_or_boolean == ONE:"
... print("integer 1")

* the Django example could be written more idiomatically by relying more
on destructuring instead of having a guard:

>>> match value:
... case [first, *_, label := (Promise() | str())]:
... value = value[:-1]
... case _:
... label = key.replace('_', ' ').title()

Cheers,
Baptiste

[1] as in: I skimmed through most of the threads and believe they have
not already been said (famous last words…)
___
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/P7BNZEOOKAEVZCSOVAN7WZYYHLZYO4QR/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622 questions

2020-08-17 Thread Jean Abou Samra
Hi,

Thanks for your reply!

> Le 16 août 2020 à 22:41, Guido van Rossum  a écrit :
> 
>> On Sun, Aug 16, 2020 at 12:37 PM Jean Abou Samra  wrote:
>> Hi there,
>> 
>> As a poor user, I am extremely excited about the possibilities PEP 622 
>> (structural pattern matching) opens. I'd like to ask a few questions.
>> 
>> I hope these were not already answered in other threads, which it is hard to 
>> follow given the amounts of information.
> 
> Most of the threads can hardly be considered information -- at best it's 
> debate, arguments and opinions. :-)

You're entirely right.

>  
>> First, I'd like to know wether walrus patterns are encouraged as an 
>> expressive way to explain the code in addition to comments, for example:
>> 
>> match number:
>>   case exact := numbers.Rational():
>>   ...
>>   case inexact:
>>   ...
>> 
>> Here we rename number depending on the case clause that was taken. Would 
>> this be considered good practice? Maybe it'd be worth codifying in PEP 8 if 
>> PEP 622 is accepted?
> 
> I think we should wait a while to see what style develops before recommending 
> specifics. Right now I'm not excited about it, mostly because the first case 
> is a lot longer. Assuming the code blocks in the cases aren't very long, it 
> doesn't seem hard to keep the context ("is the number exact or inexact 
> here?") in mind without using the different variable names.

I recognise that my example was somehow too trivial; it would likely look more 
natural when rewriting visitors, where you could end up with a lot of code in 
each case clause. For instance, if I had to rewrite
https://github.com/sympy/sympy/blob/c3087c883be02ad228820ff714ad6eb9af1ad868/sympy/parsing/ast_parser.py
I may write: case num := Num(), etc.

(By the way, if you read sympy_parser.py in the same directory, it's full of 
examples where pattern matching would be useful.)

I also noticed this in the PEP, under "Capture patterns":

match greeting:
case "":
print("Hello!")
case name:
print(f"Hi {name}!")

Anyway, I agree that the best way forward is to wait and see what usage 
patterns develop (no pun intended).

>> A nit: how is the keywords module going to integrate soft keywords? Perhaps 
>> not at all?
> 
> Already taken care of -- it has a separate list `softkwlist` (currently 
> empty) and corresponding function `issoftkeyword`. If any soft keywords 
> appear in the grammar the code generation process will update keyword.py.

My bad, I should have checked out the dev documentation since the PEG parser is 
a novelty...

>> Also, I see potential for a caveat:
>> 
>> match number:
>>   case int: # missing parentheses!
>>   ...
>>   case float:
>>   ...
>>   case Fraction:
>>   ...
>> 
>> In this case, if I understand the specification correctly, the first case 
>> will always match, right? Maybe the interpreter could throw a SyntaxWarning 
>> when a bare capture pattern (without a guard) is used as a pattern in any 
>> case clause other than the last one? As far as I understand, this could 
>> possibly prevent many of the mistakes in load/store that people have been 
>> rightfully complaining about so far. It's merely a stronger measure than 
>> letting static checkers do the work (since we don't all use these tools).
> 
> The reference implementation in fact does issue a SyntaxWarning for this case.

Good! (Sorry, I couldn't check that as mybinder.org currently seems 
unavailable... :-( ).
 
>> Finally, was as-based syntax considered as an alternative to walrus 
>> patterns, that is, PATTERN as NAME instead of NAME := PATTERN, as we have in 
>> the try statement? Given the extensive discussion, I guess it might have 
>> been rejected, so it could deserve a place under "Rejected ideas" -- this 
>> holds for all the above too, which I'm sorry about if it's dumb.
> 
> I don't recall it was discussed. A very early draft (that wasn't published) 
> used `as` instead of `case`, and that draft used `:=` for this purpose. It's 
> always made sense to use that, so I've never considered `as`. Do you think 
> there are situations where `as` has a clear advantage over `:=`?

Let's see: it probably avoids some uglinesses that occur with the use of = in 
class patterns.

case Expr(value=(add := BinOp(op=Add(:
vs.
case Expr(value=(BinOp(op=Add()) as add))

There is also
case Line(start := Point(x, y), end):
which might be confused with
case Line(start=Point(x, y), end):

However, the main reason why I was asking is that 'as' parallels well with the 
current context that is closest to pattern matching, namely the try statement. 
The walrus parallels with assignment expressions, so this is in fact a story of 
wether patterns should look more like expressions or the LHS of an assignment, 
as I see it.

The walrus highlights the structure that you're trying to fit in: "This is an 
Expr, having as a value an addition, which looks like ...". By contrast, having 
the name after the pattern makes you think

[Python-Dev] Re: PEP 622 questions

2020-08-17 Thread Jean Abou Samra
> OOI, what possibilities? I'm genuinely interested know what problems PEP 622 
> would solve for you.


It's somehow the same use case as Oscar Benjamin's: transform algebraic 
expressions (the goal being to calculate them step by step -- still under 
development). You have a series of rules to apply, like transforming x*1 into 
x, and more complicated ones. These rules can be written naturally using 
patterns.

Also, I have the loose project of writing a new ABC to LilyPond converter (both 
are text-based music notation formats). This is all about manipulating 
different tree structures held in dataclasses, so the match statement, possibly 
in conjunction with algebraic types, would be useful as well.

Best,
Jean Abou Samra

___
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/WYJWDEJKSGFM3OWTBM6P56R5D6GVHAS2/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-08-17 Thread Jean Abou Samra
> (the example with changing HTTP_OK value is downright horrifying).

As was just mentioned by Guido in another thread, there is a SyntaxWarning to 
alert you.


> This leads to the idea that, if a special syntax if eventually used for Value 
> Patterns, using the comparison operator in it might be useful.


Have a look at 
https://www.mail-archive.com/[email protected]/msg109254.html . 
Unfortunately, this doesn't scale well with attribute checks...

Cheers,
Jean Abou Samra___
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/FXHQ57FFHPJLAHOG7MQO2MTFWXGK4BRA/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622 questions

2020-08-17 Thread Guido van Rossum
On Mon, Aug 17, 2020 at 10:04 AM Jean Abou Samra  wrote:

[Jean]

> Finally, was as-based syntax considered as an alternative to walrus
>> patterns, that is, PATTERN as NAME instead of NAME := PATTERN, as we have
>> in the try statement? Given the extensive discussion, I guess it might have
>> been rejected, so it could deserve a place under "Rejected ideas" -- this
>> holds for all the above too, which I'm sorry about if it's dumb.
>>
>
[Guido]

> I don't recall it was discussed. A very early draft (that wasn't
> published) used `as` instead of `case`, and that draft used `:=` for this
> purpose. It's always made sense to use that, so I've never considered `as`.
> Do you think there are situations where `as` has a clear advantage over
> `:=`?
>
>
[Jean]

> Let's see: it probably avoids some uglinesses that occur with the use of =
> in class patterns.
>
> case Expr(value=(add := BinOp(op=Add(:
> vs.
> case Expr(value=(BinOp(op=Add()) as add))
>
> There is also
> case Line(start := Point(x, y), end):
> which might be confused with
> case Line(start=Point(x, y), end):
>
> However, the main reason why I was asking is that 'as' parallels well with
> the current context that is closest to pattern matching, namely the try
> statement. The walrus parallels with assignment expressions, so this is in
> fact a story of wether patterns should look more like expressions or the
> LHS of an assignment, as I see it.
>
> The walrus highlights the structure that you're trying to fit in: "This is
> an Expr, having as a value an addition, which looks like ...". By contrast,
> having the name after the pattern makes you think like the interpreter:
> "Try to fit this into BinOp(op=Add()), and if that succeds, put it in
> 'add'." Both are defendable. I think the latter would be a little easier to
> teach, so I'd encourage considering it.
>

Okay, I opened an issue in the PEP team's internal tracker about this:
https://github.com/gvanrossum/patma/issues/140


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

___
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/Q55YSICYDK5Z5DXSTVKL5IIH3BUVHYHH/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622 questions

2020-08-17 Thread Guido van Rossum
On Mon, Aug 17, 2020 at 3:37 AM Mark Shannon  wrote:

>
>
> On 16/08/2020 9:41 pm, Guido van Rossum wrote:
> > On Sun, Aug 16, 2020 at 12:37 PM Jean Abou Samra  > > wrote:
> > Also, I see potential for a caveat:
> >
> > match number:
> >case int: # missing parentheses!
> >...
> >case float:
> >...
> >case Fraction:
> >...
> >
> > In this case, if I understand the specification correctly, the first
> > case will always match, right? Maybe the interpreter could throw a
> > SyntaxWarning when a bare capture pattern (without a guard) is used
> > as a pattern in any case clause other than the last one? As far as I
> > understand, this could possibly prevent many of the mistakes in
> > load/store that people have been rightfully complaining about so
> > far. It's merely a stronger measure than letting static checkers do
> > the work (since we don't all use these tools).
> >
> >
> > The reference implementation in fact does issue a SyntaxWarning for this
> > case.
>
> Shouldn't that detail be in the PEP?
>

Good point. I have added a note about this in the section on static
checkers, under "Note about constants":
https://github.com/python/peps/commit/6a7d6b831f9af7db651269231c77037aff6bad8f

(I should mention that the PEP authors are also grateful for your
observation about what users expect for `case True`, and we are now
discussing this in our issue tracker at
https://github.com/gvanrossum/patma/issues/139. We're also discussing
Jean's point about `as` vs. `:=` in issue 140.)

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

___
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/KQD4D3SMFDJZKUEUWEWKQIFO7WDRDNHX/
Code of Conduct: http://python.org/psf/codeofconduct/