From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,6129ccd596d4814d X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news1.google.com!news.glorb.com!border1.nntp.dca.giganews.com!border2.nntp.dca.giganews.com!nntp.giganews.com!elnk-atl-nf1!newsfeed.earthlink.net!stamper.news.atl.earthlink.net!newsread3.news.atl.earthlink.net.POSTED!d9c68f36!not-for-mail From: Marin David Condic User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.2) Gecko/20040804 Netscape/7.2 (ax) X-Accept-Language: en-us, en MIME-Version: 1.0 Newsgroups: comp.lang.ada Subject: Re: Abstract Operations On A Tagged Record References: <2uhsidF2ahq9fU1@uni-berlin.de> In-Reply-To: <2uhsidF2ahq9fU1@uni-berlin.de> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Message-ID: <3qqhd.16031$ta5.3884@newsread3.news.atl.earthlink.net> Date: Mon, 01 Nov 2004 12:58:39 GMT NNTP-Posting-Host: 209.165.22.76 X-Complaints-To: abuse@earthlink.net X-Trace: newsread3.news.atl.earthlink.net 1099313919 209.165.22.76 (Mon, 01 Nov 2004 04:58:39 PST) NNTP-Posting-Date: Mon, 01 Nov 2004 04:58:39 PST Organization: EarthLink Inc. -- http://www.EarthLink.net Xref: g2news1.google.com comp.lang.ada:5953 Date: 2004-11-01T12:58:39+00:00 List-Id: Thanks for the response. As both you and Dimitry observed, I rather neglected to toss in the class parameter. I should have put in an example with a base class operation that looked like: procedure Some_Op (The_Thing : in out Some_Tagged_Type'Class) is abstract ; Then the intent was to discuss the need to have child operations with different parameter profiles: procedure Some_Op (The_Thing : in out Some_Tagged_Type_Child1 ; Parm1 : in Integer) is abstract ; procedure Some_Op (The_Thing : in out Some_Tagged_Type_Child2 ; Parm1 : in Boolean; Parm_2 : in Float) is abstract ; My understanding from your explanation is that I can't really get around having to fill in *something* for: procedure Some_Op (The_Thing : in out Some_Tagged_Type'Class) is abstract ; but that overloading takes care of the other cases. I was hoping to avoid having a useless operation dangling around like that. However, I had thought of the case you mention wherein I could provide another tagged type for the parameter list and do something like this in the base class: procedure Some_Op (The_Thing : in out Some_Tagged_Type'Class; Its_Parms : in Another_Tagged_Type'Class) is abstract ; That sounds like a reasonable answer to the abstraction problem I had. I can identify the need for some parameters down the line without having to specify what they are in the base class. It keeps me from proliferating operations all over the place while allowing me to insist that a certain operation must be provided from anything inherited from the base class. Thanks for the help. MDC Nick Roberts wrote: > Marin David Condic wrote: > >> Can someone clarify my understanding (perhaps again) on abstract >> operations and the implications as a class heierarchy is being >> constructed? Specifically, what I want is something like this: >> >> A base class has an abstract operation, but I may not yet know the >> data types of the parameters - or possibly even the number of >> parameters. ... >> The base class wants to express the basic necessity of "Some_Op" but >> it really doesn't know if it will have 1, 2 or N parameters or of what >> type. My understanding is that if I express that as an abstract >> operation, when I get to the child class, I'll have to supply a real >> operation of the same name and same parameter profile. > > > Correct. > >> (Or can I use a different parameter profile & satisfy the need for a >> concrete implementation of the abstract op? > > > No. > >> My recollection is the compiler whines about it or creates an >> overloading. Is this correct? > > > Correct. (The compiler whines ;-) > >> I realize I can make another procedure "Some_Op" with a different >> parameter list and that overloading will take care of me, but then I >> didn't really need the abstract procedure in the first place, did I? >> It becomes unnecessary baggage that you have to fill in just because >> its there, but you have no intention of using it. > > > Worse than that, you have no dynamic dispatching, which is the whole > point of using a tagged type in the first place. Disaster. > >> Do I understand this correctly? Is there away around it? > > > The solution is simple, Marin. You use /two/ type hierarchies, one to > represent the primary objects, and a secondary one to represent the > detailed parameters of the primitive operation in question. > > For example, suppose we have a primary hierarchy of shapes, and we > want a primitive operation transforming a shape according to a set > of parameters that depends on the shape (and the kind of > transformation): > > type Root_Shape_Type is abstract tagged private; > > type Transformation_Spec is abstract tagged private; > > function Transform (Shape: in Root_Shape_Type; > Spec: in Transformation_Spec'Class) > return Root_Shape_Type'Class is abstract; > > Transformation_Error: exception; > > Note carefully that Transform is a primitive operation of the primary > type Root_Shape_Type. The Spec parameter is of a class wide type, and so > is the result (since a transformation might produce a different kind of > shape). > > We could then declare some transformations, such as: > > type Rotation is new Transformation_Spec with > record > Angle: Radians; > end record; > > type Translation is new Transformation_Spec with > record > Offset: Surface_Offset; > end record; > > and we might declare a polygon, say, as follows: > > type Polygonal_Shape is new Root_Shape_Type with private; > > function Points (Shape: in Polygonal_Shape) return Point_Vector; > > ... -- other polygon operations > > function Transform (Shape: in Polygonal_Shape; > Spec: in Transformation_Spec'Class) > return Root_Shape_Type'Class; > > The body of the Transform function for polygons would have to test the > actual type of the Spec parameter to determine which tranformation to > perform: > > function Transform (Shape: in Polygonal_Shape; > Spec: in Transformation_Spec'Class) > return Root_Shape_Type'Class is > begin > if Spec in Rotation then > declare > Rot_Spec: constant Rotation := Rotation(Spec); > Center: constant Point := Centerpoint(Shape); > Old_Points: constant Point_Vector := Points(Shape); > New_Points: Point_Triple(Old_Points'Range); > begin > for P in Old_Points'Range loop > New_Points(P) := > Rotate( Old_Points(P), Center, Rot_Spec.Angle ); > end loop; > return To_Polygon(New_Points); > end; > elsif Spec in Translation then > ... > else > raise Transformation_Error; -- unrecognized transformation > end if; > end Transform; > > I think it is interesting to note that some languages, such as Cecil, > provide a way to select an operation's implementation (body) on two or > more parameters, rather than just one. Cecil is a very interesting > language (but not yet mature enough for real use, I think). > > Nevertheless, Ada's lowly single selection still permits new shapes to > be added to a program without having to worry about how this affects > other parts of the program (in general), and this could be very useful. > > Note also that you might possibly wish to swap the roles of shape and > transformation, so that Transform becomes a primitive operation of > Transformation_Spec (instead of Root_Shape_Type), and bodies of the > function have to test for different shapes. This would allow you to > add new transformations in a very independent manner. > > HTH > -- ====================================================================== Marin David Condic I work for: http://www.belcan.com/ My project is: http://www.jsf.mil/NSFrames.htm Send Replies To: m o d c @ a m o g c n i c . r "Power corrupts. Absolute power is kind of neat" -- John Lehman, Secretary of the Navy 1981-1987 ======================================================================