Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!uupsi!sunic!dkuug!diku!juul From: juul@diku.dk (Anders Juul Munch) Newsgroups: comp.object Subject: Re: Readability of Ada Message-ID: <1991Apr23.193715.23815@odin.diku.dk> Date: 23 Apr 91 19:37:15 GMT References: <3878@ssc-bee.ssc-vax.UUCP> <20245@alice.att.com> Sender: juul@skinfaxe.diku.dk Organization: Department of Computer Science, U of Copenhagen Lines: 87 jls@rutabaga.Rational.COM (Jim Showalter) writes: [stuff deleted] >I've been wanting to ask someone who purports to know the answer >this question for over a year. >Consider the shapes example. Suppose that the given example goes >out in binary form, and arrives at my site, and I want to add a new >shape. Suppose that the initial shapes were limited to triangles and >squares. Suppose that I now add a Circle, which has a new method >defined for it that does NOT apply to triangles or squares and which >was never previously defined in the base class for shapes--radius. >This method returns the radius as some floating point number from 0 >to whatever. >Now, I want to take a heterogeneous list of shapes, including triangles, >circles, and squares, and I want to iterate over the list and print >out all of the radii. Who wrote the heterogeneous-list code? The guy who supplied the shape classes? Of course not, because then he would have realized the need for a shape method to identify exactly what kind of shape it is. >How do I do this? I can't get elements out of the list and call >the Radius method on all of them, because not all of them HAVE such >a method defined. I can't add the new method to the base class (with >a null implementation as the default for those shapes for which it >is a meaningless operation) because the base class is in binary. I >can't ask the shapes to tell me their Kind because there is no such >operation defined on them in C++. That's why any C++ library programmer with just a little bit of sense adds such an operation. If the guy who wrote your binary collection of shape classes didn't do that, that's not a C++ problem: No language, not even Ada can protect you against stupid programmers. C++ has a built-in type-discriminating mechanism called "dynamic binding". It's not universal, but it's there for free, without the programmer having to write special code or declare special tags for this purpose. And you still have the option of declaring and using an explicit tag, whenever you need one. But most of the time, a sufficent mechanism is already there, not cluttering your code with enumerator and union field names. >It is my claim that solving this problem in C++ results in a solution >that is every bit as messy as simply using a discriminated record >and an enumeration type in Ada--and Ada doesn't HAVE inheritance. I suppose the kind of language construct you are referring to is the equivalent of Pascal variant records (RECORD-CASE) or C enums and unions. Good luck with your table-driven software!! By the way, how about adding the tag method like this: typedef enum { CIRCLE_TAG, TRIANGLE_TAG, SQUARE_TAG } TAG; class TAG_BASE { virtual TAG Tag() = 0; }; #define TAGIFY(SHAPE) \ class SHAPE##_TAG : TAG_BASE { TAG Tag() { return SHAPE##_TAG } }; \ class MY_##SHAPE : SHAPE, SHAPE##TAG {} TAGIFY(CIRCLE); TAGIFY(SQUARE); TAGIFY(TRIANGLE); This leaves you with three new classes, MY_CIRCLE, MY_SQUARE and MY_TRIANGLE, with all the functionality of the old classes, plus, if x is an instance of one of these classes, you may inquire whether "x.Tag()==CIRCLE_TAG", and your problem is solved. Still, this approach has it's problems, and I'm not claiming C++ to be superior to Ada. I am claiming, however, that dynamic binding is a valuable feature which Ada is missing. >-- >* The opinions expressed herein are my own, except in the realm of software * >* engineering, in which case I borrowed them from incredibly smart people. * I suggest you find some that are even smarter :-) >* * >* Rational: cutting-edge software engineering technology and services. * -- Anders Munch