Re: colored point redux
Vadim Nasardinov <[email protected]> Sun, 25 Feb 2007 22:21:28 -0500
| Newsgroups | gmane.comp.lang.lightweight |
|---|---|
| Message-ID | <[email protected]> |
On Sunday 25 February 2007 06:45, Pascal Costanza wrote: > On 25 Feb 2007, at 04:23, Vadim Nasardinov wrote: > > Much better because it's more honest. We have now completely > > abandoned any pretense of Liskov substitutability: 'COLOR-POINT is > > no longer a subtype of 'COLOR. Which is as it should be. If we > > are completely honest, however, we should take this a step further > > and change the IS-A relationship to HAS-A. > > ...and this relates to generic functions how? It shows a typical pattern of abuse. First, you paint yourself into a corner by treating ColorPoint as a subtype of Point -- a demonstrably false proposition. Once cornered, you reach for the Swiss-army chainsaw of generic methods to try to dig yourself out of this hole. (One must mix metaphors now and then.) A better way to handle this is relax, take a deep breath, and see with startling clarity that all this pain is entirely self-inflicted. ColorPoint is not a subtype of Point. Hence, it shouldn't be a subclass. Once this crucial insight is gained, everything else falls into place quite neatly and without multiple dispatch. I'm not dismissing multiple dispatch as entirely useless. I'm saying it's overused in much the same way that macros are overused in Common Lisp. 90% of the uses of macros in Lisp would disappear if only Lisp had lightweight thunks like the call-by-name syntax in Scala. Now, some will undoubtedly object that I can't generalize with such sweeping abandon about 90% of something I haven't seen. However, it will take more than the quibbles of armchair epistemologists to convince the average programmer that what they see with their own eyes is not the truth. > > As Eric Gamma says, "Favor composition over inheritance": > > Yes, just another opinion. It's an opinion based on the following cold hard fact (Message-Id: <[email protected]>): | There's a tight coupling between the base class and the subclass, | because of the implicit context in which the subclass code I plug | in will be called. Composition has a nicer property. The coupling | is reduced by just having some smaller things you plug into | something bigger, and the bigger object just calls the smaller | object back. From an API point of view defining that a method can | be overridden is a stronger commitment than defining that a method | can be called. > But what do you think the following lines simulate? > > [...] > > | if (!(obj instanceof Point)) { return false; } > > | Point that = (Point) obj; > [...] Pray tell.