340 likes | 569 Views
Subprograms. subroutines, procedures, functions, methods. Why subprograms?. top-down structure - chunking attach a name to a composite of instructions reusable code branch away and branch back. main. call sub. call sub. sub. Vocabulary. parameter profile. header / prototype.
E N D
Subprograms subroutines, procedures, functions, methods
Why subprograms? • top-down structure - chunking • attach a name to a composite of instructions • reusable code • branch away and branch back main call sub call sub sub
Vocabulary parameter profile header / prototype float average(float list[], int n) { … } protocol formal parameters actual (arguments) av = average(marks,20); call
Functions vs Procedures • procedures are statements - do not return a value Collections.sort(marks, 20); • functions are expressions - return a value double x = 1000.0 + Math.exp(10.0); • in c, c++, Java, all methods are functions; can be used as procedures; ‘void’s must be used as procedures
Parameters • pass-by- • value • reference • name in mode (call) inout (call-return) out (return) keyword positional • example Java: • all parameters are positional • primitive parameters are in, pass by value • object parameters are inout, pass by reference
Keyword parameter passing • order of actual parameters can be changed if each parameter is identified by keyword (FORTRAN, Ada) • natural match with default parameters av = average(n=>20,list=>marks) av = average(list=>marks, n=>20)
Extended parameter models • variable numbers of parameters java varargs: last parameter can be array or sequence of arguments: public int sum(int… args) call: int[] x = {2,3,4,5,6,7}; int xsum = sum(x); int csum = sum(2,3,4,5,6,7);
Modes: Direction of data passing in - data goes into subprogram only at beginning of execution out - data goes from subprogram back to caller at end of execution inout - data passes in both directions: into subroutine at call and back to caller at end of execution
Direction of data passing in - protects caller’s data from effects of subprogram out - useful for initializing data in caller; alternative route for returning data inout - gives subprogram access to change caller data subprogram caller subprogram caller subprogram caller
Implementing parameters (1) • Pass-by-value • pass-by-value (in) • pass-by-result (out) • pass-by-value-result (inout) • Data is copied between actual and formal parameters a = 10 proc sub(int x) sub (a) { print a print x x = 1000 print x } x a
Implementing parameters (1) • Pass-by-value • pass-by-value (in) • pass-by-result (out) • pass-by-value-result (inout) • What happens when actual parameters are not variables? (constants or expressions)
Implementing parameters (1) • Pass by value,result, value-result a = 10 proc sub(int x) sub (a) { print a print x x = 1000 print x } sub stack x a
Implementing parameters (2) • Pass-by-reference (inout OR in if actual parameters are made read-only) • Formal parameter refers to same memory cell as actual parameter a = 10 proc sub(int x) sub (a) { print a print x x = 1000 print x } x a
Implementing parameters (2) • Pass-by-reference a = 10 proc sub(int x) sub (a) { print a print x x = 1000 print x } sub stack address of a a x
Implementing parameters (2) • Pass-by-reference • Formal parameter refers to same memory cell as actual parameter • What happens when actual parameters are not variables? (constants or expressions) java example jButton.addActionListener(new ButtonListener());
Implementing parameters (3) • Pass-by-name • formal is bound to actual only when accessed or assigned (i.e., not at call) • effect depends on form of actual parameter: • constant - same as pass-by-value • variable - same as pass-by-reference • expression - like reference but reference may change
Implementing parameters (3) - pass-by-name example procedure BIGSUB integer GLOBAL, LIST[1:2]; procedure SUB(PARAM) begin PARAM := 3; GLOBAL := GLOBAL + 1; // note scope! PARAM := 5; end; begin LIST[1] := 2; LIST[2] := 2; GLOBAL := 1; SUB(LIST[GLOBAL]); end;
Implementing Parameters (3) • Pass-by-name thunk list[j] sub(x) j=2 sub(list[j]) x j=4 x j list
Parameters - design issues (1) • type checking • no checking - mismatched types -> reinterpretation of data • type checking - control of type match or legal coercion
Parameters - design issues (2) • array parameters - for 2 or more dimensions, length of 2nd, 3rd, etc dimensions is needed to computer offset • tradeoff • compile-time (efficient) offset expression forces fixed array dimensions • call-time (less efficient) offset expression handles arrays of any size (java)
Parameters - design issues (3) security / efficiency tradeoff • security: design according to minimum access requirements: • in , out, inout • efficiency: reference is time and space efficient for large data objects but implies inout • compromises • allow programmer choice • ‘read-only’ references (C++) • what does java offer?
Passing procedures as parameters • example of procedure passing procedure m() var integer[3] arr = {1,2,3}; procedure s (integer[3] k) begin print (k[1]+k[2]+k[3]); end procedure sub (integer[3] cc, procedure w) begin w(cc); end begin sub(arr, s); end
Issues unique to procedure parameters (1) • Does protocol of actual parameter procedure match protocol of formal? • early Pascal unchecked • later Pascal – parameters in formal procedure parameter • c pointers to procedures are passed; their type identifies protocol
Issues unique to procedure parameters (2) scoping of variables • from definition of actual parameter • environment of call • environment of execution procedure m() var integer[3] arr = {1,2,3}; procedure s (integer[3] k) begin print (k[1]+k[2]+k[3]); end procedure sub (integer[3] cc, procedure w) begin w(cc); end begin sub(arr, s); end
Procedure parameters:procedures as data • LISP: functions are a data type • can be manipulated as data (define (area r)(times pi r r)) and • executed (interpreted) (eval(define (area r)(times pi r r))) (eval (area 10))
Function design (COSC 3036) • extreme definition: NO SIDE-EFFECTS • no access to global variables • only call parameters • only effect through return value • return values: • single primitive value – math model • single value including reference/pointer • any one value including record, array or procedure
Coroutines – preview to concurrency • subroutines in symmetric control model (not caller-callee relationship) • goal: virtual parallelism • Simula – process simulation • java – threads • classic example – large file copy • read and write coroutines with shared buffer
Sharing data space • global identifiers by scoping rules • instructions to compiler to share space (Fortran COMMON) • explicit specification of external units needed (Fortran 90, java)
Reusability with subprograms • OVERLOADING: reusing a subprogram name • in different scopes • with different protocols (like operators*) • conflict with default parameters • POLYMORPHIC: • different parameter types in different activations • dynamic typing • type templates C++ *C++ allows overloading of operators
generic parameter typesC++ templates template <class Etype> void Swap (Etype & First, Etype & Second) { Etype Temp = First; First = Second; Second = Temp; } ... in calling program int X = 5, Y = 6, Z = 7; double A = 3.5, B = 9.4; Swap(X,Y); //instantiate int version Swap(X,Z); //re-use int version Swap(A,B); //instantiate double version Swap(A,Z); // illegal – type mismatch
Reusability and compilation • problem: variables and procedures defined in one unit and accessed in another – type checking • separate compilation (Ada) • compile time check of compatibility • independent compilation (c) • no type checking – run time type errors • no compilation except complete programs (original Fortran II)
Separate Compilation • compilation checks library of exported entities for types and protocols of external references library A’s compilation unit int max(int,int) ? compile A unit A unit B function int max(int,int) i = max(j,k) compile B