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

Reply via email to