Functions and Subprograms
Monolithic Structure
•	Programs seen so for are just of made of a
–	single unit programs: one single block of declarations and statements
•	Single block monolithic programs fine for small programs (50 or less LOC)
•	Not good for larger programs that you will write; definitely not for your projects
•	Very difficult to understand, debug and develop 
•	Some way of structuring the code required
Programming with Subroutines
•	All modern PLs have features to structure the code into multiple units
•	This feature enables composing a large program from a number of smaller subprograms 
•	A typical program consists of 
–	a number of subprograms
–	and a main program 
•	The main program is invoked by the user 
•	The main program, in turn, invoke the other subprograms
Design Decomposition
This structuring mechanism has lot of advantages:

•	Readability and understandability of code improves
–	Main program and subprograms can be individually read and understood

•	 Supports structured development process 
–	Break a complex problem into simple ones,
–	arrive at subprograms for smaller ones
–	 Problem definition, algorithm design, verification, coding and testing all are decomposed

Advantages of Subprograms
•	Concurrent and independent design of subprograms (Teams of programmers)
•	Reuse of existing code
–	 If someone had already solved one of the subtasks, use them by taking the solution as a subprogram (avoids reinvention)

–	Library of reusable components or units
Subroutine Definition
A subroutine is an independent program unit:

       SUBROUTINE name ( argument_list)
         ...
         Declaration Section
         ...
         Executable section

         RETURN
       END SUBROUTINE [name]
Programs and Subroutines
•	A subroutine almost resembles normal programs
•	It has its own name, a declaration part and an executable part
•	It is compiled separately
•	One difference is: 
–	It can not be directly executed,
–	executed via the (main) program
•	Another difference is:
–	a list of arguments, variable names
–	arguments are dummy, placeholders
Calling subroutines
•	A subroutine is executed by the main program
•	This happens when main program executes a statement
		CALL subroutine_name (argument_list)
•	We say that the main program `calls' the subroutine
•	When the main program calls the subroutine, 
–	its execution is suspended
–	Control jumps to the beginning of execution part of the subroutine
•	When the subroutine completes its execution (by executing the RETURN statement or reaching the end of subroutine)
–	Control returns to the main program
–	Execution proceeds from the next statement
Call Control Flow

Call Data Flow
•	The arguments given in a call statement are called actual arguments
•	The number, order and type of actual arguments must match that of dummy arguments
•	Subroutine declaration includes dummy argument declarations
•	When the subroutine is invoked (called) by the main program, the values of actual and dummy arguments are exchanged.
•	Values of some actual arguments are passed to the corresponding dummy ones at the beginning
•	Values of some dummy arguments are passed to the actual ones at the end of the call
INTENT Declaration
•	Dummy arguments are of three kinds:
		REAL, INTENT(IN)::            dummy1
		INTEGER, INTENT(OUT):: dummy2
		REAL, INTENT(IN OUT)::   dummy3

•	dummy1 input argument: receives value at the beginning from corresponding actual argument

•	dummy2 output argument: It passes a value at the end of the call to the corresponding actual argument

•	dummy3 input-output argument: It receives a value at the beginning and passes a value at the end from/to the actual argument
Local Variables
•	Besides dummy arguments, other variables may be declared in a subroutine
•	They are called local since they are accessible only locally 
•	Main program can not access them
•	The names of these variables (or dummy arguments) may be same as some other variables in the main program
•	The name spaces are distinct
•	Same variables names, labels can appear in a subroutine
Example
     Subroutine swap (var1,var2)
! swaps the contents of var1 and var2
implicit none

integer, intent(inout):: var1,var2

!local variable
integer :: temp

temp = var1
var1 = var2
var2 = temp

return
end Subroutine
 Explanation
•	This subprogram takes two input arguments, swaps their contents and returns
•	The two parameters are of intent INOUT so that values can be passed to and returned from them
•	temp is a local variable
•	This subroutine can be separately compiled 
•	It can be invoked from a main program
Main program
    program sort3
     implicit none
     integer *, x1,x2,x3
     read *, x1,x2,x3
     if (x1 > x2) then 
     call swap (x1,x2)   ! call to the subroutine
     if (x2 > x3) then
           call swap (x2,x3)
           if (x1 > x2) then 
              call swap(x1,x2)
          endif
     endif
elseif (x2 > x3) then 
      call swap(x2,x3)
      if (x1 > x2) then 
          call swap(x1,x2)
      endif
endif
write *, x1, x2, x3
end program
 Observation
•	Any number of calls to the subroutines

•	Each call supplies a list of actual arguments

•	values of actual arguments will be changed after the call  if they are INOUT or OUT arguments

•	Local variable temp is used in all the invocations

•	Its value is different in different invocations

•	It does not retain its value across invocations
 CALL statement
•	CALL is an executable statement
•	This can appear in the main program and even in the subroutine
•	When the call statement in a subroutine is executed, control transfers to subroutine named in the call
•	So, starting from a main program, a series of calls can be made to same or different subroutines
•	Calls to the same subroutine possible - Recursive Call
Call - Return Sequence

Internal Procedures
•	Subroutines appearing within the main program definitions are called internal procedures
–	Their definition appear before the end statement of the program
–	all subroutines given one after another
–	no nesting of definition
–	before the first subroutine, write  CONTAINS
–	exactly one CONTAINS in a program
–	variables declared in the main program can be used in the routine
–	Global variables
Example
          Program example
          !declaration
          . . .
          !executable statement
               . . .
     
          Contains
                 Subroutine proc1
              ...
             end subroutine
            ...
        end Program

External Subroutines
•	Subroutines can appear in separate files
–	All the files compiled for generating a.out file
–	They can be separately compiled to create .o file
–	all the .o files and .for files can be finally compiled to create the final a.out file
•	Libraries
–	Many useful routines developed, compiled and collected together
–	These can be used in your programs
–	When compiling your programs the object codes of library routines are linked to get an executable
–	Process of Linking
–	intrinsic functions
General Picture of Compilation

Functions
•	Functions are like subroutines
•	Called from main program to do some independent computations
•	The result of computations not passed via parameters
•	Instead the function itself returns a value
•	Functions are called inside an expression
•	No separate call statement
Example
    Real Function x_mul(x)

!to evaluate the value of x(1-x*x)/5

implicit none

integer, intent(IN):: x

x_mul = x*(1 - x**2)/5

end function
 Observation
•	The above is a function that computes x(1-x2), when given x
•	The function definition looks similar to subroutines
•	The value returned by the function is given in the header (Real)
•	Note the intent declaration
•	There is an assignment that assigns a variable with the same name as the function
Using a function
Program sum

real *, x, Sum
integer *, I

Sum = 0.0
do I = 1, 10
  
   Sum = Sum + x_mul(I)

end

print *, Sum

end program
Side Effects
•	Invocation of the function takes place inside expression
•	It is like evaluation, returns a value which is used in the expression
•	Always use parameters to be of INPUT intent
•	Otherwise, function invocation may change the contents of actual parameters
•	Then after an expression evaluation, variables would change values
•	This is called side effect
Functions and Subroutines
•	Only one result would be returned by a function
•	Type of the result given in the definition
•	For multiple results, use subroutines
•	Like subroutines, functions can call other functions
•	Functions can be internal or external
•	Many useful functions in libraries
PGPLOT Library
•	This is a standard library for drawing graphs
•	This library consists of various subroutines and functions 
•	For drawing various kinds of graphs with colours
•	on a variety of medium like screen, plotters, etc.
•	you can use the functions and routines of this library
•	while compiling the name of the library need to be mentioned
•	A separate tutorial on use of PGPLOT library
Save Attribute
•	Local variables lose their values across different invocations
•	Sometimes one would like to retain the values
•	Recording of history
•	Save attribute is used for this
•	Declare in the procedure
–	type_name, SAVE :: var_name
•	Or initialize the local variable
An Example
Subroutine save_var(mark)
implicit none
integer :: passed = 0 ! This makes it retain the value
!alternately use, integer,save:: passed = 0

if (mark > 35) then
    passed = passed + 1
endif
if (mark < 0) then
    print *, passed
endif
end subroutine