[comp.lang.pascal] Gotos are ok

ts@uwasa.fi (Timo Salmi) (01/10/91)

In article <1991Jan10.031015.15282@cs.mcgill.ca> einstein@cs.mcgill.ca (Michael CHOWET) writes:
>
>  Well, not to flame or anything, but my background was kept "GOTO-free". I
>was educated (and still am) in the spirit of "good programming" (whatever
>*that* may be :-). And even when going through the Pascal manual I found the
>GOTO statement, I didn't even bother looking at how to do this. All I saw
>was a statement that was a throwback to my BASIC days on an Apple ][+, an Atari
>400, or worse on our Commodore VIC-20.
:

You are intermixing, or rather confusing two separate issues here. 
Programming puritanism which is often an end itself (frequently
counter-productive at that), and getting a problem solved with the
available means.  There is nothing wrong with using gotos in Turbo
Pascal.  No gotos is just a mumbo jumbo myth by programming purists. 
Of course it is often desirable for the sake of clarity to avoid
gotos, but this stigma that has been ingrained and incantated to by
the self-chosen guards of programming purity is ridiculous.  Welcome
to the real world where programming is needed because something
needs to be performed, and where the format of code is secondary. 
Don't confuse the ends and means. 

...................................................................
Prof. Timo Salmi        (Moderating at anon. ftp site 128.214.12.3)
School of Business Studies, University of Vaasa, SF-65101, Finland
Internet: ts@chyde.uwasa.fi Funet: gado::salmi Bitnet: salmi@finfun

ts@uwasa.fi (Timo Salmi (LASK)) (01/18/91)

In article <1991Jan16.005523.28337@syacus.acus.oz> ian@syacus.acus.oz (Ian Joyner) writes:
>Prof. Timo Salmi writes-
>
>>No gotos is just a mumbo jumbo myth by programming purists. 
:
>>Don't confuse the ends and means. 
>
>I can't believe I am reading this in this day and age. Dear prof Salmi,
>if you tried writing gotoless programs you would soon realise it is
>practical, but takes a little more effort to begin with, and highly
>profitable. I am talking about programs with 10k to 100k lines of source.
>This is the real world, where you need discipline to make your programs
>work, and maintainable, and modifyable.
:

Even at the risk at sounding arrogant (not my purpose, as yours
probably wasn't to sound so patronizing) please let me point out
that I have written several hundred (yes indeed) Turbo Pascal
applications in the 10K - 100K source code range, most (> 90%) of
them entirely gotoless.  I have nothing against good programming
practices, on the contrary.  I write highly modular code with much
documentation.  But I don't have any silly compunctions to let any
self-imposed puritanism stand in my way when I can write easier or
more efficient code by inserting an occasional helpful goto.  So I
still say, wake up to the real world. 

...................................................................
Prof. Timo Salmi        (Moderating at anon. ftp site 128.214.12.3)
School of Business Studies, University of Vaasa, SF-65101, Finland
Internet: ts@chyde.uwasa.fi Funet: gado::salmi Bitnet: salmi@finfun

raymond@math.berkeley.edu (Raymond Chen) (01/18/91)

[Followups redirected to alt.religion.computers, since this has escalated
into a religious argument.]

In article <1991Jan16.005523.28337@syacus.acus.oz>, ian@syacus (Ian Joyner) writes:
>Prof. Timo Salmi writes-
>>No gotos is just a mumbo jumbo myth by programming purists. 
>Dear prof Salmi,
>if you tried writing gotoless programs you would soon realise it is
>practical...

I believe Mr Joyner is missing the point.  The object of the game
is *not* to write so-called "gotoless" programs.  The object of the
game is to write "structured" programs.

For some reason, people have latched onto the concept of "goto-less
programming" as if it were some sort of divine incantation, and that
the word "goto" is blasphemy against God and Heaven.

>The problem is [gotos] are too powerful, and thus
>subject to undisciplined use.

The same can be said for global variables and pointers (in languages
that support them).  Does Mr Joyner advocate the heavy-handed elimination
of global variables?

Selected juicy quotes from people who should know:

    The criticism has been voiced that the method of structured
    programming is in essence nothing more than programming by
    painstakingly avoiding the use of jumps (goto statements).  One may,
    indeed, come to this conclusion by looking at the entire issue in the
    reverse direction.  ... [T]he absence of jumps is not the initial aim,
    but the final outcome of the exercise.  <<The claim that structured
    programming was invented by proving that all programs can be
    formulated without goto statements is therefore based on a fundamental
    misunderstanding.>>

    -- Niklaus Wirth, author of the Pascal language

    Please don't fall into the trap of believing that I am terribly
    dogmatical about [the goto statement].  I have this uncomfortable
    feeling that others are making a religion out of it, as if the
    conceptual problems of programming could be solved by a single trick,
    by a simple form of coding discipline!

    -- Edsger Dijkstra, author of "Go to statement considered harmful"

It has also been proved (initally by Knuth-Floyd; sharper results were
later obtained by Ashcroft-Manna, Bruno-Steiglitz, Kosaraju, and
Peterson-Kasami-Tokura) that total elimination of goto's cannot be
accomplished without the introduction of extraneous flag variables, or
redundant computation.

One might wish to read Computing Surveys, Vol 6. Nr. 4 (Dec 1974),
which contains articles on the topic of structured programs (including
Knuth's famous "Structured programming with go to statements").

tsmith@plains.NoDak.edu (Timothy Lyle Smith) (01/18/91)

In article <1991Jan16.005523.28337@syacus.acus.oz>
ian@syacus.acus.oz (Ian Joyner) writes:
>Prof. Timo Salmi writes-
>
>>No gotos is just a mumbo jumbo myth by programming purists.
>>Of course it is often desirable for the sake of clarity to avoid
>>gotos, but this stigma that has been ingrained and incantated to by
>>the self-chosen guards of programming purity is ridiculous. Welcome
>>to the real world where programming is needed because something
>>needs to be performed, and where the format of code is secondary.
>>Don't confuse the ends and means.

  I don't believe that the format of the code is secondary, it should give
some indication of the function of the code.  Granted that this is not
always possible for a given language.  If you can figure out how to do
something in a sloppy manner then there is most likely another way to do
it which not so sloppy.  The other way of writing it should not be so
difficult as you already have a solution to the problem.

>
>
>Sure gotos work very well. The problem is they are too powerful, and thus
>subject to undisciplined use. Last year I was working in a language with
>the only control structures being -
>
>if <boolean> <statement>
>and
>goto <label>
>
>All my code that I wrote in this language used these to simulate well
>disciplined structures of -
>
>if <boolean> <compound>
>else <compound>
>
>
>The argument for gotos is based in the mind set that programmers are such
>mindless bookkeepers, but then have the super human capability to be
>able to get themselves out of the mess that they get themselves in.
>
>Programming must be elevated to a craft, where the programmers can take
>care and pride in what they do. The advocates of undisciplined goto
>usage are undermining our progress towards this goal, a goal which
>ultimately produces software which does what it is supposed to do,
>--
>Ian Joyner                                     ACSNet:
ian@syacus.oz

Mr. Joyner, IMHO your argument is seriously flawed.  If I understand you
correctly you are advocating disciplined programming and you consider the
use of gotos to be undisciplined.  My opinion is based of the following
facts and assumptions:

      Fact: A programming language is a collection of tools that can
            be used to solve problems.

            The reason that a language is a collection of tools rather
            than a tool unto itself is that you do not have to use all
            the elements of the language to solve every problem.  Thus
            the if-then-else structure is an element as is the goto.

      Assumption:
            The user of a tool will understand it better and be more
            skilled with it by using it.  It the tool is never used then
            the user will never understand it.

            This is an assumption because not everybody is created equal
            in this case.  Some people will understand a tools purpose
            with the first use while others will never understand it.

      Assumption:
            Discipline is learned, it can not be forced.  It is based on
            understanding the environment in which the person must have
            discipline.

            This assumption is based on personal experience.

  Given these assumptions and fact, I again state that IMHO your position
is flawed.  The existence of the goto in any language is irrelevant to the
argument of whether the goto is a good tool or a bad tool, it is just a
tool.  Just as it is foolish to used a nuclear bomb to crack a peanut there
are places where one should not use a goto.

  However if you want to remove the goto from a language you should be able
to prove that it will never be needed, that the function it serves can be
completely covered by another existing tool or tools.  You can not add
another tool to replace it.

  If you teach people how to use a tool then they have a chance to become
familiar with it's use.  It these same people are unfamiliar with the tool
they will not become familiar with it's use and will not understand the
tool.  Without understanding there can be no discipline.

  If you can teach people to use gotos in a disciplined fashion then you
will find that the goto is a very useful and important part of any language.
You must remember however, if a person is not familiar in the use of a tool
that person can not teach another to be familiar with the tool unless the
student is quicker than the teacher.  On a similar line, discipline can not
be taught by a teacher who is undisciplined unless the student views the
teacher's undiscipline ways with distaste and strives to be disciplined so
as not to be like the teacher.

     respectively

        Tim Smith
-- 
Tim Smith  
Minard 300                      UUCP:        ...!uunet!plains!tsmith
North Dakota State University,  BITNET:      tsmith@plains.bitnet
Fargo, ND  58105                INTERNET:    tsmith@plains.NoDak.edu

T.Moore@massey.ac.nz (T. Moore) (01/18/91)

>>Of course it is often desirable for the sake of clarity to avoid
>>gotos, but this stigma that has been ingrained and incantated to by
>>the self-chosen guards of programming purity is ridiculous.  Welcome
>>to the real world where programming is needed because something
>>needs to be performed, and where the format of code is secondary. 
>>Don't confuse the ends and means. 
>
>Sure gotos work very well. The problem is they are too powerful, and thus
>subject to undisciplined use. 
>
>care and pride in what they do. The advocates of undisciplined goto
                                                  ^^^^^^^^^^^^^
>usage are undermining our progress towards this goal, a goal which

I don't think you are as far apart as you think. The operative word is
underlined above. If possible, a program should be tree structured which
essentially means not using spaghetti code. 

Dijkstra first wrote about the dangers of gotos but later said that he did
not intend that people elevate the idea to the staus of a religion. 
It is just as mindless to blindly follow a rule without
thinking about the reasons for it. A more sensible rule is to only use
gotos if it makes the program structure clearer. An exit statement in the
language would probably eliminate most of the cases in which gotos might
sometimes aid clarity.
If you want to totally avoid gotos - fine.
If you ocassionally use them in a tree structured manner - I don't mind
If you want to write spaghetti code - that's up to you but don't blame
the language designer for permitting you that freedom.
-- 

Terry Moore <T.Moore@massey.ac.nz>
 Department of Mathematics and Statisics,
 Massey University, Palmerston North, New Zealand

Kroneker:  "God made the natural numbers, the rest is the work of man."
Zermelo:   "But I can construct the natural from the empty set alone."
Bystander: "Who said 'You can't get something for nothing.'?"

dmurdoch@watstat.waterloo.edu (Duncan Murdoch) (01/18/91)

In article <1991Jan17.205508.16059@massey.ac.nz> T.Moore@massey.ac.nz (T. Moore) writes:
>
>I don't think you are as far apart as you think. The operative word is
>underlined above. If possible, a program should be tree structured which
>essentially means not using spaghetti code. 

I don't think a program should be tree structured.  Perhaps a routine should
be, but certainly not a whole program.  Programs should be onion-shaped: a
few routines at the top for general control, widening out into specialized
fairly high level routines for specific tasks, and then narrowing in again to
a common library of low-level routines, to maintain a constant interface
to the user and the data.

Duncan Murdoch

mac@harris.cis.ksu.edu (Myron A. Calhoun) (01/18/91)

In article <2802@oucsace.cs.OHIOU.EDU> tswingle@oucsace.cs.OHIOU.EDU (Tom Swingle) writes:

   [many lines deleted]

>....(by the way isn't exit just a special form of goto?) 

Yes.  Also BREAK.  In assembly language the "GOTO-less" style was
achieved by simple renaming:  JuMP, BRAnch, etc.!-)

And CASE, THEN/ELSE/ELSEIF, and similar constructs have GOTO's
"hidden" within them.

Sometimes such "hiding" makes things easier to understand, and
sometimes working around such hiding makes things harder to understand.

Or, putting it another way,
sometimes unhidden GOTO's make things harder to understand, and
sometimes including them deliberately makes things easier to understand.

GOTO's are a tool much as a sharp knife is a tool.  They may both be
used wisely or foolishly or not at all.
--Myron.
--
# Myron A. Calhoun, Ph.D. E.E.; Associate Professor   (913) 539-4448 home
# INTERNET: mac@cis.ksu.edu   (129.130.10.2)                532-6350 work
# UUCP: ...{rutgers, texbell}!ksuvax1!harry!mac             532-7353 fax
# AT&T Mail:  attmail!ksuvax1!mac                   W0PBV @ K0VAY.KS.USA.NA

jfr@locus.com (Jon Rosen) (01/19/91)

In article <1991Jan18.151104.13742@maverick.ksu.ksu.edu> mac@harris.cis.ksu.edu (Myron A. Calhoun) writes:
>In article <2802@oucsace.cs.OHIOU.EDU> tswingle@oucsace.cs.OHIOU.EDU (Tom Swingle) writes:
>
>   [many lines deleted]
>
>>....(by the way isn't exit just a special form of goto?) 
>
>Yes.  Also BREAK.  In assembly language the "GOTO-less" style was
>achieved by simple renaming:  JuMP, BRAnch, etc.!-)
>
>And CASE, THEN/ELSE/ELSEIF, and similar constructs have GOTO's
>"hidden" within them.
>
>Sometimes such "hiding" makes things easier to understand, and
>sometimes working around such hiding makes things harder to understand.
>
>Or, putting it another way,
>sometimes unhidden GOTO's make things harder to understand, and
>sometimes including them deliberately makes things easier to understand.
>
>GOTO's are a tool much as a sharp knife is a tool.  They may both be
>used wisely or foolishly or not at all.

This philosophy, IMHO, is incorrect... of course, CASE, IF/THEN/ELSE,
WHILE, etc have hidden branch instructions... These are not, however,
GOTOs in the sense intended by Dikstra in his famous article... 
What is objected to when one talks about "GOTO-less programming" is
the use of unrestricted or undisciplined branching... The actual words
used to describe the branch mechanism are not relevant... A GoTo/Jump
Branch are the same thing... A one-way leap into the hell of unstructured
programming... CASE, IF/THEN/ELSE, WHILE, REPEAT, etc are highly disciplined
structured constructs that, while containing branches, enforce a rigor that
makes it less likely to have errors in the code... They have a beginning
and an end... Gotos (and their derivatives) have only a beginning (or and
end depending on your view...)... Does this make LEAVE/EXIT/RETURN Gotos?
Of course not... they are disciplined exit mechanisms for structrured
constructs... You don't get to say where you want to GOTO... You only 
can say I want to leave from here (this is not always true of some
languages aberational Leaves where you can add a label)... Maybe this
should better be called label-less programming... Any construct that
works in a label-less environment is a good one... If you need a label
to get there (i.e., with a traditional GOTO) it is probably bad...
 
Example:
 
   WHILE1 something
    ...
     WHILE2 something
      ...
     ENDWHILE2
    ...
   ENDWHILE1

is a legal structured programming construct...     
whereas:

    WHILE1 something
     ...
      WHILE2 something
    ENDWHILE2
       ...
      ENDWHILE2
is obviously illegal...
This is preventable in GOTOless programming by the compiler...
It is not preventable in programming where the normal 
labelled GOTO is permitted...

I have NEVER seen a situation where use of a real labelled GOTO
made something clearer... Depending on the compiler it may have
made it faster... that is always possible... But that is not
a good justification for supporting the use of a bad construct...
It is a justification for better compilers that can optimize
the performance of the program without requiring that the 
programmer destroy the clean semantics of the code...
 
Jon Rosen
  

John G. Spragge <SPRAGGEJ@QUCDN.QueensU.CA> (01/19/91)

I have never had to use the goto statement in Pascal and, like
Professor Salmi, I have written my share of Pascal code. However,
I believe that refraining from the use of gotos can be a useful
discipline. The issue of gotos is debated so fervently because
it turns on the question of what place these minor disciplines
have in programming.

Because computers are so flexible, I find that disciplined
programming is an essential method for controlling complexity.
I program according to a very rigid set of rules:

PROCEDURE  Demonstrated    { this is a demonstration procedure  }
(
 VAR    a     :   INTEGER  { comment describes the parameter    }
);


VAR
   n          :   REAL;    { each declaration is commented      }

BEGIN           { demonstrated }
   n := FLOAT (a);                 { must convert to a real     }
   a := ROUND (n * 72)
END;            { demonstrated }

All of these habits can be defended as improving the readability
of the program in some way (having the comments always end in the
same column makes it easier to pick out the commented lines,
commenting the variables makes it possible to remember what they
do, and so on); but what the discipline of staying in the format
principally accomplishes is to make me stop and think periodically
about what I'm doing. This in turn allows me to develop the
clearest possible structures for coding. I developed the habit
of never going past column 72 on an IBM system where that Pascal
compiler required the programmer to set margins, but I found it
a useful discipline, both because it was a good way of making
sure I could always print my listings, and also because it
discouraged me from using loops that were nested to deeply.
Students are often told to ensure their procedures fit on a page;
that helps make sure that no procedure can get overly complex.

Consider an example used earlier:
In article <2802@oucsace.cs.OHIOU.EDU>, tswingle@oucsace.cs.OHIOU.EDU (Tom
Swingle) says:

<<<<< I reformatted the quote so it would fit on my screen >>>>>>

>
>Here is a situation where I found a goto to be the neatest, easiest way to
>solve a problem.  I had a procedure with nested repeat loops, at least two
>deep.  I wanted to break out of the procedure if an error occurred, but first
>there were things that had to be done (restoring screen, closing files, etc.)
>before I could leave the procedure.  These things needed to be done with
>either normal or abnormal termination of the procedure, and its code was
>several lines long.  Normally, it would be done at the end of the procedure
>(logical, right?) but if I needed to get out immediately, I needed a way to
>execute this code and leave.  Here's a skeleton of the procedure:

<<<< Mr. Swingle's skeleton deleted. Here's my approach to the problem >>>>


VAR
   cc   :  INTEGER;           { Control circuit counter                }
   inv  :  BOOLEAN;           { invalid input flag                     }
   rec  :  datatype;          { record type buffer                     }

BEGIN          { procedure }
   REPEAT                     { outer repeat loop                      }
                              { any set of statements you like         }
        REPEAT                { next repeat loop                       }
                              { any other statement you like           }

              cc := 0;
              inv := false;
              WHILE (cc < 3) AND NOT inv DO   { loop/select command    }
              BEGIN
                  cc := cc + 1;               { next command           }
                  CASE cc OF
                      1 :  BEGIN
                              getfirstfield (rec);
                              inv := rec.first < 0
                           END;
                      2 :  BEGIN
                              getsecondfield (rec);
                              inv := rec.second > 10000
                           END;
                      3 :  BEGIN
                              getthirdfield (rec);
                              inv := (rec.third > 100) AND
                                     (rec.third < -100);
                           END;
                  END { Case }
              END     { While }
        UNTIL inv OR (innerloopend)
   UNTIL inv OR innerloopend;
                                   { cleanup code goes in here      }
END;           { procedure }

I can foresee three objections to this code. Let me take them in order.

1) That code isn't efficient.

   In my experience, almost all users prefer a program that takes
   five minutes more to run over one that locks up, bombs, or
   produces erroneous output once in a thousand runs. Of all uses
   for run time, taking time to check your errors and implement a
   clear structure is about the most easily forgiven by the user.
   If the program isn't fast enough, find a better algorithm. If
   you can't do that, recode the 1% to 10% of the program where
   speed is critical in assembler. But don't use "efficiency" as an
   excuse to put in a goto.

2) It uses an extra variable.

   Control and state variables aren't "extra". They're a much a
   part of the program as data buffers and counters. And please
   note that using a goto does NOT save you a declaration: you
   have to declare the label you jump to.

3) It isn't really clear.

   If you don't like this technique, you don't have to use it. I use
   it to group repetitive tests for the validity of input together
   rather than using a bunch of if-then constructs. It has three
   advantages: it's succinct; you can tell clearly what's being
   done and in what order; the test that gets you out of the input
   process is done in one place; it leaves the close code knowing
   that invalid input was received, and in the CC variable, you get
   a record of exactly what input was wrong. It's useful for most
   of my purposes.

The point is, you have no "obligation" to avoid gotos. But for
every goto you include, you should probably consider what other
technique you could have used to accomplish the same thing, and
know why you chose to us the goto instead. Programming discipline
is not about keeping rules; the rules are there so that when you
bump into them you have to think about what you're doing.

disclaimer: Queen's University merely supplies me with computer services, and
            they are responsible for neither my opinions or my ignorance.

John G. Spragge

mac@harris.cis.ksu.edu (Myron A. Calhoun) (01/19/91)

In article <21350@oolong.la.locus.com> jfr@locus.com (Jon Rosen) writes:
>In article <1991Jan18.151104.13742@maverick.ksu.ksu.edu> mac@harris.cis.ksu.edu (Myron A. Calhoun) writes:
>>In article <2802@oucsace.cs.OHIOU.EDU> tswingle@oucsace.cs.OHIOU.EDU (Tom Swingle) writes:

>>   [many lines deleted]

>..... CASE, ....[is a] highly disciplined
>structured constructs that, while containing branches, enforce a rigor that
>makes it less likely to have errors in the code... They have a beginning
>and an end....

And in the C programming language, lots of middles!-)

I'm aware this group is comp.lang.pascal, but what you say about
CASE sure isn't true in C, where each case usually needs a hidden
GOTO (i.e., BREAK) to get to the end of the CASE construct.

Aren't computer languages interesting?!
--Myron.
--
# Myron A. Calhoun, Ph.D. E.E.; Associate Professor   (913) 539-4448 home
#  INTERNET:  mac@harris.cis.ksu.edu (129.130.10.2)         532-6350 work
#      UUCP:  ...rutgers!ksuvax1!harry!mac                  532-7353 fax
# AT&T Mail:  attmail!ksuvax1!mac                   W0PBV @ K0VAY.KS.USA.NA

devisser@cs.utwente.nl (Jan de Visser) (01/21/91)

In article <2802@oucsace.cs.OHIOU.EDU>, tswingle@oucsace.cs.OHIOU.EDU
(Tom Swingle) writes:
|> Here is a situation where I found a goto to be the neatest, easiest
way to 
|> solve a problem.  I had a procedure with nested repeat loops, at
least two 
|> deep.  I wanted to break out of the procedure if an error occured,
but first
|> there were things that had to be done (restoring screen, closing
files, etc.)
|> before I could leave the procedure.  These things needed to be done
with either
|> normal or abnormal termination of the procedure, and its code was
several lines
|> long.  Normally, it would be done at the end of the procedure
(logical, right?)
|> but if I needed to get out immediately, I needed a way to execute
this code and
|> leave.  Here's a skeleton of the procedure: 
|> 
|> [much deleted]

How about: placing your 'exit-code' in a 'local' procedure, called, say,
ExitProc, and
use the following code in case of an error:

  IF <error>  THEN BEGIN ExitProc; Exit END;

No gotos!

Jan.

Disclaimer: I know nothing, I'm from Barcelona!

kushmer@bnlux0.bnl.gov (christopher kushmerick) (01/22/91)

In article <1991Jan21.134342@cs.utwente.nl> devisser@cs.utwente.nl (Jan de Visser) writes:
>In article <2802@oucsace.cs.OHIOU.EDU>, tswingle@oucsace.cs.OHIOU.EDU
>(Tom Swingle) writes:

>|> leave.  Here's a skeleton of the procedure: 

>How about: placing your 'exit-code' in a 'local' procedure, called, say,
>ExitProc, and
>use the following code in case of an error:
>
>  IF <error>  THEN BEGIN ExitProc; Exit END;
>
>No gotos!

Except for the fact that an exit is just a fancy way of spelling goto, with the
effective label being a automatic label right before the ultimate end. (I do
not know if this is how it is actualy implemented, it may be a return, but
from a logical viewpoint, this is what it is.)

I like to use gotos within programming blocks, but not between programming
blocks, by programming block, I mean a begin-end pair.

I also do like the exit construct mentioned above, but I understand that it is
a goto.

Now: goto work :-)
-- 
Chris Kushmerick kciremhsuK sirhC
kushmer@bnlux0.bnl.gov    <===Try this one first
kushmerick@pofvax.sunysb.edu 

derek@sun4dts.dts.ine.philips.nl (derek) (01/23/91)

with your comments about Macs and PCs you are actually being to sound like a
bigot. Beware, I'm considering putting you in my kill file! (Is a smiley
necessary?)

I think the summary of this argument looks something like:
Only good programmers should use gotos when they have to. Beginners should
not use them until they have mastered their trade.

I think you can all draw good parallels here (such as learners only riding
small cc motorbikes etc.) that make the whole argument actually make sense.

Best Regards, Derek Carr
DEREK@DTS.INE.PHILIPS.NL           Philips I&E TQV-5 Eindhoven, The Netherlands 
Standard Disclaimers apply.

ts@uwasa.fi (Timo Salmi) (01/23/91)

In article <1991Jan21.233859.10468@syacus.acus.oz> ian@syacus.acus.oz (Ian Joyner) writes:
>Well, I received a bit of flak over personal mail about my attack on
>gotos, indicating that this was a religious war, that should not be
>entered into. I disagree, and here is part of the reply to crystalize
:
>languages, but people who use honky tonk ms-dos against a finely crafted
>Macintosh, and those who stick to their ib/m systems no matter what superior
>systems the competition may offer.
:

You really surprise us with these contradictions.  If the latter is
not a computer-religious statement, what is? (Please note that this
is a rhetorical question). 

These kind of cheap shots are considered to belong to the category
"hey you wimps".  They lead nowhere.  Let's refrain. 

...................................................................
Prof. Timo Salmi        (Moderating at anon. ftp site 128.214.12.3)
School of Business Studies, University of Vaasa, SF-65101, Finland
Internet: ts@chyde.uwasa.fi Funet: gado::salmi Bitnet: salmi@finfun

Gary_Wong@kcbbs.gen.nz (Gary Wong) (01/24/91)

>I can foresee three objections to this code. Let me take them in
>order.

Okay, I will discuss how I feel with your three objections too:
>1) That code isn't efficient.
>   If the program isn't fast enough, find a better algorithm. If
>   you can't do that, recode the 1% to 10% of the program where
>   speed is critical in assembler. But don't use "efficiency" as
>an
>   excuse to put in a goto.

I see your point about not using gotos, and I agree that in 90% at least 
of cases where a goto could be used, it is not the best choice.  But 
rewriting a section of code in assembler to avoid a goto?  Once your 
in assembler, make sure it runs only on a 986 processor which eliminates 
all JMP instructions and replaces them with FOR, RPT?? I would much 
rather keep it in pascal (unless its *really* speed critical) and by 
writing it in assembler you have the problem with it bombing once in 
a thousand times you mentioned earlier.  
>2) It uses an extra variable.
Well, it doesnt sound like much, but when I come across this situation 
I'm always annoyed.  I realise that I'm worrying too much but I consider 
the extra space it takes up in the declartion, (even in the exe!!) and 
I end up using 1 variable to do 2 different things which I know I shouldnt 
do but i do anyway.  But you have to declare a label to use a goto so 
i guess the variable doesnt make a lot of difference.
>3) It isn't really clear.
Now this is what I disagree with you about.  People have mentioned that 
gotos make code unclear, so why bother using another solution that makes 
code unclear?  I agree that a goto is not a nice solution to this problem, 
but yours is not perfect either.

Although I have argued about your examples for {not using gotos, I should 
say that I have come across almost exactly the same situation, many 
times.  And I havent used a goto yet.  Also, when writing Pascal I like 
to know exactly what the code will compile to.  By using a goto Im always 
afraid (I have no idea how valid this is) that Im going to jump over 
an important section of code like a PUSH or POP - at best, you lose 
a word of stack space, at worst, the entire stack dies - and that the 
best solution would be for the compiler to implement a 'Local exit' 
command (i remember 'exit for' from when i programmed in basic a while 
back, cant remember exactly how it works) and I think that would be 
the most elegant solution.  Between structured constructs (repeat etc), 
exit's, and local exits, theres not many cases where a goto would be 
needed at all.
Gary.

jfr@locus.com (Jon Rosen) (01/25/91)

In article <2427@bnlux0.bnl.gov> kushmer@bnlux0.bnl.gov (christopher kushmerick) writes:
>In article <1991Jan21.134342@cs.utwente.nl> devisser@cs.utwente.nl (Jan de Visser) writes:
><stuff deleted>
>Except for the fact that an exit is just a fancy way of spelling goto, with the
>effective label being a automatic label right before the ultimate end. (I do
>not know if this is how it is actualy implemented, it may be a return, but
>from a logical viewpoint, this is what it is.)
>
>I like to use gotos within programming blocks, but not between programming
>blocks, by programming block, I mean a begin-end pair.
>
>I also do like the exit construct mentioned above, but I understand that it is
>a goto.
>
As in any religious discussion, people have a way of misstating (or
misunderstanding) the reality... EXIT (insert any other exit-type
construct: LEAVE, BREAK, RETURN...) is NOT simply a misspelled GOTO...
The difference between EXIT/LEAVE/etc and GOTO is that EXIT/LEAVE/...
can ONLY goto to a SINGLE place... I.e., in the abstract, the programmer
can't make a mistake... 
 
In the following pseudo-code:
   
   Repeat...
    ...
    if ... then leave;  
    ...
   EndRepeat;
   
There is only ONE place the leave statement can place the program...
That is after the EndRepeat statement... The programmer can only
make a mistake in his logic (does he really want to LEAVE this
loop at this time?)... He can make NO mistake in his syntax... 
 
If this statement is replaced with a GOTO, he needs to add a label.
Once the issue of labels enters into the picture, any NUMBER of
errors can start to crop up... He can misplace the label... He can
misspell the label... (and end up somewhere else entirely)...
Also, maintenance becomes a problem... If someone comes along and
modifies the program by putting a new statement BETWEEN the end
of the loop and our label, we may be kaboshed...

Don't tell me that any of you have never had this kind of problem
in a program with GOTOs:  
 
   Repeat...
    ...
    if ... then goto xx2;
    ...
   EndRepeat;
   xx1: ... (place we WANTED to goto)
    ...
    (much later in program)
   xx2: ... (we did NOT want to end up here)
 
If you can honestly say this has never happened to you (and you use
gotos) then you are the most accurate programmer I have ever met...
This kind of error, especially in a large program with lots of labels
and sympathetic behavior (i.e., where what happens in the wrong place
is close enough to what you wanted to happen that simple testing may
not even disclose the problem... things don't go BANG until the absolute
worst moment) can be extremely difficult to uncover...

This does not mean that by removing Gotos we can eliminate problems...
However, in my years of working with and teaching younger programmers,
I have found that by enforcing rigorous structured programming on them,
I reduce their level of errors considerably... Those that embrace the
idea become much better programmers... those that object do not generally
become as good...
 
Is this a religion?  Absolutely not... There are obvious times when the
use of a judicious GOTO is appropriate (certain kinds of error handling
come to mind)... All I am trying to say is that the use of a GOTO exposes
you to more error potential than programs without GOTOs and you have to
be appropriately careful in that situation... Use many comments, explain
WHY you are using the goto, make the label clear and unambiguous, double
check everthing, and hope for the best...  

maine@elxsi.dfrf.nasa.gov (Richard Maine) (01/25/91)

On 24 Jan 91 17:38:35 GMT, jfr@locus.com (Jon Rosen) said:

Jon> can ONLY goto to a SINGLE place... I.e., in the abstract, the programmer
Jon> can't make a mistake... 
Jon>  
Jon> In the following pseudo-code:
Jon>    
Jon>    Repeat...
Jon>     ...
Jon>     if ... then leave;  
Jon>     ...
Jon>    EndRepeat;
Jon>    
Jon> There is only ONE place the leave statement can place the program...
Jon> That is after the EndRepeat statement... The programmer can only
                   ^^^  (as in THE only such statement anywhere?)
Jon> make a mistake in his logic (does he really want to LEAVE this
Jon> loop at this time?)... He can make NO mistake in his syntax... 

I wasn't going to enter this religious discussion, *but* I think
there is a factual error in the above.  The goto and the exit
are subject to simillar problems.  You could just as legitimately
have said "There is only one place the goto statement can place the
program... That is after the label."  Both your statement and my
modification ignore the important point that there may be multiple
EndRepeat statements or multiple labels.

(Actually I don't think "syntax" is the right term for the class of
errors you are talking about, but your meaning is reasonably clear
even if the word isn't quite right).

In some ways (not all, I agree) the above code is *more* prone to
errors than the equivalent using goto.  Suppose, for instance, I
have the above code working but later decide to add a repeat..endrepeat
loop to handle an input error check (or whatever).  If I don't look
carefully, the code becomes

  Repeat (the original one)
   ...
   Repeat (the added one)
    ...
    if ... then leave
    ...
   EndRepeat
   ...
  EndRepeat

Instant bug.  I don't think this is particularly esoteric either.
I've done it and I've seen others do it.  In this particular case,
the goto construct would not have been as prone to the problem.

Now if the original had been in Fortran 90 (hmm, is my religion
showing?) and looked like

  the_loop: do
   ...
   if (...) exit the_loop
   ...
  end do the_loop

then the odds of introducing errors would be lower I'd think.

For my part, well Fortran is my major language (for various reasons,
some of which are just my religious preferences, and others of which
are more objective, but all of which are irrelevant here).  It's
really hard to do ANSI standard Fortran 77 code without gotos.  Not
impossible, but hard and awkward enough that I don't try.  So of
course I use gotos, but I do use them with discipline.  (Well, anyway
I think so).

I Fortran 90, which I've started dabbling with in anticipation of
compilers coming out, I use far fewer gotos because the language
has constructs like the above example.  Yes, I know the above
exit is a goto in disguise, but its a disguise that I find useful.
Fewer is not the same as none.

Yes, I know you Pascal types don't really care much about the
Fortran aspects of the above.

--
Rich Maine
maine@elxsi.dfrf.nasa.gov

zhou@brazil.psych.purdue.edu (Albert Zhou) (01/25/91)

I certainly agree that exit (leave or whatever) is different from goto
although you can implement exit with goto. When I posted the original
article, I was plagued by the limitation of "exit" implemented on Turbo
Pascal. I wanted exit several nested subroutines altogether, but I
could find a direct way to do it. Before this posting, I virtually had
never touch "goto" in Pascal. Unfortunately I found that goto's couldn't
go across modules (subroutines). I had thought that labels declared
globally could be refered everywhere just like global variable. As I
later realized, global labels can cause disasters for those who use goto
at all.

To further demonstrate the limitation of exit, please see the following
example:
Some suggest to implement an exit functioning like break in C, it will
work for
		repeat
		  ...
                  if c then exit
		until whatever

However, for a multiple-loop structure, one should be enabled to exit
a specified number of nested blocks:

		for i := 1 to 2
		  for j := 1 to 3 do
		  begin
          	     ...
		     if c then exit(2)
		  end

We also need such kind of exits for subroutines. Sorry I already use
the word exit for exiting blocks. So let me use exitsub for this.
So exitsub(3) means to exit from level n (current level) to level n-3.
If n-3 is negative, it will of course stop after exiting to the top level.
This is very useful for error handling procedures.                    

exitsub would be very easy to use and very useful too, as long as your
program is structured (I guess most people programming in pascal do
write structured programs). For example, one can write exitsub(3) when
he/she wants to exit from level 7 to level 4.

devisser@cs.utwente.nl (Jan de Visser) (01/27/91)

In article <MAINE.91Jan24230505@ra.dfrf.nasa.gov> maine@elxsi.dfrf.nasa.gov (Richard Maine) writes:
>On 24 Jan 91 17:38:35 GMT, jfr@locus.com (Jon Rosen) said:
>
>Jon> can ONLY goto to a SINGLE place... I.e., in the abstract, the programmer
>Jon> can't make a mistake... 
>Jon>  
>Jon> In the following pseudo-code:
>Jon>    
>Jon>    Repeat...
>Jon>     ...
>Jon>     if ... then leave;  
>Jon>     ...
>Jon>    EndRepeat;
>Jon>    
>I wasn't going to enter this religious discussion, *but* I think
>there is a factual error in the above.  The goto and the exit
>are subject to simillar problems.  You could just as legitimately
>have said "There is only one place the goto statement can place the
>program... That is after the label."  Both your statement and my
>modification ignore the important point that there may be multiple
>EndRepeat statements or multiple labels.
>
Rich, you obviously never programmed in TP. If you ever did, you would
know that the TP 'Exit' leaves the current Program Block, that is the 
Procedure/Function/Main Program. So 'Exit' cannot be misunderstood. A
small example:

var i:integer;

begin
  i:=1;
  while true do
  begin
    i:=i+1;
    if i>=10 the exit;
  end;
  writeln('This message is never printed.')
end.

Anyway, I just keep on using whatever language mechanisms it takes to
solve my problems. But up to today, I never used a single goto in
Pascal (but I did use exit & halt).

Jan.

 

phys169@csc.canterbury.ac.nz (01/28/91)

In article <11724@j.cc.purdue.edu>, zhou@brazil.psych.purdue.edu (Albert Zhou) writes:
> When I posted the original
> article, I was plagued by the limitation of "exit" implemented on Turbo
> Pascal. I wanted exit several nested subroutines altogether, but I
> could find a direct way to do it.

That would be extremely useful, but is hard to implement, especially without a
frame pointer register. As I recall, Burroughs Algol did this "bad goto" quite 
slowly, since the stack could contain all sorts of rubbish. Somebody mentioned a
version of Pascal (UCSD) that could do this. Maybe Borland may adopt it some
day. I feel that the main use of this facility would be in error handling,
where a plain exit from the procedures might not be enough, however. FORTRAN
has a method of passing an alternative exit label to a routine (dirty but
powerful). Better still, might be an "on error=expr ..." construct before the
calls, and a "generate error(n)" within the procedures. The main question is
how you think about side-effects. 

Exiting loops within loops is easier in theory, but could cause confusion. Your
example...
> 		for i := 1 to 2
> 		  for j := 1 to 3 do
> 		  begin
>           	     ...
> 		     if c then exit(2)
> 		  end
> 
suffers from the same risks (as far as simple mistakes on the programmer's part
going undetected by the compiler is concerned) as the humble goto. Agreed, it
is darned useful, as is exitting from several layers of procedure, but some
discussion is needed as to the best way to implement it. I prefer an exit to a
goto, but they have similar problems (what you write in your program, and what
you think you're coding, can be different, and it tends to break the main line
of the code, which can upset programmers' concentration).

My favourite is to require the NAME of the procedure or loop to be given with
the exit (e.g. "if c then exit for i" in the above example, so you could
add complexity (a 3rd loop, another if, etc, and the program would work the
same way). I would also like to see a "next" statement for loops, which in
effect goes to a label before the end of the (given) loop, e.g. "next j". It is
possible to manage without the "next" by using (convoluted, in my opinion) if's
or procedure calls, or (of course) a goto.

The best way to debate emotive issues (like the goto question) is, as you have
done, provide an example of what is required, and it is then up to the various
"camps" to supply neat answers to it. The particular problem, exitting from
several layers of routine, can be done in Turbo Pascal with an if statement
following each call to procedures that may be affected (which could be a big or
a little problem, and tends to be sensitive to small changes in the program),
or a (dirty) method involving saving the stack pointer before the nested
procedure calls and letting some error-handling routine (perhaps a software
interrupt, since we're talking about TP) use brute force to exit. (not that I'm
recommending the latter, but that might be behind a future compiler's
implementation, mightn't it?). Comments?

Mark Aitchison, Physics, University of Canterbury, New Zealand. 

ian@syacus.acus.oz (Ian Joyner) (01/29/91)

5@maytag.waterloo.edu>

dmurdoch@watstat.waterloo.edu (Duncan Murdoch) writes:

>In article <1991Jan17.205508.16059@massey.ac.nz> T.Moore@massey.ac.nz (T. Moore) writes:
>>
>>I don't think you are as far apart as you think. The operative word is
>>underlined above. If possible, a program should be tree structured which
>>essentially means not using spaghetti code. 

>I don't think a program should be tree structured.  Perhaps a routine should
>be, but certainly not a whole program.  Programs should be onion-shaped: a
>few routines at the top for general control, widening out into specialized
>fairly high level routines for specific tasks, and then narrowing in again to
>a common library of low-level routines, to maintain a constant interface
>to the user and the data.

Neither paradigm is far from my thinking, as I have thought in both of those
ways, but now I think in the OO paradigm, which I think will accomodate
both, but also allow you to arrange things without the shakles of either.
OO allows you to put the right things in the right place, and helps
avoid unwanted interdependencies (no globals has already been mentioned. If
you find yourself tempted to use globals, maybe you have discovered
another class!) I think T.Moore's original point was correct, we were not
that far apart after all!

Unfortunately, OO has suffered in the same way as the goto avoidance debate,
in that it has seemingly become a religious thing, and the original good
idea is lost beneath some silly unreasoned war. Now if we can get back to
the real reasons.....
-- 
Ian Joyner                                     ACSNet: ian@syacus.oz
ACUS (Australian Centre for Unisys Software)   DNS:  ian@syacus.oz.au
Tel 61-2-390 1328      Fax 61-2-390 1391       UUCP: ...uunet!munnari!syacus.oz

ian@syacus.acus.oz (Ian Joyner) (01/30/91)

kushmer@bnlux0.bnl.gov (christopher kushmerick) writes:

>Except for the fact that an exit is just a fancy way of spelling goto, with the
>effective label being a automatic label right before the ultimate end. (I do
>not know if this is how it is actualy implemented, it may be a return, but
>from a logical viewpoint, this is what it is.)

I think Chris makes the important point here, which perhaps underlines that it
is not the gotos that are problematic, it is the labels. Every control
structure in an HLL hides an implicit goto. Even sequential execution implies
"goto next instruction", however no machine code is generated in this case.
The point about return (or exit) is that it goes to one well defined place,
you don't have to hunt the label down, which could be anywhere. This makes
programs easier to follow, as the reader does not even have to think what
the implications of the instruction is, as the jump is well defined and 
contained.
-- 
Ian Joyner                                     ACSNet: ian@syacus.oz
ACUS (Australian Centre for Unisys Software)   DNS:  ian@syacus.oz.au
Tel 61-2-390 1328      Fax 61-2-390 1391       UUCP: ...uunet!munnari!syacus.oz

ian@syacus.acus.oz.au (Ian Joyner) (01/31/91)

e.philips.nl>

derek@sun4dts.dts.ine.philips.nl (derek) writes:

>with your comments about Macs and PCs you are actually being to sound like a
>bigot. Beware, I'm considering putting you in my kill file! (Is a smiley
>necessary?)

No, its not a matter of bigotry, rather history!

MS-DOS was derived from QDOS (for Quick and Dirty OS) from Seattle Computer
Systems. This was meant as an intermediate OS for 8080s until CP/M was
implemented on them. An enterprising Bill Gates seized upon the opportunity
to sell this to ibm. And full credit to him for arranging a perfect marriage.

Now the Xerox family of machines (including Sun, Apollo, Lisa, Mac, NeXT, etc)
were developed over a long period of time by visionaries such as Alan Kay,
Larry Tesler and Adele Goldberg. I regard them as a cut above Bill Gates
(who I still think was a smart cookie in his position, if only Xerox
had had an opportunist like Gates.)

I don't think we should tolerate any sacred cows in this industry, neither
MS-DOS nor Mac, nor Fortran nor Cobol, nor C, nor even Eiffel. Everything
has its time and place and everything will pass. I think we need to be
more discerning, and give credit where credit is due, appear more
fickle to the vendor, so that our customers have power, not the vendors.

Here's a smiley for you Derek.

References:

MS-DOS Encyclopaedia
SmallTalk-80 The Language and its Implementation. Goldberg and Robson
Mindstorms. Seymour Papert
Big Blue: IBM's use and abuse of Power. Richard DeLamarter

(Can someone suggest a more appropriate follow up group if required)
-- 
Ian Joyner                                     ACSNet: ian@syacus.oz
ACUS (Australian Centre for Unisys Software)   DNS:  ian@syacus.oz.au
Tel 61-2-390 1328      Fax 61-2-390 1391       UUCP: ...uunet!munnari!syacus.oz

ian@syacus.acus.oz.au (Ian Joyner) (02/05/91)

phys169@csc.canterbury.ac.nz writes:

>That would be extremely useful, but is hard to implement, especially without a
>frame pointer register. As I recall, Burroughs Algol did this "bad goto" quite 
>slowly, since the stack could contain all sorts of rubbish. Somebody mentioned a
>version of Pascal (UCSD) that could do this. Maybe Borland may adopt it some

Correct, Mark, Algol calls the MCP Block_exit procedure to clean up the
stack, however many routine calls back. This may entail releasing arrays
that have been set up as local variables, etc. (Hence why so many people
use global arrays only in this language, ugh, but then it beats writing
in assembler.) And it really is called a "bad goto". Shows you that you
can't even trust a simple goto to generate a simple machine jump.

One of the languages I enjoyed most, was the gotoless B1000 SDL. This
solved the problem by optionally labelling blocks. eg

do this forever % the only flavour of loop in the language.
   do that forever
      .....
      if <be> undo this;  % Jump out of outer loop.
      ......
   end that;
   ...
end this;

I don't recall  whether you could "exit" multiple procedures by this method,
but then you get the question of where do you exit to in a multiple 
recursive situation?

People were always amazed when I could quite assuredly state that the
whole operating system was written without one goto. That was easy to
know, as SDL had no goto.
-- 
Ian Joyner                                     ACSNet: ian@syacus.oz
ACUS (Australian Centre for Unisys Software)   DNS:  ian@syacus.oz.au
Tel 61-2-390 1328      Fax 61-2-390 1391       UUCP: ...uunet!munnari!syacus.oz

catone@scrolls.wharton.upenn.edu (Tony Catone) (02/20/91)

In article <1991Jan28.112029.50@csc.canterbury.ac.nz> phys169@csc.canterbury.ac.nz writes:
>Somebody mentioned a
>version of Pascal (UCSD) that could do this. Maybe Borland may adopt it some
>.....
>My favourite is to require the NAME of the procedure or loop to be given with
>the exit

This is the mechanism UCSD pascal used.  And also Apple Pascal, which was
a modified version of UCSD Pascal.  UCSD Pascal used to be available on
MS-DOS machines, in native code mode, from Pecan Software, but my understanding
is that this is no longer the case.  I know this because I have recently
been working on a port of a program originally written in Apple Pascal that
makes much use of the exit() facility, primarily for error handling, as most
people expected.  Translating these into Turbo 6.0 is no fun.

- Tony
  catone@desci.wharton.upenn.edu