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 info@imagine1.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.
| Arithmetic operators | **, +, -, /, * |
| Relational operators | <, <=, ==, /=, >, >= |
| Logical operators | .not., .and., .or., .eqv., .neqv. |
| Character concatenation | // |
| Defined operator | .letters. |
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
dependent.
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.