hirchert@uxe.cso.uiuc.edu (12/09/89)
Walt Brainerd (brainerd@unmvax.unm.edu) writes: >Computed GO TO is on a list of a few noncontroversial things >with the property that they could be considered for removal >from the next standard (2001?) after the one coming up. No, computed GO TO is not on the "obsolescent features" list. Only _assigned_ GO TO is on that list.
hirchert@uxe.cso.uiuc.edu (12/12/89)
I'd like to offer a few more points about the "obsolescent features list". o If a series of block IFs were the only possible replacements for assigned GO TO and alternate RETURN, I doubt whether it would have been possible to muster the votes in X3J3 to put them on the obsolescent features list. In both cases, computed GO TO can be used to provide a replacement whose is comparable to that of the original feature. o PAUSE is a bit of a special case. In some systems, it is quite true that one cannot reproduce its functionality with input/output statements. (E.g., on one multiuser system I have used, it holds up the entire system until the system operator responds!) However, none of these extended functionalities are portable. The committee concluded that it was better to use the input/output statements to get the portable functionality and access the special functionalities by calling procedures (written in C or Pascal or Ada or assembly language or whatever is necessary to implement that special functionality on the given machine). o It has been suggested that DO loops with integer indices cannot exactly replace the behavior of loops with real or double precision indices. In fact they can. For example the loop DO 10 X=0.0,1.0,0.1 ... 10 <some statement> could be exactly replaced by em1=0.0 em3=0.1 iters=(1.0-em1+em3)/em3 X=em1 DO 10a it=1,iters ... 10 <some statement> 10a X=X+em3 [The variable em1 was not really needed in this case; X could have been defined earlier and used in its place. However, in the general case, the expressions controlling the iteration might involve the old value of X, so it might not be acceptable to define X earlier. Similarly, in many cases, it may be possible to simply move the label 10 down to the incrementing of X, but having two distinct labels will be necessary if the loop contains any branches to 10.] The above is simply an encoding of the description of the DO loop found in section 11 of FORTRAN 77. The only case where it might not work would be if the processor handles loops whose number of iterations is greater than the maximum value representable by an integer. The above characterization of this loop also illustrates what is wrong with using real variables as DO loop indices. The expression for the number of iterations can easily give 10 or 11, depending on which way the binary representation of 0.1 is rounded. Even worse, there is an accumulation of error in the incrementation of X, so the successive values of X can be quite different from what is expected. The loop could execute only 10 times with the final iteration being for a value less than 0.9 or the loop could execute 11 times with the final iteration being for a value greater than 1.0. There can be more extreme problems: For example on an IBM mainframe, a loop such as DO 20 Y=1000000.,1000001.,0.01 should execute approximately 100 times with Y equal to 1000000. on every iteration because the difference between 1000000. and 1000001. is represent- able by the real type, but the difference between 1000000. and 1000000.01 is not. To avoid these kinds of arithmetic problems, it is usually better to replace our original loop with something like DO 10 it=0,10 X=0.0+0.1*it ... 10 <some statement> This may not produce exactly the same results as the original loop, but in cases where they differ, this result is likely to be more accurate and more portable. (If you want to be extra careful, make it X=MIN(0.0+0.1*it,1.0).) Although computed GO TO is _not_ on the list of obsolescent features, there has also been some discussion of eventually replacing it with the CASE construct (some time in the next century). I would note the following: * In my experience, most uses of computed GO TO are to simulate CASE constructs, although in many cases this is masked by one of the cases being something like an EXIT or CYCLE of a loop. Obviously, in these cases it would be more appropriate to use the CASE construct once it is available. * In those cases where a computed GO TO cannot be construed as implementing a CASE construct, it is possible to simulate its effect by putting unconditional GO TO statements inside a CASE construct. . If the number of different branches is significantly smaller than the number of different case values, the CASE construct representation may still be more readable than a computed GO TO with repeated labels in the list. . Even in those cases where the CASE representation is more verbose and less readable, it should always possible. The size of a computed GO TO is limited by the number of allowed continuation lines, but a CASE construct consists of multiple statement and is thus not subject to this limit. If, in the interests of making the language smaller, we could retain only one of these features in the language, I would choose the CASE statement because it appears to be more appropriate more often and would involve no loss of functionality in those cases where it is not more appropriate. Fortunately, however, such a decision, if it ever needs to be made, is decades away. Kurt W. Hirchert hirchert@ncsa.uiuc.edu National Center for Supercomputing Applications
hirchert@uxe.cso.uiuc.edu (12/15/89)
jlg@lambda.UUCP writes: >The feature that REALLY replaces the assigned GOTO is internal >procedures. Except internal procedures can't be nested and >assigned GOTO can allow nested usage. In the sense that internal procedures are nested, procedures simulated with assigned GO TO are not nested at all; i.e. they have no local scope. Procedures simulated with assigned GO TO can call each other, but then so can internal procedures. What is it that you can do with the assigned GO TO that you think you can't do with an internal procedure? >MOST uses of the computed GOTO can be done as CASE statements. Indeed, >most of my usage of computed GOTO directly emulates CASE statement >semantics. However, neither block IFs nor CASE statements allow a >satisfactory replacement for the following: > > GOTO (101,102,103), iselect > STOP 'ISELECT is out of range' > > 101 continue > [Print the day of week] > 102 continue > [Print the date] > 103 continue > [Print the time] > >Here the code has been written to "gradually" change its behaviour >based on the ISELECT variable. It either prints just the time, or >the date and the time, or the day-of-week plus date and time. >Solutions to do this without the computed GOTO always are harder >to read and maintain than this is. I come across this "gradual" >code shift problem only once in a while, but when I do there's >nothing better than the existing computed GOTO. This is very much a matter of taste. Some people would argue that IF (1 <= iselect .and. iselect<=3) THEN IF (iselect <= 2) THEN IF (iselect <= 1) THEN [Print the day of week] END IF [Print the date] END IF [Print the time] ELSE STOP 'ISELECT is out of range' END IF is more descriptive of what you are doing. Others would argue in favor of SELECT CASE (iselect) CASE(1) CALL PRINT_DAY_OF_WEEK CALL PRINT_DATE CALL PRINT_TIME CASE(2) CALL PRINT_DATE CALL PRINT_TIME CASE(3) CALL PRINT_TIME CASE DEFAULT STOP 'ISELECT is out of range' END SELECT where the logic to print the day of week, date, and time has been moved to appropriately named internal procedures. Another might argue in favor of itemp=iselect DO SELECT CASE (itemp) CASE(1) [Print day of week] CASE(2) [Print date] CASE(3) [Print time] EXIT CASE DEFAULT STOP 'ISELECT is out of range' END SELECT itemp=itemp+1 END DO Yet another might replace the above loop with a DO loop starting at iselect. Someone else might control the who process by a decision table. Finally, some people might simply replace your computed GO TO with SELECT CASE (iselect) CASE(1); GO TO 101 CASE(2); GO TO 102 CASE(3); GO TO 103 CASE DEFAULT; STOP 'ISELECT is out of range' END SELECT and claim that although this is somewhat more verbose it is equally readable and maintainable. Fortunately, computed GO TO is an ordinary part of Fortran 8x, which means that at worst it would be made obsolescent in the next revision in order to be removed from the revision following that, so none of us are likely to have to worry about replacing any computed GO TOs for at least 20 years. Kurt W. Hirchert hirchert@ncsa.uiuc.edu National Center for Supercomputing Applications