Search

A Look at Fortran 90

This 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.

Overview

Fortran 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?

  1. Fortran is still the number one language for computationally intensive applications. This is probably why you selected Fortran in the first place. The new standard upholds this tradition of being the language of choice for scientific and engineering applications.
  2. Modern language features found in Fortran 90 help you write tighter and faster code while you avoid the costs of learning and rewriting your working programs in another language.
  3. The portability of Fortran code enables you to move your applications to a variety of platforms.
  4. You can learn Fortran 90 at your own pace. The ability to run your Fortran 77 programs using a 90 language system gives you the option of simply running your 77 code, re-coding certain portions of your program in 90, or rewriting the entire program.
Let's take a look at the most important features of Fortran 90.

Data

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

Pointers

Pointers 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.

Kind

The 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

Declarations

Data 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.

Constructors

Array 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 Control

FORTRAN 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.

Arrays

Array Expressions

Complicated 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 Sections

Enable users to gain greater control of arrays by using subscript triplets and vector subscripts.

WHERE Construct

Masked 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 Arrays

Dummy arrays can take their shape from the corresponding actual arguments.

Automatic Arrays

Arrays 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

Intrinsics

There are 75 new intrinsic functions in Fortran 90 including the following:

Inquiry Functions

Find 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 Function

Treat one data entity as if it were of the type of another data entity.

Array Intrinsics

Various 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

Modules

Modules 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.

Interfaces

The 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 Procedures

Internal 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 Arguments

Optional 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.

Other Features

Standard Source Form

Comments are introduced by an exclamation point. Multiple statements per line are allowed with the ; delimiter.

Free Source Form

No 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 90

This 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 Information

If 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.