A Look at Fortran 90This page introduces you to the "new" language of choice for scientific and engineering applications--Fortran 90. By highlighting the 90 features that will immediately impact your Fortran programming, we hope to take some of the mystery out of Fortran 90 and encourage you to adopt this new standard for all of your programming.
OverviewFortran 90 was developed jointly by the X3 technical subcommittee, X3J3, and the International Fortran Standard organization, WG5. Thomas M. Lahey, CEO of Lahey Computer Systems and a developer of Fortran compilers for over twenty-five years, is a participating member of both of these groups. Being a member of these organizations gave our company the opportunity to influence the decisions about which features to incorporate into the new standard and allowed us to begin early design of our own Fortran 90 language system.
As jointly stated by these organizations in the Fortran 90 Standard guide, "The purpose of this International Standard is to promote portability, reliability, maintainability, and efficient execution of Fortran programs for use on a variety of computing systems." The result is the Fortran 90 Standard. It is a combination of the entire Fortran 77 Standard (with four minor exceptions), popular Fortran 77 extensions, and an extensive collection of new features. By creating a new standard, portability of programs has increased, new programming techniques and practices have been introduced, and users can take better advantage of advances in both hardware and language design. The Fortran programmer has gained new freedom and flexibility in their coding without losing one of the key elements of Fortran: portability.
For companies and users who have invested in Fortran, what are the benefits of continuing to use this language?
Structures (Derived Types)You can group your data using derived types. This enables users to combine intrinsic types (including arrays and pointers) into new types whose individual components can be accessed using the percent sign as a delimiter. (Derived types are known as records in VAX Fortran.)
! Example using derived types and modules. module pipedef type pipe ! Define new type 'pipe', which real diameter ! is made up of two reals, an real flowrate ! integer, and a character. integer length character(len=10) :: flowtype end type pipe end module pipedef program main use pipedef ! Associate module pipedef with main. type(pipe) water1, gas1 ! Declare two variables of type 'pipe'. water1 = pipe(4.5,44.8,1200,"turbulent") ! Assign value to water1. gas1%diameter = 14.9 ! Assign value to parts gas1%flowrate = 91.284 ! of gas1. gas1%length = 2550 gas1%flowtype = 'laminar' . . . end program
PointersPointers allow a program to refer to more than one data area with one name. For anyone familiar with C pointers, Fortran 90 pointers are much more restrictive, and therefore less likely to be buggy and easier for a compiler to optimize. Data objects with the pointer attribute can have their associated storage allocated and deallocated, facilitating dynamic memory use. Pointers can be associated with other pointers and with other objects, facilitating modern data structures such as lists and trees.
KindThe kind type enables the user to request which intrinsic type is used based on precision and/or range. This facilitates an improved numerical environment. Programmers porting their programs to different machines must deal with differing digits of precision. Using kind, the programmer can specify the numeric precision required.
! Example using the KIND attribute and KIND function. ! This example would require a compiler that had implemented the character, ! kind(2), data type. This is allowed in F90, but not required. program main integer, parameter :: kanji_char_kind = 2 ! Use of the kind attribute to define a known kind. character(kind = kanji_char_kind, len=20), dimension(20) :: name ! Use of the kind function to define the kind from an entity of known kind. real(kind = kind(0.0d0)) :: pi=3.14159265359d0 open(unit=1, file='names', form='formatted', access='sequential') read(1,10) (name(i), i=1,20) write(*,20) name write(*,30) pi close(unit=1) 10 format(a20) 20 format(1x,t7,a20,t30,a20,t55,a20) 30 format(1x,1p,d18.11) end program
DeclarationsData objects may have combinations of 12 different attributes, such as POINTER, SAVE, etc. Fortran 90 introduces an "entity-oriented" declaration, in which objects with the same attribute combinations can be declared with all their attributes in one statement.
ConstructorsArray and derived type data objects can both be initialized in the declaration statement. A constructor can also be used as a constant where an array or derived type is expected.
IMPLICIT NONE*This standardization of a popular F77 extension makes it mandatory for all data objects to be explicitly declared.
Program ControlFORTRAN 77 programs were often designed with a flow chart mentality. This kind of design lead naturally into code composed of a lot of testing and branching_programs were hard to enhance, had a lot of bugs, and had very little reusability. Modern program design methods involve decomposing a larger problem into smaller problems until the solutions are trivial. The new Fortran 90 Standard control constructs make it easier to implement modern software designs.
DO / END DO*END DO replaces the traditional labeled CONTINUE statement for DO loop termination. This makes the DO label optional.
DO WHILE*Repeat a block as long as a condition holds true.
CASE Constructs*Replaces complicated IF/ELSE IF constructs or computed GO TO's. Makes code easier to read and write.
! Example using CASE Constructs. ! (c)Copyright 1993, Lahey Computer Systems, Inc. All RIGHTS RESERVED ! Test: case1 ! ! Legal - all possible case-value-range types for integer*4 ! integer*4 i integer n /9/, a (9) /1,-11,81,31,41,51,61,71,25/ do 50 j = 1, n i = a (j) select case ( i ) case (1) print*,"should be 1, is ",i case ( : -11 ) print*,"should be 11 or less, is ",i case ( 81 : ) print*,"should be 81 or greater, is ",i case ( 31 : 32 ) print*,"should be 31 or 32, is ",i case ( 41, 50:51, 61 :61, 71:72 ) print*,"should be 41, 50, 51, 61, 71, or 72, is ",i case default print,"should be any other number, is ",i end select 50 continue end
CYCLE, EXIT*Leave a particular iteration of a DO loop or an entire loop before completing the repeated block. This reduces the need for GO TO's.
Construct Names*You can label IF, DO, and CASE constructs to make code more readable and enable CYCLE or EXIT to outer levels of nested loops.
Array ExpressionsComplicated DO loops can now be reduced to a single statement. Use entire arrays in expressions or as arguments to intrinsic functions.
! Example program using attributes within a type stmt, and array expressions. program main ! Declare dim1 as a parameter, with value 5. integer, parameter :: dim1=5 ! Declare res, x, & y as 5 element arrays, and initialize x & y. real, dimension(dim1) :: res, x=(/1.,2.,3.,4.,5./),y=(/5.,4.,3.,2.,1./) ! Add corresponding elements of x & y, and assign to res. res = x + y ! All elements of res should equal 6. write(*,10) res 10 format(1x,5(f3.0,4x)) end program
Allocatable Arrays*Allocate memory for arrays at runtime.
Array SectionsEnable users to gain greater control of arrays by using subscript triplets and vector subscripts.
WHERE ConstructMasked array assignment enables a user to make array assignments based on a mask over an entire array.
! Example using allocatable arrays and the where construct. program main integer number_of_students, number_of_tests ! Declare arrays 'scores' and 'letter_grade' as allocatable and 2 dimensional. integer, allocatable, dimension(:,:) :: scores character(len=1), allocatable, dimension(:,:) :: letter_grade open(unit=1,file='grades',form='formatted',access='sequential') read(1,10) number_of_students, number_of_tests ! Allocate memory for arrays. allocate (scores(number_of_students,number_of_tests)) allocate (letter_grade(number_of_students,number_of_tests)) read(1,10) ((scores(i,j),i=1,number_of_students), j=1,number_of_tests) close(1) ! Use the where construct to assign value to array 'letter_grade' based on ! values in array 'scores'. where(scores >= 90) letter_grade = 'A' where(scores >= 80 .and. scores < 90) letter_grade = 'B' where(scores >= 70 .and. scores < 80) letter_grade = 'C' where(scores >= 60 .and. scores < 70) letter_grade = 'D' where(scores < 60) letter_grade = 'F' write(*,*) letter_grade deallocate(scores,letter_grade) ! Free memory used by arrays. 10 format(i3,t5,i3) end program
Assumed Shape ArraysDummy arrays can take their shape from the corresponding actual arguments.
Automatic ArraysArrays in a procedure have dimensions that are based on the values of variables.
! Example using automatic and assumed shape arrays. program main integer :: dim=8 real :: a(4)=(/44.3,77.5,88.21,14.35/) call sub1(a,dim) end program subroutine sub1(x,dim1) integer dim1 real x(:), b(dim1) ! Declare 'x' with the same shape as actual argument'a' . . ! Declare 'b' with 'dim1' elements. . end subroutine sub1
IntrinsicsThere are 75 new intrinsic functions in Fortran 90 including the following:
Inquiry FunctionsFind out from the program at runtime the characteristics of an array or the status of a pointer. Find out from the compiler the characteristics of a data type.
Transfer FunctionTreat one data entity as if it were of the type of another data entity.
Array IntrinsicsVarious new array reduction functions, vector and matrix multiplication, array construction, reshaping, shifting, transposition, and location of minimum and maximum values.
Bit Manipulation*Set, clear, test, and shift bits in integer data. Perform logical AND, OR, exclusive OR and complement.
Modules & Procedures
ModulesModules are essentially places to put things for shared use. This new variety of program unit can contain data, procedures, derived type definitions, and interface blocks (and even common blocks), all of which are brought into a scoping unit by a USE statement. A module can even be used to hide procedure code from customers. The same module can be used in numerous programs.
InterfacesThe compiler can be used to check results if the characteristics of the procedure are available in an explicit interface. A user-provided interface body looks very much like the function definition statement and associated declarations. The compiler knows the interface to every procedure defined within a program unit. With an interface the compiler will check the characteristics of a function result against what is expected in the caller and check the characteristics of each argument against what is expected in the procedure. Generic Procedures Programmers can use generic procedures (procedures with the same name) by using an interface block to provide the information for determining which procedure to invoke. The specific procedure to be invoked is determined using the kind, type, and rank of the arguments.
! Example using generic procedures. module procedure_def ! Define generic interface 'force' to specific functions ! 'real_force' and 'double_force'. interface force ! Declare function and dummy argument types. function real_force(mass, accel) result(force) real force, mass, accel end function real_force function double_force(mass, accel) result(force) double precision force, mass, accel end function double_force end interface end module program main use procedure_def ! Associate procedure_def with main. real rmass, raccel, rforce double precision dmass, daccel, dforce data rmass/2401.0/, raccel/9.81245/ data dmass/2401.0d0/, daccel/9.81245d0/ ! Reference function 'force'. The compiler resolves the first ! reference to 'real_force', and the second to 'double_force'. rforce = force(rmass, raccel) dforce = force(dmass, daccel) write(*,'(1x,1p,e16.9,t25,d16.9)') rforce, dforce end program ! Actual functions executed when a reference to 'force' is made. function real_force(mass, accel) result(force) real force, mass, accel force = mass*accel end function real_force function double_force(mass, accel) result(force) double precision force, mass, accel force = mass*accel end function double_force
Internal ProceduresInternal procedures make it easier to organize code that is only used in one place and reduce the number of external routines that need to be known by the programmer. Program units and module procedures can contain their own internal subroutines and functions. The interfaces of these internal procedures are known throughout the containing program unit.
Recursion*Recursion is standardized in 90. If a procedure is to be called recursively, even indirectly, it must be declared using the RECURSIVE keyword.
Optional & Keyword ArgumentsOptional keyword arguments add flexibility in the invocation of subroutines and functions. In FORTRAN 77, you were forced to specify every argument. In Fortran 90, arguments can be optional and their order arbitrary. The names of dummy arguments (keyword arguments) are then used in the procedure invocation to resolve the correspondence between actual and dummy arguments. A new intrinsic function allows the procedure to determine which arguments are present in the actual argument list.
Standard Source FormComments are introduced by an exclamation point. Multiple statements per line are allowed with the ; delimiter.
Free Source FormNo column has any particular significance, blanks are significant, continuation uses a special character at the end of a line, and comments are introduced on any line by an exclamation point. Multiple statements per line are allowed with the ; delimiter. Lines may be up to 132 characters therefore allowing longer names and more indenting for added freedom and readability.
Long Names*The maximum length is 31 characters in both forms. Underscores are permitted.
Include Files*The INCLUDE line has been standardized.
Relational Operators*Operators like .LT. and .GT. can be replaced by their mathematical symbols < and >.
Lahey's Fortran 90This professional language system combines Lahey's award-winning Fortran compiler design with Intel's highly optimized code generation technology. It is optimized for 386, 486, and Pentium PCs and is a full implementation of the Fortran 90 Standard. Contact us for product literature.
More InformationIf you are interested in a more comprehensive and detailed understanding of Fortran 90, we recommend Migrating to Fortran 90 by James Kerrigan. You can purchase this book directly from us for $27.95 plus $3.00 shipping and handling. REFERENCES Adams, Jeanne C., Walter S. Brainerd, Jeanne T. Martin, Brian T. Smith, and Jerrold L. Wagener. Fortran 90 Handbook. New York: McGraw-Hill, 1992. Baker, Steven. "Modernizing Fortran." Software Development November 1993, International Standards Organization, ISO/IEC 1539: 1991 (E). The International Fortran Standard. Kerrigan, James F. Migrating to Fortran 90. Sebastopol: O'Reilly & Associates, 1993. Metcalf, Michael and John Reid. Fortran 90 Explained. New York: Oxford University Press, 1990. *These features are already contained in Lahey's FORTRAN 77 language sytems, F77L and F77L-EM/32.