One useful feature of Fortran that I recently
	    discovered are procedure pointers, which allow us to
	    effectively alias a function (or subroutine) name. I
	    wanted to write a program which could calculate virial
	    coefficients for a range of particle shapes (e.g. spheres,
	    spheroids, spherocylinders etc.). The basic code is the
	    same in all cases, except for the subroutine which checks
	    for overlaps between the particles. Usually, I would just
	    switch the subroutines as needed and recompile, but
	    wouldn't it be great to just specify the shape in an input
	    file? Since the overlap routine is called a lot, using an
	    IF statement each time we call it is a
	    non-starter. Instead, we can use a procedure pointer at
	    the start of the program to select the function we
	    want.
The first thing we have to do is set up an interface
	    block for our procedure. This tells the main program how
	    to use the procedure and defines the what arguments the it
	    will take. Both this, and the multiple overlap-test
	    subroutines, are in the same module called
	    "overlaps".
MODULE overlaps
  INTERFACE
     SUBROUTINE sub_interface(r, u1, u2, over)
       REAL(8) :: r(3), u1(3), u2(3)
       LOGICAL :: over
     END SUBROUTINE sub_interface
  END INTERFACE
  PROCEDURE(sub_interface),pointer :: overlap
Each overlap test will take three real arrays as
	    inputs. r is the separation between two particles, and u1
	    and u2 are the unit vectors giving the particle
	    orientations. The parameter over, which has type logical,
	    is returned, and is set to be TRUE when the particles
	    overlap and FALSE when they do not. At the end, we declare
	    a pointer with name "overlap", which will point to one of
	    the overlap tests we will define next.
Now we have to define the procedures. The exact code is
	    excluded here for brevity, but note how the subroutines
	    take the same variables as the interface above. Also note
	    that it does not matter what we call these in the
	    functions, just that their types (and shapes, if they are
	    arrays) matches those in the interface. 
CONTAINS
  SUBROUTINE overlap_spherocylinder(r12, u1, u2, over)
    REAL(8) :: r12(3), u1(3), u2(3)
    LOGICAL :: over
    ! overlap test for spherocylinders
  END SUBROUTINE overlap_spherocylinder
  SUBROUTINE overlap_cut_sphere(rij, ui, uj, over)
    REAL(8) :: rij(3), ui(3), uj(3)
    LOGICAL :: over
    ! overlap test for cut-spheres
  END SUBROUTINE overlap_cut_sphere
  SUBROUTINE overlap_sphere(r12, u1, u2, over)
    REAL(8) :: r12(3), u1(3), u2(3)
    LOGICAL :: over
    ! overlap test for spheres
  END SUBROUTINE overlap_sphere
  SUBROUTINE overlap_oblate_spherocylinder(r12, u1, u2, over)
    REAL(8) :: r12(3), u1(3), u2(3)
    LOGICAL :: over
    ! overlap test for oblate spherocylinders
  END SUBROUTINE overlap_oblate_spherocylinder
  SUBROUTINE overlap_spheroid(rab, ua, ub, over)
    REAL(8) :: rab(3), ua(3), ub(3)
    LOGICAL :: over
    ! overlap test for spheroids
  END SUBROUTINE overlap_spheroid
END MODULE overlaps
Finally, we have to select which of the procedures we
	    want to use, and point to it. In the main programme we
	    define a character variable shape, which will have the
	    name of the shape we want to work with. An IF statement is
	    then used to choose which overlap test we will point
	    at.
PROGRAM calc_virial
  USE overlaps
  IMPLICIT NONE
  CHARACTER(40) :: SHAPE
  SHAPE = TRIM(shape)
  IF (shape .EQ. 'sphere') THEN
     overlap => overlap_sphere
  ELSEIF (shape .EQ. 'spherocyl') THEN
     overlap => overlap_spherocylinder
  ELSEIF (shape .EQ. 'oblate_spherocyl') THEN
     overlap => overlap_oblate_spherocylinder
  ELSEIF (shape .EQ. 'cut_sphere') THEN
     overlap => overlap_cut_sphere
  ELSEIF (shape .EQ. 'spheroid') THEN
     overlap => overlap_spheroid
  ENDIF
END PROGRAM calc_virial