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

2020-06-24 Thread Greg Ewing

On 25/06/20 6:36 am, Brandt Bucher wrote:

Another option I've considered is using the `keys` method, since most non-dict 
mappings would get this called anyways for patterns with `**rest`.

All the more reason why we should allow the implementation some flexibility. ;)


My concern was only that it might be using some private feature of
collections.defaultdict to get the specified behaviour. But if it's
only using the standard mapping protocol, I don't think it matters
exactly how it's using it.

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


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

2020-06-24 Thread Emily Bowman
On Wed, Jun 24, 2020 at 3:15 PM Ethan Furman  wrote:

> > I too thought "why not else:?" at first. But "case _:" covers it in
> > the one obvious way after grasping how general wildcard matches are.
>
> "case _:" is easy to miss -- I missed it several times reading through the
> PEP.
>
> > Introducing "else:" too would be adding a wart (redundancy) just to
> > stop shallow-first-impression whining.
>
> Huh.  I would consider "case _:" to be the wart, especially since "case
> default:" or "case anything:" or "case i_dont_care:" all do basically the
> same thing (although they bind to the given name, while _ does not bind to
> anything, but of what practical importance is that?) .
>

There's always making everyone equally annoyed, and allowing 'case else:'
(not a very serious suggestion, though it does have a certain sort of
symmetry).
___
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/5FEGF436IVEMMDPGMPTPDWEW2VDFTU7A/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-06-24 Thread Greg Ewing

On 25/06/20 3:31 am, Taine Zhao wrote:

https://thautwarm.github.io/Site-32/Design/PEP622-1.html


In your AND pattern example, you seem to envisage there being a Urlopen
class whose __match__ method has the side effect of opening the URL.

This makes it much more than just a pattern to be matched, as it's
also doing some of the work of your program. I would say this goes
against the spirit of what the PEP proposes, which is that patterns
should just be passive declarations of things to look for and should
not have side effects.

That's not to say there are no uses for deconstructing the same
object more than one way, but your case would be more persuasive if
you could come up with a side-effect-free example.

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


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

2020-06-24 Thread Barry Warsaw
On Jun 23, 2020, at 16:26, Guido van Rossum  wrote:
> 
> (I'm replying to several messages in one reply. But there is too much to 
> respond to so this is merely the first batch.)

I’m really glad to know that the PEP 622 team is deliberating internally about 
all the suggestions and comments made on this thread.  Thank you, and I look 
forward to the updated PEP.

> On Tue, Jun 23, 2020 at 12:07 PM Barry Warsaw  wrote:
> Couldn’t you adopt a flat indentation scheme with the minor change of moving 
> the expression into a `match:` clause?  E.g.
> 
> match:
> expression
> case a:
>  foo()
> case b:
> bar()
> else:
> baz()
> 
> I didn’t see that in the rejected alternatives.

I’ll just answer the one question Guido asked (Apple Mail didn’t seem to quote 
it properly):

> We discussed it, but ultimately rejected it because the first block would be 
> a novelty in Pythonic syntax: an indented block whose content is a single 
> expression rather than a sequence of statements. Do you think we need to add 
> this to the Rejected Ideas section?

Yes, I think with some short rationale, it will short-circuit this question in 
subsequent discussions.

Cheers,
-Barry



signature.asc
Description: Message signed with OpenPGP
___
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/UMJWAAP2QIUYWYZREK5WIIY6FKC576WA/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-06-24 Thread Greg Ewing

I had another thought about a way to make the bound names explicit.

   # Keyword
   case Point(x -> px, y -> py):

   # Positional
   case Point(-> x, -> y):

   # Sub-pattern, positional
   case Line(Point() -> p1, Point() -> p2):

   # Sub-pattern, keyword
   case Line(start: Point() -> p1, end: Point() -> p2):

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


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

2020-06-24 Thread Ambient Nuance
I don't mean to be rude, but I would like to chip in and back up Taine here.

The 'or' operator:
- Already unambiguously associated with a logical OR, which is effectively what 
takes place in this circumstance. Using a different symbol to have the same 
effect is bound to be confusing to a reasonably large number of people.

The '|' character:
- Saves one character, but I think it would be easier to miss compared to a 
keyword which is easy to highlight in an editor.
- It's existing usages are very context-specific (between two dict objects, 
within a regex expression) - using it here I think would start to bring it into 
the language in a more general way. Because of this, I think a more holistic 
discussion on its place within Python is appropriate before it is reached for 
as a bespoke solution.
___
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/FPYVL42BPC3LMK62WWY7J37AKGMXXDSD/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-06-24 Thread Stephen J. Turnbull
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? ;-)

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] Re: PEP 622: Structural Pattern Matching

2020-06-24 Thread Barry Warsaw
On Jun 23, 2020, at 23:25, Emily Bowman  wrote:

> I wonder if it's time to officially designate _ as a reserved name.

That would break the i18n use case.

Cheers,
-Barry



signature.asc
Description: Message signed with OpenPGP
___
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/NTKJJHZ4OJP2W4SGRSIUDGHIVZ5KRSLT/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-06-24 Thread Tim Peters
[Taine Zhao ]
> "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.
>
> You said "All reuse of symbols carries baggage", I'd say,
>
> All **inconsistent** reuse of symbols carries baggage,  but the
> consistent reuse builds good intuitive sense and shows the good
> taste of designers.

We're not talking about abstract computation here:  this is a specific
feature, and "|" is the _only_ infix operator.  The PEP considered and
rejected "&" and a unary "not", so that's the universe we're left
with.  With only one "operator", it's really hard to "mislead" ;-)

In any case, the model here is far more regular expressions than
Python int arithmetic or set unions.  "|" means essentially the same
thing in the PEP as it does in Python regexps:  tru supatterns one at
a time, left to right.
___
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/LH6WUBPBAEPSOAMSB37ZWA2Z2G7X47AB/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-06-24 Thread Taine Zhao
> 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.

You said "All reuse of symbols carries baggage", I'd say,

All **inconsistent** reuse of symbols carries baggage,  but the consistent 
reuse builds good intuitive sense and shows the good taste of designers.
___
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/LVZPTOGDX6WCWZZV6T7QDL2MLDRFOXDA/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-06-24 Thread MRAB

On 2020-06-24 23:14, Ethan Furman wrote:

On 06/24/2020 01:49 PM, Tim Peters wrote:


I too thought "why not else:?" at first. But "case _:" covers it in
the one obvious way after grasping how general wildcard matches are.


"case _:" is easy to miss -- I missed it several times reading through the PEP.


Introducing "else:" too would be adding a wart (redundancy) just to
stop shallow-first-impression whining.


Huh.  I would consider "case _:" to be the wart, especially since "case default:" or "case 
anything:" or "case i_dont_care:" all do basically the same thing (although they bind to the given name, 
while _ does not bind to anything, but of what practical importance is that?) .[snip]


The point of '_' is that it can be used any number of times in a pattern:

case (_, _):

This is not allowed:

case (x, x):

When a pattern matches, binding occurs, and why bind to a name when you 
don't need/want the value?

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


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

2020-06-24 Thread Guido van Rossum
On Wed, Jun 24, 2020 at 5:30 PM Greg Ewing 
wrote:

> On 24/06/20 11:26 am, Guido van Rossum wrote:
> > A design pattern where a group of record-like classes is
> > combined into a union is popular in other languages that support pattern
> > matching and is known under a name of algebraic data types [2]_ or ADTs.
>
> Whoo, that's confusing! I read "ADT" as "Abstract Data Type" and totally
> missed that you were using it for something different.
>
> I think it would be better to just call them "algebraic types" (which
> is the term I learned) and not use an acronym.
>

You're right, that *is* confusing. We'll fix it.

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


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

2020-06-24 Thread Greg Ewing

On 24/06/20 11:26 am, Guido van Rossum wrote:

A design pattern where a group of record-like classes is
combined into a union is popular in other languages that support pattern
matching and is known under a name of algebraic data types [2]_ or ADTs.


Whoo, that's confusing! I read "ADT" as "Abstract Data Type" and totally
missed that you were using it for something different.

I think it would be better to just call them "algebraic types" (which
is the term I learned) and not use an acronym.

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


[Python-Dev] Re: Intended invariants for signals in CPython

2020-06-24 Thread Yonatan Zunger via Python-Dev
... Reading through more of the code, I realized that I greatly
underestimated the number of interruptible operations.

That said, the meta-question still applies: Are there things which are
generally intended *not* to be interruptible by signals, and if so, is
there some consistent way of indicating this?

On Wed, Jun 24, 2020 at 2:34 PM Yonatan Zunger  wrote:

> Hi everyone,
>
> I'm in the process of writing some code to defer signals during critical
> regions, which has involved a good deal of reading through the CPython
> implementation to understand the behaviors. Something I've found is that
> there appears to be a lot of thoughtfulness about where the signal handlers
> can be triggered, but this thoughtfulness is largely undocumented. I've put
> together a working list of behaviors from staring at the code, but what I'd
> like to figure out is which of these behaviors the devs think of as
> intended to be invariants, versus which are just accidents of how the code
> currently works and might change unpredictably.
>
> And if there are things which are intended to be genuine invariants, would
> it be reasonable to document these formally and make them part of the
> language, not just for inside the CPython codebase?
>
> What appears to be true is this:
>
>- Signal handlers are only invoked in the main thread (documented with
>the signal library)
>- High-level: Signal handlers may be invoked at any instruction
>boundary. External C libraries *may* invoke them as well, but there
>are no general guarantees. (Documented with the signal library)
>- Low-level: Certain functions can be described as "interruptable,"
>and signal handlers may be invoked whenever these functions are called.
>- Signal handlers are thus partially reentrant: a signal handler may
>be interrupted by another signal iff it invokes an interruptable function.
>
> In particular, the thing whose intentionality I'm not sure about is
> whether the notion of an interruptable function or instruction is meant to
> be an actual property of the language and/or of the CPython runtime, or
> whether it's actually intended that only the "high-level" rule above be
> true, and that all signal handlers should be considered to be fully
> reentrant at all times. The comments in sysmodule.c about avoiding
> triggering PyErr_CheckSignals() suggest that there definitely is some
> thinking about this within the CPython code itself.
>
> The reason it would be useful to document this is so that if I'm trying to
> write a fairly generic library that handles signals (like the one I'm doing
> now) I can reason about where I need to be defensive about an instruction
> being interrupted by yet another signal, and maybe avoid calls to certain
> functions which are known to be interruptable, much like I would avoid
> calling malloc() in a C signal handler.
>
> In the current implementation, the interruptable functions and
> instructions are:
>
> Big categories:
>
>- Any function which calls PyErr_SetFromErrno, *if* errno == EINTR.
>(Catalogue needs to be made of these -- it's a much smaller set than the
>set of all calls to PyErr_SetFromErrno)
>- Basically any open, read, or write method of a raw or buffered file
>object.
>- Likewise, any open, read, or write method on a socket.
>- In any interactive console readline, or in input().
>- object.__str__, object.__repr__, and PyObject_Print, and anything
>that falls back to these.
>
> Specific instructions:
>
>-
>- Multiplication, division, or stringification of long integers.
>
> More specific functions:
>
>- In `multiprocessing.shared_memory`, SharedMemory.__init__, .close,
>and .unlink.
>- In `multiprocessing.semaphore`, Semaphore.acquire. (But
>interestingly, *not* threading.Semaphore.acquire)
>- In `signal`, pause, signal, sigwaitinfo, sigtimedwait, pthread_kill,
>and pthread_sigmask.
>- In `fcntl`, fcntl and ioctl.
>- In `traceback`, any of the print methods.
>- In `faulthandler`, dump_traceback
>- In `select`, all of the methods. (select, epoll, etc)
>- In `time`, sleep.
>- In `curses`, whenever you look for key input.
>- In `tkinter`, during the main loop of a Tcl/Tk app.
>- During an SSL handshake.
>
> --
>
> Yonatan Zunger
>
> Distinguished Engineer and Chief Ethics Officer
>
> He / Him
>
> zun...@humu.com
>
> 100 View St, Suite 101
>
> Mountain View, CA 94041
>
> Humu.com   · LinkedIn
>   · Twitter
> 
>


-- 

Yonatan Zunger

Distinguished Engineer and Chief Ethics Officer

He / Him

zun...@humu.com

100 View St, Suite 101

Mountain View, CA 94041

Humu.com   · LinkedIn
  · Twitter

___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe 

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

2020-06-24 Thread Tim Peters
[Ethan Furman ]
> "case _:" is easy to miss -- I missed it several times reading through the 
> PEP.

As I said, I don't care about "shallow first impressions".  I care
about how a thing hangs together _after_ climbing its learning curve -
which in this case is about a nanometer tall ;-)

You're not seriously going to maintain that you're struggling to grasp
the meaning of "case _:" now, right?

> Huh.  I would consider "case _:" to be the wart, especially since "case 
> default:"
> or "case anything:" or "case i_dont_care:" all do basically the same thing 
> (although
> they bind to the given name,

Having climbed the trivial learning curve, only a deliberate wise ass
would code garbage like "case i_dont_care:". I don't care about them
either. The one obvious way to do it has already been made clear to
them. You may as well, e.g., complain that there's nothing to stop a
wise ass from writing "-5+6" where everyone else writes "+1".

> while _ does not bind to anything, but of what practical importance is that?) 
> .

One obvious way to do it is of major practical importance.

> ...
> Besides which, if we use "|" instead of "or" then we can't later allow more
> general expressions.

Good!  The PEP is quite complicated enough already.  But if you want
to pursue this seriously, you're going to have your work cut for you
to explain why "|" is more sacred than "or" with respect to "more
general expressions".  If you don't want to preclude anything, then
you need to invent syntax that has no meaning at all now.

>> ".NAME" grated at first, but extends the idea that dotted names are
>> always constant value patterns to "if and only if". So it has mnemonic
>> value.

> How do you get from "." to "iff" ?

See reply to Glenn. Can you give an example of a dotted name that is
not a constant value pattern? An example of a non-dotted name that is?
If you can't do either (and I cannot)), then that's simply what "if
and only if" means.
___
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/YGTDPCASYUQYCMU5PS2S5YO7DBNDYYWP/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-06-24 Thread Tim Peters
[Tim]
>> ".NAME" grated at first, but extends the idea that dotted names are
>> always constant value patterns to "if and only if". So it has mnemonic
>> value. When context alone can't distinguish whether a name is meant as
>> (in effect) an lvalue or an rvalue, no syntax decorations can prevent
>> coding errors. Names in destructuring constructs are overwhelmingly
>> intended as lvalues, so adding extra cruft to say "no, I meant rvalue"
>> is the pragmatic choice.


[Glenn Linderman ]
> This is just a bunch of words to me, without meaning.
>
> I'd like to understand it.

Did you read the PEP?

> What do you mean by "the idea that dotted names are always constant
> value patterns"?

Under the PEP's "Constant Value Pattern"  section:

Every dotted name in a pattern is looked up using normal Python
name resolution rules, and the value is used for comparison by
equality with the matching expression (same as for literals).

That's what I meant.  "Contains a dot" implies "constant value pattern".

> What do you mean by 'extends (the above) to "if and only if" '?

Because the next sentence from the PEP:

 As a special case to avoid ambiguity with name patterns, simple
 names must be prefixed with a dot to be considered a reference:

completes turning "contains a dot" into a necessary and sufficient
("if and only if") condition for distinguishing a constant value
pattern from a name pattern.  Where "constant value pattern" and "name
pattern" are again used with the PEP's meanings.


> As a result of not understanding the above, I see no mnemonic value.

While I do.  "If I want `xyz` to be interpreted as a constant value
pattern, it needs to contain a dot: `.xyy` should do it.  If I want
`enums.HI` to be interpreted as a constant value, it already contains
a dot, so it will be."

> My understanding of the "." as proposed is that it is optional, except
> in cases where it would be ambiguous... seems like it would be better if
> it were required for one case or the other, so that there would be no
> need to determine whether or not it is ambiguous by the surrounding
> state/code/declarations.

A dot is required, when and only when you want the chunk of syntax to
be interpreted as a constant value pattern.  I said nothing at all
about "_leading_" dots, which appear to be all you have in mind there.
_Some_ dot is mandatory to make it a constant value pattern; a
_leading_ dot may or may not be required.
___
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/YEUQNW5NUAW2OGMRJN22G3JMSIB4PA4J/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-06-24 Thread Brett Cannon
On Tue, Jun 23, 2020 at 5:08 PM Guido van Rossum  wrote:

> [SNIP]
> On Tue, Jun 23, 2020 at 12:11 PM Brett Cannon  wrote:
>
>> I will say that trying to follow
>> https://github.com/python/peps/blob/master/pep-0622.rst#runtime-specification
>> was really hard. Any chance of getting some pseudo-code that shows how a
>> match is performed? Otherwise all of that wording tries so hard to be a
>> spec that I found it hard to follow in my head in how things function.
>>
>
> Sorry about that. This section was subject to heavy editing recently and
> lost clarity. I will try to make it better! Writing it as pseudo code will
> take a little time, but I will give it a try.
>

I leave the decision about pseudocode up to you if you think you can just
find words to clarify that section.


>
>
>> For instance, "When __match_args__ is missing (as is the default) or
>> None, a single positional sub-pattern is allowed to be passed to the call"
>> is really misleading as it seems that a "sub-pattern" in this case is just
>> going to be a constant like `[1, 2, 3]`. Otherwise how does `["<"|">"]` or
>> `[1, 2, *_]` get represented as a "single positional sub-pattern" (if
>> either of those examples is possible)? The use of the term "sub-pattern"
>> feels misleading because while you may consider even constant patterns a
>> "pattern", going that generic feels like any pattern should fit in that
>> definition when in fact it seems to only be an object where a direct
>> equality check is done.
>>
>> It seems the way things work is basically:
>>
>> 1. `__match__(obj)` returns a proxy object to have Python match against;
>> it is passed in the thing that `match` is running against, returning `None`
>> if it know there's no chance a match will work
>> 2. If `__match_args__` is present, then it is used to map positional
>> arguments in the pattern to attributes on the proxy object
>> 3. From there the `match` functionality does a bunch of comparisons
>> against attributes on the proxy object to see if the match works
>>
>> Is that right? That suggests all the work in implementing this for
>> objects is coming up with a way to serialize an object to a proxy that
>> makes pattern matching possible.
>>
>
> Yes, that's right, and the protocol was defined carefully so that the
> author of __match__ doesn't have to do any pattern matching -- all they
> have to do is produce an object that has the right attributes, and the
> interpreter does the rest. Note that it is __match__'s responsibility to
> check isinstance()! This is because __match__ may not want to use
> isinstance() but instead check for the presence of certain attributes --
> IOW, the class pattern supports duck typing! (This was a little easter egg.
> :-)
>

Ah, so that's how you're going to have people simply match against
protocols. :)


>
>
>> One thing I see mentioned in examples but not in the `__match__`
>> definitions is how mappings work. Are you using `__match_args__` to map
>> keys to attributes? Or are you using `__getitem__` and that just isn't
>> directly mentioned? Otherwise the section on how `__match__` is used only
>> mentioned attributes and never talks about keys.
>>
>
> Oh, __match__ is *only* used for class patterns. Mapping patterns are done
> differently. They don't use __getitem__ exactly -- the PEP says
>
> Matched key-value pairs must already be present in the mapping, and not
> created
> on-the-fly by ``__missing__`` or ``__getitem__``.  For example,
> ``collections.defaultdict`` instances will only match patterns with keys
> that
> were already present when the ``match`` block was entered.
>
> You shouldn't try to depend on exactly what methods will be called -- you
> should just faithfully implement the Mapping protocol.
>
>
OK, so `__contains__` then.

-Brett


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


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

2020-06-24 Thread Glenn Linderman

On 6/24/2020 1:49 PM, Tim Peters wrote:

".NAME" grated at first, but extends the idea that dotted names are
always constant value patterns to "if and only if". So it has mnemonic
value. When context alone can't distinguish whether a name is meant as
(in effect) an lvalue or an rvalue, no syntax decorations can prevent
coding errors. Names in destructuring constructs are overwhelmingly
intended as lvalues, so adding extra cruft to say "no, I meant rvalue"
is the pragmatic choice.

This is just a bunch of words to me, without meaning.

I'd like to understand it.

What do you mean by "the idea that dotted names are always constant 
value patterns"?


What do you mean by 'extends (the above) to "if and only if" '?

As a result of not understanding the above, I see no mnemonic value.

My understanding of the "." as proposed is that it is optional, except 
in cases where it would be ambiguous... seems like it would be better if 
it were required for one case or the other, so that there would be no 
need to determine whether or not it is ambiguous by the surrounding 
state/code/declarations.

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


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

2020-06-24 Thread Ethan Furman

On 06/24/2020 01:49 PM, Tim Peters wrote:


I too thought "why not else:?" at first. But "case _:" covers it in
the one obvious way after grasping how general wildcard matches are.


"case _:" is easy to miss -- I missed it several times reading through the PEP.


Introducing "else:" too would be adding a wart (redundancy) just to
stop shallow-first-impression whining.


Huh.  I would consider "case _:" to be the wart, especially since "case default:" or "case 
anything:" or "case i_dont_care:" all do basically the same thing (although they bind to the given name, 
while _ does not bind to anything, but of what practical importance is that?) .


"|" is also a fine way to express alternatives. "case" has its own
sub-language with its own rules, and "|" is widely used to express
alternatives (whether in regexps, formal grammars, ...). Spell it,
e.g., "or", and then I wonder "what does short-circuiting have to do
with it?". All reuse of symbols carries baggage.


Well, the PEP says the alternatives are short-circuiting, so it's okay if you 
notice.  ;-)

Besides which, if we use "|" instead of "or" then we can't later allow more 
general expressions.


".NAME" grated at first, but extends the idea that dotted names are
always constant value patterns to "if and only if". So it has mnemonic
value.


How do you get from "." to "iff" ?

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


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

2020-06-24 Thread Joao S. O. Bueno
On Wed, 24 Jun 2020 at 16:40, 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'
>

I'd like also to see considerations about the issue of an alternative
spelling that would
not resemble a class instantiation, brought first by Antoine Pitrou:
```

case Point with (x, y):
 print(f"Got a point with x={x}, y={y}")
 ```

And somewhere on the other thread, someone pointed
the possibility of all assignments in a case be well
delimited, even with angle parentheses - (yes, that
addresses the "foot gun" again, but it is a step beyond
dot or not dot in instant-readability:

```
case Point with (, ):
 print(f"Got a point with x={x}, y={y}")
```

(AFAIC, the "dot" thing falls in the category of speckles on Tim's monitor)

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


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

2020-06-24 Thread Ambient Nuance
> match get_node() into c:

+1 to scoping name pattern related objects upfront. (mirrors my post, so no 
bias :P)

Using a namespace to group capture variables is a good idea, though new 
attributes are introduced throughout the match block. In my view, this is very 
similar to the use a special character like '$', the difference being that such 
a modifier can be 'named'.

I second your idea of an 'into' keyword to align the match statement with 
others in Python. It was a consideration of mine, but I was likewise wary of 
the first-line verbosity. I think it's worth it for the increased familiarity, 
especially since capture variables are in a sense auxiliary to the match 
statement (so just pop them at the end).

Flattening your capture object into individual variables does this while still 
being explicit from the beginning about what variables can be used for name 
matching:
match get_node() into a, b, c:

As far as the naming of the 'into' keyword, I think yours is a solid candidate. 
Others are sure to present a healthy range of alternatives I'm sure :). My only 
preference would be that the qualification of the match statement is appended, 
rather than done in place like match(a, b, c) get_node():
___
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/C6EP2L66LBJKT5RHDE6OIKG7KWM2NMLV/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Intended invariants for signals in CPython

2020-06-24 Thread Yonatan Zunger via Python-Dev
Hi everyone,

I'm in the process of writing some code to defer signals during critical
regions, which has involved a good deal of reading through the CPython
implementation to understand the behaviors. Something I've found is that
there appears to be a lot of thoughtfulness about where the signal handlers
can be triggered, but this thoughtfulness is largely undocumented. I've put
together a working list of behaviors from staring at the code, but what I'd
like to figure out is which of these behaviors the devs think of as
intended to be invariants, versus which are just accidents of how the code
currently works and might change unpredictably.

And if there are things which are intended to be genuine invariants, would
it be reasonable to document these formally and make them part of the
language, not just for inside the CPython codebase?

What appears to be true is this:

   - Signal handlers are only invoked in the main thread (documented with
   the signal library)
   - High-level: Signal handlers may be invoked at any instruction
   boundary. External C libraries *may* invoke them as well, but there are
   no general guarantees. (Documented with the signal library)
   - Low-level: Certain functions can be described as "interruptable," and
   signal handlers may be invoked whenever these functions are called.
   - Signal handlers are thus partially reentrant: a signal handler may be
   interrupted by another signal iff it invokes an interruptable function.

In particular, the thing whose intentionality I'm not sure about is whether
the notion of an interruptable function or instruction is meant to be an
actual property of the language and/or of the CPython runtime, or whether
it's actually intended that only the "high-level" rule above be true, and
that all signal handlers should be considered to be fully reentrant at all
times. The comments in sysmodule.c about avoiding triggering
PyErr_CheckSignals() suggest that there definitely is some thinking about
this within the CPython code itself.

The reason it would be useful to document this is so that if I'm trying to
write a fairly generic library that handles signals (like the one I'm doing
now) I can reason about where I need to be defensive about an instruction
being interrupted by yet another signal, and maybe avoid calls to certain
functions which are known to be interruptable, much like I would avoid
calling malloc() in a C signal handler.

In the current implementation, the interruptable functions and instructions
are:

Big categories:

   - Any function which calls PyErr_SetFromErrno, *if* errno == EINTR.
   (Catalogue needs to be made of these -- it's a much smaller set than the
   set of all calls to PyErr_SetFromErrno)
   - Basically any open, read, or write method of a raw or buffered file
   object.
   - Likewise, any open, read, or write method on a socket.
   - In any interactive console readline, or in input().
   - object.__str__, object.__repr__, and PyObject_Print, and anything that
   falls back to these.

Specific instructions:

   -
   - Multiplication, division, or stringification of long integers.

More specific functions:

   - In `multiprocessing.shared_memory`, SharedMemory.__init__, .close, and
   .unlink.
   - In `multiprocessing.semaphore`, Semaphore.acquire. (But interestingly,
   *not* threading.Semaphore.acquire)
   - In `signal`, pause, signal, sigwaitinfo, sigtimedwait, pthread_kill,
   and pthread_sigmask.
   - In `fcntl`, fcntl and ioctl.
   - In `traceback`, any of the print methods.
   - In `faulthandler`, dump_traceback
   - In `select`, all of the methods. (select, epoll, etc)
   - In `time`, sleep.
   - In `curses`, whenever you look for key input.
   - In `tkinter`, during the main loop of a Tcl/Tk app.
   - During an SSL handshake.

-- 

Yonatan Zunger

Distinguished Engineer and Chief Ethics Officer

He / Him

zun...@humu.com

100 View St, Suite 101

Mountain View, CA 94041

Humu.com   · LinkedIn
  · Twitter

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


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

2020-06-24 Thread David Mertz
I gave a longer example, but the short version is that I cannot tell from
the Class Pattern or Runtime section how class patterns interact with
properties (i.e. when access changes state).

On Wed, Jun 24, 2020, 3:45 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.)
>
> --
> --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/N7HOQYIAFT7QDCM4MBSZ5723VFRANNQL/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-06-24 Thread Jim F.Hilliard
I'm also not a big fan of the 'else' proposal.

Context matters and in the context of match expressions a case with a
wildcard pattern makes sense, an else, not so much.
___
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/XYF2H2ACRMBEULHGPDHZIGFZFG56DHHH/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-06-24 Thread Tim Peters
You got everything right the first time ;-)  The PEP is an extended
illustration of "although that way may not be obvious at first unless
you're Dutch".

I too thought "why not else:?" at first. But "case _:" covers it in
the one obvious way after grasping how general wildcard matches are.
Introducing "else:" too would be adding a wart (redundancy) just to
stop shallow-first-impression whining.

"|" is also a fine way to express alternatives. "case" has its own
sub-language with its own rules, and "|" is widely used to express
alternatives (whether in regexps, formal grammars, ...). Spell it,
e.g., "or", and then I wonder "what does short-circuiting have to do
with it?". All reuse of symbols carries baggage.

".NAME" grated at first, but extends the idea that dotted names are
always constant value patterns to "if and only if". So it has mnemonic
value. When context alone can't distinguish whether a name is meant as
(in effect) an lvalue or an rvalue, no syntax decorations can prevent
coding errors. Names in destructuring constructs are overwhelmingly
intended as lvalues, so adding extra cruft to say "no, I meant rvalue"
is the pragmatic choice.
___
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/YDEHQRHB5S4O6KP5ROUZGOKSR3H54T34/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-06-24 Thread Luciano Ramalho
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.

Cheers,

Luciano




On Tue, Jun 23, 2020 at 1:04 PM 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):
> 

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

2020-06-24 Thread Ethan Furman

On 06/24/2020 11:08 AM, Guido van Rossum wrote:


Nearly every other language whose pattern matching syntax we've examined uses _ 
as the wildcard.

The authors don't feel very strongly about whether to use `else:` or `case _:`. 
The latter would be possible even if we added an explicit `else` clause, and we 
like TOOWTDI. But it's clear that a lot of people *expect* to see `else`, and 
maybe seeing `case _:` is not the best introduction to wildcards for people who 
haven't seen a match statement before.


It seems to me that TOOWTDI is already violated.  I don't think most people 
will see a significant different between:


case _:

and

case a_name:


As far as alignment, I think "else" should align with "match" -- it more 
strongly signifies that no match was found - at least to me ;) .

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


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

2020-06-24 Thread Jelle Zijlstra
El mar., 23 jun. 2020 a las 9:10, Guido van Rossum ()
escribió:

> 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.
>
> Thanks to Guido and all the others working on this! It's going to be a
great addition to the language.

One piece of bikeshedding: I agree with the previous posters who said that
the ".x" syntax for referring to variables isn't great, and I'd prefer
marking variables that are being assigned to with a special symbol. So
instead of:

y = 3
case Point(x, .y): ...  # x is assigned to, y is looked up

we'd have

y = 3
case Point($x, y): ...  # x is assigned to, y is looked up

The trouble with the current syntax is that if you forget the ".", you
always get a hard-to-detect bug: your pattern unexpectedly matches and "y"
suddenly has a different value. Even if you find the bug, it's hard to find
out where exactly the mistake happened.

But with the proposed "$" syntax, if you forget the "$", you probably will
just immediately get a NameError that will tell you exactly where your bug
is. (Except of course if you happen to already have the name "x" in scope,
but that's hopefully not very common, and it's already what happens if you
typo a local variable name.)
___
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/MN2B6JOEJ2JTCEPL5YSH3SUMOQS6WSOG/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-06-24 Thread Guido van Rossum
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] Re: PEP 622: Structural Pattern Matching

2020-06-24 Thread Guido van Rossum
On Wed, Jun 24, 2020 at 11:47 AM M.-A. Lemburg  wrote:

> Something I know the Perl camp is always very fond of is the
> matching on regexps. Is this possible using the proposal (sorry,
> I don't quite understand the __match__() protocol yet) ?
>

No, that's left for another day. Scala has string matching built into its
pattern matching syntax, but for Python it would be an uphill battle to try
to compete with regular expression syntax.


> The problem I see with "case _" is that it's just too easy to
> miss when looking at the body of "match", even more so, since
> people will not necessarily put it at the end, or add it
> as or'ed add-on to some other case, e.g.
>
> match something:
> case 0 | 1 | 2 | _:
> print("Small number or something else")
> case [] | [_]:
> print("A short sequence")
> case _:
> print("Not sure what this is")
> case str() | bytes():
> print("Something string-like")
>

That's just a bug in the user's code. We can't *stop* users from writing
"case _:" -- note there are even more ways to spell it, e.g. "case x:"
(where x is otherwise unused), or "case object():".


> You could even declare the above stand-alone or or'ed
> use of "_" illegal and force use of "else" instead to push
> for TOOWTDI.
>

I guess we *could* syntactically disallow 0|_, but why bother? I don't
expect anyone is going to write that and then expect the next case to be
reachable. When it comes to catching unreachable code I think we have
bigger fish to fry (e.g. f.close without the ()).

That said, we're on the fence on adding else.

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


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

2020-06-24 Thread Paul Moore
On Wed, 24 Jun 2020 at 19:49, M.-A. Lemburg  wrote:

> match something:
> case 0 | 1 | 2 | _:
> print("Small number or something else")
> case [] | [_]:
> print("A short sequence")
> case _:
> print("Not sure what this is")
> case str() | bytes():
> print("Something string-like")
>

Because the semantics is "first matching clause applies", putting
`case _` anywhere but at the end wouldn't work as expected. The `str()
| bytes()` case above would never match.
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/YZOMXXY5XCADTTXBUMDE2KA6PCVCNEJP/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 620: Hide implementation details from the C API

2020-06-24 Thread Stefan Behnel
Gustavo Carneiro schrieb am 24.06.20 um 19:19:
> On Wed, 24 Jun 2020 at 17:22, Victor Stinner wrote:
>> The question becomes: how to promote the limited C API? Should it
>> become the default, rather than an opt-in option?
> 
> It would be interesting to find out what is the performance impact of using
> limited C API, vs normal API, on some popular extensions.  This is
> something that I wish had been included in PEP 384.

It couldn't because even today it is still fairly difficult to convert
existing code to the limited API. Some code cannot even be migrated at all,
e.g. because the entire buffer protocol is missing from it. Some bugs were
only fixed in Py3.9, time will tell if anything else is missing.

The only major project that I know has been migrated (recently, with a lot
of effort) is the PyQt project. And a GUI toolkit probably doesn't have all
that many performance critical parts that are dominated by the CPython
C-API. (I'm just guessing, it probably has some, somewhere).


> It would be great if the limited API could be the default, as it allows
> building extensions once that work across most python versions.

We are adding a C compile mode for the limited API to Cython. That's also a
lot of effort, and probably won't be finished soon, but once that becomes
any usable, we'd have a whole bunch of real-world extensions that we could
use for benchmarking, many of which were written for speed. We could even
take a regular Python module and compile it in both variants to compare
"pure Python" to "full C-API" to "limited C-API".

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


[Python-Dev] Re: PEP 620: Hide implementation details from the C API

2020-06-24 Thread Stefan Behnel
Victor Stinner schrieb am 24.06.20 um 17:40:
> My practical problem is how to prevent C extensions accessing the
> PyFloatObject.ob_fval member directly.

Do extensions really do that in their code? I mean, there *is* a macro for
doing exactly this thing, which suggests that users should exactly *not* do
it themselves but use the macro. I would simply say that anyone accessing
the structure fields directly instead of using the intended macro is simply
on their own with that choice. If their code breaks, they'll have to fix it
in the way that was intended for the last 23 years (I looked that up).

I don't have any data, but to me, this sounds like a non-issue to start with.


> In my tests, I renamed PyObject
> members. For example, rename PyObject.ob_type to PyObject._ob_type,
> and update Py_TYPE() and Py_SET_TYPE(). If a C function accesses
> directly PyObject.ob_type, a compilation error is issued.

I think the path of
- making macros / (inline) functions available for all use cases
- making them available in a backport header file
- telling people to use those instead of direct struct access

is the right way. If/when we notice in the future that we need to change an
object struct, and macros are available for the use cases that we break (or
can be made available during a suitable deprecation phase), then extension
authors will notice at that point that they will have to switch to the
macros instead of doing whatever breaks for them (or not).


> One option would be to have a different stricter build mode where
> PyFloat_AS_DOUBLE() becomes a function call. Example:
> 
> #ifndef Py_LIMITED_API
> #  ifdef OPAQUE_STRUCTURE
> #define PyFloat_AS_DOUBLE(op) PyFloat_AsDouble(op)
> #  else
> #define PyFloat_AS_DOUBLE(op) (((PyFloatObject *)(op))->ob_fval)
> #  endif
> #endif

I think that's too broad. Why make all structs opaque, when we don't even
know which ones we may want to touch in the future at all? And, who would
really use this mode?


> Or maybe it's time to extend the limited C API: add
> PyFloat_AS_DOUBLE() macro as a function call. Extending the limited C
> API has multiple advantages:
> 
> * It eases the transition of C extensions to the limited C API
> * Py_LIMITED_API already exists, there is no need to add yet another
> build mode or any new macro
> * Most structures are *already* opaque in the limited C API.

We will have to grow it anyway, so why not. We could also add yet another
optional header file that adds everything from the full C-API that we can
somehow map to the limited C-API, as macros or inline functions. In the
worst case, we could still implement a missing function as a lookup and
call through a Python object method, if there's no other way to do it in
the limited C-API.

In the end, this could lead to a "full C-API wrapper", implemented on top
of the limited C-API. Sounds like a good way to port existing code.


> The question becomes: how to promote the limited C API? Should it
> become the default, rather than an opt-in option?

With the above "full wrapper", it could become the default. That would give
authors three choices:

- the full C-API (being tied to a minor release)
- the limited C-API (limited but providing forward compatibility)
- the wrapper (being slower but providing forward+backward compatibility)

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


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

2020-06-24 Thread pylang
Great timing! Last week I was trying to emulate a certain Rust example in
Python.
Rust has a way to implement families of classes without subclassing,
which I think could be a great addition to Python someday.  I'll explain
below.

Here is a Rust example (https://youtu.be/WDkv2cKOxx0?t=3795)
that demonstrates a way to implement classes without subclassing.

# Rust Code
enum Shape {
Circle(f32),
Square(f32),
Rectangle(f32, f32)
}

impl Shape {
fn area(self) -> f32 {
match self {
Shape::Circle(r) => 3.1 * r * r,
Shape::Square(l) => l * l,
Shape::Rectangle(l, w) => l * w
}
}
}

fn main () {
let c = Shape::Circle(3.0);
let s = Shape::Square(3.0);
let r = Shape::Rectangle(3.0, 7.5);
println!("○ {}", c.area());
println!("□ {}", s.area());
println!("▭ {}", r.area());
}

# Output
○ 27.88
□ 9
▭ 22.5

The general idea is:
- declare classes that share a certain type
- extend common methods with a match-case style

That's it.  No sub-classing required.

I wondered if someday, can we do this in Python? This match-case proposal
seems to fit well in this example.

While I know this PEP does not focus on detailed applications,
does anyone believe we can achieve elegant class creation (sans
subclassing) with match-cases?


On Wed, Jun 24, 2020 at 2:04 PM Guido van Rossum  wrote:

> On Tue, Jun 23, 2020 at 11:27 PM Emily Bowman 
> wrote:
> > I wonder if it's time to officially designate _ as a reserved name.
>
> Alas, it's too late for that. The i18n community uses _("message text") to
> mark translatable text. You may want to look into the gettext stdlib module.
>
> --
> --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/P6EKIKFP6MX2N2KVFFCF4XUVVMSJ6Q5B/
> 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/ZUBYRUF4G5CWYQGX5Z3C57K2ZWEHRDWJ/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-06-24 Thread M.-A. Lemburg
On 24.06.2020 20:08, Guido van Rossum wrote:
> On Wed, Jun 24, 2020 at 7:27 AM M.-A. Lemburg  > wrote:
> 
> Wow, so 19 years after PEP 275, we are indeed getting a switch
> statement. Nice :-)
> 
> 
> Indeed. Fortunately there are now some better ideas to steal from other
> languages than C's switch. :-)

Your PEP certainly is a lot more powerful than the good ol' C
switch :-)

Something I know the Perl camp is always very fond of is the
matching on regexps. Is this possible using the proposal (sorry,
I don't quite understand the __match__() protocol yet) ?

> Something which struck me as odd when first scanning through the PEP
> is the default case compared to other Python block statements:
> 
> match something:
>     case 0 | 1 | 2:
>         print("Small number")
>     case [] | [_]:
>         print("A short sequence")
>     case str() | bytes():
>         print("Something string-like")
>     case _:
>         print("Something else")
> 
> rather than what a Pythonista would probably expect:
> 
> match something:
>     case 0 | 1 | 2:
>         print("Small number")
>     case [] | [_]:
>         print("A short sequence")
>     case str() | bytes():
>         print("Something string-like")
>     else:
>         print("Something else")
> 
> Was there a reason for using a special value "_" as match-all value ?
> I couldn't find any explanation for this in the PEP.
> 
> 
> Nearly every other language whose pattern matching syntax we've examined
> uses _ as the wildcard.
> 
> The authors don't feel very strongly about whether to use `else:` or
> `case _:`. The latter would be possible even if we added an explicit
> `else` clause, and we like TOOWTDI. But it's clear that a lot of people
> *expect* to see `else`, and maybe seeing `case _:` is not the best
> introduction to wildcards for people who haven't seen a match statement
> before.
> 
> A wrinkle with `else` is that some of the authors would prefer to see it
> aligned with `match` rather than with the list of cases, but for others
> it feels like a degenerate case and should be aligned with those. (I'm
> in the latter camp.)
> 
> There still is a lively internal discussion going on, and we'll get back
> here when we have a shared opinion.

Great. Thanks for considering it.

I'd make "else" match its use in other statements, which would
mean aligning it with "match", but don't really feel strong about
either way.

The problem I see with "case _" is that it's just too easy to
miss when looking at the body of "match", even more so, since
people will not necessarily put it at the end, or add it
as or'ed add-on to some other case, e.g.

match something:
case 0 | 1 | 2 | _:
print("Small number or something else")
case [] | [_]:
print("A short sequence")
case _:
print("Not sure what this is")
case str() | bytes():
print("Something string-like")

You could even declare the above stand-alone or or'ed
use of "_" illegal and force use of "else" instead to push
for TOOWTDI.

Oh, and thanks for not having continue / break in the switch cases !
Those tend to often cause subtle bugs in C applications (ie. a
missing break).

-- 
Marc-Andre Lemburg
eGenix.com

Professional Python Services directly from the Experts (#1, Jun 24 2020)
>>> Python Projects, Coaching and Support ...https://www.egenix.com/
>>> Python Product Development ...https://consulting.egenix.com/


::: We implement business ideas - efficiently in both time and costs :::

   eGenix.com Software, Skills and Services GmbH  Pastor-Loeh-Str.48
D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg
   Registered at Amtsgericht Duesseldorf: HRB 46611
   https://www.egenix.com/company/contact/
 https://www.malemburg.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/UABXTHJR6O3PB4ARF5QDLBQYXZ2PA3QL/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-06-24 Thread Brandt Bucher
Guido van Rossum wrote:
> So why not  .get(key, )? You can reuse the sentinel, and this way 
> it's a single call instead of two -- e.g. the code in Mapping implements both 
> __contains__() and get() by calling __getitem__() and catching KeyError.

Good point. Another option I've considered is using the `keys` method, since 
most non-dict mappings would get this called anyways for patterns with `**rest`.

All the more reason why we should allow the implementation some flexibility. ;)
___
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/RLBJKQNWFOTCBSAJT47J7RO2K26ZFQAL/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-06-24 Thread Guido van Rossum
On Wed, Jun 24, 2020 at 7:27 AM M.-A. Lemburg  wrote:

> Wow, so 19 years after PEP 275, we are indeed getting a switch
> statement. Nice :-)
>

Indeed. Fortunately there are now some better ideas to steal from other
languages than C's switch. :-)

Something which struck me as odd when first scanning through the PEP
> is the default case compared to other Python block statements:
>
> match something:
> case 0 | 1 | 2:
> print("Small number")
> case [] | [_]:
> print("A short sequence")
> case str() | bytes():
> print("Something string-like")
> case _:
> print("Something else")
>
> rather than what a Pythonista would probably expect:
>
> match something:
> case 0 | 1 | 2:
> print("Small number")
> case [] | [_]:
> print("A short sequence")
> case str() | bytes():
> print("Something string-like")
> else:
> print("Something else")
>
> Was there a reason for using a special value "_" as match-all value ?
> I couldn't find any explanation for this in the PEP.
>

Nearly every other language whose pattern matching syntax we've examined
uses _ as the wildcard.

The authors don't feel very strongly about whether to use `else:` or `case
_:`. The latter would be possible even if we added an explicit `else`
clause, and we like TOOWTDI. But it's clear that a lot of people *expect*
to see `else`, and maybe seeing `case _:` is not the best introduction to
wildcards for people who haven't seen a match statement before.

A wrinkle with `else` is that some of the authors would prefer to see it
aligned with `match` rather than with the list of cases, but for others it
feels like a degenerate case and should be aligned with those. (I'm in the
latter camp.)

There still is a lively internal discussion going on, and we'll get back
here when we have a shared opinion.

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


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

2020-06-24 Thread Guido van Rossum
I declare this post Off Topic. Please open another thread (preferably on
python-ideas).

Everybody else, please don't respond to this particular post by the OP.

On Wed, Jun 24, 2020 at 11:12 AM pylang  wrote:

> Great timing! Last week I was trying to emulate a certain Rust example in
> Python.
> Rust has a way to implement families of classes without subclassing,
> which I think could be a great addition to Python someday.  I'll explain
> below.
>
> Here is a Rust example (https://youtu.be/WDkv2cKOxx0?t=3795)
> that demonstrates a way to implement classes without subclassing.
>
> # Rust Code
> enum Shape {
> Circle(f32),
> Square(f32),
> Rectangle(f32, f32)
> }
>
> impl Shape {
> fn area(self) -> f32 {
> match self {
> Shape::Circle(r) => 3.1 * r * r,
> Shape::Square(l) => l * l,
> Shape::Rectangle(l, w) => l * w
> }
> }
> }
>
> fn main () {
> let c = Shape::Circle(3.0);
> let s = Shape::Square(3.0);
> let r = Shape::Rectangle(3.0, 7.5);
> println!("○ {}", c.area());
> println!("□ {}", s.area());
> println!("▭ {}", r.area());
> }
>
> # Output
> ○ 27.88
> □ 9
> ▭ 22.5
>
> The general idea is:
> - declare classes that share a certain type
> - extend common methods with a match-case style
>
> That's it.  No sub-classing required.
>
> I wondered if someday, can we do this in Python? This match-case proposal
> seems to fit well in this example.
>
> While I know this PEP does not focus on detailed applications,
> does anyone believe we can achieve elegant class creation (sans
> subclassing) with match-cases?
>
>
> On Wed, Jun 24, 2020 at 2:04 PM Guido van Rossum  wrote:
>
>> On Tue, Jun 23, 2020 at 11:27 PM Emily Bowman 
>> wrote:
>> > I wonder if it's time to officially designate _ as a reserved name.
>>
>> Alas, it's too late for that. The i18n community uses _("message text")
>> to mark translatable text. You may want to look into the gettext stdlib
>> module.
>>
>> --
>> --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/P6EKIKFP6MX2N2KVFFCF4XUVVMSJ6Q5B/
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
>

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


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

2020-06-24 Thread Guido van Rossum
On Wed, Jun 24, 2020 at 2:56 AM Greg Ewing 
wrote:

> One other thing that the PEP doesn't make clear -- is it possible
> to combine '=' and ':=' to match a keyword argument with a sub
> pattern and capture the result? I.e. can you write
>
> case Spam(foo = foo_value := Blarg()):
>
> ?
>

The full grammar in the Appendix makes this clear -- you can't write it
like that, but you could write

case Spam(foo=(foo_value := Blarg()):

I'll get to your other points eventually.

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


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

2020-06-24 Thread Guido van Rossum
On Wed, Jun 24, 2020 at 11:05 AM Brandt Bucher 
wrote:

> Guido van Rossum wrote:
> > IIUC the pattern matching uses either .get(key, ) or
> .__contains__(key) followed by .__getitem__(key). Neither of those will
> auto-add the item to a defaultdict (and the Mapping protocol supports
> both). @Brandt: what does your implementation currently do? Do you think we
> need to specify this in the PEP?
>
> I still prefer under-specifying rather than over-specifying, in order to
> allow the implementation some flexibility. Basically, "if you've got a
> funny mapping, it may behave funny".
>
> For example, we currently perform a length check before even getting to
> this point, which is allowed because the spec isn't very strict. This is a
> good thing; we already have a section in the PEP that explicitly allows
> compiler to perform transformations such as C(x) | C(y) -> C(x | y).
>
> If we have to specify it, __contains__ followed by __getitem__ is the way
> to do it. The current behavior is subtly different (and probably wrong),
> but I was going to change it today anyways... I had an outstanding TODO for
> it.
>

So why not  .get(key, )? You can reuse the sentinel, and this way
it's a single call instead of two -- e.g. the code in Mapping implements
both __contains__() and get() by calling __getitem__() and catching
KeyError.

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


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

2020-06-24 Thread Guido van Rossum
On Wed, Jun 24, 2020 at 3:02 AM Chris Jerdonek 
wrote:

> I have an exploratory question. In this section:
>
> The alternatives may bind variables, as long as each alternative binds the
>> same set of variables (excluding _). For example:
>> match something:
>> ...
>> case Foo(arg=x) | Bar(arg=x):  # Valid, both arms bind 'x'
>> ...
>> ...
>
>
> Tweaking the above example slightly, would there be a way to modify the
> following so that, if the second alternative matched, then 'x' would have
> the value, say, None assigned to it?
>
> match something:
>> ...
>> case Foo(arg=x) | Bar() (syntax assigning, say, None to x?)
>> ...
>> ...
>
>
> That would let Bar be handled by the Foo case even if Bar doesn't take an
> argument. I'm not sure if this would ever be needed, but it's something I
> was wondering. I didn't see this covered but could have missed it.
>

That sounds like you are planning to put an 'if x is not None' check in the
block. In most cases it would probably be cleaner to separate this out into
two cases. (And yes, I can think of counterexamples, but they don't feel
compelling enough to try and invent such syntax.)

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


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

2020-06-24 Thread Guido van Rossum
On Tue, Jun 23, 2020 at 11:27 PM Emily Bowman 
wrote:
> I wonder if it's time to officially designate _ as a reserved name.

Alas, it's too late for that. The i18n community uses _("message text") to
mark translatable text. You may want to look into the gettext stdlib module.

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


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

2020-06-24 Thread Brandt Bucher
Guido van Rossum wrote:
> IIUC the pattern matching uses either .get(key, ) or 
> .__contains__(key) followed by .__getitem__(key). Neither of those will 
> auto-add the item to a defaultdict (and the Mapping protocol supports both). 
> @Brandt: what does your implementation currently do? Do you think we need to 
> specify this in the PEP?

I still prefer under-specifying rather than over-specifying, in order to allow 
the implementation some flexibility. Basically, "if you've got a funny mapping, 
it may behave funny".

For example, we currently perform a length check before even getting to this 
point, which is allowed because the spec isn't very strict. This is a good 
thing; we already have a section in the PEP that explicitly allows compiler to 
perform transformations such as C(x) | C(y) -> C(x | y).

If we have to specify it, __contains__ followed by __getitem__ is the way to do 
it. The current behavior is subtly different (and probably wrong), but I was 
going to change it today anyways... I had an outstanding TODO for it.
___
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/FGHL3HV3Z5W5DBURTE76WU4YI23IRZ3Z/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-06-24 Thread Jakub Stasiak


> On 24 Jun 2020, at 19:14, Guido van Rossum  wrote:
> 
> (Jakub, next time please trim the original post from your quote to what's 
> necessary.)
> 
Apologies, unintentional, I was replying from the web interface since I wasn’t 
subscribed to this gorup when the thread was started and I clicked some wrong 
buttons.

> 
> So, now for the one thing that makes me unhappy: the rejected idea to make it 
> an expression. In my short experience with pattern matching, mainly in Rust, 
> roughly half (very vague estimate) of its usefulness came from it being an 
> expression. It's even small things like
> 
> let i = match i {
> 9 => 10,
> 10 => 9,
> _ => i,
> };
> 
> and
> 
> let mut file: Box = match filename.as_ref() {
> "-" => Box::new(io::stdout()),
> _ => Box::new(File::create(filename).expect("Cannot open file for 
> writing")),
> };
> 
> and it adds up. I'm not sure how to approach this with Python syntax and I'll 
> think about this, but I feel that it'd be a huge missed opportunity to not 
> have this.
> 
> We considered it, but it simply doesn't work, for the same reason that we 
> haven't been able to find a suitable multi-line lambda expression. Since 
> Python fundamentally is not an expression language, this is no great loss -- 
> you simply write a match statement that assigns a value to the variable in 
> each branch. Alternatively, the match could be inside a function and each 
> block could return a value.
> 
> -- 
> --Guido van Rossum (python.org/~guido)
> Pronouns: he/him (why is my pronoun here?)

That’s fair, but there’s a way in which this doesn’t have to be equivalent to 
multi-line lambda expressions. Granted, I should’ve clarified that I thought 
about it being an expression in a very limited, special way.

Let’s take one example from the PEP text:

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

Let’s say we allow prepending “match …” with an assignment and the value of the 
assignment is the value of the last statement/expression in the block that’s 
selected, this allows for the following hypothetical code:

message = match greeting:
case "":
"Hello!"
case name:
   f"Hi {name}!”

So I didn’t express this clearly – it’s not a bout full-blown match expressions 
but rather an optional "assigning form” of match statements. This seems like it 
wouldn’t affect parsing massively.

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


[Python-Dev] Re: PEP 620: Hide implementation details from the C API

2020-06-24 Thread Gustavo Carneiro
On Wed, 24 Jun 2020 at 17:22, Victor Stinner  wrote:

[...]


> The question becomes: how to promote the limited C API? Should it
> become the default, rather than an opt-in option?
>

It would be interesting to find out what is the performance impact of using
limited C API, vs normal API, on some popular extensions.  This is
something that I wish had been included in PEP 384.

It would be great if the limited API could be the default, as it allows
building extensions once that work across most python versions.

-- 
Gustavo J. A. M. Carneiro
Gambit Research
"The universe is always one step beyond logic." -- Frank Herbert
___
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/BS7QTLNLEMCODXPEGAIRENGYR24JBZK3/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-06-24 Thread Guido van Rossum
(Jakub, next time please trim the original post from your quote to what's
necessary.)

On Wed, Jun 24, 2020 at 9:11 AM  wrote:

> Wow, I totally didn't see this coming, not after seeing what seems like a
> lot of rejected ideas on this topic (there was at least one PEP already
> that proposed this, right?). I have to admire the authors' determination to
> write such a lengthy and (from skimming it) complex and comprehensive
> proposal *and* providing a reference implementation on top of that, the
> amount of work (including internal bikeshedding) must've been substantial.
>
> Needless to say it's +1 from my humble person, big time, and I wouldn't
> want the comment below to detract from that.
>
> So, now for the one thing that makes me unhappy: the rejected idea to make
> it an expression. In my short experience with pattern matching, mainly in
> Rust, roughly half (very vague estimate) of its usefulness came from it
> being an expression. It's even small things like
>
> let i = match i {
> 9 => 10,
> 10 => 9,
> _ => i,
> };
>
> and
>
> let mut file: Box = match filename.as_ref() {
> "-" => Box::new(io::stdout()),
> _ => Box::new(File::create(filename).expect("Cannot open file for
> writing")),
> };
>
> and it adds up. I'm not sure how to approach this with Python syntax and
> I'll think about this, but I feel that it'd be a huge missed opportunity to
> not have this.
>

We considered it, but it simply doesn't work, for the same reason that we
haven't been able to find a suitable multi-line lambda expression. Since
Python fundamentally is not an expression language, this is no great loss
-- you simply write a match statement that assigns a value to the variable
in each branch. Alternatively, the match could be inside a function and
each block could return a value.

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


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

2020-06-24 Thread Eric Wieser
As a tangential follow-up to my thought that _"the `:=` walrus operator seems 
to be usable as a substitute for new syntax"_, you can actually build a 
seemingly complete (if somewhat error-prone) _run-time_ pattern matching API 
using it:

https://gist.github.com/eric-wieser/da679ff9b1b1e99aa660d54cb0dbd517

Taking the `group_shapes` example from the PEP, the gist lets you write
```python
g = group_shapes()
if g in M(([], [point := M[Point](x := M._, y := M._), *(other := M._)])):
print(f"Got {point.value} in the second group")
process_coordinates(x.value, y.value)
elif g in M(...):
# etc
```
This isn't an argument against adding new syntax, but I figured those 
discussing the PEP might be interested in what can already be done with today's 
syntax.

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


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

2020-06-24 Thread Jakub Stasiak



> On 24 Jun 2020, at 17:57, mi...@drach.uk wrote:
> 
> To me match also sound confusing as a keyword. You don't match things to 
> cases in English.
> Maybe match x: against 1? https://idioms.thefreedictionary.com/match+against
> 
> match point:
>against (x, 1):
>...
>against (1, y):
>...
> 
> Better yet it feels to me to have:
> 
> 
> handle point:
>as (x, 1):
>...
>as (1, y):
>...
>as None:
>...
> ___
> 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/LGPOSO6L2GUFMR2RZ6YMAECGG4TMPIZD/
> Code of Conduct: http://python.org/psf/codeofconduct/

I think the match/case terminology is so common in this area that introducing 
different names for this would be counterproductive.
___
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/4AEQ47MONYJSG6OEMDN4GGW6UOL6Q6YX/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-06-24 Thread Ethan Furman

On 06/24/2020 08:57 AM, mi...@drach.uk wrote:


To me match also sound confusing as a keyword. You don't match things to cases 
in English.



Maybe match x: against 1? https://idioms.thefreedictionary.com/match+against


Python uses English words, but is not English.

Having said that, you can "match against several cases" to see which one is 
what you are looking for:

Google search, not sure which dictionary, said:

noun: case; plural noun: cases
1.
an instance of a particular situation; an example of something occurring.



So in your example we have three cases of interest:
- point is Point(?, 1)
- point is Point(1, ?)
- point is None

So we are matching the point given against three different cases, and

match :
case <1>:
# blah
case <2>:
# blah
case <3>:
# blah

flows naturally from that.

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


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

2020-06-24 Thread MRAB

On 2020-06-24 13:37, Antoine Pitrou wrote:

On Wed, 24 Jun 2020 21:54:24 +1200
Greg Ewing  wrote:

On 24/06/20 5:20 am, Antoine Pitrou wrote:
> suddently `Point(x, 0)` means something entirely
> different (it doesn't call Point.__new__, it doesn't lookup `x` in the
> locals or globals...).  


This is one reason I would rather see something explicitly marking
names to be bound, rather than making the binding case the default.
E.g.

case Point(?x, 0):

This would also eliminate the need for the awkward leading-dot
workaround for names to be looked up rather than bound.


That looks quite a bit better indeed, because it strongly suggests
that something unusual is happening from the language's POV. Thank you
for suggesting this.


Could the name be omitted when you're not interested in the value?

case Point(?, 0):


One other thing that the PEP doesn't make clear -- is it possible
to combine '=' and ':=' to match a keyword argument with a sub
pattern and capture the result? I.e. can you write

case Spam(foo = foo_value := Blarg()):


Yuck :-S


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


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

2020-06-24 Thread Guido van Rossum
On Wed, Jun 24, 2020 at 8:26 AM Eric Wieser 
wrote:

> Thanks for the reply.
>
> Independent of whether the spelling is encouraged, does the PEP in its
> current form consider `(name := _)` to be legal, or is `_` forbidden on the
> RHS of a `:=` by a similar argument to forbidding `_`  in `**_`?
>

It is legal.

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


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

2020-06-24 Thread misha
Better yet:

given point:
as (x, 1):
...
as (1, y):
...
as None:
...
___
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/RWKM3YA4G7VVGAJCODSP56Y2G2MLFCSE/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 620: Hide implementation details from the C API

2020-06-24 Thread Victor Stinner
Le mer. 24 juin 2020 à 16:20, Stefan Behnel  a écrit :
> Note, I understand the difference between ABI and API. Keeping
> PyTuple_GET_ITEM() a macro or inline function can break the ABI at some
> point once PyTupleObject changes in an incompatible way in Py3.14, and it
> may do different things in PyPy entirely at some point. That's fine. We
> have a policy of allowing ABI breakage between CPython minor releases.

In the short term, I agree that it's ok that PyFloat_AS_DOUBLE()
continues to read directly PyFloatObject.ob_fval. There is no *need*
to enforce a function call at the ABI level for now.

My practical problem is how to prevent C extensions accessing the
PyFloatObject.ob_fval member directly. In my tests, I renamed PyObject
members. For example, rename PyObject.ob_type to PyObject._ob_type,
and update Py_TYPE() and Py_SET_TYPE(). If a C function accesses
directly PyObject.ob_type, a compilation error is issued.

One option would be to have a different stricter build mode where
PyFloat_AS_DOUBLE() becomes a function call. Example:

#ifndef Py_LIMITED_API
#  ifdef OPAQUE_STRUCTURE
#define PyFloat_AS_DOUBLE(op) PyFloat_AsDouble(op)
#  else
#define PyFloat_AS_DOUBLE(op) (((PyFloatObject *)(op))->ob_fval)
#  endif
#endif

The function is not available in the Py_LIMITED_API, so other Python
implementations don't have to implement it.

But an OPAQUE_STRUCTRE macro would declare the macro as a function
call: alias to PyFloat_AsDouble().

Or maybe it's time to extend the limited C API: add
PyFloat_AS_DOUBLE() macro as a function call. Extending the limited C
API has multiple advantages:

* It eases the transition of C extensions to the limited C API
* Py_LIMITED_API already exists, there is no need to add yet another
build mode or any new macro
* Most structures are *already* opaque in the limited C API.


The question becomes: how to promote the limited C API? Should it
become the default, rather than an opt-in option?


> That's what I mean by "public CPython 3.X C-API". Don't discourage its use,
> don't hide away details. Just make it clear what is CPython specific and
> what isn't, but without judging. It's a good thing for extensions to be
> fast on CPython.

I modified "make install" in Python 3.8 to install the internal C API
to make it possible to use it outside CPython.

Victor
-- 
Night gathers, and now my watch begins. It shall not end until my death.
___
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/ZZGKPTLMK7JL2J22GIV2QKAWDFJYV3BE/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-06-24 Thread misha
To me match also sound confusing as a keyword. You don't match things to cases 
in English.
Maybe match x: against 1? https://idioms.thefreedictionary.com/match+against

match point:
against (x, 1):
...
against (1, y):
...

Better yet it feels to me to have:


handle point:
as (x, 1):
...
as (1, y):
...
as None:
...
___
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/LGPOSO6L2GUFMR2RZ6YMAECGG4TMPIZD/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-06-24 Thread jakub
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,
> Rust,
> F#;
> Several extensive discussions on python-ideas, culminating in a
> summarizing
> blog
> post
> by Tobias Kohn;
> An independently developed draft
> PEP
> by Ivan Levkivskyi.
> 
> Implementation
> A full reference implementation written by Brandt Bucher is available
> as a fork) of
> the CPython repo.  This is readily converted to a pull
> request).
> Examples
> Some example
> code 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:
> 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"):
> case 401|403|404:
> return "Not allowed"
> 
> Patterns can look like unpacking assignments, and can be used to bind
> variables:
> # 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
> pattern is a double extraction, which makes it conceptually similar to
> the unpacking assignment (x, y) = point.
> If you are using classes to structure your data (e.g. data classes)
> you can use the class name followed by an argument list resembling a
> constructor, but with the ability to extract variables:
> from dataclasses import dataclass
> 
> @dataclass
> class Point:
> x: int
> y: int
> 
> def whereis(point):
> match point:
> case Point(0, 0):
> print("Origin")
> case Point(0, y):
> print(f"Y={y}")
> case Point(x, 0):
> print(f"X={x}")
> case Point():
> print("Somewhere else")
> case _:
> print("Not a point")
> 
> We can use keyword parameters too.  The following patterns are all
> equivalent (and all bind the y attribute to the var
> variable):
> Point(1, var)
> Point(1, y=var)
> Point(x=1, y=var)
> Point(y=var, x=1)
> 
> Patterns can be arbitrarily nested.  For example, if we have a short
> list of points, we could match it like this:
> match points:
> case []:
> print("No points")
> case [Point(0, 0)]:
> print("The origin")
> case [Point(x, y)]:
> print(f"Single point {x}, {y}")
> case [Point(0, y1), Point(0, y2)]:
> 

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

2020-06-24 Thread Misha Drachuk
I really dislike the fact that case with is instance check looks like 
instantiation.

case Node(children=[…])

Along with checks for int or enum cases, "is instance” and attribute checks 
like the one above will be perceived as equality check.

Basically what happens is based on context the round brackets () next to the 
class name mean different things, which will confuse people a lot.

If instead the curly brackets {}were used for "match checks” the code would be 
more explicit about not being an equality check:

case Node{children=[…]}

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


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

2020-06-24 Thread Eric Wieser
Thanks for the reply.

Independent of whether the spelling is encouraged, does the PEP in its
current form consider `(name := _)` to be legal, or is `_` forbidden on the
RHS of a `:=` by a similar argument to forbidding `_`  in `**_`?

Eric

On Wed, 24 Jun 2020 at 16:12, Guido van Rossum  wrote:

> On Wed, Jun 24, 2020 at 5:23 AM Eric Wieser 
> wrote:
>
>> In regards to
>> https://www.python.org/dev/peps/pep-0622/#alternatives-for-constant-value-pattern,
>> was this alternative considered?
>> ```
>> match obj:
>> case SomeClass(field := _):  # is this already allowed by the PEP?
>> pass
>> case some_constant:  # my proposal: do not require `.some_constant`
>> here
>> pass
>> case (other := _):  # is this already allowed by the PEP? If so, do
>> we need the extra `case other:` spelling?
>> print(other)
>> ```
>>
>> It seems like `:=` already provides all the necessary syntax for
>> distinguishing bindings from constants, admittedly at the cost of 6
>> characters per binding (eg `Point(x := _, y := _)`) - so introducing
>> additional syntax seems unnecessary.
>>
>
> In languages that have pattern matching, it is the primary way to extract
> pieces of a compound data structure into individual variables. For the use
> cases where match would be a good fit in Python, the same will be true. So
> using your proposed syntax here is too verbose to consider.
>
>
>> If this was considered but rejected for verbosity concerns, it would be
>> nice to see it mentioned in the rejected alternatives section.
>>
>
> We can't discuss every single idea in that section. I don't think anyone
> else has proposed this, so I don't think it needs to be discussed for
> posterity. There are plenty of better ideas in this thread that deserve a
> mention there.
>
> --
> --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/DPWXB74BRYRYAPUI32M4ETT5TWVP5EEB/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-06-24 Thread Taine Zhao
Thanks a lot for making this. I've been keeping excited since I heard this 
several hours ago!

I'm a researcher(and also a student) in some field dedicated in the study of 
programming language constructs, including pattern matching.

**Python Pattern Matching** is something special to me, which finally shaped 
the route of my life.
I'd say the design is quite clean and impressive, however still, I found many 
issues, and I wrote a blog post for this, in order to present my points clearly 
to you promoters and developers of PEP 622:
https://thautwarm.github.io/Site-32/Design/PEP622-1.html

The summary of the key points in my blog post:

1. There is a scoping issue which is not specified to be solved in the 
specification of PEP 622, and can be a dangerous bug.
2. The reason for accepting AND patterns, and its use case for enhancing the 
composability of programs.
3. Guards as patterns can be useful for pattern matching in Python.
4. An alternative '__match__' protocol which can be beneficial.
5. Reason for voting 'else' clause, just like Ethan and other kind people 
proposed.

I also feel like to implement PEP 622, and I'm familiar with steps concerning 
the implementation.
___
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/JTXWUF3IJ3FQQVSCKU2VKVAV5E5ATD7O/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-06-24 Thread Guido van Rossum
On Wed, Jun 24, 2020 at 5:23 AM Eric Wieser 
wrote:

> In regards to
> https://www.python.org/dev/peps/pep-0622/#alternatives-for-constant-value-pattern,
> was this alternative considered?
> ```
> match obj:
> case SomeClass(field := _):  # is this already allowed by the PEP?
> pass
> case some_constant:  # my proposal: do not require `.some_constant`
> here
> pass
> case (other := _):  # is this already allowed by the PEP? If so, do we
> need the extra `case other:` spelling?
> print(other)
> ```
>
> It seems like `:=` already provides all the necessary syntax for
> distinguishing bindings from constants, admittedly at the cost of 6
> characters per binding (eg `Point(x := _, y := _)`) - so introducing
> additional syntax seems unnecessary.
>

In languages that have pattern matching, it is the primary way to extract
pieces of a compound data structure into individual variables. For the use
cases where match would be a good fit in Python, the same will be true. So
using your proposed syntax here is too verbose to consider.


> If this was considered but rejected for verbosity concerns, it would be
> nice to see it mentioned in the rejected alternatives section.
>

We can't discuss every single idea in that section. I don't think anyone
else has proposed this, so I don't think it needs to be discussed for
posterity. There are plenty of better ideas in this thread that deserve a
mention there.

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


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

2020-06-24 Thread Guido van Rossum
On Wed, Jun 24, 2020 at 7:30 AM Eric Nieuwland 
wrote:

> Great PEP!
>

Thanks!

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).


> 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.

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


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

2020-06-24 Thread Guido van Rossum
On Wed, Jun 24, 2020 at 4:05 AM Greg Ewing 
wrote:

> On 24/06/20 11:57 am, Guido van Rossum wrote:
> > Matched key-value pairs must already be present in the mapping, and not
> > created
> > on-the-fly by ``__missing__`` or ``__getitem__``.  For example,
> > ``collections.defaultdict`` instances will only match patterns with keys
> > that
> > were already present when the ``match`` block was entered.
>
> Does that mean the pattern matching logic is in cahoots with
> collections.defaultdict? What if you want to match against
> your own defaultdict-like type?
>

IIUC the pattern matching uses either .get(key, ) or
.__contains__(key) followed by .__getitem__(key). Neither of those will
auto-add the item to a defaultdict (and the Mapping protocol supports
both). @Brandt: what does your implementation currently do? Do you think we
need to specify this in the PEP?

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


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

2020-06-24 Thread Guido van Rossum
On Wed, Jun 24, 2020 at 7:40 AM Ethan Furman  wrote:

> Okay, I took Paul Moore's advice and went looking in existing code for
> some examples, and came across the following:
>
>  if isinstance(v, int):
>  # v is an offset
>  elif isinstance(v, str):
>  # v is a docstring
>  elif isinstance(v, tuple) and len(v) in (2, 3) and isinstance(v[0],
> baseinteger) and isinstance(v[1], (basestring, NoneType)):
>  # v is an offset, a docstring, and (maybe) a default
>  elif isinstance(v, tuple) and len(v) in (1, 2) and isinstance(v[0],
> (basestring, NoneType)):
>  # v is a docstring and (maybe) a default
>
> That seems like it would be a perfect match (hah) for the new syntax, but
> I am not confident in my efforts.
>
> This is what I started with:
>
>  match v:  # goal here is to turn v into an (offset, docstring,
> default value)
>  case int:
>  v = v, None, None
>  case str:
>  v = None, v, None
>  case (str, ):
>  # how to combine with above case?
>  v = None, v[0], None
>  case (int, str):
>  v += (None, )
>  case (int, str, default):
>  pass
>  case (str, default):
>  v = None, v[0], v[1]
>
> Which got me to here:
>
>  match v:  # goal here is to turn v into an (offset, docstring,
> default value)
>  case int(offset):
>  v = offset, None, None
>  case str(doc) | (str(doc), ):
>  v = None, doc, None
>  case (int(offset), str(doc)):
>  v = offset, doc, None
>  case (int(offset), str(doc), default):
>  # already correct
>  pass
>  case (str(doc), default):
>  v = None, doc, default
>
> Is this correct?
>

Yes.

Side note: I would much rather read "case str(doc) or (str(doc), )" instead
> of a |.
>

Duly noted, we'll come back to this.

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


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

2020-06-24 Thread Guido van Rossum
On Tue, Jun 23, 2020 at 10:10 AM MRAB  wrote:

> Why are:
>
>  case ._:
>
> not OK?
>
> In this:
>
>  case .BLACK:
>  ...
>  case BLACK:
>  ...
>
> the first matches the value against 'BLACK' and the second succeeds and
> binds the value to 'BLACK'.
>
> Replacing 'BLACK' with '_':
>
>  case ._:
>  ...
>  case _:
>  ...
>
> I'd expect something similar, except for the binding part.
>
> I think the same could be said for:
>
>  case Color.BLACK:
>
> and:
>
>  case _.BLACK:
>

The PEP authors discussed this last night and (with a simple majority) we
agreed that this restriction isn't all that important, so we're dropping it.
https://github.com/python/peps/commit/410ba6dd4841dc445ce8e0cd3e63ade2fa92ddc4

(We're considering other feedback carefully, but most of it require more
deliberation.)

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


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

2020-06-24 Thread M.-A. Lemburg
On 24.06.2020 16:27, M.-A. Lemburg wrote:
> Wow, so 19 years after PEP 275, we are indeed getting a switch
> statement. Nice :-)
> 
> Something which struck me as odd when first scanning through the PEP
> is the default case compared to other Python block statements:
> 
> match something:
> case 0 | 1 | 2:
> print("Small number")
> case [] | [_]:
> print("A short sequence")
> case str() | bytes():
> print("Something string-like")
> case _:
> print("Something else")
> 
> rather than what a Pythonista would probably expect:
> 
> match something:
> case 0 | 1 | 2:
> print("Small number")
> case [] | [_]:
> print("A short sequence")
> case str() | bytes():
> print("Something string-like")
> else:
> print("Something else")
> 
> Was there a reason for using a special value "_" as match-all value ?
> I couldn't find any explanation for this in the PEP.

To clarify:

The Python compiler could turn the "else:" into what
"case _:" would produce. The syntax would just look
more intuitive, IMO.

The question was not about using "_" as match-all in general.

> Cheers.
> 
> 
> 
> On 23.06.2020 18:01, 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:
>> 

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

2020-06-24 Thread M.-A. Lemburg
Wow, so 19 years after PEP 275, we are indeed getting a switch
statement. Nice :-)

Something which struck me as odd when first scanning through the PEP
is the default case compared to other Python block statements:

match something:
case 0 | 1 | 2:
print("Small number")
case [] | [_]:
print("A short sequence")
case str() | bytes():
print("Something string-like")
case _:
print("Something else")

rather than what a Pythonista would probably expect:

match something:
case 0 | 1 | 2:
print("Small number")
case [] | [_]:
print("A short sequence")
case str() | bytes():
print("Something string-like")
else:
print("Something else")

Was there a reason for using a special value "_" as match-all value ?
I couldn't find any explanation for this in the PEP.

Cheers.



On 23.06.2020 18:01, 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 _:
>         

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

2020-06-24 Thread Ethan Furman

On 06/23/2020 09:01 AM, Guido van Rossum wrote:


PEP 622


Okay, I took Paul Moore's advice and went looking in existing code for some 
examples, and came across the following:

if isinstance(v, int):
# v is an offset
elif isinstance(v, str):
# v is a docstring
elif isinstance(v, tuple) and len(v) in (2, 3) and isinstance(v[0], 
baseinteger) and isinstance(v[1], (basestring, NoneType)):
# v is an offset, a docstring, and (maybe) a default
elif isinstance(v, tuple) and len(v) in (1, 2) and isinstance(v[0], 
(basestring, NoneType)):
# v is a docstring and (maybe) a default

That seems like it would be a perfect match (hah) for the new syntax, but I am 
not confident in my efforts.

This is what I started with:

match v:  # goal here is to turn v into an (offset, docstring, default 
value)
case int:
v = v, None, None
case str:
v = None, v, None
case (str, ):
# how to combine with above case?
v = None, v[0], None
case (int, str):
v += (None, )
case (int, str, default):
pass
case (str, default):
v = None, v[0], v[1]

Which got me to here:

match v:  # goal here is to turn v into an (offset, docstring, default 
value)
case int(offset):
v = offset, None, None
case str(doc) | (str(doc), ):
v = None, doc, None
case (int(offset), str(doc)):
v = offset, doc, None
case (int(offset), str(doc), default):
# already correct
pass
case (str(doc), default):
v = None, doc, default

Is this correct?

Side note: I would much rather read "case str(doc) or (str(doc), )" instead of 
a |.

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


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

2020-06-24 Thread Daniel Moisset
Wow, this looks fantastic, I've wanted this for a long time! I really
appreciate the work that has been put here.

As a bit of context for this and future emails, I fury wanted to say:
* I'm strongly positive about this even if I propose changes
* I've explored a bit on my own how to do this, so I'm (painfully) aware of
some of the design tensions, in particular the "a pattern is neither an
expression(something that you'd fight on the RHS of an assignmen) nor a
target (something you'd find in the LHS of an assignment), but has a little
bit of both"

That being send, here are my comments (which I'll split into separate
emails so we can thread separately):

*The "We use a name token to denote a capture variable and special syntax
to denote matching the value of that variable" feels a bit like a foot-gun*

Other people had said this so, this is mostly a +1, but I wanted to provide
alternatives, and also reinforce that deciding in this way is much more
likely to cause mistakes than the opposite. The most likely mistake seems
for me to be using the normal instead of the "special" syntax (the dot
prefix); if i write "case constant" by mistake now, I'm getting 1) a match
when there likely wasn't one and 2) I clobbered my constant. Both are hard
to debug. If we had special syntax for capture and I wrote "case variable"
by mistake, I would likely get a NameError, which should be easier to
figure out.

I saw some of the rejected approaches (like capturing with $var) and I
found them visually ugly, so I want to put two others on the table, which I
think I found "reasonable":


   - 1.A: use angle brackets for capture:

match get_node():
case Node(value=, color=RED): print(f"a red node with value {x}")
case Node(value=, color=BLACK): print(f"a black node with value {x}")
case : print(f"This is a funny colored node with value {n.value}")

This agains adds new syntax like the original proposal, but I think it
makes the capture quite visible without feeling noisy; it reminds me of
metaparameters in the help for command line tools (i.e. "cp 
"). Even if we had this, I'm happy with "_" as a placeholder
(rather than "<_>"). It should be posible to have <*x> or <**x> in other
patterns (rather than * or **)... and I would probably be happy of
using standalone * and ** rather than *_ and **_ (this last suggestion
could work with the current syntax too).


   - 1.B. use a "capture object". No "new" syntax (syntax for patterns is
   new, but looks like other expressions):

match get_node() into c:
case Node(value=c.x, color=RED): print(f"a red node with value {c.x}")
case Node(value=c.x, color=BLACK): print(f"a black node with value
{c.x}")
case c.n: print(f"This is a funny colored node with value {c.n.value}")

The idea here is that instead of spreading captured names into the local
namespace, we only have a single capture object in the locals, and all
captures happen inside it. This also allows to syntactically (although not
in the grammar) to recognize what is a variable capture and what isn't.
This one is somewhat more verbose (specially if you use a longer name for
the "capture") but looks much more familiar to pythonistas (and to IDE
syntax highlighters ;-) ). I added the "into c" syntax without thinking too
much, perhaps using "as c" or "in c", or "match(c)" could be better, I
didn't want to stop much into that part before discussing the idea of using
a "capture object". The capture object is mostly an attribute placeholder
(I might like it to have an extra attribute to get the original matched
value which is generally useful and might be easier than using a walrus,
but this is a minor feature).

What does the rest of the community (and the original authors think about
these alternatives?


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 

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

2020-06-24 Thread Eric Nieuwland
Great PEP!

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.

Not a native speaker I don’t have a reasonable alternative, though.
___
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/TDWDDAROGWNSARY6AS4O52XAZ44CQDGW/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 620: Hide implementation details from the C API

2020-06-24 Thread Stefan Behnel
Victor Stinner schrieb am 24.06.20 um 02:14:
> Le mar. 23 juin 2020 à 16:56, Stefan Behnel a écrit :
>>> Members of ``PyObject`` and ``PyTupleObject`` structures have not
>>> changed since the "Initial revision" commit (1990)
>>
>> While I see an advantage in hiding the details of PyObject (specifically
>> memory management internals), I would argue that there simply isn't much to
>> improve in PyTupleObject, so these two don't fly at the same level for me.
> 
> There are different reasons to make PyTupleObject opaque:
> [Some reeasons why *PyObject* should not be exposed]
>
> * Prevent C extensions to make assumptions on how a Python
> implementation stores a tuple. Currently, C extensions are designed to
> have best performances with CPython, but it makes them run slower on
> PyPy.
> 
> * It becomes possible to experiment with a more efficient PyTypeObject
> layout, in terms of memory footprint or runtime performance, depending
> on the use case. For example, storing directly numbers as numbers
> rather than PyObject. Or maybe use a different layout to make
> PyList_AsTuple() an O(1) operation. I had a similar idea about
> converting a bytearray into a bytes without having to copy memory. It
> also requires to modify PyBytesObject to experiment such idea. An
> array of PyObject* is the most efficient storage for all use cases.

Note, I understand the difference between ABI and API. Keeping
PyTuple_GET_ITEM() a macro or inline function can break the ABI at some
point once PyTupleObject changes in an incompatible way in Py3.14, and it
may do different things in PyPy entirely at some point. That's fine. We
have a policy of allowing ABI breakage between CPython minor releases.

But this does not mean that PyTupleObject needs to become an opaque type
that requires a function call into CPython for PyTuple_GET_ITEM(). It *may*
become that at some point, when there is a reason to change it into a
function call. In the current implementation, there is no such reason. In a
future implementation, there may or may not be a reason. We do not know
that. As of now, we're just needlessly slowing down existing code by
disallowing the C compiler to see that PyTuple_GET_ITEM() literally just
does a single pointer dereference.

This applies ten-fold to types like PyLong and PyFloat, where getting
straight at the native C value is also just a pointer dereference.

Basically, what I'm asking is to keep things as efficient as they are *in
CPython* as long as there is no reason to change them *in CPython*.


>> If we remove CPython specific features from the (de-facto) "official public
>> Python C-API", then I think there should be a "public CPython 3.X C-API"
>> that actively exposes the data structures natively, not just an "internal"
>> one. That way, extension authors can take the usual decision between
>> performance, maintenance effort and platform independence.
> 
> I would like to promote "portable" C code, rather than promote writing
> CPython specific code.
> 
> I mean that the "default" should be the portable API, and writing
> CPython specific code would be a deliberate opt-in choice.

That's what I mean by "public CPython 3.X C-API". Don't discourage its use,
don't hide away details. Just make it clear what is CPython specific and
what isn't, but without judging. It's a good thing for extensions to be
fast on CPython.


>> I haven't come across a use
>> case yet where I had to change a ref-count by more than 1, but allowing
>> users to arbitrarily do that may require way more infrastructure under the
>> hood than allowing them to create or remove a single reference to an
>> object. I think explicit is really better than implicit here.
> 
> Py_SET_REFCNT() is not Py_INCREF(). It's used for special functions
> like free lists, resurrect an object, save/restore reference counter
> (during resurrection), etc.

Exactly, so it is Py_INCREF() or Py_DECREF(), just without side-effects.
I'm arguing that the use case is also practically the same: increase or
decrease the refcount of an object, but without triggering the deallocation
machinery. Now read my paragraph above again. :)

Is it too late in the Py3.9 cycle to switch to two separate macros?

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


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

2020-06-24 Thread Ambient Nuance
Hello everyone, this is my first crack at commenting on a PEP, so apologies for 
mistaking any developer colloquialisms, or if this is the wrong channel to go 
through.

In a nutshell, I was mulling over my initial difficulty in understanding name 
patterns and had the thought of ‘declaring’ so-called ‘placeholder’ variables 
at the beginning of the match block, so that the reader is ‘primed’ for their 
use throughout:

x_literal = a_value
y_literal = another_value

match point:
proxy x, y
case (x_literal, y):
print(f”Y={y} at literal X”)
case (x, y_literal):
print(f”X={x} at literal Y”)
case (x_literal, y_literal):
print(“That is the literal point”)
case (x, y):
print(f”Arbitrary point: X={x}, Y={y}”)
case _:
raise ValueError(“Not a point”)

The use of ‘proxy’ instead of ‘placeholder’ is simply an attempt at brevity 
without diverging substantially from the meaning.

The use of a placeholder variable reminded me a lot of comprehensions, which 
are explicit in where  placeholders come from, but only towards the end of the 
comprehension:
y = [f(a, b) for a, b in iterable]
A contrasting example is the lambda function, which ‘declares’ its placeholders 
upfront:
y = map(lambda x, y: f(x, y), iterable)
In reading these two examples left to right, I believe that it is easier to 
understand the lambda function in a first pass, whereas the list comprehension 
often requires looking back at the expression after reading the ‘for’ clause at 
the end. This difference in first-pass understanding becomes more apparent when 
the expression or function is more complex. In this vein, ‘declaring’ 
placeholder variables upfront makes sense to me when the context in which they 
can be used is (relatively) large and not self-contained.

Now, this does add “new syntax”, which is addressed in the ‘Alternatives for 
constant value pattern’ section of the PEP; but in reading this thread, it 
seems like such a solution remains appealing. For myself, a one-off 
‘declaration’ with a reasonably unambiguous keyword like proxy makes the code 
easier to follow as one reads through it, without the need for variables to be 
typed out differently (consistent with all other variable usage).

I reckon something like this idea would improve comprehensibility (not just raw 
readability) and is more in line with other prose-like constructs in Python 
(try/except, with, and/or).  This is particularly important for people that are 
new to either this feature (everyone at first), or the language as a whole.

Not being all too familiar with CPython implementation details myself, my idea 
is certainly open to technical critique (and of course qualitative 
impressions). As a bit of a stab in the dark, ‘proxy’ could be a soft keyword 
within a match block, similar to ‘match’ being a soft global keyword.
___
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/FRC5ZNXQPWWA4D2SJM4TYWMN5VALD3O6/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-06-24 Thread Rhodri James

On 23/06/2020 17:01, 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.


Can I just say thanks for all this work.  I really like the concept, but 
like everyone else I have opinions on the details :-)  I didn't have 
time to read the PEP until about midnight last night, and responding 
then seemed like a bad idea, so apologies about being late to this game. 
 My basic problem can be summed up as the more I read, the more it 
seemed like exceptions were breeding.


Running through the basics, I'm very happy with the indentation of

  match expression:
  case pattern1:
  suite1()
  case pattern2:
  suite2()

since it fits exactly how I indent switch statements in C :-)

The patterns are where things start coming unstuck.

Literal patterns: fine, no problem, everything works as you would 
expect.  Not being able to use expressions is a disappointment I'm used to.


Name patterns: um.  OK, I can cope with that.  If you squint, it looks 
like an assignment and/or unpacking, _except_ for "_".  Which, what? 
Just because I use "_" as a throwaway doesn't mean I'll never want to 
use it as an actual name.  Do we actually need a non-binding wildcard 
anyway?  It may make some matches a little faster, I suppose, but we're 
always being told names are cheap.


And yes, I think "case _:" is a rubbish way of spelling "else:".  I'd 
honestly be more likely to write "case everything_else:" or even "case 
dummy:" than "case _:" just to be more readable.


Constant value patterns: now I'm getting really uneasy.  A leading dot 
is all but invisible to the reader, and we are compounding the 
specialness of "_".  I'm having to squint harder to see name patterns as 
assignments.  The exceptions to how I would normally read Python code 
are breeding and getting more complicated.


Sequence patterns: and we have more exceptions.  I guess the current 
syntax would need some cooperation from the string classes, but I'd 
quite like to be able to take byte protocols apart and do something like


  match msg:
case bytes((len, 0, cmd, *rest)):
  process_command[cmd](len, rest)
case bytes((len1, len2, 0, cmd, *rest)) if len1 >= 0x80:
  process_command[cmd]((len1 & 0x7f) | (len2 << 7), rest)
else:
  handle_comms_error(msg)

(the protocol I'm currently working on is that horrid :-)

Mapping patterns: makes sense, pace my uneasiness about names.

Class patterns: this crosses the line from uneasy to outright "no".  I'm 
fairly confident I will never read "case Point(x,y):" without thinking 
first there's an instantiation happening.  It gets even worse when you 
add named subpatterns, because in


  case name := Class(x, y)

the "Class(x,y)" part both is and is not an instantiation.  I honestly 
stared at the example in the PEP for a good ten minutes before I grokked 
it properly.


I only have a problem with using "|" to combine patterns because I'd 
really like to have expressions as patterns :-)


The way that exceptions to the usual rules of reading Python got more 
numerous and more complicated the further I read through the PEP makes 
me think the approach to when to use name-binding and when to use values 
may be arse-backwards.  The PEP justifies its approach by pointing out 
that name patterns are more common in typical code, which is fine for 
name patterns, but looks weird for class patterns and really weird when 
you involve named subpatterns.


Here's a quick sketch of rearranging the syntax with that in mind.  Bits 
of it aren't lovely, but I still think they read more naturally than the 
current PEP.


Literal patterns: as before.  It's a classic.

Constant value patterns: just use the name:

  BLACK = 1

  match colour:
case "Not a colour, guv":
  print("Um")
case BLACK:
  print("Paint It Black!")

There's an obvious generalisation to constant expressions that would be 
really nice from my point of view.


Class patterns: don't use syntax that looks like instantiation!

  case Point as x, y:

(I used "as" because it's short.  Someone else suggested "with", which 
probably makes more sense.)  This gets a little messy when patterns 
start nesting.


  case Line as (start := (Point as x, y), end) if start == end:

but the original example in the PEP is just as messy and puts a lot more 
of the wrong thoughts in my head.


Name patterns fall naturally out of this, even if they look a little 
unusual:


  case int as x:

The catch-all

  case object as obj:

looks odd, but actually I don't have a problem with that.  How often 
should code be catching any old thing rather than something of a more 
specific class or classes?  If the catch-all looks odd, perhaps it will 
dissuade people from using it thoughtlessly.


Sequence and mapping patterns are a bit more than just syntactic sugar 
for class patterns for list, tuple, and dict.  I wouldn't 

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

2020-06-24 Thread Antoine Pitrou
On Wed, 24 Jun 2020 21:54:24 +1200
Greg Ewing  wrote:
> On 24/06/20 5:20 am, Antoine Pitrou wrote:
> > suddently `Point(x, 0)` means something entirely
> > different (it doesn't call Point.__new__, it doesn't lookup `x` in the
> > locals or globals...).  
> 
> This is one reason I would rather see something explicitly marking
> names to be bound, rather than making the binding case the default.
> E.g.
> 
> case Point(?x, 0):
> 
> This would also eliminate the need for the awkward leading-dot
> workaround for names to be looked up rather than bound.

That looks quite a bit better indeed, because it strongly suggests
that something unusual is happening from the language's POV. Thank you
for suggesting this.

> One other thing that the PEP doesn't make clear -- is it possible
> to combine '=' and ':=' to match a keyword argument with a sub
> pattern and capture the result? I.e. can you write
> 
> case Spam(foo = foo_value := Blarg()):

Yuck :-S

Regards

Antoine.

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


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

2020-06-24 Thread Eric Wieser
A cursory search of this thread suggests that no one has mentioned this yet, 
but apologies if I missed one of the existing replies about this.

In regards to 
https://www.python.org/dev/peps/pep-0622/#alternatives-for-constant-value-pattern,
 was this alternative considered?
```
match obj:
case SomeClass(field := _):  # is this already allowed by the PEP?
pass
case some_constant:  # my proposal: do not require `.some_constant` here
pass
case (other := _):  # is this already allowed by the PEP? If so, do we need 
the extra `case other:` spelling?
print(other)
```

It seems like `:=` already provides all the necessary syntax for distinguishing 
bindings from constants, admittedly at the cost of 6 characters per binding (eg 
`Point(x := _, y := _)`) - so introducing additional syntax seems unnecessary.
If this was considered but rejected for verbosity concerns, it would be nice to 
see it mentioned in the rejected alternatives section.

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


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

2020-06-24 Thread Paul Moore
On Wed, 24 Jun 2020 at 11:44, Greg Ewing  wrote:
> Another possibility would to be allow cases to share the same
> suite by stacking them:
>
> case 401:
> case 402:
> case 403:
>...

I feel as though this could be useful (although I don't have a
specific use case in mind). The obvious alternative would be to define
a named function:

def handle_40x():
...

case 401:
handle_40x()
case 402:
handle_40x()
   case 403:
handle_40x()

But in spite of arguments about naming functions being cheap and good
practice, I can still see myself missing the "stacked alternatives"
form sometimes.

Covering a few other points made in the thread:

* I can't see much value in having `else:` - `case _` is a common way
of writing a "catch all" pattern in many languages (although certainly
"else" is used too) and I'd rather there be a single valid way, to
avoid endless debates over style. We can't realistically disallow
`case _`, as that's just a consequence of the general rules, so `else`
should be the one to drop.
* The use of `_` as wildcard feels fine to me (i18n notwithstanding).
It's a common convention in Python, and in other languages that have
match constructs.
* The .VALUE syntax makes me sad, although I don't have a particularly
good alternative to suggest. I'd certainly be able to learn to live
with it, though.
* Putting the expression on a line below the match keyword feels less
natural to me than the current proposal. I don't have a particular
logic or analogy for that (arguments about "it's like try...except"
don't feel compelling to me), I just prefer the syntax in the PEP.

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


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

2020-06-24 Thread Greg Ewing

On 24/06/20 11:57 am, Guido van Rossum wrote:
Matched key-value pairs must already be present in the mapping, and not 
created

on-the-fly by ``__missing__`` or ``__getitem__``.  For example,
``collections.defaultdict`` instances will only match patterns with keys 
that

were already present when the ``match`` block was entered.


Does that mean the pattern matching logic is in cahoots with
collections.defaultdict? What if you want to match against
your own defaultdict-like type?

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


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

2020-06-24 Thread Greg Ewing

On 24/06/20 9:31 am, Chris Angelico wrote:

I can't find it among the rejected alternatives, but was it considered
to use "..." as the wildcard, rather than "_"?


It currently has a value as an expression, so you might want
to match against it. (I don't think the syntax in the PEP
currently allows it to be used that way, but it could do).

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


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

2020-06-24 Thread Greg Ewing
   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.)


This would be my preferred option.

Another possibility would to be allow cases to share the same
suite by stacking them:

   case 401:
   case 402:
   case 403:
  ...

Or perhaps both. The stacking option could be useful if the
cases are complicated.

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


[Python-Dev] Re: Draft PEP: Remove wstr from Unicode

2020-06-24 Thread Victor Stinner
I commented https://github.com/python/peps/pull/1462 as a review.

Le mer. 24 juin 2020 à 10:21, Inada Naoki  a écrit :
> Do you mean APIs relating to Py_UNICODE, but not relating to
> wstr nor legacy Unicode? (e.g. PyLong_FromUnicode, PyUnicode_Encode, etc...)
>
> We can remove them one-by-one basis.

Oh, I forgot about these. I suggest to deprecate all of them in Python
3.10 and remove them in Python 3.12. Or is there any good reason to
keep them?

> Since they are independent from wstr and legacy Unicode object,
> I don't want to handle them in this PEP.

Ok.

Victor
-- 
Night gathers, and now my watch begins. It shall not end until my death.
___
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/3UZTXZ4BIKHT4TMGXDAH5LKU4LEKBTHM/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-06-24 Thread Chris Jerdonek
On Tue, Jun 23, 2020 at 9:12 AM 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.
>
...
>
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
>

I have an exploratory question. In this section:

The alternatives may bind variables, as long as each alternative binds the
> same set of variables (excluding _). For example:
> match something:
> ...
> case Foo(arg=x) | Bar(arg=x):  # Valid, both arms bind 'x'
> ...
> ...


Tweaking the above example slightly, would there be a way to modify the
following so that, if the second alternative matched, then 'x' would have
the value, say, None assigned to it?

match something:
> ...
> case Foo(arg=x) | Bar() (syntax assigning, say, None to x?)
> ...
> ...


That would let Bar be handled by the Foo case even if Bar doesn't take an
argument. I'm not sure if this would ever be needed, but it's something I
was wondering. I didn't see this covered but could have missed it.

--Chris




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


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

2020-06-24 Thread Greg Ewing

On 24/06/20 5:20 am, Antoine Pitrou wrote:

suddently `Point(x, 0)` means something entirely
different (it doesn't call Point.__new__, it doesn't lookup `x` in the
locals or globals...).


This is one reason I would rather see something explicitly marking
names to be bound, rather than making the binding case the default.
E.g.

   case Point(?x, 0):

This would also eliminate the need for the awkward leading-dot
workaround for names to be looked up rather than bound.

The PEP says this was rejected on the grounds that binding is
more common than matching constants, but code is read more often
than it is written, and readability counts.

It would also help with the problem that in

   case Spam(foo = blarg):

the name being bound is on the right, whereas in

   case Spam(foo := Blarg()):

the name being bound is on the left. I found myself having to think
quite hard while reading the PEP to keep these two straight. With
explicit marking of bound names, they would be

   case Spam(foo = ?blarg):

   case Spam(?foo := Blarg()):

which, particularly in the first case, would make it much clearer
what's being bound.

One other thing that the PEP doesn't make clear -- is it possible
to combine '=' and ':=' to match a keyword argument with a sub
pattern and capture the result? I.e. can you write

   case Spam(foo = foo_value := Blarg()):

?

--
Greg



  Obviously, there are cases where this is

worthwhile, but still.

It may be useful to think about different notations for these new
things, rather than re-use the object construction notation.

For example:

 case Point with (x, y):
  print(f"Got a point with x={x}, y={y}")

or:

 case Point @ (x, y):
  print(f"Got a point with x={x}, y={y}")

(yes, "@" is the matrix multiplication operator... but it's probably
much less likely to appear in common code and especially with a class
object at the left)


Regards

Antoine.


On Tue, 23 Jun 2020 09:01:11 -0700
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!


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


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

2020-06-24 Thread Antoine Pitrou
On Tue, 23 Jun 2020 14:56:47 -0700
Barry Warsaw  wrote:
> On Jun 23, 2020, at 14:34, Richard Levasseur  wrote:
> 
> > I agree with not having flat indentation. I think having "case" indented 
> > from "match" makes it more readable overall.  
> 
> I don’t know whether my suggestion to use `match:` and putting the expression 
> inside this stanza can be accomplished, but I do want to add another point 
> about that suggestion that I’ve heard from several folks I’ve already chatted 
> with about this PEP.  Using something like
> 
> match:
> expression
> case arm1:
> pass
> case arm2:
> pass
> else:
> pass
> 
> nicely mirrors try/except and if/elif/else constructs so it looks quite 
> natural.

I find it quite un-natural.

Regards

Antoine.

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


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

2020-06-24 Thread Paul Moore
On Wed, 24 Jun 2020 at 07:40, Ethan Furman  wrote:
> Second premise:  there is no practical difference between
>
>  match color:
>  case BLACK:
>  # do stuff
>
> and
>
>  match color:
>  case _:
>  BLACK = color
>  # do stuff

You've already changed your position, so this is only marginally
relevant now, but if the match expression is long and complex,
duplicating it is messy. Using the walrus operator is an alternative,
but it's not clear to me how readable that would be if it were only
needed for one case out of many. I'd need to see a "real" example to
have a good feel on that.

(FWIW, I do find that with my ageing eyes, it's easy to miss the dot
prefix. And I feel that the use of a dot would make Uncle Timmy sad
:-()

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


[Python-Dev] Re: Draft PEP: Remove wstr from Unicode

2020-06-24 Thread Inada Naoki
On Tue, Jun 23, 2020 at 6:31 PM Victor Stinner  wrote:
>
> Le mar. 23 juin 2020 à 04:02, Inada Naoki  a écrit :
> > Legacy unicode representation is using wstr so legacy unicode support
> > is removed with wstr.
> > PyUnicode_READY() will be no-op when wstr is removed.  We can remove
> > calling of PyUnicode_READY() since then.
> >
> > I think we can deprecate PyUnicode_READY() when wstr is removed.
>
> Would it be possible to rewrite the plan differently (merge
> Specification sections) to list changes per Python version? Something
> like:
>

OK, I rewrite the PEP.
https://github.com/python/peps/pull/1462

>
> Also, some functions are already deprecated. Would you mind to list
> them in the PEP? I fail to track the status of each function.
>

Do you mean APIs relating to Py_UNICODE, but not relating to
wstr nor legacy Unicode? (e.g. PyLong_FromUnicode, PyUnicode_Encode, etc...)

We can remove them one-by-one basis.

* Most APIs can be removed in 3.10.
* Some API can be undeprecated by changing Py_UNICODE to wchar_t.
* Some APIs needs more discussion (e.g. PyUnicodeEncodeError_Create,
PyUnicodeTranslateError_Create).

Since they are independent from wstr and legacy Unicode object,
I don't want to handle them in this PEP.

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


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

2020-06-24 Thread Ethan Furman

On 06/23/2020 10:11 PM, Ethan Furman wrote:


As others have noted, the leading dot to disambiguate between a name assignment 
and a value check is going to be a problem.


I suspect I wasn't as clear as I could have been, so let me try again (along 
with some thinking-out-loud...).

First premise:  the visual difference between BLACK and .BLACK is minuscule, 
and will trip people up.

Second premise:  there is no practical difference between

match color:
case BLACK:
# do stuff

and

match color:
case _:
BLACK = color
# do stuff

Conclusion:  there is no need for an always true match, since that's basically the same thing as an 
"else"  (or "case _", currently).

Since we don't need an always True match, we don't need to allow a single name after 
"case" as an assignment target, which means we don't need to support ".name" as 
a value target -- the plain name will work as a value target.

Am I just stuck on the single-name scenario and missing the bigger picture?  
What happens here:

aught = 0
match an_obj:
case Point(aught, 6):
# do stuff

for the aught in Point to match the global aught it needs the dot prefix, 
doesn't it.  But this is what guard clauses are for, right?

aught = 0
match an_obj:
case Point(x, 6) if x == aught:
# do stuff

So we still don't need a leading dot.

Going back to the example and taking a different tack [1]:

match color:
case BLACK:  # BLACK is the global variable

is really the same as

match color:
case color == BLACK:

We've been dropping the "color ==" part, but what if we only drop the "color" 
part?

match color:
case == BLACK:  # comparing against the global variable

and then

match color:
case BLACK:   # always True match with `color` assigned to `BLACK`

Equal signs are much easier to notice than a single dot.

Okay, I've pretty much done a 180 here -- a bare name should be an assignment target, but instead of 
having a leading dot be the "this is really an existing variable switch", have an operator be 
that switch: ==, <, >=, etc.  Of course "==" will be the most common, so it can be 
dropped as well when the meaning doesn't change in its absence (kind of like parentheses usually being 
optional).

--
~Ethan~


[1] https://en.wikipedia.org/wiki/Tack_(sailing)
___
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/JSAFZLYATXXETBGR6IK7Z3NAZF2ZS7SJ/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-06-24 Thread Emily Bowman
 On Tue, Jun 23, 2020 at 10:59 PM Rob Cliffe via Python-Dev <
python-dev@python.org> wrote:

>
> >> 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.
> >>
> > I think that's done for consistency. '_' is a wildcard and you can have:
> >
> > case (_, _):
> >
> > to match any 2-tuple, so:
> >
> > case _:
> >
> > would match any value, and can thus already serve as the default.
> >
> Consistency with what?  Where else is `_` currently used as a wildcard?


Calling it a wildcard for the purposes of matching is more about using the
terminology someone who wants to match a thing would search for. In other
contexts it's called a throwaway, but it serves the exact same purpose.
Calling it a throwaway would confuse people who don't know how language
features are linked, but just know they want a catchall/wildcard.

I wonder if it's time to officially designate _ as a reserved name.
___
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/QIRPBTPDQGMMYS26OB6JUTB2NN42OXBQ/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-06-24 Thread Chris Angelico
On Wed, Jun 24, 2020 at 3:49 PM Ethan Furman  wrote:
>
> On 06/23/2020 10:31 PM, Chris Angelico wrote:
> > On Wed, Jun 24, 2020 at 3:21 PM Ethan Furman wrote:
> >> On 06/23/2020 09:01 AM, PEP 622 wrote:
> >>
> >>> from enum import Enum
> >>>
> >>> class Color(Enum):
> >>>  BLACK = 1
> >>>  RED = 2
> >>>
> >>> BLACK = 1
> >>> RED = 2
> >>>
> >>> match color:
> >>>  case .BLACK | Color.BLACK:
> >>>  print("Black suits every color")
> >>>  case BLACK:  # This will just assign a new value to BLACK.
> >>>  ...
> >>
> >> As others have noted, the leading dot to disambiguate between a name 
> >> assignment and a value check is going to be a problem.  I think it's also 
> >> unnecessary because instead of
> >>
> >>   case BLACK:
> >>   blahblah()
> >>
> >> we can do
> >>
> >>   case _:
> >>   # look ma! BLACK is just "color"!
> >>   BLACK = color  # if you really want it bound to another name
> >>
> >> In other words, the PEP is currently building in two ways to do the same 
> >> thing -- make a default case.  One of those ways is going to be a pain; 
> >> the other, once renamed to "else", will be perfect!  :-)  As a bonus, no 
> >> special casing for leading dots.
> >>
> >
> > But what if that's composed into something else?
> >
> > class Room(Enum):
> >  LIBRARY = 1
> >  BILLIARD_ROOM = 2
> >  ...
> >
> > match accusation:
> >  case (Color.SCARLETT, Room.BILLIARD_ROOM):
> >  print("Correct")
> >  case (Color.SCARLETT, _):
> >  print("Not there!")
> >  case (_, Room.BILLIARD_ROOM):
> >  print("Wrong person!")
> >  case (_, _):
> >  print("Nope. Just nope.")
> >
> > Without the dots, there's no way to tell whether you're matching
> > specific values in the tuple, or matching by length alone and then
> > capturing. You can't use the 'else' keyword for a partial match.
>
> Well, your example isn't using leading dots like `.BLACK` is, and your 
> example isn't using `case _` as a final catch-all, and your example isn't 
> using "case some_name_here" as an always True match.  In other words, your 
> example isn't talking about what I'm talking about.  ;-)
>

But it IS using "_" as a catch-all. The simple "case _:" case is using
_ the same way that "case (Color.SCARLETT, _):" is.

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


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

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


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.



I think that's done for consistency. '_' is a wildcard and you can have:

    case (_, _):

to match any 2-tuple, so:

    case _:

would match any value, and can thus already serve as the default.


Consistency with what?  Where else is `_` currently used as a wildcard?
___
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/SXLNU6FB3Z5AT6APEQUYVGUAJKJH7BZO/
Code of Conduct: http://python.org/psf/codeofconduct/