



Procedures as Arguments In the next example, the subroutine GRAPH plots a graph of a function MYFUNC between specified limits, with its argument range divided somewhat arbitrarily into 101 points. For simplicity it assumes the existence of a subroutine PLOT which moves the pen to position (X,Y). Some other subroutines would, in practice, almost certainly be required.
SUBROUTINE GRAPH(MYFUNC, XMIN, XMAX) *Plots functional form of MYFUNC(X) with X in range XMIN:XMAX. REAL MYFUNC, XMIN, XMAX XDELTA = (XMAX - XMIN) / 100.0 DO 25, I = 0,100 X = XMIN + I * XDELTA Y = MYFUNC(X) CALL PLOT(X, Y) 25 CONTINUE END |
GRAPH can then be used to plot a function simply by providing its
name them as the first argument of the call. The only other requirement is that
the name of each function used as an actual argument in this way must be
specified in an INTRINSIC or EXTERNAL statement, as appropriate. Thus:
PROGRAM CURVES INTRINSIC SIN, TAN EXTERNAL MESSY CALL GRAPH(SIN, 0.0, 3.14159) CALL GRAPH(TAN, 0.0, 0.5) CALL GRAPH(MESSY, 0.1, 0.9) END REAL FUNCTION MESSY(X) MESSY = COS(0.1*X) + 0.02 * SIN(SQRT(X)) END |
MESSY. These functions must, of course, have the same procedure interface themselves
and must be called correctly in the GRAPH procedure.
It is possible to pass either a function or a subroutine as an actual argument in
this way: the only difference is that a CALL statement is used instead of a
function reference to execute the dummy procedure. It is possible to pass a
procedure through more than one level of procedure call in the same way.
Continuing the last example, another level could be introduced like this:
PROGRAM CURVE2 EXTERNAL MESSY INTRINSIC SIN, TAN CALL GRAPH2(PRETTY) CALL GRAPH2(TAN) END SUBROUTINE GRAPH2(PROC) EXTERNAL PROC CALL GRAPH(PROC, 0.1, 0.7) END |
GRAPH2 sets limits to each plot and passes the procedure name
on to GRAPH. The symbolic name PROC must be declared in an EXTERNAL
statement as it is a dummy procedure: an EXTERNAL statement is required
whether the actual procedure at the top level is intrinsic or external. The
syntax of the INTRINSIC and EXTERNAL statements is given in section 9.12
below.
The name of an intrinsic function used as an actual argument must be a specific name and not a generic one. This is the only circumstance in which you still have to use specific names for intrinsic functions. A full list of specific names is given in the appendix. A few of the most basic intrinsic functions which are often expanded to in-line code (those for type conversion, lexical comparison, as well as MIN and MAX) cannot be passed as actual arguments.