[comp.lang.ada] Another reason for goto

Marc.Graham@SEI.CMU.EDU (01/18/89)

Ada does not have a `continue' or `abandon' statement for loop
control. Such a statement is orthogonal in some sense to exit. One
uses it in the body of a loop when one wishes to terminate this
iteration of the loop and start on the next one. To simulate it, one
issues a goto a <<label>> on a null; which is the final statement in the
loop block being continued.

Also, consider the case of input editing in a situation in which, if
the input does not pass the edit, it will be reacquired until the
input is good. Without goto one writes this as

loop
   -- get input
   case input
     when good_alt_1 =>
                   . . .
                   exit;
     when good_alt_2 =>
                   . . .
                   exit;
     .
     .
     .
     when others => null;
   end case;
end loop;

Even though I do that myself, I can't help thinking that its wrong.
There really isn't a loop here, in some sense. Good input is
processed; bad input is rejected. The thing looks better as

<<get_in>>
    -- get input
    case input
     when good_alt_1 =>
                   . . .
     when good_alt_2 =>
                   . . .
     .
     .
     .
     when others => goto <<get_in>>;
   end case;

This should occupy a hair's breadth less space and consume a hare's
breath less time. More importantly, it more nearly captures the
essence of what's going on (in my opinion, which is rarely humble).

Good code is not the result of a mindless policy of goto removal; bad
code is not the result of a sensible policy of goto insertion.

Marc H. Graham                    Software Engineering Institute
marc@sei.cmu.edu                  Carnegie Mellon University
(412) 268 7784                    Pittsburgh, PA   15213
                   

wbralick@afit-ab.arpa (William A. Bralick) (01/18/89)

In article <8901171823.AA20919@bx.sei.cmu.edu> Marc.Graham@SEI.CMU.EDU writes:
)
)Ada does not have a `continue' or `abandon' statement for loop
)control. Such a statement is orthogonal in some sense to exit. One
)uses it in the body of a loop when one wishes to terminate this
)iteration of the loop and start on the next one.

This sounds like a rather exceptional case ... :-)

)To simulate it, one
)issues a goto a <<label>> on a null; which is the final statement in the
)loop block being continued.
)
) [loop example implementation deleted to conserve bandwidth]
)
)There really isn't a loop here, in some sense. Good input is
)processed; bad input is rejected. The thing looks better as
)
)<<get_in>>
)    -- get input
)    case input
)     when good_alt_1 =>
)                   . . .
)     when good_alt_2 =>
)                   . . .
)     .
)     .
)     .
)     when others => goto <<get_in>>;
)   end case;
)
)This should occupy a hair's breadth less space and consume a hare's
)breath less time.

This sort of concern with micro-efficiency is only warranted if you have
identified this section of code as being part of the 20% wherein your
program spends 80% of its time, otherwise it is inappropriate.

) More importantly, it more nearly captures the
)essence of what's going on (in my opinion, which is rarely humble).

I disagree, you have a classic "loop until good input" situation here.
It can be directly implemented as follows:

loop

   begin

      --  get input

      case input is

         when good_alt_1 =>  do_alt_1_stuff;
         when good_alt_2 =>  do_alt_2_stuff;
         ...
         when good_alt_n =>  do_alt_n_stuff;

         when others     =>  null;  -- this handles a legal, but undesirable
                                    -- input, alternatively, you could do
                                    -- something with all the rest of the cases.
      end case;

      exit;

   exception

      when  DATA_ERROR  =>  handle_it; -- this handles the truly "bad" input

   end;

end loop;
   

The exception exists to handle the kind of situation that you are
apparently trying to address with the goto.  Why not use it?
(See section 14.7 of your LRM for another example.)

)
)Good code is not the result of a mindless policy of goto removal; bad
)code is not the result of a sensible policy of goto insertion.

However, I have yet to see a case where the goto is *necessary*  It is
a direct tweek at the program counter and is generally at too low a 
level of abstraction for a HOL.  If time (and space) are that critical
in a given section of code you should "goto" C (using pragma interface)
or assembler if absolutely necessary.

Regards,
-- 
Will Bralick : wbralick@afit-ab.arpa  |  If we desire to defeat the enemy,
Air Force Institute of Technology,    |  we must proportion our efforts to 
                                      |  his powers of resistance.
with disclaimer;  use disclaimer;     |               - Carl von Clauswitz

leake@cme.nbs.gov (Stephe Leake) (01/19/89)

In article <820@afit-ab.arpa> wbralick@afit-ab.arpa (William A. Bralick) writes:

   ...

   However, I have yet to see a case where the goto is *necessary*  It is
   a direct tweek at the program counter and is generally at too low a 
   level of abstraction for a HOL.  If time (and space) are that critical
   in a given section of code you should "goto" C (using pragma interface)
   or assembler if absolutely necessary.

Ada can be either a High level language, _or_ a low-level one. Why
should I abandon strong typing just because I need to do something
fast? If I need a fast subroutine, I write it in "low-level" ada; no
tasks, exceptions, etc; I would feel free to use a goto (although I
have yet to see a need for one). In fact, in Ada I can use single
precision, which can often cut execution in half!

Lets not limit ourselves by arbitrary notions that _all_ Ada code must
be high-level and abstract.

Stephe Leake 	(301) 975-3431 		leake@cme.nbs.gov
National Institute of Standards and Technology
(formerly National Bureau of Standards)
Rm. B-124, Bldg. 220
Gaithersburg, MD  20899

billwolf@hubcap.clemson.edu (William Thomas Wolfe,2847,) (01/20/89)

From article <849@primus.cme.nbs.gov>, by leake@cme.nbs.gov (Stephe Leake):
> 
> If I need a fast subroutine, I write it in "low-level" ada; no
> tasks, exceptions, etc; I would feel free to use a goto (although I
> have yet to see a need for one). 

     Tremblay and Sorenson summarize:

        A common thought among proponents of the GOTO is: "I just
        might need it; something might come up."  The answer to this
        appears to be: "Nothing ever does." 



                                       Bill Wolfe

                                wtwolfe@hubcap.clemson.edu

leake@cme.nbs.gov (Stephe Leake) (01/25/89)

What does it actually _cost_ us to have goto in the language? If you
never use it, the only cost is the paragraph or so in the LRM, and
some code (never executed) in the compiler. For such a small cost, why
should we bother removing it?

I know of one CASE tool that generates Ada code, with lots of goto's.
Yes, you would not code it that way if you were writing Ada directly,
but that's the point of a CASE tool; it gives you a different
(hopefully better/more productive/more readable) way to write code.
Personally, I prefer Ada, but I do not want to discourage work on
better CASE tools.

Stephe Leake 	(301) 975-3431 		leake@cme.nbs.gov
National Institute of Standards and Technology
(formerly National Bureau of Standards)
Rm. B-124, Bldg. 220
Gaithersburg, MD  20899