Essential Lahey Fortran 90 Rationale
Please think about the following statement:
"There is a new programming language hiding within Fortran 90. This new language contains some of the features of FORTRAN 77 (IF THEN ELSE, input/output, GO TO, ... but not COMMON, DATA, ASSIGNED GO TO, ARITHMETIC IF, ...) plus almost all the features Fortran 90 introduced."
This new programming language is more than the best scientific programming language. This language has the potential to be the programming language of the future.
Based on this belief, Lahey Computer Systems, Inc. has created a proper subset of Fortran 90, Essential Lahey Fortran 90. This paper has three parts. 1) The requirements Essential LF90 meets. 2) An informal definition of Essential LF90. This part presents what was deleted from Fortran 90 (definition by deletion). 3) Some of the rationale for how the decisions were reached.
2.1. Essential LF90 Requirements.
Essential LF90 meets the following criteria:
1. Essential 90 programs run on any standard-conforming Fortran 90 language system. The only impediment to realizing this requirement is the set of Fortran 90 features that the standard identifies as processor-dependent. This requirement has two consequences:
There are no extensions to Essential LF90 - none!
Work toward reducing the number of processor-dependent features!
2. All the Fortran 95 standard-identified deleted and obsolescent features have been removed.
3. Alternative ways of doing the same thing have been reduced.
4. Essential LF90 requires more discipline than Fortran 95, e.g., the IMPLICIT NONE statement is required.
5. What you see is what you get, e.g., STOP and RETURN are required versus "executing" either a CONTAINS or an END statement.
6. If you know Essential LF90, you know the essential features of Fortran. It's the past you have not learned.
7. Because Essential LF90 is the Fortran community's first proper subset, Essential LF90 should error on the side of taking out too much and requiring too much.
8. Because of the above requirements, existing FORTRAN 77 usage is not a consideration.
Note: * items below have been deleted in the Fortran 95 Standard, ** items are candidates for elimination in Fortran 2000.
2.2. Deleted Statements.
Essential LF90 does not process these 24 statements:
1. The ALLOCATABLE, DIMENSION, POINTER, PARAMETER, SAVE, and TARGET attributes are declared together with type using the double colon syntax Fortran defined for the type declaration statement.
2. Deletion of the ASSIGN statement implies a *FORMAT specifier cannot be ASSIGNed to an integer variable.
3. Deletion of the BLOCK DATA, COMMON, DATA, and INCLUDE statements implies global variables must be declared and initialized in a MODULE.
4. The DATA statement is eliminated which means the BOZ constants are also, but BOZ input/output remains. Initialization and attribute declarations are done in a type statement. **Fortran 95 requires that DATA statements not appear amongst executable statements.
5. To declare double precision REAL in Essential LF90 requires KIND a la COMPLEX of non-default KIND.
6. Deletion of the DO-label statement implies the END DO must be used and that one or more DO statements cannot terminate on an executable statement. **Fortran 95 only requires the DO terminate on either a CONTINUE or END DO statement.
7. **Elimination of the statement function encourages internal procedures
2.3. Deleted Features.
The following Fortran features are not supported in Essential LF90:
2.4. Essential LF90 Requirements.
The following Essential LF90 requirements are optional in Fortran 90.
Note: Due to the one or more of the following requirements, FORTRAN 77 program units will not compile without some modifications.
Blanks for all multiple-word keywords, e.g., IN OUT, and GO TO; not INOUT or GOTO.
PROGRAM statement for the main program unit.
Explicit interface for each external procedure; most effectively accomplished by putting all externals in MODULEs and USEing the modules.
SUBROUTINE s( ) and CALL s( ), i.e., Essential LF90 requires the parens.
RESULT on the RECURSIVE FUNCTION statement.
SUBROUTINE arguments must have INTENT declared. Dummy arguments declared INTENT(IN OUT) must be set and used, otherwise the variables must be declared either INTENT(IN) or INTENT(OUT).
FUNCTION arguments must be declared INTENT(IN). INTENT(IN) dummy arguments is one of the requirements for PURE FUNCTIONs, i.e., no side effects. Fortran 95 introduced PURE FUNCTIONs.
Tip: A dummy argument that is an external SUBROUTINE has neither type nor intent; but an external FUNCTION as an argument has type; both procedures require explicit interfaces.
Dummy arrays are either explicitly declared constant dimensions or assumed-shape, dummy CHARACTER arguments are assumed-length. This eliminates adjustable dimensions, adjustable lengths, and assumed-size (last upper bound is "*"); but both automatic and allocatable arrays are available. **Fortran 95 only eliminated assumed-size arrays.
IMPLICIT NONE. Requiring this statement makes Essential LF90 a strongly-type language.
Type declarations (REAL, INTEGER, ..., TYPE) use :: syntax. A variable's attributes (INTENT, SAVE, ...) are also declared, possibly with initialization, in the type declaration statement.
CHARACTER statement. No implicit length of one, i.e., all lengths must be declared explicitly. When the length is appended to the word CHARACTER, e.g., CHARACTER(LEN=5), the length is applicable to all variables in the list with no overrides, i.e., length may not appear on variable declared to the right of the "::". If LEN is not declared on the left, then each variable must have its own length explicitly declared. **Fortran 95 makes the CHARACTER* form of the declaration obsolescent.
The DIMENSION attribute may not be overridden (similar to the Essential LF90 CHARACTER LEN attribute), i.e., if the DIMENSION attribute appears, then all variables have the same dimensionality (shape for nonallocatable arrays, but only rank for allocatable); if the DIMENSION attribute does not appear on the left, then dimensions can be declared to the right of the ::.
Note: Declaring dimensions to the right of the double colon means that scalars and arrays can be declared in the same type statement.
Statement labels must be referenced; i.e., no clutter. This implies that first and specification statements may not have labels. Essential LF90 extends this to END IF, END DO, CONTAINS, and END.
Note: *Branching to an END IF statement from outside its IF BLOCK is eliminated.
CASE statement: DEFAULT, if it appears, must be last.
Execute a RETURN or STOP, i.e., can't execute either an END or a CONTAINS statement.
END PROGRAM name, END SUBROUTINE name, and END FUNCTION name are required.
2.5. Some Rationale.
In addition to the Essential LF90 requirements, the rationale below contributed to the decisions that were reached; not all decisions were unanimous.
Specification statements: Reviewed for those attributes (ALLOCATABLE, DIMENSION, INTENT, PARAMETER, POINTER, SAVE, TARGET) that could (and should) be declared in a type declaration statement. The corresponding statement for each of these attributes was eliminated. For various reasons, Essential LF90 has kept the INTRINSIC, OPTIONAL, PRIVATE, PUBLIC, and SEQUENCE statements.
FORMAT: Many-line FORMAT statements are common. If Essential LF90 didn't have the FORMAT statement, that would lead to many-line I/O statements. A CHARACTER PARAMETER could be used but this leads to difficulty with apostrophes and quotes when entering the text. Kept FORMAT.
INCLUDE and DO WHILE were discussed and it was decided to keep them; later we decided to eliminate them based on 1) They are frowned on. 2) There are alternative ways. 3) We can add easier than we can delete. Still later, we decided to keep DO WHILE based on a John Reid article and what we felt was "ugly code."
LOGICAL IF versus IF/THEN/ELSE. The requirement to minimize alternative ways of doing the same thing lead to considering eliminating the LOGICAL IF statement. Kept it because we didn't think it elegant to have to write:
IF ( logical_expression ) THEN GO TO label or CYCLE or EXIT END IF
This matter was reviewed again in March 1996 and again the decision was to keep LOGICAL IF.
SEQUENCE. Kept since, in the general case, it is required for argument passing to other languages.
Get rid of all but G? No, since additional control is given to the individual specifiers, e.g., G chooses between E and F based on the magnitude of the datum. A user might want to align a table of numbers. All but D and H were kept.
Eliminate D. At the bottom of page 165 of the Fortran 95 Standard, a table entry instructs to output D, E, or 0 if the exponent has magnitude less than 99; if there is a three digit exponent, there is no D or E. Since the D specifier does not force D output, the D specifier was eliminated. Kept the D exponent on numeric input.
END=, ERR=, and EOF= require labels and, in general, labels are ugly. However, if these specifiers were eliminated, it is not believed the resulting code that would process the IOSTAT value would be that pretty. These I/O specifiers and the required labels were kept.
Eliminate BLANK= specifier in OPEN. In Fortran 90, BN and BZ do it and are the only way to do it for internal files, i.e., the language is not orthogonal. Further, this is a punched-card oriented feature and the cards are no longer with us.
Mixed mode arithmetic. Kept, it's functional and Fortran is functional.
Eliminating precedence was considered; kept.
Relational operators delimited by periods. It was recognized that this feature should be eliminated. However, due to preserving precedence for when a dot-relational operator is overloaded, user-defined dot-operators would not port to other processors; kept.
Dummy arrays are assumed-shape, dummy CHARACTER arguments are assumed-length. It was noted that when the actual argument is an array section, this avoids copy-in/copy-out which one user reported slowed his program.
We didn't change passing an actual argument more than once in an invocation even when its INTENT is OUT or IN OUT.
Note: If the language did restrict this at compile time, it could be circumvented by using pointers. The language system could have a runtime check.
OPEN statement must have the POSITION= specifier for sequential files to guarantee portability since the standard does not specify where the file is positioned after an OPEN statement is executed. Remember: You can redefine a file's attributes by OPENing an OPENed file.
Make keywords reserved words. Decided that Fortran was Fortran and as the language evolves, variable names could become keywords. Didn't do it.
We considered requiring the ELSE in IF and DEFAULT in CASE constructs. Didn't want to force things that might end up bogus, i.e., empty blocks. To improve readability, we decided to require the DEFAULT case to appear last when present.
Have the compiler warn if DEFAULT does not appear and at execution time, if a DEFAULT should have been executed, have an ABORT occur; a la Pascal. Neither of these were done.
KIND on all REAL statements. Rationale:
Didn't do it: Too much typing.
SELECT_REAL_KIND, not KIND, on REALs and COMPLEXes. Rationale: Requires some awareness of the numerical aspects of the problem being solved. Didn't do it: too much typing.
Version 2.00, 1996.
Essential LF90 was reviewed as a part of preparing Version 2.00 for September 1996. The following additional changes have been made:
Removed FORMAT( ), i.e., a FORMAT statement without any specifiers is a synonym for list-directed I/O.
Require the type name on an END TYPE statement.
Removed the ENDFILE, REWIND, and BACKSPACE syntax that does not require parenthesis.
Removed the WHERE statement (not the construct).
Removed the PRINT and READ * statements, because they duplicate READ (*, *) and WRITE (*,*).
Version 4.00, 1998.
Essential LF90 was reviewed as a part of preparing Version 4.00 for September 1998. The following additional changes have been made:
Restored, the INTRINSIC statement to allow users to enhance generic intrinic procedures.
Plan to eliminate CHAR and ACHAR.