On Mon, Aug 24, 2020 at 01:10:26PM -0400, Ricky Teachey wrote:

> SIGNATURE === SEMANTICS
> (self, a, b) === (self, key_tuple, value)
> 
> In the above, a on the left side, semantically, is the key tuple, and b in
> the value on the RHS.

That's not how Python works today. Individual values aren't packed into 
a tuple.

    mylist[5] = "value"

calls `__setitem__(5, "value")`. The argument here is the int 5, not the 
tuple (5,).

Presumably you wouldn't say that the semantics are:

    __setitem__(self, key_tuple, value_tuple)

just because we have this:

    obj[1] = spam, eggs, cheese


I think that the best (correct?) way of interpreting the subscript 
behaviour is that the subscript pseudo-operator `[...]` has a lower 
precedence than the comma pseudo-operator. So when the parser sees the 
subscript square brackets:

    obj[   ]

it parses the contents of those brackets as an expression. What do 
commas do inside expressions? They make tuples. So "positional 
arguments" to a subscript are naturally bundled together into a tuple. 
It's not that the interpreter has a special rule for this, it's just a 
way the precedence works out.

(I welcome correction if that is wrong.)

In the same way that assignment has lower precedence than comma, so the 
parser automatically bundles the `spam, eggs, cheese` into a single 
value which just happens to be a tuple before doing the assignment.


[...]
> Signature dependent semantics, as the name suggests, would change the
> semantic meaning of the __setitem__ signature in the case that more than
> two parameters are given in the signature.
> 
> In other words, if a signature is provided like this, with 3 or more
> arguments:
> 
> def: __setitem__(self, a, b, c): ...
> 
> ...then in that case, the language would know there is a different semantic
> meaning intended.

The only way it could tell that would be to inspect *at runtime* the 
`__setitem__` method. And it would have to do this on every subscript 
call. Introspection is likely to be slow, possibly very slow. This would 
make subscripting slow.

And it would break backwards compatibility. Right now, it is legal for 
subscript methods to be written like this:

    def __setitem__(self, item, value, extra=something)

and there is no way for subscripting to call the method with that extra 
argument provided. Only if the user intentionally calls the dunder 
method themselves can they provide that extra argument.

Not only is that legal, but it's also useful. E.g. the class might call 
the dunder directly, and provide non-default extra arguments, or it 
might use parameters as static storage (see the random module for 
examples of methods that do that).

But your proposal will break that code.

Right now, I could even define my dunder method like this:

    def __setitem__(*args)

and it will Just Work because there is nothing special at all about 
parameter passing, even self is handled as a standard argument. Your 
proposal will break that:


    obj[1, 2, 3] = None

    # current semantics will pass in
    # args = (obj, (1, 2, 3), None)

    # your semantics will presumably pass in
    # args = (obj, 1, 2, 3, None)


So, we have a proposal for a change that nobody has requested, that adds 
no useful functionality and fixes no problems, that is backwards 
incompatible and will slow down every single subscripting operation. 
What's not to like about it? :-)

Maybe we wouldn't have designed subscripting this way back in Python 1 
if we know what we know now, but it works well enough, and we have heard 
from numpy developers like Stephan Hoyer that this is not a problem that 
needs fixing. Can we please stop trying to "fix" positional subscripts?

Adding keywords to subscripts is a genuinely useful new feature that I 
personally am really hoping I can use in the future, and it is really 
frustrating to see the PEP being derailed time and time again.


-- 
Steve
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/VGZ57HTDRB7A72OHDLXUSIWNDNPPM26N/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to