- Introduction
- 1. Source code form
- 2. Alternative representations
- 3. Specifications
- 4. Conditional statement
- 5. DO-loop
- 6. Program units
- 7. Character string variables
- 8. Input
- 9. Vector and matrix management
- 10. Dynamic storage
- 11. Intrinsic functions
- 12. Use of the user-defined data type
- 13. Modules
- 14. The data type "bit"
- 15. Pointers
- 16. User extensions

Below follows a short summary of the new standard. Please note that only some more essential parts and not the whole new standard are discussed here.

As an alternative to the old source-code (punched card oriented) form, there is a free form, which does not take any consideration to columns and where blanks are significant. Comments can be given on the line if preceded by an exclamation mark !, several statements can be given on the same line if using the semicolon ; as a separator, and statements that continue on the next line are continued on the present line (not the next line) with an ampersand &.

The underline symbol _ is permitted inside the names of variables, and the length of variables must have at most 31 characters (instead of at most 6 in the Fortran 77 standard).

Blanks become significant in the free form of the source code. Old commands like `ENDIF
`and `GOTO `can also in the future be written either as `END IF `or `GO
TO `respectively, but of course not like `EN DIF `or `GOT O`. To permit
significant blanks in the old (fixed) form of the source code would not be possible, since
it for example is permitted to write `END `in the following silly way

E N D

`INCLUDE `can be used to include source code from an external file. The construct is
a line where there is `INCLUDE `and a character string and, perhaps, some
concluding comments. Interpretation is implementation-dependent, normally the character
string is treated as the name of the file that holds the source code that should be
included. Nesting is permitted (and the number of levels is implementation-dependent), but
recursion is not permitted for the `INCLUDE `statement.

As in most Algol-type languages the word `END `can be complemented with the name
of the routine or function like `END FUNCTION GAMMA`.

The special characters < and > can now be used

< .LT. > .GT. <= .LE. >= .GE. == .EQ. /= .NE.

These can now be written on one line

REAL, DIMENSION (3), PARAMETER :: & a = (/ 0.0, 0.0, 0.0 /), b = (/ 1.0, 1.0, 1.0 /) COMPLEX, DIMENSION(10) :: john

while the variables a and b become constant vectors with 3 elements and the floating-point values 0.0 and 1.0, respectively, while john becomes a complex vector with 10 complex elements, not yet assigned any values.

If you wish to use the Algol principle to specify all variables, this is simplified by
the command `IMPLICIT NONE `which switches off the implicit-type rules.

Double precision has been implemented with a more general method to give the desired
precision, namely the parameter `KIND `for which precision we wish, useful on all
variable types.

INTEGER, PARAMETER :: LP = SELECTED_REAL_KIND(20) REAL (KIND = LP) :: X, Y, Z

The above two statements thus declare the variables `X, Y `and `Z `to be `REAL
`floating-point variables with at least 20 decimal digits accuracy with a data type
that is called `LP `(where `LP `stands for `LONG PRECISION)`.

The new command is

SELECT CASE (expression) CASE block-switch block CASE block-switch block CASE DEFAULT default block END SELECT

Typical construct:

SELECT CASE(3*I-J) ! the control variable is 3*i-j CASE(0) ! for the value zero : ! you execute the code here CASE(2,4:7) ! for the variables 2, 4, 5, 6, 7 : ! you execute the code here CASE DEFAULT ! and for all other values ! you execute the code here : ! END SELECT

If the `CASE DEFAULT `is missing and none of the alternatives is valid, the
execution continues directly with the next statement following the `END SELECT`,
without any error message.

Another example:

INTEGER FUNCTION SIGNUM(N) SELECT CASE (N) CASE (:-1) SIGNUM = -1 CASE (0) SIGNUM = 0 CASE (1:) SIGNUM = 1 END SELECT END

Three new constructs are included. The first one gives in principle an infinite loop,
which however can be terminated with a conditional `GOTO`-statement.

name: DO executable statements END DO name

The usual `DO`-loop has the following new simplified form without statement
number,

name: DO i = integer_expr_1, integer_expr_2 ,integer_expr_3 executable statements END DO name

where `i `is called control variable, and where `,integer_expr_3 `is
optional. Finally there is also the `DO WHILE `loop

name: DO WHILE (logical_expression) executable statements END DO name

The name is optional but can be used for nested loops in order to indicate which one
that is to be iterated once again with the `CYCLE `statement or terminated with the
`EXIT `statement.

S1: DO IF (X > Y ) THEN Z = X EXIT S1 END IF CALL NEW(X) END DO N = 0 LOOP1: DO I = 1, 10 J= I LOOP2: DO K =1, 5 L = K N = N +1 END DO LOOP2 END DO LOOP1

In the latter case the final values from the variables will be as follows, in full
accordance with the standard, `I = 11, J = 10, K = 6, L = 5`, and `N = 50.`

To name the loop is completely optional. Also note that this type of name is limited to
`DO`-loop, `CASE `or `IF...THEN...ELSE...ENDIF `constructs. The old
possibilities with statement numbers are still available, also in the free form.

Routines can be called with keyword arguments and can use default arguments

SUBROUTINE solve (a, b, n) REAL, OPTIONAL, INTENT (IN) :: b

can be called with

CALL solve (n = i, a = x)

where two of the arguments are given with keywords instead of position and where the
third one has a default value. If `SOLVE `is an external routine it requires making
use of an `INTERFACE `block in the calling program. Routines can be specified to be
recursive.

RECURSIVE FUNCTION factorial (n) RESULT (fac)

but must then have a special `RESULT `name in order to return the result.

`CHARACTER `has been expanded to include also an empty string

a = ''

and assignment of an overlapping string is now permitted

a(:5) = a(3:7)

The new intrinsic function `TRIM `which removes concluding blanks is an
important addition. You can now make a free choice between the apostrophe ' and the
quotation mark " in order to indicate a character string. This can among other things
be used in such a way that if you wish to write an apostrophe inside the text, then you
use the quotation mark as indicators, and in the opposite case if you wish to have a
quotation mark inside the text you use the apostrophe as the indicator.

At last the `NAMELIST `is included in the standard! This statement, however, has
to be among the specifications. In the example below `list2 `is the name of the
list, `a `and `b `are real variables and i is an integer variable.

NAMELIST /list2 / a, i, x : READ (unit, NML = list2)

which wishes to get input data of the following form, but all variables do not have to given, and they can be given in any order.

&list2 X = 4.3, A = 1.E20, I = -4 /

This is one of the most important parts of the new standard. An array is defined to have a shape given by its number of dimensions, called "rank", and the extent for each one of these. Two arrays agree if they have the same shape. Operations are normally done element by element. Please remember that the rank for an array is the number of dimensions and has nothing at all to do with the mathematical rank of a matrix!

REAL, DIMENSION(5,20) :: x, y REAL, DIMENSION(-2:2,20) :: z : z = 4.0*y*sgrt(x)

We perhaps here wish to protect against negative elements of `X`. This is done
with the following construct

WHERE ( x >= 0.0 ) z = 4.0*y*sgrt(x) ELSEWHERE z = 0.0 END WHERE

Please note that `ELSEWHERE `has to be in one word! Compare also with the
function `SUM `which is discussed at the end of the next section.

You can pick out a part of an array. Assume that the array `A` is specified in
the following way.

REAL, DIMENSION(-4:0, 7) :: A

With `A(-3, :)` you pick the second row, while with `A(0:-4:-2, 1:7:2) `you
pick (in reverse order) its each other element in each other column. Just as variables can
form arrays, also constants can form arrays.

REAL, DIMENSION(6) :: B REAL, DIMENSION(2,3) :: C B = (/ 1, 1, 2, 3, 5, 8 /) C = RESHAPE( B, (/ 2,3 /) )

where the first argument to the intrinsic function `RESHAPE `gives the value and
the second argument gives the new shape. Two additional, but optional, arguments are
available to this function.

The above can also be written in a more compressed form using the `PARAMETER `attribute.
In the first line below the `PARAMETER `attribute is compulsory (if the assignment
is to be made on the same line), but in the second line it is optional. Remember that the `PARAMETER
`attribute means that the quantity can not be changed during execution of the program.

REAL, DIMENSION(6), PARAMETER :: B = (/ 11, 12, 13, 14, 15, 16 /) REAL, DIMENSION(2,3), PARAMETER :: C = RESHAPE( B, (/ 2, 3 /) )

Any statements for real parallel computation are not included in Fortran 90. The committee believes it is necessary with additional experience before the standardization of parallelization. See also HPF discussed in the Appendix 8.

Fortran 90 contains four different ways to make dynamical access. The first one is to use a pointer. See an example on a vector and for an example on a matrix see exercise 12.3.

The second is to use an "allocatable array", i.e. with the statements `ALLOCATE
`and `DEALLOCATE `you get and return a storage area for an array with type,
rank and name (and possible other attributes) which had been specified earlier with the
additional attribute `ALLOCATABLE`.

REAL, DIMENSION(:), ALLOCATABLE :: x : Allocate(x(N:M)) ! N and M are the integer expressions here. : x(j) = q ! Some assignment of the array. CALL sub(x) ! Use of the array in a subroutine. : DEALLOCATE (x)

Deallocation occurs automatically (if the attribute `SAVE `has not been given)
when you reach `RETURN `or `END `in the same program unit.

The third variant is an "automatic array", it is almost available in the old Fortran, where x in the example below has to be in the list of arguments. This is not required any more.

SUBROUTINE sub (i, j, k) REAL, DIMENSION (i, j, k) :: x

Dimensions for x are taken from the integers in the calling program. Finally there is an "assumed-shape array" where the storage is defined in the calling procedure and for which only the type, rank and name are given.

SUBROUTINE sub(a) REAL, DIMENSION (:,:,:) :: a

According to Metcalf and Reid (1990, 1992), section 6.3 you here require an explicit interface. This has to look as follows

INTERFACE SUBROUTINE SUB(A) REAL, DIMENSION (:,:,:) :: A END SUBROUTINE SUB END INTERFACE

If you forget the `INTERFACE `or if you have an erroneous interface, then you
will usually get "segmentation error", it means that a program unit may be
missing.

Some intrinsic functions are available to determine the actual dimension limits

DO (i = LBOUND(a,1), UBOUND(a,1)) DO (j = LBOUND (a,2), UBOUND (a,2)) DO (k = LBOUND(a,3),UBOUND (a,3))

where `LBOUND `gives the lower limit for the specified dimension and `UBOUND `gives
the upper one.

The sum of the positive value of a number of elements in an array is written

SUM ( X, MASK = X .GT. 0.0)

These statements can not be used in order to avoid division by zero at for example
summation of `1/X`, that is the mask works only with determining which numbers that
are to be included in the summation, and not whether a certain value has to be calculated
or not. But in this later case you can use the construct `WHERE`, see section 9.

Fortran 90 defines about 100 intrinsic functions and a few intrinsic subroutines. Many
of these functions can be used for arrays, e.g. for reduction (`SUM`), construct `(SPREAD)`,
manipulation (`TRANSPOSE`). Other functions permit attributes or available
parameters in the programming environment to be determined, as the largest positive
floating-point number and the largest positive integer, as well as access to the system
clock. The random numbers generator is included. Finally, the function `TRANSFER `permits
a certain physical area to be transmitted to another area without type conversion.

The function `SPREAD `is discussed more fully in the solution of exercise
(11.1).

All intrinsic functions and subroutines are discussed in Appendix 5.

Fortran had earlier not permitted use of any user-defined type. This has now become possible.

TYPE staff_member CHARACTER(LEN=20) :: first_name, last_name INTEGER :: identification, department END TYPE

which can be used in order to describe an individual. A combination of individuals can also be formed

TYPE(staff_member), DIMENSION(100) :: staff

Individuals can be referred to as staff(number) and a field can be referred as `staff(number)%first_name`.
You can also nest definitions

TYPE company CHARACTER(LEN=20) :: company_name TYPE(staff_member), DIMENSION(100) :: staff END TYPE : TYPE(company), DIMENSION(10) :: several_companies

A numerically more interesting example is a sparse matrix `A` with at most one
hundred non-zero elements, which can be specified with the following statement

TYPE NONZERO REAL VALUE INTEGER ROW, COLUMN END TYPE

and

TYPE (NONZERO) :: A(100)

You then get the value of `A(10) `by writing `A(10)%VALUE`. Assignment
can be done, for example with

A(15) = NONZERO(17.0,3,7)

In order to use user-defined data types in for example `COMMON`, or to make sure
that two data types which look the same are treated as identical, you can use the `SEQUENCE
`statement, in the latter case it is also required that no variable is specified `PRIVATE`.

Modules are collections of data, type definitions and procedure definitions, which give
a more secure and general replacement for the `COMMON `concept.

The data type "bit" is not included in the standard, but there are available
various bit operations of integers according to an earlier military standard MIL-STD 1753.
In addition, binary, octal and hexadecimal constants are included, as well as the
possibility to use these quantities in input/output through the three new format-letters.
In a `DATA `statement you can use an assignment to

B'01010101010101010101010101010101'

for binary,

O'01234567'

for octal, and

Z'ABCDEF'

for hexadecimal numbers.

Pointers have been included, but not in the usual way as a new data type but as an attribute to the other data types. A variable with a pointer attribute can be used as an ordinary variable and in a number of new ways. Pointers in Fortran 90 are not memory addresses as in many languages or in certain Fortran variants (dialects), but are more like extra names (aliases).

Pointers are discussed in chapter 12.

The new language contains a possibility for the user to extend it with his own concepts, for example interval arithmetics, rational arithmetics or dynamic character strings. By defining a new data type or operator, and overloading operations and procedures (so that you can also use the plus + as the symbol of addition of intervals and not only of ordinary numbers), we can create a package (a module) without using a preprocessor. We can soon expect a number of extensions for different applications in the form of modules from different manufacturers. Some are already available from NAG.

Go to Appendix 2 Go to Index Go to Appendix 4