# Liskov's substitution principle and prototypical languages

Do prototypical languages provide a remedy from Liskov's problem?

So the way I see this is: a subclass is very tightly coupled with it's superclass and this creates subtle side effects when polymorphic types are used.

So can this be remedied by prototypical languages in the sense that classes inherits from a copy of the superclass instead of all pointing to the same one superclass?

To give an example, suppose I have this class:

``````class Rectangle
constructor(width, length)
this.width = width
this.height = height

function double_width()
this.width = this.width * 2
``````

And now the program uses the rectangles to do business or whatever it needs to do:

``````function Main
Rectangles[] all_rectangles_in_program = new Rectangles[]
all_rectangles_in_program.append(new Rectanlge(5, 10))
do_some_buisness_logic(all_rectangles_in_program)
``````

And then someone in the future needs to add a new feature:

``````class Square inherits Rectangle
constructor(side_length)
super(side_length, side_length)

function double_width()
this.width = this.width * 2
this.length = this.length * 2

// MAIN HAS BEEN CHANGED BY OUR COLLEAGUE IN THE FUTURE

function Main
Rectangles[] all_rectangles_in_program = new Rectangles[]
all_rectangles_in_program.append(new Rectangle(5, 10))

Square s = new Square(10)                         <--- new code
all_rectangles_in_program.append(s)               <--- new code

``````

The problem is that square overrides the function double_width but introduces a side effect that rectangle didn't have namely that when you change the width now the length changes too. This is a problem because the original program `do_some_business_logic` may have relied somewhere on the fact that the length of a rectangle doesn't change when you change it's width. Remember that the array `all_rectangles_in_program` is polymorphic type and the original code `do_some_business_logic` doesn't know if these are rectangles or squares in it. The run-time system decides which version of `double_width` to call.

So my question is, does prototypical inheritance alleviate this problem because you don't inherit one superclass everywhere in the program but instead inherit your own copy of the superclass?

If not, then what's the advantage of prototypical languages over class based languages?

• I don't find that one OOP mechanism is necessarily superior, just different. You might be interested in checking out the design of Self. Commented Jan 11, 2017 at 1:09
• This is just the standard square-rectangle problem, and whether you use a prototype-based inheritance model or not doesn't change anything. Commented Jan 11, 2017 at 1:50
• I have no idea what you mean by "inherit your own copy of the superclass"? Maybe you misunderstand what prototypal inheritance means, there is no copying involved. Commented Jan 11, 2017 at 1:52
• I think your example is bad... why not just instantiate the square as a rectangle that just happens to have width == length. Then when width is doubled, it will just be a normal rectangle. Is there an example of this problem which CANNOT be solved as I've done here? Basically, the example is over-doing polymorphism. Commented Jan 12, 2017 at 5:03

All squares are rectangles but not all rectangles are squares.

You've violated the History constraint of LSP.

• Actually abstract square is not abstract rectangle, because it behaves differently. Commented Jan 12, 2017 at 14:02

Your `double_width` function in Square class does not double width, but doubles both dimensions.

So it is not `double_width` at all and cannot override parent method... It is prohibited for Square to double width only.

You have to have method like `double_dimensions`, either in parent or just in square.

• Hi Vadim. You said "Your double_width function in Square class does not double width, but doubles both dimensions". That must be the case because a Sqaure must have width == length. How would you double the width of a square?
– Jenia Ivanov
Commented Jan 11, 2017 at 1:33
• Please, look at this from other side. Yes, square has width == length. It means there is no way to double width only, so method double_width must do nothing with square (may throw exception as example).