1. Home
  2. EXIT directive

EXIT directive

Exits from a control structure.

Options

NTIMES = scalar Number of control structures, n, to exit (if n exceeds the number of control structures of the specified type that are currently active, the exit is to the end of the outer one; while for n negative, the exit is to the end of the –n‘th structure in order of execution); default 1
CONTROLSTRUCTURE = string token Type of control structure to exit (job, for, if, case, procedure); default for
REPEAT = string token Whether to go to the next set of parameters on exit from a FOR loop or procedure (yes, no); default no
EXPLANATION = text Text to be printed if the exit takes place; default *

Parameter

    expression Logical expression controlling whether or not an exit takes place

Description

Sometimes you may want simply to abandon part of a program: you may be unable to do any further calculations or analyses. For example, if you are examining several subsets of the units, you would wish to abandon the analysis of any subset that turned out to contain no observations. Another example would be if you wanted to abandon the execution of a procedure whenever an error diagnostic has appeared. The EXIT directive allows you to exit from any control structure.

In its simplest form EXIT has no parameter setting, and the exit is unconditional: Genstat will always exit from the control structure or structures concerned. You are most likely to use this as part of an ELSE block of a block-if or multiple-selection structure. For example

IF N.GT.0

  CALCULATE Percent = R * 100 / N

ELSE

  PRINT [IPRINT=*] 'Incorrect value ',N,' for N.'

  EXIT [CONTROLSTRUCTURE=procedure]

ENDIF

prints an appropriate warning message for a zero or negative value of N, and then exits from a procedure.

If the warning message is simply a text or string, the EXPLANATION option can be used to print it on exit. For example

EXIT [CONTROLSTRUCTURE=procedure;\

  EXPLANATION='Incorrect value for N.'] N.LE.0

CALCULATE Percent = R * 100 / N

has the same effect except that the actual value of N is no longer printed.

The CONTROLSTRUCTURE option specifies the type of control structure from which to exit. The default setting is for, causing an exit from a FOR loop. For the other settings: if causes an exit from a block-if structure (as introduced by the IF directive), case exits from a multiple-selection structure (as introduced by CASE), procedure exits from a procedure (see the PROCEDURE directive), and job causes the entire job to be abandoned (see JOB). Sometimes, to exit from one type of control structure, others must be left too. To exit from the procedure in the above example, requires Genstat to exit also from the block-if structure. Generally, Genstat does these nested exits automatically, as required. However, inside a procedure, you can exit only from FOR loops and block-if or multiple-selection structures that are within the procedure. You cannot put, for example,

EXIT [CONTROLSTRUCTURE=if]

within a part of the procedure where there is no block-if in operation, and then expect Genstat to exit both from the procedure and from a block-if structure in the outer program from which the procedure was called. Genstat regards a procedure as a self-contained piece of program.

The NTIMES option indicates how many control structures of the specified type to exit from. If you ask Genstat to exit from more structures than are currently in operation in your program, it will exit from as many as it can and then print a warning. If NTIMES is set to zero or to missing value no exit takes place. If NTIMES is set to a negative value, say –n, the exit is to the end of the nth structure of the specified type, counting them in the order in which their execution began. Consider this example:

FOR I=A[1...3]

  FOR J=B[1...3]

    FOR K=C[1...3]

      FOR L=D[1...3]

        "contents of the inner loop, including:"

        EXIT [NTIMES=Nexit]

        "amongst other statements"

      ENDFOR "end of the loop over D[]"

    ENDFOR "end of the loop over C[]"

  ENDFOR "end of the loop over B[]"

ENDFOR "end of the loop over A[]"

If the scalar Nexit has the value 2, the exit is to the end of the loop over C[]; so the two exits are from the loop over D[] and the loop over C[]. But if Nexit has the value -2 the exit is to the end of the loop over B[], as this is the second loop to have been started.

A further possibility when EXIT is used within a FOR loop is that you can choose either to go right out of the loop and continue by executing the statement immediately after the ENDFOR statement, or to go to ENDFOR and then repeat the loop with the next set of parameter values. To repeat the loop, you need to set option REPEAT=yes. For example, suppose that variates Height and Weight contain information about children of various ages, ranging from five to 11. The RESTRICT statement causes the subsequent GRAPH statement to plot only those units of Height and Weight where the variate Age equals Ageval. The EXIT statement ensures that the graph is not plotted if there are no units of a particular age; the program then continues with Ageval taking the next value in the list.

FOR Ageval=5,6,7,8,9,10,11

  RESTRICT Height,Weight; CONDITION=Age.EQ.Ageval

  EXIT [REPEAT=yes] NVALUES(Height).EQ.0

  GRAPH Height; X=Weight

ENDFOR

The REPEAT option can also be used within a procedures to ask Genstat to call the procedure with the next set of parameter settings.

The example of the heights and weights of children also illustrates the use of the parameter of EXIT, to make the effect conditional. The parameter is an expression which must evaluate to a single number which Genstat interprets as a logical value. If the value is zero, the condition is false and no exit takes place; for other values the condition is true and the exit takes effect as specified. This is particularly useful for controlling the convergence of iterative processes: for example

CALCULATE Clim = X/10000

FOR [NTIMES=999]

  CALCULATE Previous = Root

  & Root = (X/Previous + Previous)/2

  PRINT Root,Previous; DECIMALS=4

  EXIT ABS(Previous-Root) < Clim

ENDFOR

will calculate the square root of X to four significant figures.

Options: NTIMES, CONTROLSTRUCTURE, REPEAT, EXPLANATION.

Parameter: unnamed.

See also

Directives: FOR, CASE, IF, FAULT, CALCULATE.

Commands for: Program control.

Example

" Example PROC-1: Defining a procedure"

PROCEDURE 'SQUARERT'
   " Define the options & parameters of the procedure "
   OPTION NAME='PRINT','TRACE'; MODE=t; DEFAULT='no'
   PARAMETER NAME='X','ROOTX'; MODE=p
   " Check that the option settings are valid and set scalars
     Sprint and Strace to indicate whether they are set to yes "
   SCALAR Sprint,Strace
   FOR Setting=PRINT,TRACE; Sset=Sprint,Strace
      IF Setting .EQS. 'yes'
         CALCULATE Sset = 1
      ELSIF Setting .EQS. 'no' 
         CALCULATE Sset = 0
      ELSE 
         EXIT [CONTROLSTRUCTURE=procedure] 
      ENDIF
   ENDFOR
   " Check for invalid setting of parameter X ( i.e. < 0 ) "
   IF X < 0 
      PRINT 'X < 0 :  square root cannot be calculated'
   ELSE
   " Calculate convergence limit & initialize "
      CALCULATE Clim = X/10000  & ROOTX = X
   " Loop until convergence "
      FOR [NTIMES=20]
         CALCULATE Previous = ROOTX
         & ROOTX = (X/Previous + Previous)/2
         IF Strace 
            PRINT [IPRINT=*] ROOTX
         ENDIF
         EXIT ABS(Previous-ROOTX) < Clim
      ENDFOR
      IF Sprint 
         PRINT [IPRINT=*] 'square root of ',X,' is ',ROOTX;\ 
            JUSTIFICATION=left
      ENDIF
   ENDIF
ENDPROCEDURE

" Use the procedure"
SCALAR Rx 
SQUARERT X=48; ROOTX=Rx 
PRINT Rx

" Use it and set the option"
SQUARERT [PRINT=yes] X=48; ROOTX=Rx 
SQUARERT [PRINT=yes; TRACE=yes] 81; ROOTX=Rx
Updated on June 19, 2019

Was this article helpful?