On Wed, Jun 26, 2019 at 10:16 PM Chris Angelico email@example.com wrote:
On Thu, Jun 27, 2019 at 5:29 AM Yanghao Hua firstname.lastname@example.org wrote:
On Wed, Jun 26, 2019 at 4:47 PM Chris Angelico email@example.com wrote: [...]
There are many things that can be implemented with dunders, yes, but in Python, I would expect these two functions to behave identically:
def f1(x): return frob(x).spam
def f2(x): f = frob(x) s = f.spam return s
This correlation is critical to sane refactoring. You should be able to transform f1 into f2, and then insert print calls to see what 'f' and 's' are, without affecting the behaviour of the function. The proposed magic would change and completely break this; and as such, it violates programmer expectations *across many languages* regarding refactoring.
Chris, I might need a bit more education here. I am trying to guess what you meant to say here is if in f2(), f or s is already defined, it will then change the "usual" understanding. In this case, I am assuming when you start to assign in f2() a local variable f or s with an object that has __set/getself__(), then you know later on assigning to it will mean differently. How is this different from descriptors? when you do x.y = z and if y is a descriptor you don't expect x.y is now pointing/binding to z, you have to understand the object behavior anyway. I do not see how this is different in the set/getself() case.
Let's suppose that frob() returns something that has a __getself__ method. Will f1 trigger its call? Will f2? If the answer is "yes" to both, then when ISN'T getself called? If the answer is "no" to both,
What's the problem for the "yes" case? If you define such an object of course __get/setself__() is always called, and f1() is still equal to f2().
then when IS it called? And if they're different, then you have the refactoring headache that I described. That's a problem that simply doesn't happen with descriptors, because this example is using local variables - local variables are the obvious way to refactor anything.
What's the point if it is never called? I cannot make any sense from this example unfortunately, maybe I am too dumb ...
You're proposing allowing values to redefine local variables. That is completely different from descriptors and other forms of magic, which allow a namespace to define how it behaves.
First, this is not my proposal. The one I had is a new operator, and it is NOT allowing values to redefine local variables. But I do like this one a lot more indeed. Second, isn't descriptor doing exactly the same thing, but just within your so called "namespace"? Isn't the top level itself a namespace? isn't every function local itself a namespace? The entire descriptor concept in my view is a awkward concept that is having too many odds and special cases. And this one, on the other hand, is truly generic and universal.
I'm basically done trying to explain this to you. Multiple people have tried to explain how this is NOT the same as descriptors, and you keep coming back to "but descriptors can do this too". They cannot. You are granting magical powers to *values*, not to namespaces. That makes basically ALL code impossible to reason about.
Sheep can never explain to wolfs why it is a good idea to be vegetarian, can they? And like wise vice versa. Please help to teach me and trust that a 10 years python developer could still learn a thing or two. And don't be too childish ;-) I really just don't get the point (if there is one).