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,FREEMAIL_FROM autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,4687ad82921cf6ad X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2004-01-16 19:41:52 PST Path: archiver1.google.com!news2.google.com!newsfeed2.dallas1.level3.net!news.level3.com!news-out.visi.com!petbe.visi.com!upp1.onvoy!msc1.onvoy!onvoy.com!tethys.csu.net!newshub.sdsu.edu!elnk-nf2-pas!elnk-pas-nf1!newsfeed.earthlink.net!pd7cy1no!shaw.ca!border1.nntp.ash.giganews.com!border2.nntp.sjc.giganews.com!border1.nntp.sjc.giganews.com!nntp.giganews.com!local1.nntp.sjc.giganews.com!nntp.comcast.com!news.comcast.com.POSTED!not-for-mail NNTP-Posting-Date: Fri, 16 Jan 2004 21:41:50 -0600 Date: Fri, 16 Jan 2004 22:41:49 -0500 From: "Robert I. Eachus" User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.4) Gecko/20030624 Netscape/7.1 (ax) X-Accept-Language: en-us, en MIME-Version: 1.0 Newsgroups: comp.lang.ada Subject: Re: issue with implementing a visitor design pattern References: <100dqeul3pqiua0@corp.supernews.com> In-Reply-To: <100dqeul3pqiua0@corp.supernews.com> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Message-ID: NNTP-Posting-Host: 24.34.214.193 X-Trace: sv3-pmz63uIm9AIv0NwtI/joAiAgjg797qSBInzGpaShaczqd4kZl+2TDG+SND2Zn+FUAenU5XX0/iFfSSY!geca1uGeYSa/pDb/pq7pvvvzG+UUCOfsRS2NZdqLZwiNIg501qG2UXsfzn4J5A== X-Complaints-To: abuse@comcast.net X-DMCA-Complaints-To: dmca@comcast.net X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly X-Postfilter: 1.1 Xref: archiver1.google.com comp.lang.ada:4478 Date: 2004-01-16T22:41:49-05:00 List-Id: cl1 wrote: > i'm trying to implement a visitor pattern for a parse tree(its a simple > calculator at this point). i have an abstract type: I'll try to help... > > type Visitor_Record is abstract tagged null record; > > with primative operations Visit() for each node type like so: > > Visit(V : in out Visitor_Record; Node : in Add_Op'Class) is abstract; > ... > Visit(V : in out Visitor_Record; Node : in Assignment_Node'Class) is > abstract; Do not make Visit classwide. In other words get rid of the 'Class in the definition. For dynamic dispatching where you may need 'Class is as the type of the formal parameter in the call. > what i'm trying to do is implement a Preorder_Visitor_Record type that uses > the Visit() operation to > traverse the tree and calls an operation Visit_Operation() that is also a > primative operation on Preorder_Visitor_Record > like so: > with parse_tree_pkg; use parse_tree_pkg; -- has the parse tree nodes a > primative operation Accept_Visitor() for each node > -- and the > abstract Visitor_Record with primative operations Visit() for each node > package Preorder_Visitor_Pkg is > type Preorder_Visitor_Record is new Visitor_Record with null record; > > -- this is overidiing the abstract version in parse_tree_pkg; But it doesn't in Ada and that is your problem. It overloads not overrides in some scopes. Ada 200Y will probably have an overrides keyword which will get you an error message at compile time here. > procedure Visit ( V : in out Preorder_Visitor_Record; Node : in > Add_Op'Class); > ..... > > procedure Visit_Operation (V : in preorder_Visitor_Record; node : in > add_op'class); > end preorder_visitor_Pkg; Same problem here... > > package body Preorder_Visitor_Pkg is > > procedure Visit_Operation ( V : in out Preorder_Visitor_Record; Node : in > Add_Op'Class) > is begin > raise Not_Implemented; -- better handling in actual code with an error > message using ada.exceptions > end Visit_Operation > procedure Visit( V : in out Preorder_Visitor_Record; Node : in Add_Op'Class) > is begin > Visit_Operation(V, Node); > end Visit; > > > the actual code errors saying ambiguos call of Visit_Operation() from within > the Visit() procedure. with possible interpretations at the definition of > Preorder_Visitor_Record and at the specification for Visit_Operation. > > the code works when you take Visit_Operation out of the mix. the package > compiles and works with a test driver. but when i try to add in this > Visit_Operation it doesn't work. I don't know if there are some scoping > issues or if there is something else i need to know about primative > operations to make this work. any guidance would be appreciated. > > Thanks, > Charles Lambert The much deeper problem you have is that the Visitor pattern is a waste of effort in Ada. Not wrong, or unimplementable, but the pattern as such is much heavier weight than it needs to be. The normal approach to this problem in Ada is, in the package that declares the abstract data type, (the parse tree in this case) to have a generic procedure to do the work: package Parse_Tree_Pkg is -- I'd call it Parse_Trees, but that is a -- style issue... type Node is ...; type Parse_Tree is ...; generic with procedure Visitor (N: in out Node); procedure In_Order (PT: in out Parse_Tree); -- visit all the nodes -- of a parse tree in -- order and Visitor -- Visitor; Now you can instantiate In_Order with whatever visitor you want. Much easier to work with, and easier to change the In_Order instantiation to Pre_Order or Post_Order if the design changes. Note that the generic formal procedure doesn't mention the ADT in its profile. So you can pass the same concrete visitor implementation just as easily to a queue or stack, as long as the node type is the same. -- Robert I. Eachus "The war on terror is a different kind of war, waged capture by capture, cell by cell, and victory by victory. Our security is assured by our perseverance and by our sure belief in the success of liberty." -- George W. Bush