Square is-a Rect? (more thoughts on immutable programming)
ajoo 2002-05-07 07:27:50 there's classic paradox, "whether square is a rectangle".
Actually this question does not make sense. Without giving all the required behavior and runtime semantics definition, nobody can tell the answer.
I remember somebody presented this question to me on mit bbs. Based on my assumption of the required operations, getter and setters, I told him "yes". And then he started laughing at me, "I set a trap, and you jumped in. How do you handle the setters?"
I knew what he means, in his assumption, the interface would be like
Rectangle
int getWidth();
int getHeight();
void setWidth(int);
void setHeight(int);
Square
int getSize();
void setSize();
Then of course, Square cannot be a subtype of Rectangle because the setters are not safe after subsumption.
Square s;
Rectangle r = s;
r.setWidth(5);
//now s is not a square at all!
But the fact is: we made different assumptions.
If I implement this, I would implement it immutably. i.e.
Rectangle
int getWidth();
int getHeight();
Rectangle setWidth(int); //this is also called functional update
Rectangle setHeight(int);
Square
int getSize();
Square setSize();
then we are safe to say "Square is a Rectangle" now!
Another benefit of "immutable pattern", right?
Also, even though we want to insist on mutable implementation, dividing mutable and immutable parts can also work. i.e.
RectR
int getWidth();
int getHeight();
RectW
void setWidth(int);
void setHeight(int);
Rect: RectR, RectW
SquareR
int getSize();
SquareW
void setSize();
Square: SquareR, SquareW
Here, although there's no "is-a" relationship between Square and Rectangle, there exists such thing between SquareR and RectR, SquareW and RectW.
That is:
SquareR is a RectR (this is natural)
RectW is a SquareW (people may feel surprised by this, but, trust me, it is safe)
So, if you have a function void display(RectR rect);
you can safely use it to display a Rectangle or a Square.
Another advantage of "immutable programming".