Fortran (originally FORTRAN, an acronym for Formula Translation) is a general-purpose, compiled imperative programming language that is especially suited to numeric computation and scientific computing. Originally developed by IBM in the 1950s for scientific and engineering applications, Fortran became the first widely adopted high-level programming language. Its design emphasized efficiency of execution, particularly for mathematical operations on arrays and matrices, and it has evolved through several major standards (FORTRAN 66, FORTRAN 77, Fortran 90, 95, 2003, 2008, 2018). Despite the rise of newer languages, Fortran remains in active use in high-performance computing (HPC), weather forecasting, computational physics, and other domains where numerical performance is critical. Modern Fortran provides features such as array operations, object-oriented programming, and parallel computing support (Coarray Fortran, OpenMP, MPI).
1 History and development
1.1 Early origins (1950s)
Fortran was conceived by John Backus and his team at IBM in the early 1950s to alleviate the difficulty of programming the IBM 704 mainframe in assembly language. The first compiler, released in 1957, translated high-level algebraic expressions into efficient machine code. This marked a turning point in computing, making programming accessible to scientists and engineers.
1.2 FORTRAN I, II, and IV
FORTRAN I (1957) included basic arithmetic, control flow with IF and GOTO, and the DO loop. FORTRAN II (1958) added subprograms (FUNCTION and SUBROUTINE) and improved debugging. FORTRAN IV (1962) introduced logical data types, the COMMON block, and more consistent language rules. These early versions were largely machine dependent but established the core of the language.
1.3 FORTRAN 66 (ANSI standard)
In 1966, the American National Standards Institute (ANSI) standardized FORTRAN as FORTRAN 66 (ANSI X3.9-1966). This was the first official standard, providing portability across platforms. It defined basic language elements still present today, including the DO loop, formatted I/O, and fixed-format source form (columns 1–72).
1.4 FORTRAN 77
FORTRAN 77 (ANSI X3.9-1978) introduced block IF, ELSE IF, and END IF statements, replacing the archaic arithmetic IF. It also added the CHARACTER data type, IMPLICIT NONE, and improved I/O with direct access files. The language became more structured, though still largely procedural.
1.5 Fortran 90 and 95 (major redesign)
Fortran 90 (ISO/IEC 1539:1991) brought a major overhaul: free-form source code, modules, derived types, array operations (whole-array arithmetic and intrinsic functions), dynamic memory allocation (ALLOCATABLE/DEALLOCATE), and a revised control structure (SELECT CASE, EXIT, CYCLE). Fortran 95 (ISO/IEC 1539-1:1997) added FORALL and PURE/ELEMENTAL procedures, further enhancing array‑parallelism support.
1.6 Fortran 2003 and 2008 (object-oriented and parallel features)
Fortran 2003 (ISO/IEC 1539-1:2004) introduced full object‑oriented programming: inheritance, polymorphism, type‑bound procedures, and abstract types. It also added interoperability with C (ISO_C_BINDING), improved I/O (stream access), and the PROCEDURE pointer. Fortran 2008 (ISO/IEC 1539-1:2010) added Coarray Fortran for parallel computing (partitioned global address space), the DO CONCURRENT construct, and the BLOCK construct for local scoping.
1.7 Fortran 2018 (latest standard)
Fortran 2018 (ISO/IEC 1539-1:2018) is an incremental revision that incorporates further parallel features, such as teams of images for coarrays, impure ELEMENTAL procedures, and atomic operations. It also introduced the STOP and ERROR STOP enhancements and clarified many language rules. Work on Fortran 2023 is underway.
2 Language features
2.1 Basic syntax and data types
2.1.1 Variables, constants, and implicit typing
Fortran uses static typing. Variables are declared with a type and may be initialized. By default, names beginning with letters I–N are implicitly integer; others are real. This behavior is suppressed with IMPLICIT NONE. Named constants are declared with the PARAMETER attribute.
2.1.2 Integer, real, complex, and logical types
The language provides INTEGER, REAL (single/double precision via KIND), COMPLEX, LOGICAL, and CHARACTER. Kind parameters specify precision, e.g., INTEGER(KIND=8). Double precision can also be declared as DOUBLE PRECISION.
2.2 Arrays and array operations
2.2.1 Array declarations and intrinsic functions
Arrays can be static or allocatable. Declarations specify rank and extent, e.g., REAL, DIMENSION(10,10) :: A. Intrinsic functions include MAXVAL, SUM, MATMUL, TRANSPOSE, and RESHAPE. The SHAPE function returns an array’s shape.
2.2.2 Array slicing and whole-array operations
Fortran supports array slicing with triplets (e.g., A(1:5:2, :)) and whole-array arithmetic: C = A + B performs element‑wise addition. Array sections and expressions are evaluated efficiently, enabling concise code for linear algebra.
2.3 Control structures
2.3.1 DO loops (block, while, and implied DO)
The DO loop can be used with an index variable, a block structure, or as a DO WHILE loop. The IMPLIED DO is a special form used in I/O and array constructors, e.g., (A(I), I=1,10). EXIT and CYCLE control loop execution.
2.3.2 IF, SELECT CASE, and GOTO
Fortran supports logical IF (one statement), IF ... ELSE ... END IF, and SELECT CASE for multi‑branching. The GOTO statement remains for backward compatibility but is rarely used in modern code.
2.4 Procedures: functions and subroutines
2.4.1 Argument passing (intent IN, OUT, INOUT)
Procedure arguments have an INTENT attribute: INTENT(IN) (read only), INTENT(OUT) (write only), or INTENT(INOUT) (read/write). This helps optimization and clarity. Arguments are passed by reference by default.
2.4.2 Module-scoped procedures and interfaces
Procedures can be contained in modules. Explicit interfaces are required for many features (optional arguments, assumed‑shape arrays) and can be provided via an INTERFACE block or by placing the procedure in a module.
2.5 Modules and encapsulation
2.5.1 MODULE definition and USE association
A MODULE contains data, type definitions, and procedures. Other program units access them with USE module_name. Modules support renaming and ONLY clauses to restrict visibility.
2.5.2 PUBLIC/PRIVATE attributes
Module entities can be declared PUBLIC (accessible) or PRIVATE (hidden). This enables data hiding and controlled interfaces, essential for encapsulation.
2.6 Derived types and object-oriented programming
2.6.1 TYPE definitions and type-bound procedures
User‑defined types are created with TYPE ... END TYPE. Procedures bound to a type are declared with CONTAINS and the CLASS keyword for dynamic dispatch.
2.6.2 Inheritance, polymorphism, and abstract types
Fortran 2003 introduced inheritance (EXTENDS), polymorphism via CLASS(* ) and SELECT TYPE, and abstract types and deferred procedures (similar to C++ pure virtual). This allows full OOP design.
2.7 File I/O and formatted/unformatted operations
I/O is performed with READ, WRITE, and PRINT. Files are opened with OPEN and closed with CLOSE. Formatted I/O uses format strings or FORMAT statements; unformatted I/O writes binary data efficiently. ADVANCE=‘NO’ and stream access (ACCESS=‘STREAM’) are available.
2.8 Parallel and high-performance features
2.8.1 Coarray Fortran (partitioned global address space)
Fortran 2008 introduced coarrays: each image (parallel process) has its own private data but can access remote data using image indices, e.g., my_covar[other_image]. Synchronization is via SYNC ALL and SYNC IMAGES.
2.8.2 DO CONCURRENT (loop-level parallelism)
The DO CONCURRENT construct specifies that iterations are independent, allowing the compiler to parallelize or vectorize the loop. It is a high‑level, safe parallel construct.
2.8.3 Interfacing with OpenMP, MPI, and GPU programming
Fortran works seamlessly with OpenMP (via compiler directives) and MPI (via external libraries). GPU programming is possible with CUDA Fortran (proprietary) or OpenACC directives.
2.9 Intrinsic procedures and standard library
The standard provides hundreds of intrinsic procedures: mathematical (SQRT, SIN), array manipulation (CSHIFT, EOSHIFT), numeric inquiry (PRECISION, HUGE), character handling (LEN, TRIM), and more. The intrinsic module IEEE_ARITHMETIC offers control over floating‑point behavior.
3 Compilers and toolchains
3.1 Major Fortran compilers (GNU Fortran, Intel Fortran, NAG, IBM XL, Cray)
- GNU Fortran (gfortran): Free, open source, and widely used; supports up to Fortran 2018 partially.
- Intel Fortran (ifx/ifort): Robust optimization for Intel processors; supports full current standards.
- NAG Fortran Compiler: Highly conformant, excellent diagnostics; used for validation.
- IBM XL Fortran: Optimized for IBM Power and z/Architecture.
- Cray Fortran (cce): Specialized for Cray supercomputers and HPC.
3.2 Compilation flags and optimization
Common flags include -O2/-O3 for optimization, -g for debugging, -Wall for warnings. Vendor‑specific flags control vectorization (e.g., -xHost for Intel) and auto‑parallelism.
3.3 Debugging and profiling tools (gdb, valgrind, performance analyzers)
GDB supports Fortran symbol tables. Valgrind’s Memcheck detects memory errors. Profilers like gprof, Intel VTune, and CrayPat analyze hotspots. The -pg flag enables gprof profiling.
3.4 Interoperability with C/C++ (ISO_C_BINDING)
The ISO_C_BINDING intrinsic module provides C‑compatible data types (C_INT, C_DOUBLE) and procedure interfaces. The BIND(C) attribute allows Fortran routines to be called from C and vice versa with standard linkage.
4 Programming paradigms in Fortran
4.1 Procedural (traditional FORTRAN)
Classic Fortran relies on subroutines and functions, global COMMON blocks, and explicit I/O. It is still used in legacy codes but considered less maintainable.
4.2 Modular (Fortran 90+)
Modules replace COMMON blocks and provide explicit interfaces, better encapsulation, and data hiding. This paradigm emphasizes reusability and clarity.
4.3 Object-oriented (Fortran 2003+)
Full OOP is possible: user‑defined types with type‑bound procedures, inheritance hierarchies, and polymorphism. This suits large, complex simulations requiring abstraction.
4.4 Parallel (explicit coarray, OpenMP, MPI)
Fortran supports multiple parallel models: coarrays (language‑level), OpenMP (directives), and MPI (library calls). DO CONCURRENT is a safe, simple way to express loop parallelism.
5 Applications and domains
5.1 Scientific computing and numerical analysis
Fortran is the backbone of many numerical libraries (LAPACK, BLAS, ScaLAPACK) and is widely used in simulations of differential equations, linear algebra, and optimization.
5.2 Weather and climate modeling
Major weather codes (e.g., the Integrated Forecast System of ECMWF, the Weather Research and Forecasting Model) are written in Fortran for its performance on large grids and long time integrations.
5.3 Computational fluid dynamics (CFD)
CFD solvers such as FLOW-3D, OpenFOAM (core), and commercial codes often rely on Fortran for efficient finite‑volume or finite‑difference computations.
5.4 Finite element analysis (FEA)
Structural analysis packages (NASTRAN, ABAQUS) use Fortran for element routines and matrix assembly, leveraging array intrinsics.
5.5 Astrophysics and particle physics simulations
Cosmological simulations (GADGET, Enzo) and particle‑tracking codes (Geant4 has Fortran predecessors) exploit Fortran’s numeric strength.
5.6 Legacy codebases and modernization challenges
Many codes from the 1970s–90s still run in production. Challenges include obscure GOTO logic, COMMON blocks, and fixed‑format. Modernization involves refactoring to modules, free‑form, and adding parallel capabilities.
6 Community, standards, and future
6.1 ISO/IEC JTC1/SC22/WG5 (standardization committee)
WG5 governs the Fortran standard. The committee consists of national bodies and experts. They produce the international standard (ISO/IEC 1539‑1) and a technical specification (TS) for additional features.
6.2 Fortran forums, user groups, and conferences
The comp.lang.fortran Usenet group (now web‑based) is active. The Fortran Forum (ACM) publishes articles. The annual PLDI conference includes Fortran‑related workshops, and user groups like the Fortran Fan Club exist.
6.3 Ongoing development (Fortran 2023, future directions)
Fortran 2023 is expected to include minor enhancements: improved conformance of DO CONCURRENT, generic programming improvements, and better support for modern architectures. Future directions may include stronger async I/O, GPU intrinsics, and more expressive type system features.
7 Comparisons with other languages
7.1 Fortran vs. C/C++ for numerical computing
Fortran’s array syntax, aliasing restrictions (the compiler assumes no overlap), and intrinsic libraries often give it a performance edge for dense linear algebra. C/C++ offers more system‑level features and broader ecosystem but requires explicit vectorization and aliasing annotations.
7.2 Fortran vs. MATLAB, Python (NumPy), Julia
MATLAB and Python (with NumPy) offer interactive development and ease of use but are slower for large‑scale simulations. Julia aims for high performance with dynamic flexibility, but Fortran remains dominant in legacy HPC and certain benchmark‑critical codes.
7.3 Fortran in the age of modern HPC
Despite competition, Fortran’s coarray parallelism, well‑defined array operations, and decades of optimized compilers keep it essential in top‑500 supercomputing applications. Many codes are incrementally modernized rather than rewritten.
8 Notable example programs
8.1 “Hello, World” in Fortran
program hello
implicit none
print *, 'Hello, World!'
end program hello
8.2 Matrix multiplication using array intrinsics
program matmul_example
implicit none
real, dimension(3,3) :: A, B, C
A = reshape([1,2,3,4,5,6,7,8,9], [3,3])
B = transpose(A)
C = matmul(A, B)
print *, 'Result:'
print *, C
end program matmul_example
8.3 A simple heat equation solver
program heat2d
implicit none
integer, parameter :: nx=100, ny=100
real, dimension(nx,ny) :: T, Tnew
real :: dx=0.01, dy=0.01, dt=0.0001, alpha=0.01
integer :: i, j
! Initial condition
T = 0.0
T(nx/2, ny/2) = 100.0
do i = 2, nx-1
do j = 2, ny-1
Tnew(i,j) = T(i,j) + alpha*dt * &
((T(i+1,j)-2*T(i,j)+T(i-1,j))/dx**2 + &
(T(i,j+1)-2*T(i,j)+T(i,j-1))/dy**2)
end do
end do
! (Boundary conditions and output omitted for brevity)
end program heat2d