On Thu, Apr 14, 2022 at 10:46:46AM +1200, Greg Ewing wrote:
> On 13/04/22 8:29 am, Steven D'Aprano wrote:
> >>When multiple parent provide candidate to a method resolution, raise an 
> >>error.
> >
> >Then you aren't doing full MI any more,
> 
> That sounds like a "true Scotsman" argument. Who defines what
> "full MI" means?

If you look at languages that implement MI, and pick the implementations 
which allow it with the fewest restrictions, then that is "full MI".

Class parent/child relationships are not the same as biological 
relationships:

https://www.youtube.com/watch?v=fWQ7TFFKEz8

so I hope that we can agree that excluding cycles and loops in your 
inheritance hierarchy is a necessary restriction, for our sanity if no 
other reason. I don't know of any languages that allow cycles in 
inheritance graphs.

Beyond that, I believe that Python (and other languages) allow MI with 
the smallest set of restrictions, namely that there is a C3 
linearization possible:

https://en.wikipedia.org/wiki/C3_linearization

I believe that those 3 requirements in C3 are the fewest restrictions 
while still having logically consistent behaviour. That's what I mean by 
"full MI".

Of course languages can impose additional restrictions, e.g. that 
methods are independent, there there are no diamonds, etc. But they 
offer less than the full generality that Python (and other languages) 
offer.

For instance, I believe that Eiffel allows MI with diamonds, so long as 
methods in different branches are independent. If two classes provide 
the same method, Eiffel raises an exception.

(Michele Simionato calls this behaviour equivalent to traits.)

That is *more restrictive* than Python, and so it offers *less* than a 
fully general model of MI.

On the other hand, sometimes "less is more", and Michele has come to 
believe that Python's fully general MI is too powerful to be usable, and 
that more restrictive versions (traits) are better, or even avoiding 
inheritance in favour of generics, composition and delegation.

We can implement mixins, or traits, or Eiffel-style inheritance, or 
whatever extra restrictions you want, using decorators or metaclasses. 
They don't need a change to the language definition of MI.


> I can think of at least two languages that do something very
> similar to what malmalitia is proposing: C++ and (if I remember
> rightly) Eiffel. I don't think I've heard anyone claim that
> C++ doesn't do "full MI".

Oooh, ooh, let me sir!

"C++ doesn't do full multiple inheritance."

If you have to manually call a specific method, as shown here:

https://devblogs.microsoft.com/oldnewthing/20210813-05/?p=105554

you're no longer using inheritance, you're doing delegation.

I make no comment on whether C++ is justified on restricting inheritance 
in that way. Michele Simionato declares that C++ implements MI "badly", 
but I don't know his reason for that judgement.

Multiple inheritance is complex. Managing that complexity is hard. It 
may be that that best way to manage it is to forgo the full generality 
of MI and all the complexity it brings, or by not using inheritance at 
all.

But either way, Python currently offers MI in its full generality. 
Restricting it at the language level is a breaking change, and will not 
happen.


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

Reply via email to