comp.lang.ada
 help / color / mirror / Atom feed
From: sommar@enea.se (Erland Sommarskog)
Subject: On quitting an iterator prematurely
Date: 8 Apr 90 12:07:58 GMT	[thread overview]
Message-ID: <1151@enea.se> (raw)
In-Reply-To: 9004041704.AA17624@ajpo.sei.cmu.edu

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

       reply	other threads:[~1990-04-08 12:07 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <9004041704.AA17624@ajpo.sei.cmu.edu>
1990-04-08 12:07 ` Erland Sommarskog [this message]
1990-04-10 18:26   ` On quitting an iterator prematurely Sylvain Louboutin, University College Dublin, Ireland
1990-04-10 18:38   ` On quitting an iterator prematurely, erratum Sylvain Louboutin, University College Dublin, Ireland
1990-04-11  2:05   ` On quitting an iterator prematurely tdhammer
1990-04-13 22:04     ` David Kassover
1990-04-13 22:50       ` Mike Feldman
1990-04-11 11:38 Mats Weber
     [not found] <9004262133.AA06607@hac2arpa.hac.com>
     [not found] ` <7050@fy.sei.cmu.edu>
1990-05-01 16:09   ` On quitting an Iterator Prematurely Mike Feldman
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox