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

2020-07-10 Thread Jim Baker
I did make the following arguments about less indentation in
https://github.com/gvanrossum/patma/issues/59

To recap:

   1. Similarity to if/elif/else and try/except/finally statements in how
   code lines up
   2. Less apparent complexity, since indentation is a visual signal for
   such
   3. Smaller, more meaningful diffs when refactoring if/elif/else chains

Just to be clear, I wanted to capture these as possible objections, I'm not
greatly in favor of one indentation scheme or the other - there are good
arguments for the indentation scheme of the current PEP (which it makes).

- Jim

On Fri, Jul 10, 2020 at 5:11 PM Paul Sokolovsky  wrote:

> Hello,
>
> On Sat, 11 Jul 2020 00:35:39 +0200
> Federico Salerno  wrote:
>
> []
>
> > A few emails ago I proposed something like this (and I'm probably
> > only the last one to do so amongst many), but if anyone made an
> > argument against it I must have missed it:
>
> The PEP itself in "rejected" ideas makes an argument against it:
> indented stuff after a line ending with ":" must be a *statement*. It
> would be totally nuts for that to be something else, e.g. an expression:
>
> >
> > match:
> >  a
> > case 1:
> >  ...
> > case 2:
> >  ...
> > else:
> >  ...
>
> > (The a on a separate line being arguable.)
>
> That of course leads us to the obvious idea:
>
> match a:
> case 1:
>  ...
> case 2:
>  ...
> else:
>  ...
>
>
> Of course, PEP smartly has an argument against that too, in the vein of
> "after line ending with ':', there should be an indent suite (list of
> statements)". But that's where it goes sideways. That argument is no
> better than the argument "there should be no normally looking
> identifiers with magic behavior", but look, very this PEP does exactly
> that with the identifier "_".
>
> And if the above snippet looks weird to anybody, it's only because of
> all the "case" business. There wouldn't be such a problem if it was
> instead:
>
> match a:
> | 1:
>  ...
> | 2:
>  ...
> |:
>  ...
>
> The above ML-like syntax should be perfect for almost everyone, ...
> except the PEP authors, because they have it in "rejected ideas" either.
>
>
> --
> 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/7V7BS3ICKE5PJZD5Q2I65ALZQNXROPZU/
> 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/Y652WIGSKSHOLV7YHIIXZWRK3MJOXDID/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-07-10 Thread Paul Sokolovsky
Hello,

On Sat, 11 Jul 2020 00:35:39 +0200
Federico Salerno  wrote:

[]

> A few emails ago I proposed something like this (and I'm probably
> only the last one to do so amongst many), but if anyone made an
> argument against it I must have missed it:

The PEP itself in "rejected" ideas makes an argument against it:
indented stuff after a line ending with ":" must be a *statement*. It
would be totally nuts for that to be something else, e.g. an expression:

> 
> match:
>      a
> case 1:
>      ...
> case 2:
>      ...
> else:
>      ...

> (The a on a separate line being arguable.)

That of course leads us to the obvious idea:

match a:
case 1:
     ...
case 2:
     ...
else:
     ...


Of course, PEP smartly has an argument against that too, in the vein of
"after line ending with ':', there should be an indent suite (list of
statements)". But that's where it goes sideways. That argument is no
better than the argument "there should be no normally looking
identifiers with magic behavior", but look, very this PEP does exactly
that with the identifier "_".

And if the above snippet looks weird to anybody, it's only because of
all the "case" business. There wouldn't be such a problem if it was
instead:

match a:
| 1:
     ...
| 2:
     ...
|:
     ...

The above ML-like syntax should be perfect for almost everyone, ...
except the PEP authors, because they have it in "rejected ideas" either.


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


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

2020-07-10 Thread Glenn Linderman

On 7/10/2020 3:15 AM, Gustavo Carneiro wrote:



On Fri, 10 Jul 2020 at 10:33, Glenn Linderman > wrote:


On 7/10/2020 1:21 AM, Stefano Borini wrote:
> Just my 2 cents, I find it kind of annoying that the whole structure
> requires two levels of indentation to actually reach the operational
> code.
> This would be a first in python.
>
> I would prefer an option akin to if elif elif else where each
block is
> only one level deep.
Me too.

That would also sidestep the dilemma of whether else: (if
implemented)
should be indented like case: or like match: because they would be
the same.

match:
 t
case ("rect", real, imag):
 return complex(real, imag)
case ("polar", r, phi):
 return complex( r* cos(phi), r*sin(phi)
else:
 return None

but it does make the match: block not a statement group, which was
disturbing to some.

On the other hand, this has a correspondence to:

try:
  throw expression
except (type of expression) as exc1:
  blah blah1
except (another type) as exc2:
 blah blah2
else:
 blah blah3


The problem of the try...except structure, with less indentation, is 
that, yes, it is OK for exceptions because normally you have 2 or 3 
`except XXX` clauses, therefore it is usually easy to follow, if the 
number of vertical lines in the entire block of try-catch is low enough.


But I have had cases with catching many exception types, each with its 
own block of 4 or 5 lines, adding up to a block of try-excepts that 
doesn't even fit in a single window of my editor.  In that case, I 
always have wished for except clauses to be extra indented, to more 
easily distinguish where the try..except block ends.


Therefore, I posit that the style of try...except indentation only 
works where the number of cases is small.


But for the case of pattern matching, I expect the number of cases to 
be matched to be a lot higher than exception handling cases.  Having 
cases to be matched be indented is, IMHO, a nice visual cue to help 
the reader understand where the pattern matching block ends.


Actually, the current  if elseif elseif elseif else, used now because 
Python has no switch/match/case, has exactly the same issue as you 
describe as a problem with try if there were more cases... and if often 
has more cases, just like match will.


So your concern seems nebulous. You may have wished for extra 
indentation but it is simple to get more indentation: use 8 spaces 
instead of 4. So if you really wanted it, you could have had it. It is 
much harder to get less indentation when the language structures 
prescribe it.



In fact, one _could_ wrap this whole feature into the try:
syntax... the
match statement would be tried, and the cases would be special
types of
exception handlers:

try:
 match expression
case ("rect", real, imag):
 return complex(real, imag)
case ("polar", r, phi):
 return complex( r* cos(phi), r*sin(phi)
else:
 return None

If the expression could fail to be calculated, one could have a
mix of
except clauses also to catch those, rather than needing to wrap the
whole match expression in a separate try to handle that case
[making the
nesting even deeper :( ]

There might even be a use for using case clauses to extend "normal"
exception handling, where the exception object could be tested for
its
content as well as its class to have different handling.

try:
 raise Exception("msg", 35, things)
case Exception( x, "widgets"):
 blah blah 1
case Exception( x, "characters"):
 blah blah 2
else:
 blah blah 3

In this not-fully-thought-through scenario, maybe the keyword match
isn't even needed: "raise expression" could do the job, or they
could be
aliases to signify intent.

In other words, a match expression would always "fail". The only
mismatch here is that it points out the difference between
try-else and
match-else: try-else is executed if there is no failure, but if match
always fails, else would never be appropriate, and case _: would be.

In any case, it does seem there is a strong correlation between match
processing and try processing, that I didn't see during other
discussions of the possible structural similarities. "match 3 / 0:"
would clearly need to be wrapped in a try:

try:
 match x / y:
  case 43:
    print("wow, it is 43")
  case 22:
    print("22 seemed less likely than 43 for some reason")
 case _:
   print("You get what you get")
except ZeroDivisionError as exc:
 print(f"But sometimes you get an exception {exc}")

or:

try:
 raise x / y
case 43:
 

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

2020-07-10 Thread Brandt Bucher
Federico Salerno wrote:
> Is there anything (bar tradition or other subjective arguments) that speaks 
> in favour of this, especially in light of the fact that having the same 
> indentation level would also solve other problems? ...if anyone made an 
> argument against it I must have missed it:

We spend a fair bit of time discussing this exact proposal in the PEP (I just 
searched for "indent"):

https://www.python.org/dev/peps/pep-0622/#use-a-flat-indentation-scheme
___
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/KLP6CTEVLYXVGBGBWCTUARV2KQAPYJVS/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-07-10 Thread Federico Salerno

On 10/07/2020 12:33, Greg Ewing wrote:

A thought about the indentation level of a speculated "else" clause...

Some people have argued that "else" should be at the outer level,
because that's the way it is in all the existing compound statements.

However, in those statements, all the actual code belonging to the
statement is indented to the same level:

    if a:
    
    elif b:
    
    else:
    

    ^
    |
    Code all indented to this level

But if we were to indent "else" to the same level as "match",
the code under it would be at a different level from the rest.

    match a:
    case 1:
    
    case 2:
    
    else:
    
    ^   ^
    |   |
    Code indented to two different levels

This doesn't seem right to me, because all of the cases, including
the else, are on the same footing semantically, just as they are in
an "if" statement.


I feel all those who aren't directly arguing against it are working off 
the assumption that it is needed for match and case to have different 
levels of indentation, but is this really true? Is there anything (bar 
tradition or other subjective arguments) that speaks in favour of this, 
especially in light of the fact that having the same indentation level 
would also solve other problems?


A few emails ago I proposed something like this (and I'm probably only 
the last one to do so amongst many), but if anyone made an argument 
against it I must have missed it:


match:
    a
case 1:
    ...
case 2:
    ...
else:
    ...

(The a on a separate line being arguable.)

I think it would look neater, be reminiscent of the if/elif/else syntax 
we're all familiar with, and solve the issue of where to indent the else.


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


[Python-Dev] Summary of Python tracker Issues

2020-07-10 Thread Python tracker

ACTIVITY SUMMARY (2020-07-03 - 2020-07-10)
Python tracker at https://bugs.python.org/

To view or respond to any of the issues listed below, click on the issue.
Do NOT respond to this message.

Issues counts and deltas:
  open7530 (+10)
  closed 45482 (+58)
  total  53012 (+68)

Open issues with patches: 3058 


Issues opened (41)
==

#39542: Cleanup object.h header
https://bugs.python.org/issue39542  reopened by rhettinger

#41194: Python 3.9.0b3 crash on compile() in PyAST_Check() when the _a
https://bugs.python.org/issue41194  reopened by arcivanov

#41203: Replace references to OS X in documentation with macOS
https://bugs.python.org/issue41203  opened by pxeger

#41205: Documentation Decimal power 0 to the 0 is Nan (versus 0 to the
https://bugs.python.org/issue41205  opened by JD-Veiga

#41209: Scripts Folder is Empty
https://bugs.python.org/issue41209  opened by Jamesss04

#41210: LZMADecompressor.decompress(FORMAT_RAW) truncate output when i
https://bugs.python.org/issue41210  opened by miurahr

#41212: Emoji Unicode failing in standard release of Python 3.8.3 / tk
https://bugs.python.org/issue41212  opened by Ben Griffin

#41214: -O0: Segmentation fault in _PyArg_UnpackStack
https://bugs.python.org/issue41214  opened by Vincent LE GARREC

#41217: Obsolete note for default asyncio event loop on Windows
https://bugs.python.org/issue41217  opened by waszil

#41219: Mimetypes doesn't support audio/webm
https://bugs.python.org/issue41219  opened by cere blanco

#41220: add optional make_key argument to lru_cache
https://bugs.python.org/issue41220  opened by Itayazolay

#41221: io.TextIOWrapper ignores silently partial write if buffer is u
https://bugs.python.org/issue41221  opened by mjacob

#41222: Undocumented behaviour change of POpen.stdout.readine with buf
https://bugs.python.org/issue41222  opened by yann

#41223: `object`-backed `memoryview`'s `tolist` errors
https://bugs.python.org/issue41223  opened by jakirkham

#41226: Supporting `strides` in `memoryview.cast`
https://bugs.python.org/issue41226  opened by jakirkham

#41228: Fix the typo in the description of calendar.monthcalendar(year
https://bugs.python.org/issue41228  opened by ndini

#41229: Asynchronous generator memory leak
https://bugs.python.org/issue41229  opened by zkonge

#41231: Type annotations lost when using wraps by default
https://bugs.python.org/issue41231  opened by David Caro

#41232: Python `functools.wraps` doesn't deal with defaults correctly
https://bugs.python.org/issue41232  opened by Thor Whalen2

#41233: Missing links to errnos on Built-in Exceptions page
https://bugs.python.org/issue41233  opened by yyyan

#41234: Remove symbol.sym_name
https://bugs.python.org/issue41234  opened by nanjekyejoannah

#41236: "about" button in MacOS caused an error
https://bugs.python.org/issue41236  opened by Baozhen Chen

#41238: Python 3 shelve.DbfilenameShelf is generating 164 times larger
https://bugs.python.org/issue41238  opened by Paweł Miech

#41241: Unnecessary Type casting in 'if condition'
https://bugs.python.org/issue41241  opened by ys19991

#41245: cmath module documentation is misleading on branch cuts
https://bugs.python.org/issue41245  opened by mark.dickinson

#41246: IOCP Proactor same socket overlapped callbacks
https://bugs.python.org/issue41246  opened by tontinton

#41248: Python manual forced in maximized window
https://bugs.python.org/issue41248  opened by Mischiew Rithe

#41249: TypedDict inheritance doesn't work with get_type_hints and pos
https://bugs.python.org/issue41249  opened by keithblaha

#41253: unittest -h shows a flag -s but it doesn't work
https://bugs.python.org/issue41253  opened by Faris Chugthai

#41254: Add to/from string methods to datetime.timedelta
https://bugs.python.org/issue41254  opened by tebeka

#41255: Argparse.parse_args exits on unrecognized option with exit_on_
https://bugs.python.org/issue41255  opened by mhughes

#41256: activate script created by venv is not smart enough
https://bugs.python.org/issue41256  opened by kunaltyagi

#41257: mimetypes.guess_extension('video/x-matroska') return wrong val
https://bugs.python.org/issue41257  opened by Saber Hayati

#41259: Find adverbs is not correct on the documentation
https://bugs.python.org/issue41259  opened by Rim Chatti

#41260: datetime: strftime method takes different keyword argument: fm
https://bugs.python.org/issue41260  opened by Anthony Sottile

#41261: 3.9-dev SEGV in object_recursive_isinstance in ast.literal_eva
https://bugs.python.org/issue41261  opened by arcivanov

#41262: Convert memoryview to Argument Clinic
https://bugs.python.org/issue41262  opened by serhiy.storchaka

#41265: lzma/bz2 module: inefficient buffer growth algorithm
https://bugs.python.org/issue41265  opened by malin

#41266: Wrong hint when class methods and builtins named same
https://bugs.python.org/issue41266  opened by wyz23x2

#41268: 3.9-dev regression? TypeError: exec_module() missing 1 require

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

2020-07-10 Thread Guido van Rossum
On Fri, Jul 10, 2020 at 9:54 AM Michael Lee 
wrote:

> One small question about this part of the PEP:
>
> > For the most commonly-matched built-in types (bool, bytearray, bytes,
> dict, float, frozenset, int, list, set, str, and tuple), a single
> positional sub-pattern is allowed to be passed to the call. Rather than
> being matched against any particular attribute on the subject, it is
> instead matched against the subject itself.
>
> Correct me if I'm wrong, but I don't think the PEP currently gives us a
> way of enabling this behavior for classes not on this list. If so, would it
> be worth adding a way?
>
> It would help remove a special case and could come in handy when doing
> things like creating my own custom data structures, for example. After all,
> if `case dict(x)` makes x match the entire dict, it would be nice if I
> could make `case MyCustomMapping(x)` behave in the same way to keep the
> usage consistent.
>
> We could maybe let classes opt-in to this behavior if they define 
> `__match_args__
> = None`? Not sure if adding the extra "is None" check when doing the
> match will introduce too much overhead though.
>
> -- Michael
>

Hi MIchael,

There is a way to do this. A class could do this:
```
class C:
__match_args__ = ["__self__"]

@property
def __self__(self):
return self
```
(You can use any name for `__self__`.)

I realize this isn't particularly pretty, but we feel it's better not to
add a custom `__match__` protocol at this time: The design space for that
is itself quite large, and we realized that almost all "easy" applications
could be had without it, while the "complicated" applications were all
trying to get the `__match__` protocol to do different things.

Also, beware that if your class does this, it is stuck with this form -- if
you replace `["__self__"]` with some other set of arguments, user code that
is matching against your class will presumably break.

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


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

2020-07-10 Thread Michael Lee
One small question about this part of the PEP:

> For the most commonly-matched built-in types (bool, bytearray, bytes, dict,
float, frozenset, int, list, set, str, and tuple), a single positional
sub-pattern is allowed to be passed to the call. Rather than being matched
against any particular attribute on the subject, it is instead matched
against the subject itself.

Correct me if I'm wrong, but I don't think the PEP currently gives us a way
of enabling this behavior for classes not on this list. If so, would it be
worth adding a way?

It would help remove a special case and could come in handy when doing
things like creating my own custom data structures, for example. After all,
if `case dict(x)` makes x match the entire dict, it would be nice if I
could make `case MyCustomMapping(x)` behave in the same way to keep the
usage consistent.

We could maybe let classes opt-in to this behavior if they define
`__match_args__
= None`? Not sure if adding the extra "is None" check when doing the match
will introduce too much overhead though.

-- Michael


On Wed, Jul 8, 2020 at 8:06 AM Guido van Rossum  wrote:

> Today I’m happy (and a little trepidatious) to announce the next
> version of PEP 622, Pattern Matching. As authors we welcome Daniel F
> Moisset in our midst. Daniel wrote a lot of the new text in this
> version, which introduces the subject matter much more gently than the
> first version did. He also convinced us to drop the `__match__`
> protocol for now: the proposal stands quite well without that kind of
> extensibility, and postponing it will allow us to design it at a later
> time when we have more experience with how `match` is being used.
>
> That said, the new version does not differ dramatically in what we
> propose. Apart from dropping `__match__` we’re dropping the leading
> dot to mark named constants, without a replacement, and everything
> else looks like we’re digging in our heels. Why is that? Given the
> firestorm of feedback we received and the numerous proposals (still
> coming) for alternative syntax, it seems a bad tactic not to give up
> something more substantial in order to get this proposal passed. Let
> me explain.
>
> Language design is not like politics. It’s not like mathematics
> either, but I don’t think this situation is at all similar to
> negotiating a higher minimum wage in exchange for a lower pension,
> where you can definitely argue about exactly how much lower/higher
> you’re willing to go. So I don’t think it’s right to propose making
> the feature a little bit uglier just to get it accepted.
>
> Frankly, 90% of the issue is about what among the authors we’ve dubbed
> the “load/store” problem (although Tobias never tires to explain that
> the “load” part is really “load-and-compare”). There’s a considerable
> section devoted to this topic in the PEP, but I’d like to give it
> another try here.
>
> In case you’ve been avoiding python-dev lately, the problem is
> this. Pattern matching lets you capture values from the subject,
> similar to sequence unpacking, so that you can write for example
> ```
> x = range(4)
> match x:
> case (a, b, *rest):
> print(f"first={a}, second={b}, rest={rest}")  # 0, 1, [2, 3]
> ```
> Here the `case` line captures the contents of the subject `x` in three
> variables named `a`, `b` and `rest`. This is easy to understand by
> pretending that a pattern (i.e., what follows `case`) is like the LHS
> of an assignment.
>
> However, in order to make pattern matching more useful and versatile,
> the pattern matching syntax also allows using literals instead of
> capture variables. This is really handy when you want to distinguish
> different cases based on some value, for example
> ```
> match t:
> case ("rect", real, imag):
> return complex(real, imag)
> case ("polar", r, phi):
> return complex(r * cos(phi), r * sin(phi))
> ```
> You might not even notice anything funny here if I didn’t point out
> that `"rect"` and `"polar"` are literals -- it’s really quite
> natural for patterns to support this once you think about it.
>
> The problem that everybody’s been concerned about is that Python
> programmers, like C programmers before them, aren’t too keen to have
> literals like this all over their code, and would rather give names to
> the literals, for example
> ```
> USE_POLAR = "polar"
> USE_RECT = "rect"
> ```
> Now we would like to be able to replace those literals with the
> corresponding names throughout our code and have everything work like
> before:
> ```
> match t:
> case (USE_RECT, real, imag):
> return complex(real, imag)
> case (USE_POLAR, r, phi):
> return complex(r * cos(phi), r * sin(phi))
> ```
> Alas, the compiler doesn’t know that we want `USE_RECT` to be a
> constant value to be matched while we intend `real` and `imag` to be
> variables to be given the corresponding values captured from the
> 

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

2020-07-10 Thread Jim Baker
On Fri, Jul 10, 2020, 9:16 AM Eric Nieuwland 
wrote:

>
> On 10 Jul 2020, at 01:51, Jim Baker  wrote:
>
> ...
> Explicit namespacing (if a constant) or using a guard (if a variable)
> seems to be the right solution, as Ethan demonstrated earlier. No need for
> . or ^ or  \ or ... to disambiguate. Also it seems to me that structural
> pattern matching will build on two common usages of namespaces for
> constants:
>
> 1. Constants used from other modules are almost always used in the module
> namespace. Eg, socket.AF_UNIX or signal.SIGTERM.
> 2. New code often tends to use constants defined within an Enum namespace.
> Hopefully we will see more of this convention in usage.
>
> (Very much an aside: Interestingly with the socket module we see both used
> - it defines its constants with IntEnum and exports them traditionally. The
> namespace specifics it uses with IntEnum._convert_ to make this happen  --
> strictly speaking EnumMeta._convert, not documented, and a bit hard to
> follow -- might be possibly debatable, but it works out quite well in
> practice in providing backwards compatibility while continuing to work with
> a C source of these constants.)
>
>
>> This would also mean
>> case Point(x=\x, y=\y):
>> should be used to obtain x and y from the Point instance.
>>
>
> This approach makes deeper nesting of the structure much more cumbersome,
> I think.
>
> How to match Polygon(Point(x0,y0), Point(x1, y1), Point(x2, y2)) based on
> its structure?
> And Polygon(Point(x0,y0), p1, Point(x2, y2))?
>
>
 I'm just trying to describe what v2 of the PEP is trying to do and how it
then corresponds to a reasonable usage model. Sorry for any confusion.

So in your scenario above, Polygon and Point are used as class patterns (
https://www.python.org/dev/peps/pep-0622/#class-patterns). Consequently
they are treated accordingly and have that nice structural pattern matching
quality!

Earlier I was discussing constant patterns (
https://www.python.org/dev/peps/pep-0622/#constant-value-patterns), which
require they be namespaced in some way (a qualified name as it is described
in the PEP).

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


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

2020-07-10 Thread Eric Nieuwland

> On 10 Jul 2020, at 01:51, Jim Baker  wrote:
> 
> 
> On Thu, Jul 9, 2020 at 1:42 PM Eric Nieuwland  > wrote:
> Much of the discussion seems to focus on how to distinguish between a 
> variable as a provider of a value and a variable as receiver of a matched 
> value.
> 
> In normal Python syntax a variable in an expression provides a value, please 
> let’s keep that unchanged.
> 
> For patterns, these are no different than parameters for a function (either a 
> lambda expression or with `def`); or target assignments in unpacking 
> assignments. So just like I wouldn't wonder where `a` and `b` materialized in 
> the parameters for the function definition below
> 
> def sum2(a, b):
>   return a + b 
> 
> I think it will be straightforward to understand this in the context of a 
> `case` using a capture pattern:
> 
> match x:
>   case (a, b): 
>  return a + b
>...
> 
> (This commonality between cases and function definitions is further used in 
> Scala for example, but I don't see that approach for defining an idea of 
> partial functions -- not like functools.partial functions! -- as being that 
> useful in Python.)
> 
> 
> So it seems to me we should explicitly mark a variable to receive a matched 
> value.
> I have seen ‘?’ suggested as a prefix to do this, ‘\’ would also do fine.
> 
> This would solve the single variable issue, too:
> case foo:
> matches the value of ‘foo’, while
> case \foo:
> matches anything and stores it in ‘foo’.
> 
> 
> Explicit namespacing (if a constant) or using a guard (if a variable) seems 
> to be the right solution, as Ethan demonstrated earlier. No need for . or ^ 
> or  \ or ... to disambiguate. Also it seems to me that structural pattern 
> matching will build on two common usages of namespaces for constants:
> 
> 1. Constants used from other modules are almost always used in the module 
> namespace. Eg, socket.AF_UNIX or signal.SIGTERM.
> 2. New code often tends to use constants defined within an Enum namespace. 
> Hopefully we will see more of this convention in usage.
> 
> (Very much an aside: Interestingly with the socket module we see both used - 
> it defines its constants with IntEnum and exports them traditionally. The 
> namespace specifics it uses with IntEnum._convert_ to make this happen  -- 
> strictly speaking EnumMeta._convert, not documented, and a bit hard to follow 
> -- might be possibly debatable, but it works out quite well in practice in 
> providing backwards compatibility while continuing to work with a C source of 
> these constants.)
>  
> This would also mean
> case Point(x=\x, y=\y):
> should be used to obtain x and y from the Point instance.

This approach makes deeper nesting of the structure much more cumbersome, I 
think.

How to match Polygon(Point(x0,y0), Point(x1, y1), Point(x2, y2)) based on its 
structure?
And Polygon(Point(x0,y0), p1, Point(x2, y2))?

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


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

2020-07-10 Thread Eric Nieuwland

> On 10 Jul 2020, Stefano Borini  wrote:
> 
> Just my 2 cents, I find it kind of annoying that the whole structure
> requires two levels of indentation to actually reach the operational
> code.
> This would be a first in python.
> 
> I would prefer an option akin to if elif elif else where each block is
> only one level deep.


It very much depends on how you read it.

To me the proposed structure is like

with  as :
if   :
…
elif   :
…

and thus not really different

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


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

2020-07-10 Thread Paul Moore
On Fri, 10 Jul 2020 at 12:08, Greg Ewing  wrote:
>
> A thought about the indentation level of a speculated "else" clause...
>
> Some people have argued that "else" should be at the outer level,
> because that's the way it is in all the existing compound statements.
>
> However, in those statements, all the actual code belonging to the
> statement is indented to the same level:
>
>  if a:
>  
>  elif b:
>  
>  else:
>  
>
>  ^
>  |
>  Code all indented to this level
>
> But if we were to indent "else" to the same level as "match",
> the code under it would be at a different level from the rest.
>
>  match a:
>  case 1:
>  
>  case 2:
>  
>  else:
>  
>  ^   ^
>  |   |
>  Code indented to two different levels
>
> This doesn't seem right to me, because all of the cases, including
> the else, are on the same footing semantically, just as they are in
> an "if" statement.

That's a good point - and sufficiently compelling that (if "align else
with match" ends up being the syntax) I'd always use "case _" rather
than else.

Equally, of course, it means that aligning else with match gives users
a choice of which indentation they prefer:

* Align with cases - use "case _"
* Align with match - use "else"

I've pretty much convinced myself that whatever happens, I'll ignore
else and just use "case _" everywhere (and mandate it in projects I
work on, where I have control over style).

One thought - what will tools like black do in the "case _ vs else"
debate? I can foresee some amusing flamewars if linters and formatters
end up preferring one form over the other...

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


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

2020-07-10 Thread Greg Ewing

A thought about the indentation level of a speculated "else" clause...

Some people have argued that "else" should be at the outer level,
because that's the way it is in all the existing compound statements.

However, in those statements, all the actual code belonging to the
statement is indented to the same level:

if a:

elif b:

else:


^
|
Code all indented to this level

But if we were to indent "else" to the same level as "match",
the code under it would be at a different level from the rest.

match a:
case 1:

case 2:

else:

^   ^
|   |
Code indented to two different levels

This doesn't seem right to me, because all of the cases, including
the else, are on the same footing semantically, just as they are in
an "if" statement.

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


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

2020-07-10 Thread Gustavo Carneiro
On Fri, 10 Jul 2020 at 10:33, Glenn Linderman  wrote:

> On 7/10/2020 1:21 AM, Stefano Borini wrote:
> > Just my 2 cents, I find it kind of annoying that the whole structure
> > requires two levels of indentation to actually reach the operational
> > code.
> > This would be a first in python.
> >
> > I would prefer an option akin to if elif elif else where each block is
> > only one level deep.
> Me too.
>
> That would also sidestep the dilemma of whether else: (if implemented)
> should be indented like case: or like match: because they would be the
> same.
>
> match:
>  t
> case ("rect", real, imag):
>  return complex(real, imag)
> case ("polar", r, phi):
>  return complex( r* cos(phi), r*sin(phi)
> else:
>  return None
>
> but it does make the match: block not a statement group, which was
> disturbing to some.
>
> On the other hand, this has a correspondence to:
>
> try:
>   throw expression
> except (type of expression) as exc1:
>   blah blah1
> except (another type) as exc2:
>  blah blah2
> else:
>  blah blah3
>

The problem of the try...except structure, with less indentation, is that,
yes, it is OK for exceptions because normally you have 2 or 3 `except XXX`
clauses, therefore it is usually easy to follow, if the number of vertical
lines in the entire block of try-catch is low enough.

But I have had cases with catching many exception types, each with its own
block of 4 or 5 lines, adding up to a block of try-excepts that doesn't
even fit in a single window of my editor.  In that case, I always have
wished for except clauses to be extra indented, to more easily distinguish
where the try..except block ends.

Therefore, I posit that the style of try...except indentation only works
where the number of cases is small.

But for the case of pattern matching, I expect the number of cases to be
matched to be a lot higher than exception handling cases.  Having cases to
be matched be indented is, IMHO, a nice visual cue to help the reader
understand where the pattern matching block ends.


> In fact, one _could_ wrap this whole feature into the try: syntax... the
> match statement would be tried, and the cases would be special types of
> exception handlers:
>
> try:
>  match expression
> case ("rect", real, imag):
>  return complex(real, imag)
> case ("polar", r, phi):
>  return complex( r* cos(phi), r*sin(phi)
> else:
>  return None
>
> If the expression could fail to be calculated, one could have a mix of
> except clauses also to catch those, rather than needing to wrap the
> whole match expression in a separate try to handle that case [making the
> nesting even deeper :( ]
>
> There might even be a use for using case clauses to extend "normal"
> exception handling, where the exception object could be tested for its
> content as well as its class to have different handling.
>
> try:
>  raise Exception("msg", 35, things)
> case Exception( x, "widgets"):
>  blah blah 1
> case Exception( x, "characters"):
>  blah blah 2
> else:
>  blah blah 3
>
> In this not-fully-thought-through scenario, maybe the keyword match
> isn't even needed: "raise expression" could do the job, or they could be
> aliases to signify intent.
>
> In other words, a match expression would always "fail". The only
> mismatch here is that it points out the difference between try-else and
> match-else: try-else is executed if there is no failure, but if match
> always fails, else would never be appropriate, and case _: would be.
>
> In any case, it does seem there is a strong correlation between match
> processing and try processing, that I didn't see during other
> discussions of the possible structural similarities. "match 3 / 0:"
> would clearly need to be wrapped in a try:
>
> try:
>  match x / y:
>   case 43:
> print("wow, it is 43")
>   case 22:
> print("22 seemed less likely than 43 for some reason")
>  case _:
>print("You get what you get")
> except ZeroDivisionError as exc:
>  print(f"But sometimes you get an exception {exc}")
>
> or:
>
> try:
>  raise x / y
> case 43:
>  print("wow, it is 43")
> case 22:
>  print("22 seemed less likely than 43 for some reason")
> case exc := ZeroDivisionError:
>  print(f"But sometimes you get an exception: {exc}")
> case _:
>  print("You get what you get")
> ___
> 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/GDP2KKB3SUWQZRSNTR5N36LXZ6HDS2QL/
> Code of Conduct: http://python.org/psf/codeofconduct/
>


-- 
Gustavo J. A. M. Carneiro
Gambit Research
"The universe is always one step beyond logic." -- Frank Herbert
___
Python-Dev mailing 

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

2020-07-10 Thread robin
If we are still not certain about the exact language to describe match then I 
would ask if the 'case' token is really required. It seems that I would prefer

match expr:
pattern0:
block0
pattern1:
block1
   .
else:
blockdefault

where the else:  clause is optional.

Also for me the unusual case is the assignment to names in the pattern and I 
would prefer that that be marked in some way; I didn't like .name, but ?name 
seems OK (or perhaps => name). Also the restriction that assigned vars should 
only occur once in a pattern seems wrong.  I would regard it as an additional 
constraint on the match, but I do admit I don't fully understand what's allowed 
in patterns.

Please disregard if the above is totally stupid.
___
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/5SJY2HAT2CHG2BKYV4IZDZVM2BZILXTT/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-07-10 Thread Glenn Linderman

On 7/10/2020 1:21 AM, Stefano Borini wrote:

Just my 2 cents, I find it kind of annoying that the whole structure
requires two levels of indentation to actually reach the operational
code.
This would be a first in python.

I would prefer an option akin to if elif elif else where each block is
only one level deep.

Me too.

That would also sidestep the dilemma of whether else: (if implemented) 
should be indented like case: or like match: because they would be the same.


match:
    t
case ("rect", real, imag):
    return complex(real, imag)
case ("polar", r, phi):
    return complex( r* cos(phi), r*sin(phi)
else:
    return None

but it does make the match: block not a statement group, which was 
disturbing to some.


On the other hand, this has a correspondence to:

try:
 throw expression
except (type of expression) as exc1:
 blah blah1
except (another type) as exc2:
    blah blah2
else:
    blah blah3

In fact, one _could_ wrap this whole feature into the try: syntax... the 
match statement would be tried, and the cases would be special types of 
exception handlers:


try:
    match expression
case ("rect", real, imag):
    return complex(real, imag)
case ("polar", r, phi):
    return complex( r* cos(phi), r*sin(phi)
else:
    return None

If the expression could fail to be calculated, one could have a mix of 
except clauses also to catch those, rather than needing to wrap the 
whole match expression in a separate try to handle that case [making the 
nesting even deeper :( ]


There might even be a use for using case clauses to extend "normal" 
exception handling, where the exception object could be tested for its 
content as well as its class to have different handling.


try:
    raise Exception("msg", 35, things)
case Exception( x, "widgets"):
    blah blah 1
case Exception( x, "characters"):
    blah blah 2
else:
    blah blah 3

In this not-fully-thought-through scenario, maybe the keyword match 
isn't even needed: "raise expression" could do the job, or they could be 
aliases to signify intent.


In other words, a match expression would always "fail". The only 
mismatch here is that it points out the difference between try-else and 
match-else: try-else is executed if there is no failure, but if match 
always fails, else would never be appropriate, and case _: would be.


In any case, it does seem there is a strong correlation between match 
processing and try processing, that I didn't see during other 
discussions of the possible structural similarities. "match 3 / 0:" 
would clearly need to be wrapped in a try:


try:
    match x / y:
 case 43:
   print("wow, it is 43")
 case 22:
   print("22 seemed less likely than 43 for some reason")
    case _:
  print("You get what you get")
except ZeroDivisionError as exc:
    print(f"But sometimes you get an exception {exc}")

or:

try:
    raise x / y
case 43:
    print("wow, it is 43")
case 22:
    print("22 seemed less likely than 43 for some reason")
case exc := ZeroDivisionError:
    print(f"But sometimes you get an exception: {exc}")
case _:
    print("You get what you get")
___
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/GDP2KKB3SUWQZRSNTR5N36LXZ6HDS2QL/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-07-10 Thread Stefano Borini
Just my 2 cents, I find it kind of annoying that the whole structure
requires two levels of indentation to actually reach the operational
code.
This would be a first in python.

I would prefer an option akin to if elif elif else where each block is
only one level deep.


On Wed, 8 Jul 2020 at 16:10, Guido van Rossum  wrote:
>
> Today I’m happy (and a little trepidatious) to announce the next
> version of PEP 622, Pattern Matching. As authors we welcome Daniel F
> Moisset in our midst. Daniel wrote a lot of the new text in this
> version, which introduces the subject matter much more gently than the
> first version did. He also convinced us to drop the `__match__`
> protocol for now: the proposal stands quite well without that kind of
> extensibility, and postponing it will allow us to design it at a later
> time when we have more experience with how `match` is being used.
>
> That said, the new version does not differ dramatically in what we
> propose. Apart from dropping `__match__` we’re dropping the leading
> dot to mark named constants, without a replacement, and everything
> else looks like we’re digging in our heels. Why is that? Given the
> firestorm of feedback we received and the numerous proposals (still
> coming) for alternative syntax, it seems a bad tactic not to give up
> something more substantial in order to get this proposal passed. Let
> me explain.
>
> Language design is not like politics. It’s not like mathematics
> either, but I don’t think this situation is at all similar to
> negotiating a higher minimum wage in exchange for a lower pension,
> where you can definitely argue about exactly how much lower/higher
> you’re willing to go. So I don’t think it’s right to propose making
> the feature a little bit uglier just to get it accepted.
>
> Frankly, 90% of the issue is about what among the authors we’ve dubbed
> the “load/store” problem (although Tobias never tires to explain that
> the “load” part is really “load-and-compare”). There’s a considerable
> section devoted to this topic in the PEP, but I’d like to give it
> another try here.
>
> In case you’ve been avoiding python-dev lately, the problem is
> this. Pattern matching lets you capture values from the subject,
> similar to sequence unpacking, so that you can write for example
> ```
> x = range(4)
> match x:
> case (a, b, *rest):
> print(f"first={a}, second={b}, rest={rest}")  # 0, 1, [2, 3]
> ```
> Here the `case` line captures the contents of the subject `x` in three
> variables named `a`, `b` and `rest`. This is easy to understand by
> pretending that a pattern (i.e., what follows `case`) is like the LHS
> of an assignment.
>
> However, in order to make pattern matching more useful and versatile,
> the pattern matching syntax also allows using literals instead of
> capture variables. This is really handy when you want to distinguish
> different cases based on some value, for example
> ```
> match t:
> case ("rect", real, imag):
> return complex(real, imag)
> case ("polar", r, phi):
> return complex(r * cos(phi), r * sin(phi))
> ```
> You might not even notice anything funny here if I didn’t point out
> that `"rect"` and `"polar"` are literals -- it’s really quite
> natural for patterns to support this once you think about it.
>
> The problem that everybody’s been concerned about is that Python
> programmers, like C programmers before them, aren’t too keen to have
> literals like this all over their code, and would rather give names to
> the literals, for example
> ```
> USE_POLAR = "polar"
> USE_RECT = "rect"
> ```
> Now we would like to be able to replace those literals with the
> corresponding names throughout our code and have everything work like
> before:
> ```
> match t:
> case (USE_RECT, real, imag):
> return complex(real, imag)
> case (USE_POLAR, r, phi):
> return complex(r * cos(phi), r * sin(phi))
> ```
> Alas, the compiler doesn’t know that we want `USE_RECT` to be a
> constant value to be matched while we intend `real` and `imag` to be
> variables to be given the corresponding values captured from the
> subject. So various clever ways have been proposed to distinguish the
> two cases.
>
> This discussion is not new to the authors: before we ever published
> the first version of the PEP we vigorously debated this (it is Issue 1
> in our tracker!), and other languages before us have also had to come
> to grips with it. Even many statically compiled languages! The reason
> is that for reasons of usability it’s usually deemed important that
> their equivalent of `case` auto-declare the captured variables, and
> variable declarations may hide (override) like-named variables in
> outer scopes.
>
> Scala, for example, uses several different rules: first, capture
> variable names must start with a lowercase letter (so it would
> handle the above example as intended); next, capture variables
>