The declaration could then be
subroutine norm2s(x,y,z,r) implicit none real :: x,y,z,r r = sqrt(x**2+y**2+z**2) end subroutine norm2sThe calling program invokes the subroutine using
call norm2s(a,b,c,d)The CALL statement builds the argument stack and passes control to the subroutine; when END SUBROUTINE is encountered, the control is returned to the calling program, at the first statement after CALL. Unlike functions, subroutines communicate with the calling program via arguments (or global variables) only - they do NOT return a value associated with the subroutine's name.
For example, the main program might read in the coordinates and print the 2-norm of the vector:
program print_norm implicit none external :: norm2s real :: a, b, c, d print*, "input~3~coordinates:" read*,a,b,c call norm2s(a,b,c,d) print*,"the norm is",d end program print_normThe declaration EXTERNAL :: norm2s tells the main program that norm2 is an external subroutine (we do NOT have any type declaration associated with the name!). Again, in this particular context the declaration is superfluos, but, since it will be mandatory in other contexts, and since it improves readability, I strongly recommend its use.
The actual arguments a,b,c,d replace the formal (dummy) arguments x,y,z,r (in this order) at the time of call. The type and order of actual arguments should match exactly the type and order of their omologue formal (dummy) arguments.
An IMPLICIT NONE statement should be given in each subroutine, just as it is given in the main program.