The F language with array syntax is thus a streamlined Fortran, where the features described are the most useful in today's Fortran environment. It is recommended for beginning students of computer languages and for researchers designing new projects. There are no alternative ways for expressing any feature. There are no duplications in the language as is true in Fortran 90/95, where new and better features often substitute for some of the old time-worn facilities that remain in the language. The selection of features was based on simplifying Fortran so that a new language results where all the features in the F language are also in standard Fortran.
Many old features that are not contained in F are those that have been deleted from earlier Fortrans or are declared to be obsolete in the current standard but are not yet deleted, or ones that have been replaced by more modern and efficient features.
However, it is not the architecture (Fortran deleted and obsolete features) that has motivated the selection of items recommended, but the wish to have a modest-sized language that will serve:
An initial assumption is that most shops will already have a Fortran 90 or 95 compiler in house. This compiler will compile all the features described in F. If this is the case, there are two or three compiler options that can be used for F. The first one is to use a current Fortran 90 or Fortran 95 compiler, selecting facilities that are described in this text. Other options would be to find a Fortran 90/95 compiler that has a compiler option that flags all non-F features, or write your own precompiler that marks these features. This, in effect, is what the F compiler does. A final option currently available is an F compiler that is smaller and more efficient, for use with new research projects. These compilers are available from Imagine1 for Windows 95, Linux, and Unix systems with Windows NT, Macintosh and Salford will be available soon. The compilers are based on technology from Absoft, Fujitsu, and NAG.
It is probably best to have both an F compiler and a Fortran 90/95 compiler where F programs will run on either one. This will serve as an excellent check on F statements that are intended to be standard-conforming. A draft BNF is available with many details of the F language on the internet at:
The email address is email@example.com
However, there is less to learn in F than in Fortran or C++. And once the syntax is mastered, the programming code results should be more portable. It is a great teaching tool, and comes without all the old baggage of Fortran 66, Fortran 77, and Fortran 90/95.
The features have been gathered arbitrarily into the following categories:
Each section contains some examples to give a flavor of the contents. Further information about F is provided in the references and the bnf on the internet. These notes give some overview and conclude with a list of some of the features in F, and some of the features not in F.
The equals sign " = " is the assignment symbol. The special symbol for pointer assignment is " => ". These assignment symbols are used in:
variable = expression ! arithmetic, relational, or logical assignment or pointer => xxtarget ! pointer assignment
Examples of operators and assignment:
y + z * (q**r) (b * z) <= r nd .and. n2 d1 // c5 card .least. Safe x = sin (y) i = 20 * Animals k = (/1,2,7/) point => xxtarget r = rational (1,2)
Names of variables may be in mixed case (upper and lower), but must appear in the same way in each appearance. Undefined variables are flagged by the compiler. Implicit none is a legal statement in F, however, all variables must be declared in F, even if the statement is not there. It is as if the implicit none statement were to appear in every program unit. There is no double-precision type, which is redundant with the kind feature of Fortran 90/95.
The attributes allowed are parameter, public, private, allocatable, dimension (array specification), intent (intent spec), optional, pointer, save, and target. A list item may be a variable name or an initialization expression. Character data type has a length selector in the type declaration, and substrings may be used in the F language. Dimension and character length information may appear only on the left side of the double colon.
The informal syntax for type declarations is:
type [,attribute list] :: entity declaration listOptional initialization of a variable is allowed in the list of objects. Notice that in the syntax for declaring type, the double colons "::" are required. They are optional in Fortran 90/95 to maintain compatibility with previous Fortrans, but there is no need to omit them for new projects.
A user-defined type may be defined and subsequently used in a type statement. The type definition may declare a number of components in the declaration part, and may be used to place a number of variables in a structure.
To define a type called type_name:
type , access specification :: type_name [private] component declarations . . . end type [ type_name ]
To declare a list of variables to be of that type:
type ( type_name ) :: variable list
A component of a structure (that is, a user defined type) is identified with a % as in:
defined type name % component name
A structure constructor defines values for components as in:
type name (constructor expression list)
All the declaration statements are "attribute oriented," and not entity oriented. That is, all items in the list will have the same attributes in a given type declaration statement. Old Fortran allows both. The data statement and the block data subprogram for initializing common is not supported by the F language, nor is common or equivalence, long in favor because they were necessary in old codes.
Syntax examples of data type statements:
real :: x,y real (kind = high), dimension (10,10) :: R integer (kind = long), dimension (100) :: mappings logical :: gamma logical (kind = packed) :: sho complex :: ccm real, public :: under_palatial integer, dimension (:, :), allocatable :: x, y real, intent (out) :: gone logical :: smooth real, pointer, dimension (:,:,:) :: weight, height integer, save :: lion_hearted real, dimension (3,3,3), target :: justice, arms, law integer, parameter :: j = 1 type, public :: class integer :: year, quarter character (len = 30) :: instructor end type class type (class) :: english, geometry english % instructor = "Simms" test = class (1996,third,"Jones") geometry % instructor = "Smith"
The do construct and the exit and cycle statements have an optional construct name. Loops in the F language may have no loop control, or loop on an index variable. The form of a DO with a labeled terminal statement is not a feature. In addition, there is no optional comma after do and before an index variable. All loops are terminated with the end do statement which is not labeled, but the end do may have a construct name. The do while form of loop control is not needed and therefore not supported.
The return and the stop statements also alter the order of execution of F statements. These statements are sometimes needed for debugging when a program or procedure must terminate execution at some point.
Syntax examples of control constructs:
if (number > maximum) then number = maximum else if (number < minimum) then number = minimum end if select case (n+no) case (3) x = 34.3 case default x = 1.0 / x end select do j = 1,100 if ( j <= 50) then k = j - 4 print *, k cycle end if print *, j end do doname: do if ( value > climate_index) then exit doname end if value = new_value end do doname stop
program main . . . end program main
The F language does not accept procedures that are not in a module. Most features of Fortran 90/95 that are related to modules and module procedures are included. Statement functions are not in F. Functions and subroutines are intended to be included as module procedures. A procedure dummy argument must be described with an interface block. An interface block is also used to describe external procedures in other languages like C (or even Fortran). There are no internal procedures in F. All procedures are module procedures and follow a contains statement in a module. A result clause that returns the value of a function is required for all functions. Functions must not change the value of dummy arguments. Recursion is a feature, and the interface concept to define operators and assignment are as in Fortran 90/95.
The following statements contain a number of possibilities for the contents of a module:
module module name use statements access statements type definitions type declarations contains subroutines and functions end module module name use module name[s] [,rename list] use module name, only : [ only list]
A call statement may be used to reference a module procedure, if the module name appears in a use statement in that program unit or the calling program is in the module.
If an intrinsic procedure is used as an argument or extended with a module procedure, the name must be declared in an intrinsic statement. Most of the Fortran 90/95 intrinsic procedures are in F, and these names are reserved words along with all the other keywords in F. The following redundant intrinsic procedures are omitted from F: achar, iachar, lge, lgt, lge, llt, transfer, dble, dim, dprod, and mod. The transfer function is not really redundant, but it is not portable.
An interface block makes a non-F procedure declaration explicit. Both user-defined operators and user-defined assignment must appear in an interface block:
interface operator ( defined operator ) . . . module procedure name . . . end interface [ operator ( defined operator) ] interface assignment (=) . . . module procedure name . . . end interface [ assignment (=)]
The entry statement and alternate return are not supported. There are better ways to do these tasks in F.
Examples of syntax for modules, procedures, and units:
module shared public :: set private :: altitude complex, public :: gtx real, allocatable, public, dimension (:,:) :: x type, private :: peak real :: x, y end type peak contains subroutine set (temperature) real, intent(in):: temperature temp1 = temperature . . . end subroutine set function altitude (degrees) result (rd) . . . end function altitude end module shared __________________________________ use math, only : x call set (temp_high) _____________________________________ recursive function gift (ist) result (recursive_x) end recursive function gift intrinsic :: sin ______________________ interface operator (+) end interface operator (+) interface assignment (=) end interface assignment (=)
type, dimension (array specification) [ ,attributes ]:: array name list
All array bounds and specifications for arrays must appear before the double colons in a type declaration. Parts of an array may be accessed using the following forms:
subscript expression subscript triplet [expression] : [expression] : [stride] vector subscript integer array expression
The where construct is used to test a logical array expression for selecting elements of an array to be assigned a value. The optional elsewhere permits assignment of a value to other elements of the array not yet assigned. There is no construct name on the where construct. Dynamic storage association is managed using the allocate and deallocate feature. Pointers also permit dynamic storage using pointer assignment of a target when space may be required in a program. The nullify statement permits variables or structure components to be disassociated from any target.
An array constructor has the following form:
(/ array constructor value list /)
Examples of array syntax:
real, dimension (3,15) :: controls real, allocatable (:,:) :: a, x, y integer, dimension (1:100) :: k real, dimension (3), parameter :: y = (/4, 6, 87/) real, dimension (2) :: g g = (/14.5, 32.777/) real, dimension (100) :: a, b a = b allocate (x(9,9)) x(3,2:6:2) = 0.0 where ( b >= 0.0) sqrt_b = sqrt(b) elsewhere sqrt_b = 0.0 end where deallocate ( x )
read ( i/o control list ) [ input list ] read format [ , variable list ]
The output statements are:
write ( i/o control list ) [ output list ] print format [ , output list ]
The i/o control list must contain a unit number, and may also contain fmt, advance, iostat, rec, and size. If the unit number is a character variable, the i/o is for an internal file. The keywords for unit and format are not optional, but must appear. The end=, err=, or eor= must not appear in the control list. The read and print statements may contain an * for list-directed formatting or default formatting, or it may be explicit formatting using descriptors. Traditional unformatted input/output is also a feature of F; namelist is not.
Examples of the syntax of read and write statements:
read ( fmt = "(a)", rec = 15, unit = 9, iostat = i) past_tense write (unit = iun, rec = 24) Aa, bBet read (unit =char_nam, fmt = "(i)") size_of_file read (unit = 5, fmt = *) a write (fmt = "(a)", advance = "no", unit = ion) Bchars read (unit = iu, iostat = ii) x, u print *, x, y, z print "(a, 15f6.2)", XLIST(:) print "(I7)", k
The form of the open statement is:
open ( connection specifiers)
The connection specifiers are:
unit = external file unit file = file name expression access = scalar character expression action = scalar character expression form = scalar character expression iostat = scalar default integer variable position = scalar character expression recl = scalar integer expression status = scalar character expression
A restriction in F is that the status specifier is required and the form must not be "unknown" in an open statement. The action specifier is required in the open statement . The PAD=, DELIM=, and BLANK= are not supported in the open or the inquire statements. If the status is old, the position specifier must be present and must be rewind or append. A file must be closed in order to open it. There is no reopen for a connected file.
The form of the close statement is:
close ( close specifiers )
The close specifiers are:
unit = external file unit iostat = scalar default integer variable status = scalar character expression
The form of the inquire statement is:
inquire ( unit = external file unit, inquiry specifiers) or inquire ( iolength = scalar default integer variable) output list
The inquiry specifiers are:
unit = external file unit file = file name expression access = character action = character direct = character exist = logical form = character formatted = character iostat = integer name = character named = logical nextrec = integer number = integer opened = logical position = character read = character readwrite = character recl = integer sequential = character unformatted = character write = character
The file positioning statements are
backspace, rewind, and
endfile. These statements cannot be used on internal files.
Examples of open, close and inquire:
open (unit =11, status = "scratch", iostat = ierr, action = "readwrite") open (unit = 7, status = "new", file = "disk99",action = "write") close ( unit = 1) close (status = "delete", unit = 23, iostat = ierr) inquire ( form = ch35, unit = 7) inquire (file = "disk88", opened = op, action = ch3) inquire (iolength = count) x, y, z rewind (unit = 7)
The control edit descriptors are
tn, tln, trn, [r]/, :, s, sp, ss.
The data edit descriptors are
i, f, es, l, a.
Carriage control is not supported by F, it is file and operating system
Examples of formatting:
character (len = 11) :: fmmt fmmt = "(a, 10f8.2)" write (unit = 6, fmt = fmmt) "pressure", numbers (1:10) read (unit = 5, fmt = "(10f8.2)" ) x(1:5), y(0:4) print "(a14)" , "The F language"
allocate/deallocate assignment variable = expression pointer => target attributes access (public, private) allocatable dimension (array bounds) intent (in, out, inout) optional parameter pointer save target call control constructs if do case end (always modified by program etc.) control edit descriptors are tn, tln, trn, [r]/, :, s, sp, ss. data edit descriptors are i, f, es, l, a. execution control cycle exit return stop function ( result clause required ) input, output, file positioning read write print open close inquire backspace endfile rewind implicit none intrinsic module nullify program subroutine type declaration type definition (user defined) types integer real complex logical character user-defined type recursion use where construct
However, most of the readers do have familiarity with Fortran and other languages like C. And it is interesting to note some of those features which will not be acceptable in F. This is not a complete list.
Some of the features not in F, but in standard Fortran 90/95 are:
";" separator for multiple statements on a line "'" apostrophe as a delimiter "&" for continuation of a continued line alternate return attribute statements allocatable dimension intent optional parameter pointer save target binary, octal, hexadecimal constants in data statements block data carriage control is processor dependent common continue control statements (not constructs) data edit descriptors--b, o, z, d, e, en, g, p, x, bn, bz data statement do while do (labelled) double precision type entry end (without a modifier) equivalence err =, end =, eor = specifier in i/o control lists fixed source form format statement include internal procedures labels go to namelist i/o optional keyword syntax for unit and format in I/O PAD=, DELIM=, or BLANK= in open and inquire sequence statement functions upper case reserved words
The F Programming Language, by Michael Metcalf and John Reid, Oxford University Press, Oxford and New York, 1996.