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=-0.8 required=5.0 tests=BAYES_00,INVALID_DATE, MSGID_SHORT autolearn=no autolearn_force=no version=3.4.4 Path: utzoo!utgpu!news-server.csri.toronto.edu!rutgers!tut.cis.ohio-state.edu!snorkelwacker!bloom-beacon!eru!luth!sunic!enea!sommar From: sommar@enea.se (Erland Sommarskog) Newsgroups: comp.lang.ada Subject: On quitting an iterator prematurely Message-ID: <1151@enea.se> Date: 8 Apr 90 12:07:58 GMT References: <9004041704.AA17624@ajpo.sei.cmu.edu> Organization: Enea Data AB, Sweden List-Id: Norman H. Cohen (NCOHEN@IBM.COM) writes: >Andre' Alguero asks about how to write a procedure to iterate over >a set of discrete elements, specifying the actions to be performed >at each iteration at the point at which the procedure is invoked. >... >One Ada solution is to nest a generic procedure inside a generic >package. The generic package is parameterized by the element type >of the set. This seems like the straight-forward and natural solution to do it. In fact I suspected that I had misunderstood the original question, since this design is not difficult to come up with. However, consider Mr. Cohen's proposal: > generic > type Element_Type is (<>); -- some discrete type > package Set_Package is > type Set_Type is private; > -- Operations like union, intersection declared here... > generic > with procedure Process_One_Element (Element: in Element_Type); > procedure Process_Each_Element (Set: in Set_Type); Some years ago I wrote a binary tree package with a similar concept. When I was to use the package I discovered one thing I had missed. There was no way to interrupt the iteration. One way is of course to rewrite the package so that Process_one_element should take a second parameter Continue : OUT boolean; The problem with this is that if the user in 90% of the time wants to iterate through the entire set, this second parameter just clutters up his code, and he may even forget to initiate it with interesting results, unless the compiler catches the error. So I went for the other solution and simply and the wrote invoking procedure as: DECLARE done : EXCEPTION; PROCEDURE Test_One_Element (E : IN My_Element_Subtype) is BEGIN -- some stuff IF Found THEN RAISE Done; END IF; END Test_One_Element; PROCEDURE Find_First_Element IS NEW My_Set_Package.Process_Each_Element (Process_One_Element => Test_One_Element); BEGIN Find_First_Element (S); EXCEPTION WHEN Done => NULL; END; Now, I wouldn't say that this is the use of exception as intended, but rather a confirmation those who claim that says that exception is a structured GOTO. Yet, if this is the rare case, this solution seem to be preferable to a second, rarely-used continue parameter. What is the general opinion on this? Any better ideas? -- Erland Sommarskog - ENEA Data, Stockholm - sommar@enea.se