[Alex] > Of course, it's possible that some such wrappers are coded much > more tighter &c, so that in fact some roundabout A -> X1 -> X2 -> C > would actually be better performing than either A -> B -> C or A -> Z > -> C, but using one of the shortest available paths appears to be a > reasonable heuristic for what, if one "assumes away" any degradation, > is after all a minor issue.
I would think that the main reason for preferring the shortest path is the two degenerate cases, A->A (no adaptation necessary) and A->C (a direct adapter is available). These are always preferable over longer possibilities. > Demanding that the set of paths of minimal available length has exactly > one element is strange, though, I think you're over-emphasizing this point (in several messages); somehow you sound a bit like you're triumphant over having found a bug in your opponent's reasoning. [...] > So, yes, I'd _also_ love to have two grades of inheritance, one of the > "total commitment" kind (implying transitivity and whatever), and one > more earthly a la ``I'm just doing some convenient reuse, leave me > alone''. I'll bet that the list of situations where occasionally you wish you had more control over Python's behavior is a lot longer than that, and I think that if we started implementing that wish list (or anybody's wish list), we would soon find that we had destroyed Python's charming simplicity. My personal POV here: even when you break Liskov in subtle ways, there are lots of situations where assuming substitutability has no ill effects, so I'm happy to pretend that a subclass is always a subtype of all of its base classes, (and their base classes, etc.). If it isn't, you can always provide an explicit adapter to rectify things. As an example where a subclass that isn't a subtype can be used successfully, consider a base class that defines addition to instances of the same class. Now consider a subclass that overrides addition to only handle addition to instances of that same subclass; this is a Liskov violation. Now suppose the base class also has a factory function that produces new instances, and the subclass overrides this to produce new instances of the subclass. Then a function designed to take an instance of the base class and return the sum of the instances produced by calling the factory method a few times will work perfectly with a subclass instance as argument. Concrete: class B: def add(self, other: B) -> B: ... def factory(self) -> B: ... class C(B): def add(self, other: C) -> C: ... # "other: C" violates Liskov def factory(self) -> C: ... def foo(x: B) -> B: x1 = x.factory() x2 = x.factory() return x1.add(x2) This code works fine in today's python if one leaves the type declarations out. I don't think anybody is served by forbidding it. -- --Guido van Rossum (home page: http://www.python.org/~guido/) _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com