On 14 Feb 2015 07:39, "Isaac Schwabacher" <ischwabacher@wisc.edu> wrote:
>
> On 15-02-13, Guido van Rossum  wrote:
> > Are you willing to wait 10 days for an answer? I&#39;m out of round tuits for a while.
>
> IIUC, the argument is that the Liskov Substitution Principle is a statement about how objects of a subtype behave relative to objects of a supertype, and it doesn't apply to constructors because they aren't behaviors of existing objects. So other overriding methods *should* be able to handle the same inputs that the respective overridden methods do, but constructors don't need to. Even though __init__ is written as an instance method, it seems like it's "morally" a part of the class method __new__ that's only split off for convenience.

A potentially helpful example is to consider a type system where Square is a subclass of Rectangle.

To specify a Rectangle takes a height and a width, but a Square only needs the length of one side, and letting the height and width be specified independently would be outright wrong.

Many possible operations on a Square also *should* formally return a Rectangle, as doing something like doubling the height gives you a result that isn't a square any more. (That's also why shapes must be immutable for this particular type hierarchy to make any sense)

(You can construct similar examples for Circle & Ellipse, and Python's numeric hierarchy is a real-world example of some of the complexity that can arise)

There's simply no sensible default behaviour other than the status quo in the face of scenarios like that - whether or not there's a better answer than "return an instance of the parent class" for any given inherited method depends entirely on the invariants of the subclass and how they differ from those of the parent class.

It's certainly possible to write methods that return a new instance of the current type (that's common in alternative constructors, for example), but it usually involves placing additional expectations on the developers of subclasses. That's most commonly seen within the confines of a single project, or when defining a development framework, rather than in libraries that choose to expose some public types and also supports their use as base types.

Cheers,
Nick.

>
> If this message is unclear, it's because I don't really understand this myself and I'm trying to articulate my best understanding of what's been said on this thread and those it links to.
>
> ijs
>
> > On Fri, Feb 13, 2015 at 10:22 AM, Alexander Belopolsky <alexander.belopolsky@gmail.com(javascript:main.compose()> wrote:
> >
> > >
> > > On Fri, Feb 13, 2015 at 1:19 PM, Alexander Belopolsky <alexander.belopolsky@gmail.com(javascript:main.compose()> wrote:
> > > >>
> > > >> FWIW you&#39;re wrong when you claim that "a constructor is no different from any other method". Someone else should probably explain this (it&#39;s an old argument that&#39;s been thoroughly settled).
> > > >
> > > >
> > > > Well, the best answer I&#39;ve got in the past [1] was "ask on python-dev since Guido called the operator overriding expectation." :-)
> > >
> > >
> > > And let me repost this bit of history [1]:
> > >
> > > Here is the annotated pre-r82065 code:
> > >
> > > 39876 gvanrossum def __add__(self, other):
> > > 39876 gvanrossum if isinstance(other, timedelta):
> > > 39928 gvanrossum return self.__class__(self.__days + other.__days,
> > > 39876 gvanrossum self.__seconds + other.__seconds,
> > > 39876 gvanrossum self.__microseconds + other.__microseconds)
> > > 40207 tim_one return NotImplemented
> > > 39876 gvanrossum
> > >
> > >
> > >
> > > [1] http://bugs.python.org/issue2267#msg125979
> > >
> > >
> >
> >
> >
> >
> > --
> > --Guido van Rossum (python.org/~guido(http://python.org/~guido))
> _______________________________________________
> Python-Dev mailing list
> Python-Dev@python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe: https://mail.python.org/mailman/options/python-dev/ncoghlan%40gmail.com