> * __add__ is only part of the addition protocol, there is also > __radd__ and __iadd__
__iadd__ could be represented as def self += value:. Reflected binary operators do pose a problem. A possible solution would be to give self special meaning in this context, so def self + other: would correspond to __add__ and def other + self: to __radd__. But of course, this would be a more fundamental change to the language than just syntactic sugar. > * likewise, there is not a one-to-one correspondence between the > bool() builtin and the __bool__() special method (there are other ways > to support bool(), like defining __len__() on a container) That is a fair point, but I think this would be only a slight point of confusion. I believe for the most part other builtins such as __abs__, __len__, etc. do have a one-to-one correspondence so this syntax would make sense in almost all situations. But while were on the topic, I will take this opportunity to note that all the methods to support builtins suffer from the same ambiguity I alluded to earlier with bool(self). One solution could be to use a @builtin decorator or something to that effect, but that would more or less defeat the purpose of cleaner, more intuitive syntax. It may be that there is no viable alternative for the builtin function dunder methods. > * the mapping protocol covers more than just __getitem__ __setitem__(self, key, value) could be def self[key] = value likewise __delitem__(self, key) def del self[key]: __iter__(self) iter(self) __len__(self) len(self) > (and you also > need to decide if you're implementing a mapping, sequence, or > multi-dimensional array) Could you speak more about this? It doesn't seem to me that this would affect the method signatures since it is up to the implementer to interpret the semantic meaning of the keys. > it would break the current symmetry between between name binding > in def statements and target binding in assignment statements > With the proposed change, we'd face the > problem that the following would both be legal, but meant very > different things: > > cls.mymethod = lambda self: print(self) > def cls.mymethod(self): print(self) > > The former is already legal and assigns the given lambda function as a > method on the existing class, `cls` > > The latter currently throws SyntaxError. > > With the proposed change, rather than throwing SyntaxError as it does > now, the latter would instead be equivalent to: > > def mymethod(cls, self): print(self) > > which would be a very surprising difference in behaviour. I will admit that there is potential for confusion here as this class Formatter(object): def Formatter.displayDefault(obj): print('[{}]'.format(obj)) is rather suggestive of a static method, but I don't think the confusion arises because the syntax breaks the symmetry you reference. The self-dot syntax *is* meant to elicit target binding in assignment statements. Just as self.mymethod = lambda p1, p2: p1+p2 indicates that an instance of the class has a callable with two parameters bound to its mymethod attribute, so too does the statement def self.mymethod(p1, p2):. So I don't think this inherently breaks any symmetry. It is specifically in the case that the identifier is the same as the class name that this leads to surprising behavior, but there is already a similar risk of confusion any time the name of a class is used as an identifier within the class body. Perhaps my proposed syntax does increase this risk since the identifier doesn't look like a parameter or a variable, but hopefully the self form of this syntax would be so commonplace that seeing anything else before the dot would throw up a red flag. Thanks, -Nate
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/