Steven D'Aprano writes:
> > All we have today is the screwhammer, and in cases the screw part 
> > don't work, you're telling me to get rid of it all. hammer part 
> > included.

> That's not how I see it.

> I see that we have a screwdriver (inheritence, including multiple 
> inheritence) which is designed for the cases where you, the programmer, 
> don't want to manually specify which superclass method to call, you want 
> the interpreter to do it using the defined linearisation.

> And then we have a hammer, composition/delegation, for when you *do* 
> want to control what method is called.

What i meant was that today's super does 2 things : it decide its target, and 
then, it proxyies to it.

In my gobelin exemple, we would still benefit from a proxy feature, but since 
the targeting algorithm of super can't match our needs, we need to let go of it.
And while doing so, we have to let go of super proxying feature.

Also, i believe the idea of using anything but super to access a parent methods 
is far from obvious to most people.
Imagine you've spent your entire python life doing that with super.
You're likely not to think of the class.method syntax, especially since it's 
almost never used in any other scenarios.
at least in my 5-6 years of python (with and without multiple inheritance, may 
i add), I never encountered such a scenario.

This alone justifies the idea that any newcomer to this kind of problem would 
try to use super, at least at first.
And possibly wouldn't expect super targeting to behave like it does.

After all, inheritance means "child *is a* parent".
In the gobelin case, halfbreed *is a* proudgobelin, as much as it *is a* 
corruptedgobelin.
So what we, (experienced people that might already have learnt from painful 
experiences) would consider a naive implementation, makes sense, in term of 
concepts relationships.
On top of that, if proudgobelin and corruptegobelin are published by a 
game_engine library, the game_engine user would most likely not be aware (nor 
should he care) that they both inherit from a same parent.

You would most definitely not expect proudgobelin behavior to 'extend' 
corruptedgobelin behavior, as in this scenario, they are completely 
independant, as far as you know.

And let's face it, we would never make sure 2 classes we import from a library 
aren't sharing a parent. This could happen to all of us.

The most likely way for us to discover that, is to burn ourselves first with 
this (at the time of discovering it) unexpected behavior.

We could add a few keywords to super, such as target, to get the class targeted 
by super, use_target_mro, to get some more control over how super will visit 
the parent classes, and possibly instance, to pass the "self", which today has 
to be the second argument, and with the keyword target, we wouldn't pass the 
class as first argument, so that wouldn't be possibly placed in second.

That would cover the gobelin case, by essentially separating the targeting 
algorithm from the proxy feature.
But that on its own would not prevent the game_engine case. You would still 
have to get burnt first to realise the 2 class your inheriting from are related.

Which to me is a real issue, to say the least. There are scenarios where we 
don't have enough knowledge to fully predict the behavior of the code we are 
writing, that should most definitely not happen.

Steven D'Aprano writes:
> I for one frequently find myself being surprised by super and the MRO, 
> which I interpret as *my misunderstanding* rather than a problem with 
> super and the MRO. As soon as you leave the nice, cosy world of single 
> inheritence, things get complicated.
You can interpret it however you want, but i for one would never interpret a 
misuse of a feature as being a user's problem. And the two side of that coin 
are :
 1 feeling that "you failed" when you couldn't use properly whatever you're 
trying to use (be it a python feature, or your bank website, your door knobs, 
or whatever)
 2 Accusing users of your product to be the one in the wrong, and refusing even 
the idea that you, as the feature designer, could do anything about it.
Which is was a lot of people on this thread are doing, simply asserting that 
"this is not how to use super".

In fact, current misuse of a feature could be considered a 'UX smell' as much 
as code with too much repeatition is considered a 'code smell'
Since we are discussing the design / UX of super and MRO this is actually a 
relevant distinction.

And as much as so many of you are asserting users to be in the wrong, i 
disagree.
Specifically in this case because the most common use case (simple inheritance) 
hints at a behavior of super, that turns out to be somewhat deceptive in more 
complex cases.

This *is* the UX smell i wanna adress. And 'nah, i don't care about dumb users' 
is not a valid answer, as far as i'm concerned.
At least in this case. Again, since super hints at a behavior it doesn't 
provide.

I'll have to go for tonight, I kinda wanna talk about the Michele Simionato 
articles you linked.
Some very interesting conception there, but i don't agree with everything.
Mainly, i think the mixin talk forget about some uses of mixins today, but 
deserves to be talked about in here, and i think there's a few nice points 
about the fundamental of what we mean when we practice inheritance. Very 
interesting talks.
_______________________________________________
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/SZHULQARP3ZJA6QSR3LKDVS663GTRZMY/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to