User Tools

Site Tools


how_20to_20avoid_20gotos

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

how_20to_20avoid_20gotos [2018/03/31 13:19]
127.0.0.1 external edit
how_20to_20avoid_20gotos [2018/04/17 16:36] (current)
tbest3112 Added syntax highlighting
Line 2: Line 2:
  
 //by Richard Russell, November 2006, revised June 2007 and October 2011//\\ \\  BBC BASIC includes the **GOTO** statement, but GOTOs are generally considered to be **a bad thing**. I won't repeat the arguments for avoiding GOTOs here: they are well explained in the [[http://​www.bbcbasic.co.uk/​bbcwin/​tutorial/​appendixa.html|tutorial]],​ on [[http://​en.wikipedia.org/​wiki/​Structured_programming|Wikipedia]] and elsewhere. Suffice it to say that they can result in code which is difficult to understand, difficult to maintain and more likely to have bugs.\\ \\  Supporters of GOTO will point to code examples such as the following as justification for their use:\\ \\  //by Richard Russell, November 2006, revised June 2007 and October 2011//\\ \\  BBC BASIC includes the **GOTO** statement, but GOTOs are generally considered to be **a bad thing**. I won't repeat the arguments for avoiding GOTOs here: they are well explained in the [[http://​www.bbcbasic.co.uk/​bbcwin/​tutorial/​appendixa.html|tutorial]],​ on [[http://​en.wikipedia.org/​wiki/​Structured_programming|Wikipedia]] and elsewhere. Suffice it to say that they can result in code which is difficult to understand, difficult to maintain and more likely to have bugs.\\ \\  Supporters of GOTO will point to code examples such as the following as justification for their use:\\ \\ 
 +<code bb4w>
         FOR i = 1 TO maxi         FOR i = 1 TO maxi
           FOR j = 1 TO maxj           FOR j = 1 TO maxj
Line 13: Line 14:
  
   100   PRINT "Empty element found at: "i,j,k   100   PRINT "Empty element found at: "i,j,k
 +</​code>​
 What this code does is to scan through all the elements of a 3-dimensional array, looking for the first empty (zero) element. When found it doesn'​t bother to look any further, and terminates the search by jumping out with GOTO. If it ever finishes the search it means an empty element was never found.\\ \\  Admittedly it is clear how the code works, and it is one of the more acceptable uses of GOTO, but it is still undesirable (for example it doesn'​t clear down the stack, and could eventually result in running out of memory). How might we rework the routine to avoid the use of GOTO? One way would be to replace the FOR...NEXT loops with REPEAT...UNTIL loops:\\ \\  What this code does is to scan through all the elements of a 3-dimensional array, looking for the first empty (zero) element. When found it doesn'​t bother to look any further, and terminates the search by jumping out with GOTO. If it ever finishes the search it means an empty element was never found.\\ \\  Admittedly it is clear how the code works, and it is one of the more acceptable uses of GOTO, but it is still undesirable (for example it doesn'​t clear down the stack, and could eventually result in running out of memory). How might we rework the routine to avoid the use of GOTO? One way would be to replace the FOR...NEXT loops with REPEAT...UNTIL loops:\\ \\ 
 +<code bb4w>
         i = 0         i = 0
         REPEAT i += 1         REPEAT i += 1
Line 29: Line 32:
           PRINT "Empty element not found"           PRINT "Empty element not found"
         ENDIF         ENDIF
 +</​code>​
 This certainly avoids the GOTO, but is it as clear? And what about execution speed? A simple measurement demonstrates that this '​improved'​ version takes about 40% longer to run.\\ \\  Perhaps we can stick with using FOR...NEXT loops but avoid the GOTO another way:\\ \\  This certainly avoids the GOTO, but is it as clear? And what about execution speed? A simple measurement demonstrates that this '​improved'​ version takes about 40% longer to run.\\ \\  Perhaps we can stick with using FOR...NEXT loops but avoid the GOTO another way:\\ \\ 
 +<code bb4w>
         imt = 0 : jmt = 0 : kmt = 0         imt = 0 : jmt = 0 : kmt = 0
         FOR i = 1 TO maxi         FOR i = 1 TO maxi
Line 47: Line 52:
           PRINT "Empty element not found"           PRINT "Empty element not found"
         ENDIF         ENDIF
 +</​code>​
 This relies on the ability to terminate a FOR...NEXT loop prematurely by setting its control variable to the limit value (all versions of BBC BASIC let you do that). Note that it is now necessary to copy the indices at which the empty element was found, but the execution speed is at least as good as the first version (it may be faster, because GOTO itself is quite slow).\\ \\  Here is a radically different approach:\\ \\  This relies on the ability to terminate a FOR...NEXT loop prematurely by setting its control variable to the limit value (all versions of BBC BASIC let you do that). Note that it is now necessary to copy the indices at which the empty element was found, but the execution speed is at least as good as the first version (it may be faster, because GOTO itself is quite slow).\\ \\  Here is a radically different approach:\\ \\ 
 +<code bb4w>
         IF FNsearch(i,​j,​k) THEN         IF FNsearch(i,​j,​k) THEN
           PRINT "Empty element found at: "i,j,k           PRINT "Empty element found at: "i,j,k
Line 64: Line 71:
         NEXT i         NEXT i
         =FALSE         =FALSE
 +</​code>​
 This time we've moved most of the code into a user-defined function. Now we can exit from the loops without using a GOTO, simply by returning early from the function.\\ \\  The code is easy to understand, it runs quickly, and by moving the search routine into a function (which can be placed out of harm's way at the end of the program) we also adhere to one of the other principles of modern software practice: [[http://​en.wikipedia.org/​wiki/​Information_hiding|encapsulation]]. The theory is that it is better to move self-contained functional modules out of the main code so they don't clutter it and can be separately maintained.\\ \\  There are however a couple of problems with this code. Firstly, some versions of BBC BASIC won't let you jump out of a function without first '​unrolling'​ the FOR...NEXT loops (BBC BASIC for Windows will). Secondly some people think it is cheating, because it's effectively still jumping out of the loops - just not using GOTO to do so!\\ \\  Finally, if you're using //BBC BASIC for Windows// version 5.60 or later, you can make use of the [[http://​www.bbcbasic.co.uk/​bbcwin/​manual/​bbcwin5.html#​exit|EXIT]] statement added in that version:\\ \\  This time we've moved most of the code into a user-defined function. Now we can exit from the loops without using a GOTO, simply by returning early from the function.\\ \\  The code is easy to understand, it runs quickly, and by moving the search routine into a function (which can be placed out of harm's way at the end of the program) we also adhere to one of the other principles of modern software practice: [[http://​en.wikipedia.org/​wiki/​Information_hiding|encapsulation]]. The theory is that it is better to move self-contained functional modules out of the main code so they don't clutter it and can be separately maintained.\\ \\  There are however a couple of problems with this code. Firstly, some versions of BBC BASIC won't let you jump out of a function without first '​unrolling'​ the FOR...NEXT loops (BBC BASIC for Windows will). Secondly some people think it is cheating, because it's effectively still jumping out of the loops - just not using GOTO to do so!\\ \\  Finally, if you're using //BBC BASIC for Windows// version 5.60 or later, you can make use of the [[http://​www.bbcbasic.co.uk/​bbcwin/​manual/​bbcwin5.html#​exit|EXIT]] statement added in that version:\\ \\ 
 +<code bb4w>
         FOR i = 1 TO maxi         FOR i = 1 TO maxi
           FOR j = 1 TO maxj           FOR j = 1 TO maxj
Line 78: Line 87:
           PRINT "Empty element not found"           PRINT "Empty element not found"
         ENDIF         ENDIF
 +</​code>​
 I hope you can see that there are several ways of avoiding GOTO. Not all of them necessarily improve a program'​s structure, but there is invariably one that has all the advantages but none of the disadvantages of using GOTO. I hope you can see that there are several ways of avoiding GOTO. Not all of them necessarily improve a program'​s structure, but there is invariably one that has all the advantages but none of the disadvantages of using GOTO.
how_20to_20avoid_20gotos.txt ยท Last modified: 2018/04/17 16:36 by tbest3112