Re: "continue/next" for "loop"

From: Ole-Hjalmar Kristensen (ole-hjalmar.kristensen_at_substitute_employer_here.com)
Date: 11/03/03


Date: 03 Nov 2003 14:54:17 +0100


>>>>> "LD" == Lutz Donnerhacke <lutz@iks-jena.de> writes:

    LD> * amado.alves wrote:
>>> No. I don't know how to invert a complex loop.
>>
>> What on Earth are you talking about? The two constructs
>>
>> (1) if I mod J = 0 then
>> goto next;
>> end if;
>> Put (I'Img);
>> <<next>> null;
>>
>> (2) if I mod J /= 0 then
>> Put (I'Img);
>> end if;
>>
>> are clearly equivalent!

    LD> But both are the result of an oversimplification!

    LD> outer: loop
    LD> inner: loop
    LD> Complex_Actions_1;
    LD> if First_Condition then
    LD> Some_Justify_Actions;
    LD> goto next_outer;
    LD> end if;
    LD> Complex_Actions_2;
    LD> if Second_Condition then
    LD> Some_Other_Justify_Actions;
    LD> goto next_outer;
    LD> end if;
    LD> Complex_Actions_3;
    LD> end loop inner;
    LD> Complex_End_Statments;
    LD> exit outer when Other_Condition;
    LD> More_Statments;

    LD> <<next_outer>> null;
    LD> end loop outer;

    LD> I'd like to find a more amazing version of this braindead goto.
    LD> Please do not assume, that I'm too stupid to invert a condition in a
    LD> simplified example. IT'S NOT HOMEWORK!

It seems you are looking for a multi-level "continue" statement :-)
You need to somehow store the results of your tests if you want to
avoid the goto, because this information is used outside the scope of
the inner loop. A boolean should suffice, but is the code any more
readable?

   outer: loop
     declare
        execute_outer_statements : boolean := false;
     begin
       inner: loop
         Complex_Actions_1;
         if First_Condition then
           Some_Justify_Actions;
         else
           Complex_Actions_2;
           if Second_Condition then
             Some_Other_Justify_Actions;
           else
             Complex_Actions_3;
             execute_statements := true;
           end if;
         end if;
       end loop inner;
       if execute_outer_statements then
         Complex_End_Statments;
         exit outer when Other_Condition;
         More_Statments;
       end if;
     end;
   end loop outer;

You could of course make your inner loop an inline procedure returning
a boolean to separate the logic of the inner and outer loops more clearly:

   outer: loop
     declare
       procedure inner_loop(doit : out boolean) is
       begin
         Complex_Actions_1;
         if First_Condition then
           Some_Justify_Actions;
           doit := false;
         else
           Complex_Actions_2;
           if Second_Condition then
             Some_Other_Justify_Actions;
             doit := false;
           else
             Complex_Actions_3;
             doit := true;
           end if;
         end if;
       end inner_loop;
       pragma inline(inner_loop);
       
       execute_outer_statements : boolean;
     begin
       inner_loop(execute_outer_statements);
       if execute_outer_statements then
         Complex_End_Statments;
         exit outer when Other_Condition;
         More_Statments;
       end if;
     end;
   end loop outer;

After looking at these alternatives, I would probably stick with the goto.

-- 
Strange attractors stole my wife


Relevant Pages

  • Re: PL/SQL nested loop problem
    ... simple loop and inner loop into a while loop, but the out put is coming out ... look at where you put exit when i = 3. ... always exit before it runs the inner loop. ...
    (comp.databases.oracle.misc)
  • Re: PL/SQL question regarding nested loops
    ... simple loop and inner loop into a while loop, but the out put is coming ...
    (comp.databases.oracle.server)
  • Re: PL/SQL question regarding nested loops
    ... simple loop and inner loop into a while loop, but the out put is coming out ...
    (comp.databases.oracle.server)
  • PL/SQL question regarding nested loops
    ... simple loop and inner loop into a while loop, but the out put is coming out ... The outer loop is supposed to run 3 times while the inner loops ...
    (comp.databases.oracle.server)
  • Re: Tasks and Calendar
    ... ' Declare the variable. ... Dim oAppt as Outlook.AppointmentItem ... >> function returns an Items collection which you can loop through. ... >> For Each AnyObj in AnyCollection ...
    (microsoft.public.outlook.program_vba)