Consider the following function
my_exp(x, tol, n_max)which uses a Taylor polynomial (of order at most n_max) to approximate the value of EXP(x) within tol. We know that higher order Taylor polynomials approximate EXP better; the function chooses the optimal order for which the approximation error is less than tol; however, if tol is too small, a very large order of the approximating polynomial may be needed; in this situation the polynomial of order n_max is used, even if the error is larger than tol.
When we call the function we have to specify the argument and the desired tolerance, and the maximal order, for example
Y = my_exp(x, 1.E-6, 10)This is clumsy, since most often we use, say, tol = 1.E-6 and n_max = 10; we would like to omit the last arguments when calling the function (and use implicitly the default values); but also retain the possibility of changing the defaults to some other values now and then.
We can do this in F90 by specifying the tol and n_max as optional arguments.
real function my_exp(x, tol, n_max) implicit none real, intent(in) :: x real, intent(in), optional :: tol real :: err_max integer, intent(in), optional :: n_max integer :: order_max ... if( present(tol) ) then err_max = tol else err_max = 1.e-6 end if if( present(n_max) ) then order_max = n_max else order_max = 10 end if ... end function my_exp
The OPTIONAL parameter allow tol and n_max to be omitted when the function is called. For example,
y = my_exp(x)is a valid call and signifies that tol, n_max take the default values 1.E-6 and 10.
In the function body, the intrinsic function PRESENT(tol) returns .TRUE. if the current function call explicitly had tol as argument, and .FALSE. if tol was omitted. This distinction allows us to know when the optional arguments are not present and replace them by their default values.
Note that, when an optional argument is missing, the space on the stack associated with it is not allocated; in consequence missing optional arguments ``do not exist'' in the function body and we cannot read and write them (we can only test their existence with PRESENT()). For example the statement
{l} if( .not.present(tol))~ tol=1.e-6is wrong, since it writes a variable that has not been allocated.
Finally, let us mention that only some of the optional arguments might be missing. For example
y = my_exp(x, 1.e-8)is correct (tol=1.E-8 and n_max assumes the default value, 10). However, the statement
y = my_exp(x,12)is incorrect, and , in particular, does NOT mean default tol and n_max=12. Whenever an optional argument is missing, the following arguments must be tagged with the proper keywords (otherwise the compiler has no way of knowing which argument is which). The correct call for default tol and n_max=12 is
y = my_exp(x,n_max=12)In general it is always good practice to use keywords whenever the optional arguments are explicitly present in the procedure call.
Some built in functions (OPEN, READ, WRITE) have optional arguments and keywords - remember?