top of page
  • Writer's pictureGeorge Ebberson

First foray into Fortran!

Recently, after several friends who still study had to use Fortran for a coursework assignment, I was finally inspired enough to try out this infamous language. I already had an install of gfortran as part of my GCC install, so the process was as simple as creating a file and running the compiler. A quick Google search led me to a "hello world" example:

program hello
  print *, 'Hello, World!'
end program hello

Saving the above as hello.f90, I was able to compile and run with:

$ gfortran hello.f90 -o hello
$ ./hello
 Hello, World!

And voila! Now to try explore a little more...


Fortran, FORTRAN, and the "Formula Translating System"

Fortran, originally short for Formula Translating System has been revised as many times as can be expected for a language developed 70 years ago, and the revisions are numbered after their year of release. Fortran 90 (F90) and later seem to be the most commonly used, because that standard was a big change to the language with many new additions. I figured I'd write everything at F90 standard for the sake of simplicity. This also means that statements can be written in lowercase - one of the key restrictions of earlier versions of Fortran was that all keywords must be uppercase (this is also why the language name is often stylised as FORTRAN, as until F90 that was its name).

The Fortran language is defined by ISO/IEC 1539, which unfortunately must be bought. However, there's an excellent Wikibooks book on Fortran which covers all of the key language features at a sensible detail level for someone new to the syntax. I ended up using this extensively.


Program vs Function vs Subroutine

Trying to write my first more complicated program, I immediately ran into some confusion. The Fortran examples I could find online were defining programs, functions, and subroutines (each with their own keyword), and I didn't know what the difference was.

I relatively quickly established that "program" is the keyword that defines the entry and exit point of the function; it's like "main" in C. I made sure of this by trying to add "goodbye world" to hello.f90:

! This program fails to compile because it has two "program" statements.
program hello
  print *, 'Hello, World!'
end program hello

program goodbye
  print *, 'Goodbye, World!'
end program goodbye

Sure enough, I tried to recompile and got an error:

$gfortran hello.f90 -o hello 
    2 | program hello
      |             1
    6 | program goodbye
      |               2
Error: Two main PROGRAMs at (1) and (2)

So, that clears up "program" in at least enough detail that I can avoid compiler errors. One mysterious keyword down, two to go.

My confusion between "function" and "subroutine" was dispelled when I came across another page from the Fortran Wikibook. As the link points out, many languages do not distinguish between functions and subroutines - and as it happens, all the languages I have experience with don't.

Functions are simpler than subroutines. A function must return a single value, and can be invoked from within expressions, like a write statement, inside an if declaration if (function) then, etc. A subroutine does not return a value, but can return many values via its arguments and can only be used as a stand-alone command (using the keyword call).

Effectively, a function takes some inputs and returns exactly one value. It can be an array, so can have several numbers in it, but must only have a single return. Subroutines don't explicitly return anything, instead taking some arguments and being able to mutate them. I found myself thinking of subroutines like a C function which takes only pointers and operates on the pointed-to values, returning "void"; functions are like a C function that has some return type.

That settles that then.


Implicit None

The final bit of behaviour I want to remark on in this post is Fortran's implicit typing. This is bizarre in the 21st century, but is equally as bizarre as the fact that early Fortran only supported variable names of 6 characters. Both of these are attempts to minimise memory usage, and a product of Fortran having originally been written on punch cards.

Implicit typing in Fortran was implemented such that the first letter of a variable name indicates its type. Anything with the first letter between "i" and "n" is interpreted as an integer, and any other letter is typed "real" (a floating point number).

mynum = 5  ! Assumed to be an integer
other = 5  ! Assumed to be a real

Alternatively, you could define your own implicit typing rules! So you may open a Fortran file where e.g. all variables starting with "c" are strings of 9 characters, or anything with a "p" or "q" is a complex number, and so on...

! Anything starting "c" is a 9-character string, anything starting "p"
! or "q" is complex.
implicit character*9 (c), complex (p, q)

Implicit typing was a clever way to help reduce memory usage, but since we're no longer constrained we can disable this functionality and force everything to be explicitly typed - much less error-prone and more maintainable. And to enforce it, we use the "implicit none" statement inside a program, which must come before other code inside a program (except some "use" statements).

program hypotenuse
  implicit none
  real :: a = 3, b = 5, c
  c = sqrt(a**2 + b**2)  ! sqrt is built-in
  print *, "The hypotenuse of (", a, ", ", b, ") is ", c
end program hypotenuse

33 views0 comments


bottom of page