
I saw in the PEP that "Allow more flexible assignment targets instead" was rejected, but I actually think it's a good idea. The current PEP means there will be two different, subtly incompatible ways to destructure objects (match statement and iterable unpacking). The reasoning given was that most cases involve an if-statement, but there's no reason we can't have both flexible assignment targets and a match statement. I think unifying the concepts will make the language more consistent and easy to learn. I also think destructuring an object with only one possible pattern can be very useful, without the boilerplate to set up an entire match suite and manually raise an exception. This will make the variable assignment statement much more powerful. I don't see a good reason to arbitrarily restrict variable assignment to only allow sequence patterns. This might not be a good idea, but it can even potentially be used as an assert statement, like this: def __init__(self, version, name, point): self.version = 1 | 2 | 3 = type # assert that "version" is between 1 and 3 self.name = str() = string # assert that "name" is the correct type Point(0, self.y) = point # assert that "point" is on the y-axis The constant value pattern would have to be changed to something else, like "@constant", and even though that's also rejected, I think the benefits outweigh the costs here. The special treatment of "_" would have to go too, but there's no reason it can't be used as a wildcard by convention anyway, similar to how it can already be used in for loops. I don't see any benefit in treating it specially. Or the question mark can be the wildcard instead. If this is done, the "match statement" will become equivalent to trying different variable assignments. Maybe it can even be changed to look something like this (possibly with a keyword other than "with"): def is_tuple(node) -> bool: with Node(children=[LParen(), RParen()]) = node: return True or with Node(children=[Leaf(value="("), Node(), Leaf(value=")")]) = node: return True or with _ = node: return False def match_shape(shape): with Point(x, y) = shape: ... or with Rectangle(x, y, _, _) = shape: ... def type_new(cls, *args): with (obj,) = args: return obj.__class__ or with (name, bases, namespace) = args: return cls(name, bases, namespace) or with number_of_args = len(args): raise TypeError(f"need 1 or 3 arguments, not {number_of_args}") which has the benefit that it's obviously the same as a variable assignment (which also makes it obvious that "Point(x, y)" isn't a constructor call), making the match syntax less confusing. It also makes it more intuitive because the similar semantics with existing iterable unpacking become obvious. The expression can be seen right next to the pattern, instead of having to be searched higher up. It can also have different expressions matched for different cases. Maybe it can even be possible to stack "or with" and "elif" clauses on top of each other.

On Thu, 2 Jul 2020 at 00:04, Elliott Chen <elliottchen2004@gmail.com> wrote:
I saw in the PEP that "Allow more flexible assignment targets instead" was rejected, but I actually think it's a good idea. The current PEP means there will be two different, subtly incompatible ways to destructure objects (match statement and iterable unpacking). The reasoning given was that most cases involve an if-statement, but there's no reason we can't have both flexible assignment targets and a match statement. I think unifying the concepts will make the language more consistent and easy to learn.
I also think destructuring an object with only one possible pattern can be very useful, without the boilerplate to set up an entire match suite and manually raise an exception. This will make the variable assignment statement much more powerful. I don't see a good reason to arbitrarily restrict variable assignment to only allow sequence patterns. This might not be a good idea, but it can even potentially be used as an assert statement, like this:
def __init__(self, version, name, point): self.version = 1 | 2 | 3 = type # assert that "version" is between 1 and 3 self.name = str() = string # assert that "name" is the correct type Point(0, self.y) = point # assert that "point" is on the y-axis
The constant value pattern would have to be changed to something else, like "@constant", and even though that's also rejected, I think the benefits outweigh the costs here. The special treatment of "_" would have to go too, but there's no reason it can't be used as a wildcard by convention anyway, similar to how it can already be used in for loops. I don't see any benefit in treating it specially. Or the question mark can be the wildcard instead.
Exactly! The wildcard spelling idea I suggested in the other thread was that "?" could become a general constraint prefix used to introduce non-literal and non-keyword constraints. I was thinking purely in terms of destructuring and not in terms of data validation, but you're right that multiple assignments would allow for "multi-capture" (albeit with the usual caveats on iterable consumption). (I think match/case is fine as the spelling for the multi-target dispatch case, though) Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

Before we all get a little too excited here, I think that allowing ``` 1 = x ``` as a sneaky way of writing ``` assert x == 1 ``` would be a terrible mistake. We already have a static way to assert that something is a string: ``` self.name: str = value ``` I don't think that we'll need another way to express the same thing at runtime, so I'm not excited about ``` self.name = str() = value ``` As to allowing object destructuring syntax like ``` Point(x, y) = p ``` that definitely has merit, but it is a complex subject that should be a separate PEP. On Wed, Jul 1, 2020 at 7:19 AM Nick Coghlan <ncoghlan@gmail.com> wrote:
On Thu, 2 Jul 2020 at 00:04, Elliott Chen <elliottchen2004@gmail.com> wrote:
I saw in the PEP that "Allow more flexible assignment targets instead"
was rejected, but I actually think it's a good idea. The current PEP means there will be two different, subtly incompatible ways to destructure objects (match statement and iterable unpacking). The reasoning given was that most cases involve an if-statement, but there's no reason we can't have both flexible assignment targets and a match statement. I think unifying the concepts will make the language more consistent and easy to learn.
I also think destructuring an object with only one possible pattern can
be very useful, without the boilerplate to set up an entire match suite and manually raise an exception. This will make the variable assignment statement much more powerful. I don't see a good reason to arbitrarily restrict variable assignment to only allow sequence patterns. This might not be a good idea, but it can even potentially be used as an assert statement, like this:
def __init__(self, version, name, point): self.version = 1 | 2 | 3 = type # assert that "version" is
between 1 and 3
self.name = str() = string # assert that "name" is the correct
type
Point(0, self.y) = point # assert that "point" is on the y-axis
The constant value pattern would have to be changed to something else,
like "@constant", and even though that's also rejected, I think the benefits outweigh the costs here. The special treatment of "_" would have to go too, but there's no reason it can't be used as a wildcard by convention anyway, similar to how it can already be used in for loops. I don't see any benefit in treating it specially. Or the question mark can be the wildcard instead.
Exactly!
The wildcard spelling idea I suggested in the other thread was that "?" could become a general constraint prefix used to introduce non-literal and non-keyword constraints.
I was thinking purely in terms of destructuring and not in terms of data validation, but you're right that multiple assignments would allow for "multi-capture" (albeit with the usual caveats on iterable consumption).
(I think match/case is fine as the spelling for the multi-target dispatch case, though)
Cheers, Nick.
-- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia _______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@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/LOLDPPKH... Code of Conduct: http://python.org/psf/codeofconduct/
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>

On 01/07/2020 15:50, Guido van Rossum wrote:
Before we all get a little too excited here, I think that allowing ``` 1 = x ``` as a sneaky way of writing ``` assert x == 1 ``` would be a terrible mistake.
+1 One of Python's major virtues is that it's pretty easy to read and get the gist of what's going on, even if the details take a bit more work. If you have to second-guess every assignment, much of that virtue is lost. -- Rhodri James *-* Kynesim Ltd

I guess it might work in a separate PEP, but I'm also a little worried because the current PEP would make that impossible with its subtle incompatibilities with the existing unpacking syntax. Or even more inconsistent, if the assignment target syntax is extended to become similar to the match syntax but still slightly different for backwards compatibility. The sneaky assert wasn't the main point of my idea, it was just a weird side-effect I thought looked cool. It also kind of makes sense because to me, variable assignment/iterable unpacking is like trying to fit something in a box, but idk, it can just become discouraged practice or something. I think it's ultimately just a minor drawback. Assigning to an empty tuple is already possible. The main point is that the match syntax would be able to be used in normal assignment syntax, which also means it can be used in other places such as for loops and with statements. There would be no difference between matching a *single* pattern and variable assignment, so there would no longer be two different syntaxes for doing the same thing. Flexible object destructuring would be able to be done anywhere an assignment can, just like how sequence unpacking is already possible. The powerful syntax is no longer exclusively reserved for the match statement, which is optimized for *multiple* patterns and is just extra boilerplate otherwise. The match statement would be nothing more than a convenient way to try out multiple assignment/match patterns instead of just one, which would help unify it with the rest of the language and make the language more consistent with itself, while still being just as powerful. It could even be turned into a variant of the if/elif/else block (something like "[or ]match expression as pattern"), which would make it more flexible, and more intuitive and easy to read at first glance, since the "as"/"=" explicitly spells out that it's variable binding, which would work *exactly* the same in a match statement as it does in a "for" or "with" or assignment statement. A learner would be able to read a match statement and easily figure out what it does. The current "match/case" statement requires extra learning to figure out how exactly it works, since it's completely different from the rest of the language, and the variable binding semantics between the expression and patterns is more implicit.

On Wed, Jul 1, 2020 at 11:31 AM Elliott Chen <elliottchen2004@gmail.com> wrote:
I guess it might work in a separate PEP, but I'm also a little worried because the current PEP would make that impossible with its subtle incompatibilities with the existing unpacking syntax. Or even more inconsistent, if the assignment target syntax is extended to become similar to the match syntax but still slightly different for backwards compatibility.
In my view 1 = x is a sneaky degenerate case, and what we should really be asking is if it's cool to be able to do, say, (x, 0) = a compared with "x, y = a; if y != 0: raise ValueError". BTW, +100% to the idea that match should extend assignment semantics (e.g. to allow multiple clauses). The totally new match semantics have come up a lot when I discussed this PEP with my friends at work. Even if we get awkward corner cases out of unifying the two, the simplicity of only having one notion of lvalue, instead of two lvalue-like things, is IMO an overriding benefit. This is also more or less how match and assignment tend to work in the languages that have pattern matching, . If we are repulsed by "1 = x" and (x, 0) = y, one solution is to do what Rust did and forbid refutable patterns on the left-hand side of an assignment, but allow them on the left hand side of a match case. (With the historically-minded exception of list and tuple literals). This still makes match an extension of assignment (it's assignment + multiple cases + refutable patterns) and gives us the simplicity benefits, while forbidding "1 = x". -- Devin

If I was to do this in Python, rather than the Rust way of forbidding refutable patterns, I would put as a rule that the target must have at least one variable to bind* . It makes sense in the context that the goals of an assignment are the bindings it does, and the ValueError is an accident that the binding may be impossible sometimes. It would fit better with existing destructuring, and the python philosophy of trusting the developer and protecting the semantics with a runtime check. * only allowing the historical () I mentioned earlier in the thread for compatibility with weird programs that no one ever wrote On Wed, 1 Jul 2020 at 23:24, Devin Jeanpierre <jeanpierreda@gmail.com> wrote:
On Wed, Jul 1, 2020 at 11:31 AM Elliott Chen <elliottchen2004@gmail.com> wrote:
I guess it might work in a separate PEP, but I'm also a little worried because the current PEP would make that impossible with its subtle incompatibilities with the existing unpacking syntax. Or even more inconsistent, if the assignment target syntax is extended to become similar to the match syntax but still slightly different for backwards compatibility.
In my view 1 = x is a sneaky degenerate case, and what we should really be asking is if it's cool to be able to do, say, (x, 0) = a compared with "x, y = a; if y != 0: raise ValueError".
BTW, +100% to the idea that match should extend assignment semantics (e.g. to allow multiple clauses). The totally new match semantics have come up a lot when I discussed this PEP with my friends at work. Even if we get awkward corner cases out of unifying the two, the simplicity of only having one notion of lvalue, instead of two lvalue-like things, is IMO an overriding benefit. This is also more or less how match and assignment tend to work in the languages that have pattern matching, .
If we are repulsed by "1 = x" and (x, 0) = y, one solution is to do what Rust did and forbid refutable patterns on the left-hand side of an assignment, but allow them on the left hand side of a match case. (With the historically-minded exception of list and tuple literals). This still makes match an extension of assignment (it's assignment + multiple cases + refutable patterns) and gives us the simplicity benefits, while forbidding "1 = x".
-- Devin _______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@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/IM6NZJSZ... Code of Conduct: http://python.org/psf/codeofconduct/

We're trying to make the PEP's scope *smaller*, not larger. Let's take changes to assignment off the table. We're fully aware of the resemblance between `a, b = value` and `case a, b: ...` and we're making them behave as similar as is reasonable. On Wed, Jul 1, 2020 at 4:29 PM Daniel Moisset <dfmoisset@gmail.com> wrote:
If I was to do this in Python, rather than the Rust way of forbidding refutable patterns, I would put as a rule that the target must have at least one variable to bind* . It makes sense in the context that the goals of an assignment are the bindings it does, and the ValueError is an accident that the binding may be impossible sometimes. It would fit better with existing destructuring, and the python philosophy of trusting the developer and protecting the semantics with a runtime check.
* only allowing the historical () I mentioned earlier in the thread for compatibility with weird programs that no one ever wrote
On Wed, 1 Jul 2020 at 23:24, Devin Jeanpierre <jeanpierreda@gmail.com> wrote:
On Wed, Jul 1, 2020 at 11:31 AM Elliott Chen <elliottchen2004@gmail.com> wrote:
I guess it might work in a separate PEP, but I'm also a little worried because the current PEP would make that impossible with its subtle incompatibilities with the existing unpacking syntax. Or even more inconsistent, if the assignment target syntax is extended to become similar to the match syntax but still slightly different for backwards compatibility.
In my view 1 = x is a sneaky degenerate case, and what we should really be asking is if it's cool to be able to do, say, (x, 0) = a compared with "x, y = a; if y != 0: raise ValueError".
BTW, +100% to the idea that match should extend assignment semantics (e.g. to allow multiple clauses). The totally new match semantics have come up a lot when I discussed this PEP with my friends at work. Even if we get awkward corner cases out of unifying the two, the simplicity of only having one notion of lvalue, instead of two lvalue-like things, is IMO an overriding benefit. This is also more or less how match and assignment tend to work in the languages that have pattern matching, .
If we are repulsed by "1 = x" and (x, 0) = y, one solution is to do what Rust did and forbid refutable patterns on the left-hand side of an assignment, but allow them on the left hand side of a match case. (With the historically-minded exception of list and tuple literals). This still makes match an extension of assignment (it's assignment + multiple cases + refutable patterns) and gives us the simplicity benefits, while forbidding "1 = x".
-- Devin _______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@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/IM6NZJSZ... Code of Conduct: http://python.org/psf/codeofconduct/
_______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@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/UK4BB72K... Code of Conduct: http://python.org/psf/codeofconduct/
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>

I don't think my proposal should be off the table for scope reasons because it requires the syntaxes to be completely unified and interchangeable, which will be impossible if the current PEP is accepted. I guess it's technically possible to still have the pattern-matching syntax be slightly different from extended assignment statements, but I think that would just unnecessarily complicate the language, force users to be aware of the subtle differences when writing code, and potentially cause users to make mistakes.

It's off the table from the perspective of PEP 622 and its authors. If you want to write a competing PEP that proposes your idea that's totally fine. On Wed, Jul 1, 2020 at 8:17 PM Elliott Chen <elliottchen2004@gmail.com> wrote:
I don't think my proposal should be off the table for scope reasons because it requires the syntaxes to be completely unified and interchangeable, which will be impossible if the current PEP is accepted. I guess it's technically possible to still have the pattern-matching syntax be slightly different from extended assignment statements, but I think that would just unnecessarily complicate the language, force users to be aware of the subtle differences when writing code, and potentially cause users to make mistakes. _______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@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/HF3ALPHO... Code of Conduct: http://python.org/psf/codeofconduct/

On Wed, 1 Jul 2020 at 15:50, Guido van Rossum <guido@python.org> wrote:
Before we all get a little too excited here, I think that allowing ``` 1 = x ``` as a sneaky way of writing ``` assert x == 1 ``` would be a terrible mistake.
Well, we'll always have the sneaky way to check if an iterable is empty: () = x which admittedly would be useful for entries to the IOPPP (International Obfuscated Python Program Pageant)
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...> _______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@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/WQCHP4A2... Code of Conduct: http://python.org/psf/codeofconduct/

On Thu, 2 Jul 2020 at 00:50, Guido van Rossum <guido@python.org> wrote:
Before we all get a little too excited here, I think that allowing ``` 1 = x ``` as a sneaky way of writing ``` assert x == 1 ``` would be a terrible mistake.
The "two ways to do it" possibilities give me pause too, but it wouldn't be exactly the same as assertions or type annotations, since it would still be executed even when optimisations were enabled, and would impose a runtime check, not just a static type analysis check. The structurally split nature of the construct would also allow the default error message to be along the lines of `"AssertionError: Value {:100!r} does not match constraint {!100:!r}".format(rhs_value, lhs_literal_text)`, and still allow type analysers to make relevant inferences. (Although whether the exception should be AssertionError, ValueError, or a new exception type entirely would be open to discussion)
As to allowing object destructuring syntax like ``` Point(x, y) = p ``` that definitely has merit, but it is a complex subject that should be a separate PEP.
This is the main point I'm actually interested in, and I agree it should be a separate PEP. The key thing I'm hoping for in PEP 622 itself is that "Syntactic compatibility with a possible future enhancement to assignment statements" be considered as a constraint on the syntax for case patterns. Some of the ideas currently on the table would rule that out, since they re-use syntax that is already legal in assignment statements to mean something else (most notably, "x.y = z" means something entirely different from the initially proposed meaning of "case x.y:"). If PEP 622 were to be accepted in that form, then it would foreclose the possibility of ever allowing destructuring assignment statements. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On Wed, Jul 1, 2020 at 5:50 PM Nick Coghlan <ncoghlan@gmail.com> wrote:
The key thing I'm hoping for in PEP 622 itself is that "Syntactic compatibility with a possible future enhancement to assignment statements" be considered as a constraint on the syntax for case patterns.
That would certainly rule out ideas like writing stores as $x or x? or <x> etc., since it would be syntactically incompatible with *current* assignment statements.
Some of the ideas currently on the table would rule that out, since they re-use syntax that is already legal in assignment statements to mean something else (most notably, "x.y = z" means something entirely different from the initially proposed meaning of "case x.y:"). If PEP 622 were to be accepted in that form, then it would foreclose the possibility of ever allowing destructuring assignment statements.
I'm not worried. Even if these didn't *exactly* the same syntax users would still benefit from similarities, e.g. `a, b, *rest = value` vs. `case a, b, *rest:`. -- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>

Guido van Rossum wrote:
On Wed, Jul 1, 2020 at 5:50 PM Nick Coghlan ncoghlan@gmail.com wrote:
The key thing I'm hoping for in PEP 622 itself is that "Syntactic compatibility with a possible future enhancement to assignment statements" be considered as a constraint on the syntax for case patterns.
That would certainly rule out ideas like writing stores as $x or x? or <x> etc., since it would be syntactically incompatible with current assignment statements.
No; it would be unfortunate that it creates a second way to do things, but it wouldn't rule them out. The problem Nick pointed out is for syntax that is already meaningful, but means something different. self.y = 15 already has a meaning, but that meaning is NOT "don't really assign to X, I am using it as a constant defined elsewhere." ?x = 14 ?self.y = 15 do not yet mean anything, and if they end up being a more explicit (but also more verbose) variant of x = 14 self.y = 15 that is probably sub-optimal, but it isn't any worse than := The slight variation triggered by the "?" of ?var would be shorthand for "and if you can't make the entire assignment work, pretend I never even asked", so that ?x, 0 = (4,5) would not lose or shadow a previous binding of x. -jJ

On 2020-07-02 15:48, Jim J. Jewett wrote:
Guido van Rossum wrote:
On Wed, Jul 1, 2020 at 5:50 PM Nick Coghlan ncoghlan@gmail.com wrote:
The key thing I'm hoping for in PEP 622 itself is that "Syntactic compatibility with a possible future enhancement to assignment statements" be considered as a constraint on the syntax for case patterns.
That would certainly rule out ideas like writing stores as $x or x? or <x> etc., since it would be syntactically incompatible with current assignment statements.
No; it would be unfortunate that it creates a second way to do things, but it wouldn't rule them out. The problem Nick pointed out is for syntax that is already meaningful, but means something different.
self.y = 15
already has a meaning, but that meaning is NOT "don't really assign to X, I am using it as a constant defined elsewhere."
?x = 14 ?self.y = 15
do not yet mean anything, and if they end up being a more explicit (but also more verbose) variant of
x = 14 self.y = 15
that is probably sub-optimal, but it isn't any worse than :=
The slight variation triggered by the "?" of ?var would be shorthand for "and if you can't make the entire assignment work, pretend I never even asked", so that
?x, 0 = (4,5)
would not lose or shadow a previous binding of x.
IMHO, the assignment statement should remain as it is, not sometimes assign and sometimes not. There could be another form that does matching: try ?x, 0 = (4,5) or: ?x, 0 ?= (4,5) Perhaps it could also be used as an expression, having the value True if it matches and False if it doesn't.

I think that creating a "matching assignment" operator is unnecessary at this point. I think the original point of bringing this up as part of PEP 622 is to try to suggest that the syntax for binding a value not be incompatible with a future version of Python where that same syntax can be used for any kind of assignment. That goal is not satisfied for all cases if `case self.x` means anything except "bind the value to `self.x`". I think that you /could /probably still use $, ? or <> to mark a variable to be bound, but it would /not/ be worth the effort to make it mandatory for lvalues in general, and if you make it optional I imagine it would be rarely used, and you'd get effectively no benefit from supporting that (since people would just be confused whenever they saw it). I think that leaves as /realistic/ options here to either abandon the idea of marking read vs. store, put the marker on variables to be read (and have it be something other than "there is a . anywhere in the expression"), or abandon the goal of allowing for perfect symmetry between lvalues in case statements and lvalues in assignments. I tend to think "mark all reads" is the best course of action here, and stuff like `case self.x` would be a `SyntaxError` (like it is with assignment expressions). On 7/2/20 12:26 PM, MRAB wrote:
On 2020-07-02 15:48, Jim J. Jewett wrote:
Guido van Rossum wrote:
On Wed, Jul 1, 2020 at 5:50 PM Nick Coghlan ncoghlan@gmail.com wrote:
The key thing I'm hoping for in PEP 622 itself is that "Syntactic compatibility with a possible future enhancement to assignment statements" be considered as a constraint on the syntax for case patterns.
That would certainly rule out ideas like writing stores as $x or x? or <x> etc., since it would be syntactically incompatible with current assignment statements.
No; it would be unfortunate that it creates a second way to do things, but it wouldn't rule them out. The problem Nick pointed out is for syntax that is already meaningful, but means something different.
self.y = 15
already has a meaning, but that meaning is NOT "don't really assign to X, I am using it as a constant defined elsewhere."
?x = 14 ?self.y = 15
do not yet mean anything, and if they end up being a more explicit (but also more verbose) variant of
x = 14 self.y = 15
that is probably sub-optimal, but it isn't any worse than :=
The slight variation triggered by the "?" of ?var would be shorthand for "and if you can't make the entire assignment work, pretend I never even asked", so that
?x, 0 = (4,5)
would not lose or shadow a previous binding of x. IMHO, the assignment statement should remain as it is, not sometimes assign and sometimes not.
There could be another form that does matching:
try ?x, 0 = (4,5)
or:
?x, 0 ?= (4,5)
Perhaps it could also be used as an expression, having the value True if it matches and False if it doesn't. _______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@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/MQV7WBAS... Code of Conduct: http://python.org/psf/codeofconduct/

On Fri., 3 Jul. 2020, 2:27 am MRAB, <python@mrabarnett.plus.com> wrote:
IMHO, the assignment statement should remain as it is, not sometimes assign and sometimes not.
There could be another form that does matching:
try ?x, 0 = (4,5)
Huh, this made me wonder if "match/try" may fit people's brains better than "match/case". I know for me that I want to read case clauses the same way I would read them in C, which is thoroughly unhelpful. The following looks weird though, so I don't think I actually like it in practice: === match shape: try Point(x, y): ... try Rectangle(x0, y0, x1, y1, painted=True): ... === Cheers, Nick.

On 03/07/2020 00:12, Nick Coghlan wrote:
On Fri., 3 Jul. 2020, 2:27 am MRAB, <python@mrabarnett.plus.com <mailto:python@mrabarnett.plus.com>> wrote:
IMHO, the assignment statement should remain as it is, not sometimes assign and sometimes not.
There could be another form that does matching:
try ?x, 0 = (4,5)
Huh, this made me wonder if "match/try" may fit people's brains better than "match/case". I know for me that I want to read case clauses the same way I would read them in C, which is thoroughly unhelpful.
The following looks weird though, so I don't think I actually like it in practice:
=== match shape: try Point(x, y): ... try Rectangle(x0, y0, x1, y1, painted=True): ... ===
I don't think it looks at all weird in this example, I think it reads quite naturally, in my brain at least. It is maybe not quite so good when comparing with actual values: match value: try 42: ... try -1: ... And it has the virtue of adding one less keyword.
_______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@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/H6ZNPMH5... Code of Conduct: http://python.org/psf/codeofconduct/

On 03/07/2020 00:12, Nick Coghlan wrote:
On Fri., 3 Jul. 2020, 2:27 am MRAB, <python@mrabarnett.plus.com> wrote:
IMHO, the assignment statement should remain as it is, not sometimes assign and sometimes not.
There could be another form that does matching:
try ?x, 0 = (4,5)
Huh, this made me wonder if "match/try" may fit people's brains better than "match/case". I know for me that I want to read case clauses the same way I would read them in C, which is thoroughly unhelpful.
The following looks weird though, so I don't think I actually like it in practice:
=== match shape: try Point(x, y): ... try Rectangle(x0, y0, x1, y1, painted=True): ...
I'm actually surprised at how much I like that. It certainly gets me out of the C mindset and makes it easier for me to recognise that Point(x,y) isn't an instantiation. -- Rhodri James *-* Kynesim Ltd

On 7/3/2020 8:28 AM, Rhodri James wrote:
On 03/07/2020 00:12, Nick Coghlan wrote:
On Fri., 3 Jul. 2020, 2:27 am MRAB, <python@mrabarnett.plus.com> wrote:
match shape: try Point(x, y): ... try Rectangle(x0, y0, x1, y1, painted=True): ...
I'm actually surprised at how much I like that. It certainly gets me out of the C mindset and makes it easier for me to recognise that Point(x,y) isn't an instantiation.
I really like the verb subclause. A match statement *tries* to match an object to sequence of pattern options, accepting the first structure match. In C, the cases are values (bit patterns) and the matching is by 'equals'. For the proposed matching, equality is the trivial pattern match, but generally, a more complicated action is required. I have the impression that at least some match action failures could be detected by a caught exception, as in "try: x,y = obj" to see if obj matches pattern 'x,y'. Since exceptions are ignored, try: clauses may bee followed by another try: clause to try another pattern. -- Terry Jan Reedy

On Thu., 2 Jul. 2020, 11:18 am Guido van Rossum, <guido@python.org> wrote:
On Wed, Jul 1, 2020 at 5:50 PM Nick Coghlan <ncoghlan@gmail.com> wrote:
The key thing I'm hoping for in PEP 622 itself is that "Syntactic compatibility with a possible future enhancement to assignment statements" be considered as a constraint on the syntax for case patterns.
That would certainly rule out ideas like writing stores as $x or x? or <x> etc., since it would be syntactically incompatible with *current* assignment statements.
Yeah, having stores be unmarked is perfectly consistent with existing assignment statements and expressions, so I now think the PEP is correct to propose that. However, the two parts of the match lvalue proposal that are a genuine problem from a syntactic consistency perspective are: * using "." to mark value constraints (already means attribute binding in assignment lvalues) * using "_" to mark wildcard placeholders (already means a normal variable binding in assignment lvalues) The conclusion I came to from that observation was that to allow for potential future syntactic consistency, it isn't variable bindings that need a symbolic prefix in match lvalues, it's value constraints. That then leads to the idea of using "?" as a general "value constraint" marker in match expressions: * bare "?": wildcard placeholder that allows any value without binding it * prefix "?": constrains the value in that position without binding it * infix "?": imposes a value constraint on a value that is being bound to a name (means the walrus matching pattern is only needed in cases where a value is being both bound and deconstructed - simple cases would be written like "name?None" rather than "name:=None") With this spelling, the named value constraint example from the PEP would look like this (with an extra case added showing infix value constraints): === match color: case (primary?GREEN, highlights?BLUE): print("Two tone, huh? Nice!") case ?BLACK | ?Color.BLACK: print("Black suits every color") case BLACK: # This will just assign a new value to BLACK. ... === I'll note that adopting this approach would likely mean that "?0", "?None", etc would qualify as legal value constraints, so a separate decision would need to be made if it was allowed to omit the prefix for literal constraints on values that weren't being bound to a name. A decision would also need to be made on whether the RHS of "?" constraints was permitted to be a full expression or not (e.g. if function calls were allowed, I believe there would be significant potential for confusion with class constraints). Cheers, Nick.

Unfortunately there are millions of ideas. The PEP authors are taking the dilemma seriously and we are deliberating what to do. On Thu, Jul 2, 2020 at 4:04 PM Nick Coghlan <ncoghlan@gmail.com> wrote:
On Thu., 2 Jul. 2020, 11:18 am Guido van Rossum, <guido@python.org> wrote:
On Wed, Jul 1, 2020 at 5:50 PM Nick Coghlan <ncoghlan@gmail.com> wrote:
The key thing I'm hoping for in PEP 622 itself is that "Syntactic compatibility with a possible future enhancement to assignment statements" be considered as a constraint on the syntax for case patterns.
That would certainly rule out ideas like writing stores as $x or x? or <x> etc., since it would be syntactically incompatible with *current* assignment statements.
Yeah, having stores be unmarked is perfectly consistent with existing assignment statements and expressions, so I now think the PEP is correct to propose that.
However, the two parts of the match lvalue proposal that are a genuine problem from a syntactic consistency perspective are:
* using "." to mark value constraints (already means attribute binding in assignment lvalues) * using "_" to mark wildcard placeholders (already means a normal variable binding in assignment lvalues)
The conclusion I came to from that observation was that to allow for potential future syntactic consistency, it isn't variable bindings that need a symbolic prefix in match lvalues, it's value constraints.
That then leads to the idea of using "?" as a general "value constraint" marker in match expressions:
* bare "?": wildcard placeholder that allows any value without binding it * prefix "?": constrains the value in that position without binding it * infix "?": imposes a value constraint on a value that is being bound to a name (means the walrus matching pattern is only needed in cases where a value is being both bound and deconstructed - simple cases would be written like "name?None" rather than "name:=None")
With this spelling, the named value constraint example from the PEP would look like this (with an extra case added showing infix value constraints):
=== match color: case (primary?GREEN, highlights?BLUE): print("Two tone, huh? Nice!") case ?BLACK | ?Color.BLACK: print("Black suits every color") case BLACK: # This will just assign a new value to BLACK. ... ===
I'll note that adopting this approach would likely mean that "?0", "?None", etc would qualify as legal value constraints, so a separate decision would need to be made if it was allowed to omit the prefix for literal constraints on values that weren't being bound to a name.
A decision would also need to be made on whether the RHS of "?" constraints was permitted to be a full expression or not (e.g. if function calls were allowed, I believe there would be significant potential for confusion with class constraints).
Cheers, Nick.
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>
participants (12)
-
Brett Cannon
-
Daniel Moisset
-
Devin Jeanpierre
-
Elliott Chen
-
Guido van Rossum
-
Jim J. Jewett
-
MRAB
-
Nick Coghlan
-
Paul Ganssle
-
Rhodri James
-
Rob Cliffe
-
Terry Reedy