Fortran Syntax

Syntax is the grammar you type before semantics, speed, or style. Fortran's grammar is deliberately small: one statement per line, case-insensitive keywords, and a handful of structural rules. This lesson covers the two source forms, the skeleton every program shares, and the END-based structure that makes the language remarkably self-checking.

Two source forms: free and fixed

Fortran has two source layouts because it has two centuries of history in one file system. Modern Fortran (1990 onward) uses free form: statements start anywhere, whitespace is free, comments use !. Legacy Fortran 77 used fixed form, where columns 1–5 held statement labels, column 6 a continuation marker, and columns 7–72 the statement itself — a layout inherited from 80-column punch cards.

The file extension tells the compiler which layout to expect: .f90 .f95 .f03 .f08 .f18 .f23 mean free form; lowercase .f and .for mean fixed form. Because a wrong guess produces baffling errors (e.g. "Unclassifiable statement"), always use a free-form extension. This track uses .f90 everywhere.

Free form rules that matter

  • Case is insignificant: Program, program and PROGRAM are the same keyword. Convention is lowercase.
  • A statement may be as long as you like; break a long one with a trailing & and continue on the next line:
  total = alpha * beta * gamma + delta * epsilon &
                + zeta * eta * theta
  !            (^ the & ends the line; indentation is decorative)
  • Multiple statements share one line only if separated by ; — rare and discouraged.
  • A comment runs from the first ! to end of line; code may precede it, so comments explain statements inline.
  • Names (identifiers) are 1–63 characters, start with a letter, then letters, digits, and underscores. convergence_criterion_2 is a fine name; 2_convergence is not.

The program skeleton

Every Fortran file contains one or more program units. The next complete program shows a main program that calls a subroutine living in the same file — the two-unit shape you will use for the rest of this phase. Read the annotations: they mark the three mandatory elements of a modern unit.

program skeleton
  ! Main program unit: the entry point the runtime starts at.
  implicit none                       ! 1) ban implicit typing
  integer :: i                        ! 2) declare every variable
  do i = 1, 3
     call announce(i)                 ! 3) call a named subprogram
  end do
contains                              ! internal procedures live here
  subroutine announce(n)
    integer, intent(in) :: n          ! input-only argument (see Functions)
    print '(a,i0)', 'iteration ', n
  end subroutine announce
end program skeleton

Compile as usual — gfortran -Wall skeleton.f90 — and run. Subroutines inside contains see the host program's variables directly (host association), a power and a hazard you will manage with modules starting with the modules lesson.

Main program, module and external subroutine connected by USE and CALL

Fig. 1 — One program, three kinds of program unit; the module is the shared library of the future modules lesson.

Statements and the implicit typing trap

Each line of executable code is a statement. Fortran's most famous footgun is implicit typing: without implicit none, names starting with i, j, k, l, m, n are automatically integer and everything else real — carryover from FORTRAN I's design goal of forgiving math input. A misspelled variable silently becomes a new zero-initialized variable, corrupting results with no error. This is why every example in this track (and every serious modern codebase) starts with implicit none.

Declarations use the type [, attributes] :: name_list pattern. The double colon :: is conventional; it separates attributes from names and makes the declaration unmistakable:

program declarations
  implicit none
  integer :: n                            ! a scalar integer
  real    :: x = 1.5                      ! initialization is allowed
  integer, parameter :: steps = 10        ! compile-time constant, never changes
  real :: y(steps)                        ! fixed-size array of ten reals (Arrays)
  character(len=20) :: label              ! a twenty-character string
  print *, n, x, y(steps), label
end program declarations

END: the statement that closes every unit

Every program unit — program, module, subroutine, function, type — closes with an end statement that names its kind, optionally repeating the unit's name: end program declarations. Repeating the name lets the compiler verify you closed the right unit — in a long file the difference between end and end subroutine has caught more than one engineer. Applied consistently, this single rule makes Fortran files self-documenting at their seams.

Standard conformance and file endings

The ISO standard is the contract between your code and every compiler. gfortran's -std=f2018 (or -std=f2023) enforces it and reports a whole family of retired features as errors: the arithmetic IF, computed GO TO, PAUSE, statement functions, and the old CHARACTER*10 spelling. Mainstream open-source code has virtually stopped using these — but if you ever inherit a 1985 subroutine, -std=legacy gets it compiling today while you plan the rewrite.

Finally, a hygiene rule worth internalizing now: one program unit per file, named exactly as the unit is named — solver.f90 contains program solver or module solver. Editors, language servers, and fpm all assume it, and you will thank yourself at linking time.