From: CTips on 14 Jun 2005 20:02 Isaac Gouy wrote: > > CTips wrote: > >>Robert C. Martin wrote: >> >>>On Sun, 12 Jun 2005 07:27:44 -0400, CTips <ctips(a)bestweb.net> wrote: >>> >>> >>> >>> >>>>This means that you need to know _ALL_ other shape sub-classes out there >>>>before you can actually implement the function intersects(). >>> >>> >>>Granted. And when you add new shapes you have to modify the >>>intersection visitor. That's just part and parcel of the problem. >>> >> >>However, you're now left with the issue that: >>a) X & Y subclass shape adding X-shape & Y-shape >>b) X & Y don't know about each other, so they don't add an >>X_intersects_Y function >>c) intersect(X_shape, Y_shape) gets called and results in a run-time crash. >> >>IOW: in most dynamic dispatch languages, the type-system is not strong >>enough to ensure that at compile time [or some equivalent static >>analysis phase] all functions are filled in. > > > In several dynamic dispatch languages the type-system is perfectly > adequate: This is not a dynamic dispatch example. The *actual* type of both caller and callee are known at the call point. What you want to do is the equivalent of: do_something( Shape * A, Shape * B) { A->intersect(B); } Here you (and the compiler) have no idea of of what the type is until run-time. > I:\test\shape\shape.nice: line 3, column 6: > The implementation test failed for method nice.lang.void > intersect(test.shape.Shape s1,test.shape.Shape s2): > no alternative matches (test.rectangle.Rectangle, > test.rectangle.Rectangle) > compilation failed with 1 error > > > >>Further, since the >>information about all subclasses of the type is not centralized, it is >>non-trivial for a user to guarantee that each of these pair-wise >>functions has been filled in. > > > I guess we could collect those intersect methods in the same place: > > //--- separate file > package test.intersect; > import test.shape; > import test.circle; > import test.rectangle; > > intersect(Circle s1, Rectangle s2){} > intersect(Rectangle s1, Circle s2){} > > > > //--- separate file > package test.shape; > abstract class Shape {} > void intersect(Shape s1, Shape s2); > > //--- separate file > package test.circle; > import test.shape; > class Circle extends Shape {} > intersect(Circle s1, Circle s2){} > > //--- separate file > package test.rectangle; > import test.shape; > class Rectangle extends Shape {} > //intersect(Rectangle s1, Rectangle s2){} > > //--- separate file > import test.shape; > import test.rectangle; > import test.circle; > import test.intersect; > > void main(String[] args){ > let r = new Rectangle(); > let c = new Circle(); > c.intersect(r); > c.intersect(c); > r.intersect(c); > r.intersect(r); > } > > > > >>Contrast this to the implementation using a big-old-switch (of switches) >>statement. Each shape will have a tag to control the switch() statement. >>This tag will (probably) be an enumerated type. It is relatively >>straightfoward for: >>- the user to determine all the pairs that are required >>- the compiler to spit out a waring regarding an unimplemented pair > >
From: Isaac Gouy on 14 Jun 2005 20:31 CTips wrote: > This is not a dynamic dispatch example. The *actual* type of both caller > and callee are known at the call point. What you want to do is the > equivalent of: > do_something( Shape * A, Shape * B){ A->intersect(B);} > > Here you (and the compiler) have no idea of of what the type is until > run-time. We get the same compiler error message as before (if we comment out the intersect definition in test.rectangle). //--- separate file import test.shape; import test.rectangle; import test.circle; import test.intersect; void main(String[] args){ let r = new Rectangle(); let c = new Circle(); testIntersect(c,r); testIntersect(c,c); testIntersect(r,c); testIntersect(r,r); } void testIntersect(Shape s1, Shape s2){ s1.intersect(s2); } //--- separate file package test.intersect; import test.shape; import test.circle; import test.rectangle; intersect(Circle s1, Rectangle s2){ println("circle rectangle"); } intersect(Rectangle s1, Circle s2){ println("rectangle circle"); } And if we run the program: I:\test>java -jar test.jar circle rectangle rectangle circle
From: CTips on 14 Jun 2005 21:53 Isaac Gouy wrote: > CTips wrote: > >>This is not a dynamic dispatch example. The *actual* type of both caller >>and callee are known at the call point. What you want to do is the >>equivalent of: >>do_something( Shape * A, Shape * B){ A->intersect(B);} >> >>Here you (and the compiler) have no idea of of what the type is until >>run-time. > What language are you using? Java? Out of curiosity, why isn't main in a class? Is this now legal in Java? > We get the same compiler error message as before (if we comment out the > intersect definition in test.rectangle). > > //--- separate file > import test.shape; > import test.rectangle; > import test.circle; > import test.intersect; > > void main(String[] args){ > let r = new Rectangle(); > let c = new Circle(); > testIntersect(c,r); > testIntersect(c,c); > testIntersect(r,c); > testIntersect(r,r); > } > void testIntersect(Shape s1, Shape s2){ s1.intersect(s2); } > > > //--- separate file > package test.intersect; > import test.shape; > import test.circle; > import test.rectangle; > intersect(Circle s1, Rectangle s2){ println("circle rectangle"); } > intersect(Rectangle s1, Circle s2){ println("rectangle circle"); } > > > And if we run the program: > > I:\test>java -jar test.jar > circle rectangle > rectangle circle >
From: Jeff Brooks on 14 Jun 2005 22:35 Robert C. Martin wrote: > A fractal is like a newsgroup thread. They are all self similar > regardless of scale. :-) hehe Jeff Brooks
From: topmind on 14 Jun 2005 22:44
I am having difficulty finding coherent requirements or code samples for a dosage system. How about we focus on stuff that polymorphs in that example. What are the polymorphic types or classes? -T- |