home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #26 / NN_1992_26.iso / spool / comp / programm / 3114 < prev    next >
Encoding:
Text File  |  1992-11-11  |  6.3 KB  |  156 lines

  1. Newsgroups: comp.programming
  2. Path: sparky!uunet!destroyer!gatech!hubcap!mjs
  3. From: mjs@hubcap.clemson.edu (M. J. Saltzman)
  4. Subject: Re: Help - What Is Wrong?
  5. Message-ID: <1992Nov11.194809.18616@hubcap.clemson.edu>
  6. Organization: Clemson University, Clemson SC
  7. References: <544@ulogic.UUCP> <1992Nov9.154402.16285@hubcap.clemson.edu> <1992Nov10.135848.3730@jyu.fi>
  8. Date: Wed, 11 Nov 1992 19:48:09 GMT
  9. Lines: 145
  10.  
  11.  
  12. In article <1992Nov10.135848.3730@jyu.fi> sakkinen@jyu.fi (Markku Sakkinen) writes:
  13. >In article <1992Nov9.154402.16285@hubcap.clemson.edu> mjs@hubcap.clemson.edu (M. J. Saltzman) writes:
  14. >>Discussing a fragment of code of the form 
  15. >>
  16. >>    for ( i = 0;  i != 5;  i++ )
  17. >>        ...
  18. >>
  19. >>hartman@ulogic.UUCP (Richard M. Hartman) writes:
  20. >>>
  21. >>>I've always seen (and used) the "i<max" form of the for loop, and
  22. >>>messed up when faced w/ anything else.  "i!=max" WILL work, but
  23. >>>is less safe for a number of reasons (more so if initial condition
  24. >>    ^^^^^^^^^
  25. >>>is set by variable instead of literal).
  26. >>
  27. >>Presumably, "i != 5" is "less safe" because a failure of the initial
  28. >>condition to satisfy i < 5 will not result in an infinite loop
  29. >>(especially if the initializer "i = 0" is replaced by, say, "i = j + 1",
  30. >>or if the initial i is passed as a parameter).  On the other hand,
  31. >>this may not be the best kind of "safety" to have.
  32. >>
  33. >>In _The_Science_of_Programming_[1], David Gries argues that the guards
  34. >>on loops should be as weak as possible, so that if the initial
  35. >>condition is violated, the program will fail catastrophically (i.e.
  36. >>with an infinite loop).  His reasoning is that the failure of i to be
  37. >>less than 5 indicates an error elsewhere in the code, which might go
  38. >>undetected if the loop fails to execute at all (with the program
  39. >>giving a wrong answer).  If the program goes into an infinite loop,
  40. >>you can be sure you've stumbled on a bug.
  41. >
  42. >Looks like pretty bad advice from such an acknowledged authority.
  43. >If catastrophic failure is required, it should be an abort or the like,
  44. >not an infinite loop.  Perhaps if the programmer herself is always
  45. >tending to her programme when it is run(!), she may reason:
  46. >"Far too much time has passed for this stage, it _must_ be stuck
  47. >in an infinite loop somewhere."
  48. >Infinite loops can be a particularly bad idea in multitasking systems.
  49.  
  50. But someone would catch such a loop pretty quickly, or you would run
  51. out of resources (you do set time limits on your batch jobs, don't
  52. you?).
  53.  
  54. I quote from the Master:
  55.  
  56.     Some object at first to finding the guard in this way, because
  57.     Tradition would use the guard "i < n" instead of "i != n". However, 
  58.     "i != n" is better, because a software or hardware error that made
  59.     i > n would result in nonterminating execution.  It is better to waste
  60.     computer time than suffer the consequences of having an error go
  61.     undetected, which would happen if the guard "i < n" were used.
  62.  
  63. I should also point out that this discussion is taken somewhat out of
  64. context.  As someone pointed out in e-mail to me, the real reason for
  65. weak loop guards is that the post-condition of the loop is a
  66. conjunction involving the invariant and the negation of the guard.
  67. Weak guards imply strong postconditions, which can help prove that the
  68. loop accomplishes the desired function.  In fact, the guard is derived
  69. as the complement of the postcondition needed to prove the desired
  70. result.  Loop derivation also involves a bound function, bounded below
  71. and decreased at every iteration, so termination is guaranteed if the
  72. precondition is satisfied.
  73.  
  74. >In this specific example as is, there is not much difference
  75. >between the alternatives.  But suppose a little modification:
  76. >    for ( i = whiz(x);  i != 5;  i++ ) ...
  77. >will be sensible only if you are absolutely sure that 'whiz(x)'
  78. >returns a value < 5;  otherwise you should insert an explicit test.  
  79.  
  80. That's right, and it is the point.  Remember that Gries's discussion
  81. is in the context of deriving correct programs, so you have presumably
  82. proved that the precondition "i < 5" is satisified in this case, but
  83. if you should encounter a bug due to a typo, or someone else's code...
  84.  
  85. >On the contrary, 'i < 5' works perfectly also in this case,
  86. >if the intent is not to execute the loop at all if the value is >= 5.
  87.  
  88. But if the intent is that i > 5 is an error, you want to write code
  89. that will catch it.
  90.  
  91. >Also, the code might be modified so that the increment is 2 instead of 1;
  92. >'i < 5' still works in a way that may be sensible.
  93. >In general, it looks much more robust than 'i != 5'.
  94.  
  95. Surely if you are going to change the increment, you should re-derive the
  96. guard as well!
  97.  
  98. >>On the other hand, Gries recommends that guards on "if" and "else"
  99. >>statements should be as strong as possible, and that the default
  100. >>action for any case not explicitly covered in the guards should be to
  101. >>abort.  The reasoning is the same: if one of the "if" or "else"
  102. >>conditions is not met, there is a failure elsewhere in the program
  103. >>that could go undetected if the program is allowed to continue.
  104. >
  105. >Obviously you are quoting from memory (see below), and this does
  106. >not make any sense.  'If ... then ... else ... endif'
  107. >always covers all cases!
  108.  
  109. To be sure, it was from (recent) memory.  But let me elaborate:
  110. Consider a piece of code that takes action based on the value of
  111. some nonnegative variable k.  You might write:
  112.  
  113.     if ( k > 0 ) {
  114.     ...
  115.     } else {  /* k == 0 (since we're sure k >= 0) */
  116.     ...
  117.     } 
  118.  
  119. Or you might write
  120.  
  121.     if ( k > 0 ) {
  122.     ...
  123.     } else if ( k == 0 ) { 
  124.     ...
  125.     } else abort();
  126.  
  127. Gries's principle would advocate the latter, "all other things being equal."
  128.  
  129. >>[1] This book is a classic, and a very readable introduction to the
  130. >>ideas underlying derivation of provably correct programs.  (Sorry, I
  131. >>don't have the publisher information handy.)
  132.  
  133. Springer Verlag, 1981.
  134.  
  135. >If Gries strongly suggests infinite loops in many places,
  136. >the book is evidently aiming at provably _partially_ correct programs. :-)
  137.  
  138. Oh, cheap shot!
  139.  
  140. >
  141. >----------------------------------------------------------------------
  142. >Markku Sakkinen (sakkinen@jytko.jyu.fi)
  143. >       SAKKINEN@FINJYU.bitnet (alternative network address)
  144. >Department of Computer Science and Information Systems
  145. >University of Jyvaskyla (a's with umlauts)
  146. >PL 35
  147. >SF-40351 Jyvaskyla (umlauts again)
  148. >Finland
  149. >----------------------------------------------------------------------
  150.  
  151.  
  152. -- 
  153.         Matthew Saltzman
  154.         Clemson University Math Sciences
  155.         mjs@clemson.edu
  156.