Cosc 2P90 PROCEDURES, METHODS AND FUNCTIONS (c) S. Thompson, M. Winters 1
Procedures, Functions & Methods The are varied and complex rules for declaring, defining and calling procedures, methods and functions Focus Parameter passing Types, effects and side-effects Storage allocation Different calling mechanisms and effects on reliability (c) S. Thompson, M. Winters 2
Parameters Formal parameters Found in declaration of routine E.g. int myfunc( int parama, int paramb ) Actual parameter Found in the call of the function E.g. myfunc( 1, 2 ); Example: C++ swap void swap(int& first, int& second) { int intermediate; intermediate = first; first = second; second = intermediate; } // swap swap( high, low); swap( left, right ); Procedural abstraction Allows you to think at a higher level (c) S. Thompson, M. Winters 3
Methods Found in object-oriented languages Exist as a component of a class target object implicit parameter bk1.deposit(6); vs deposit(bk1,6); Access to non-local data Discouraged in procedures In methods access to target object member data ok Self reference (this, self) privmethod(); vs this.privmethod(); Class methods (a.k.a. static methods) Act the same as regular functions (c) S. Thompson, M. Winters 4
Parameter Passing 3 modes for parameter passing in - Info goes into a procedure out Info is returned from a procured update info is passed into a procedure and modified implementations In call-by-value, call-by-constant-value, call-by-reference-constant Out call-by-result In/Out call-by-value-result call-by-reference call-by-name (c) S. Thompson, M. Winters 5
In Parameters Call-by-value Pascal, C++, C, Java formal is copy of actual int total(int val) { int sum = 0; while (val > 0) { sum += val; val--; } return sum; }// total modifying the parameter (c) S. Thompson, M. Winters 6
In Parameters call-by-constant-value Ada, FORTRAN 90 call-by-value but formal is a constant function total(val : in Integer) return Integer is sum : Integer := 0; count : Integer := val; explicit copy begin while count > 0 loop sum := sum + count; count := count + 1; end loop; return sum; end total; (c) S. Thompson, M. Winters 7
In Parameters call-by-reference Large structures are expensive to copy by value Pascal, C++, C# formal is reference to actual no protection call-by-reference-constant Ada, FORTRAN 90, C++ call-by-reference but formal is declared constant C++ float sum(const Matrix& m) { } (c) S. Thompson, M. Winters 8
In Parameters value vs constant-value vs reference-constant call-by-value max reference value copy val reference value max reference value call-by-constant-value val value copy call-by-reference-constant max reference copy value val reference (c) S. Thompson, M. Winters 9
Out Parameters call-by-result Ada, C# formal is uninitialized local value copied to actual at exit procedure read_negative(neg_number : out Integer) is number : Integer; begin get(number); while number >= 0 loop put_line( number not negative, try again ); get(number); end loop; neg_number := number; end read_negative; Actual out parameters require an l-value In C# actual parameters require out keyword e.g. int i; read_negative( out i ); Algol W address of actual computed at exit, instead of entry (c) S. Thompson, M. Winters 10
Update Parameters call-by-value-result Ada formal is copy with copy back to actual at exit procedure update(balance : in out Integer) is transaction : Integer; begin for j in 1.. 10 loop get(transaction); balance := balance + transaction; end loop; end update; (c) S. Thompson, M. Winters 11
Update Parameters call-by-reference Pascal procedure update(var balance : Integer); C++ void update(int& balance); C# void update( ref int balance ); value-result vs reference No difference to the end-ser Aliasing actual in inherited scope and parameter same actual as multiple parameters expression parameters? Pascal, Ada, C++ require l-value Fortran, PL/1 allowed variables through a local copy Const & in C++ allows this (c) S. Thompson, M. Winters 12
Update Parameters currentacc reference value call-by-value-result copy out balance reference value copy in currentacc reference value call-by-reference copy balance reference value (c) S. Thompson, M. Winters 13
Java call-by-value (basic types) cannot modify primitive type parameters object variables are references reference passed object can be modified, but cannot change to different object (c) S. Thompson, M. Winters 14
Java Example static void test( int i ) { i += 4; System.out.println( i ); } static void test2( Point p ) { p = new Point( 1, 2 ); System.out.println( p.tostring() ); } static void test3( Point p ) { p.setlocation( 1, 2 ); System.out.println( p.tostring() ); } public static void main(string[] args) { int j = 4; test(j); System.out.println( j ); Point t2 = new Point( 100, 200 ); Point t3 = new Point( 100, 200 ); test2( t2 ); test3( t3 ); System.out.println( t2.tostring() ); System.out.println( t3.tostring() ); (c) S. Thompson, M. Winters 15
C call-by-value only can pass addresses (& operator) procedure treats as pointer void swap(int *first, int *second) { int intermidiate; intermidiate = *first; *first = *second; *second = intermidiate; } swap(&higher, &lower); Disadvantages NULL pointers (c) S. Thompson, M. Winters 16
Call-by-name Straight textual substitution ALGOL 60 actual parameter is unevaluated at call, but evaluated upon each reference seldom used in imperative languages used in functional languages (lazy evaluation) C preprocessor functions #define max( a, b ) ( (a) > (b)? (a) : (b) ) a = max( random(), 5.0f ); spot the bug! (c) S. Thompson, M. Winters 17
Languages & Mechanisms Language value constantvalue referenceconstant Mechanism result reference valueresult name Algol 60 * * Fortran 90 *??? Pascal * * C * C++ * * * Ada (scalars) * * * Ada (others)????? Java * (c) S. Thompson, M. Winters 18
Comparison var element : Integer; a : array [1.. 2] of Integer; procedure whichmode(x :? mode Integer); begin a[1] := 6; element := 2; x := x + 3; end; begin a[1] := 1; a[2] := 2; element := 1; whichmode(a[element]); (c) S. Thompson, M. Winters 19
Comparison Mechanism Result a[1] a[2] element call-by-value 6 2 2 call-by-value-result (Algol W) 6 4 2 call-by-value-result 4 2 2 call-by-reference 9 2 2 call-by-name 6 5 2 (c) S. Thompson, M. Winters 20
Overloading Overloading refers to having multiple procedures or methods with the same name must differ in signature Example class Writer { void print( int c ) { }; void print( float f ) { }; void print( char c ) { }; } Most languages don t allow overloading to only differ by return type Other languages have special cases (Pascal) to achieve this Not available to the programmer (c) S. Thompson, M. Winters 21
Default Parameters An alternative to overloading Provide a default value for parameters can omit actual parameters must be last parameters procedure inc (item: in out integer; by: in integer := 1; mul: in integer :=1) is begin item := item*mul+by; end inc; : inc(i); Useful to reduce complexity of functions and interfaces (c) S. Thompson, M. Winters 22
Named Parameters Normally position is how we associate formal and actual parameters Fortran, PL/1, Ada, Python also have named parameters Associate the formal with the actual by name instead of position inc(by=>2,mul=>3,item=>i); inc(i,mul=>3); This leads to easier code to read Myfunc( 1, 4, test ) vs. Myfunc( height: 1, width: 4, displaystring: test ) Related to enums vs bool argument as parameters (c) S. Thompson, M. Winters 23
Functions A procedure which returns a value differentiation, e.g. none in C, ALGOL 60 Association with mathematical function Specifying result assignment to function name (Algol 60, Pascal, FORTRAN) return statement (C, Java) Result can be considered extra result parameter Return type simple type ALGOL 60, Java, Pascal but also references structured type Ada, C, C++, FORTRAN 90, Algol 68 Order of evaluation a = b() + c() Usually not defined in language, up to compiler side effects Modifying parameters side effects Ada in out/out not permitted on functions C++ const (c) S. Thompson, M. Winters 24
Examples Fortran 90 FUNCTION TWICE(A) INTEGER TWICE INTEGER A TWICE = A + A END FUNCTION TWICE Algol 60 integer procedure twice(a); value a; integer a; twice := a + a Java int twice(int a) { return a + a; }// twice Pascal function twice(a : Integer):Integer; begin twice := a + a end; {twice} C++ int twice(int a) const { return a + a; }// twice Ada function twice(a : in Integer) begin return a + a; end twice; return Integer is (c) S. Thompson, M. Winters 25
Properties (not in text) In many O-O class to provide proper encapsulation class members are exposed through accessors & mutators class myclass { private int myvar; public int getmyvar() { return myvar; } public void setmyvar(int i) { myvar = i; } } Newer languages have introduced properties as an intermediate between fields and methods Acts like a field Allows validation of data Properties clearly represent what data is required for an object Used for automated serialization Found in python, C#, Delphi Can be implemented in C++ (c) S. Thompson, M. Winters 26
Properties Example C# class MyClass { private int myvar; } public int MyVar { get { return myvar; } set { myvar = value; } } MyClass obj = new MyClass(); obj.myvar = 5; func( obj.myvar ); (c) S. Thompson, M. Winters 27
Operators Operators use infix, functions use prefix a+b vs. add(a,b) functions define new operations declaring new operators really functions with different syntax Ada: function + (today : in Day; n : in Integer) return Day is begin return Day val((day pos(today) + n) rem 7); end; C++ Day operator+(day today, int n) const { } choice of operator existing operator symbols other symbols (usually not permitted) precedence rules (c) S. Thompson, M. Winters 28
Storage Management storage for local variables static pre-allocation - load-time binding efficient access size of each item known at compile time no data item has multiple simultaneous occurrences no recursion FORTRAN (c) S. Thompson, M. Winters 29
Storage Management Stack storage management Used in block-structured languages Reference Binding at block entry, de-allocation at exit Uses a stack of activation records (AR) Storage only for locals of active methods Code generated requires additional statements to bind references Addresses as offsets Useful if all local variables are known at compile time Some hardware has special support to speed this up (c) S. Thompson, M. Winters 30
Stack-based example program Main(output); var b, d : Integer; procedure z; var e, f : Integer; begin end {z}; procedure y; var g, h : Integer; begin z; end {y}; begin y; z; end. int d, b; void z() { int e, f; } void y() { int g,h; z(); } int main() { y(); z(); } (c) S. Thompson, M. Winters 31
data area for z data area for y data area for y data area for y data area for Main data area for Main data area for Main data area for Main Start program Enter y Enter z from y Exit z data area for Main Exit y data area for z data area for Main Enter z from Main data area for Main Exit z (c) S. Thompson, M. Winters 32
Activation Records An activation record is the set of local variables & parameter references, along with system information system information contains return address restore stack pointer a.k.a. dynamic chain Static chains Required in languages with nested procedures Pointer points to the data area of it s textually enclosing block static chain access is distance up chain plus offset (c) S. Thompson, M. Winters 33
program Main(output); var b, d : Integer; procedure z; var e, f : Integer; begin end {z}; procedure y; var g, h : Integer; procedure x; var j, k : Integer; begin end {x}; begin z; x; end {y}; begin end. z; y; (c) S. Thompson, M. Winters 34
data area for Main data area for Main data area for y data area for y data area for z data area for x Run-Time stack space for e and f static chain pointer dynamic chain pointer return address space for g and h static chain pointer dynamic chain pointer return address space for b and d system information space for j and k static chain pointer dynamic chain pointer return address space for g and h static chain pointer dynamic chain pointer return address space for b and d system information when z has been called from y when x has been called from y (c) S. Thompson, M. Winters 35
Activation Records Recursion stack-based supports recursion each invocation has its own storage multiple ARs for different invocations of same procedure int factorial(int n) { if (n > 1) return n * factorial(n 1); else return 1; }// factorial (c) S. Thompson, M. Winters 36
Activation Records factorial(3) 3 * factorial(2) 3 * 2 * factorial(1) 3 * 2 * 1 data area for the call factorial(1) data area for the call factorial(2) data area for the call factorial(3) data area for the main program (c) S. Thompson, M. Winters 37
Forward References Many languages require a declaration before use for procedures. Allows the compiler to only do a single pass What if a() calls b() and b() calls a()? (mutual recursion) Forward references tell the compiler everything it needs to know about the procedure (c) S. Thompson, M. Winters 38
procedure operand(var ca : Character); forward; procedure exp( var cb : Character); begin operand(cb); while cb = + do operand(cb) end {exp}; procedure operand(var ca : Character); begin read(ca); if ca = ( then begin exp(ca); if ca <> ) then writeln( missing brackets ) end else if ca <> a then writeln( missing operand ); read(ca) end {operand}; (c) S. Thompson, M. Winters 39
Forward References function prototypes in C & C++ void operand(char *); function specification vs function body in Ada function a(b : Integer) return Real; function a(b : Integer) return Real is begin end a; ALGOL 60, Algol 68 & Java don t require defined before use compiler must do multiple passes (c) S. Thompson, M. Winters 40
Subprogram as Parameters functions and procedures passed as parameters basic principle in functional languages less widely used in imperative languages specification of function parameters types of their parameters? function slope(f(y : Real) : Real; x1, x2 : Real) : Real; begin if x1 = x2 then slope := 0 else slope := (f(x2) f(x1)) / (x2 x1) end {slope}; (c) S. Thompson, M. Winters 41
function straight(x : Real) : Real; begin straight := 2 * x + 1 end {straight}; function tan(x : Real) : Real; begin tan := sin(x) / cos(x) end {tan}; slope(straight, 3.8, 3.83); slope(tan, 3.8, 3.85); (c) S. Thompson, M. Winters 42
Subprograms as Parameters Other languages move a step furthur than Pascal by allowing procedures to be types. At it s base level, what is a procedure? A memory address to branch to. So a procedure can be represented by a reference variable In C, called a function pointer. (c) S. Thompson, M. Winters 43
Subprogram as Parameters Modula 2 TYPE realfunc = PROCEDURE(REAL) : REAL; var fx : realfunc; fx := straight; PROCEDURE slope(f : realfunc; x1, x2 : REAL) : REAL; BEGIN IF x1 = x2 THEN RETURN 0 ELSE RETURN (f(x2) f(x1)) / (x2 x1) END END slope; (c) S. Thompson, M. Winters 44
C Example void printcoursecode() { printf( "COSC 2P90\n" ); } void printcoursename() { printf( O-Ol Programming\n" ); } void DisplayString( void (*displaystring)() ) { printf( "******************************\n" ); (*displaystring)(); printf( "******************************\n" ); } int main() { DisplayString( printcoursecode ); DisplayString( printcoursename ); // local variable void (*callback)() = NULL; // assignment & calling callback = printcoursecode; (*callback)(); return 0; } (c) S. Thompson, M. Winters 45
Subprograms as Parameters - Ada Ada uses generics instead of subprogram parameters compile-time parameters generic instantiation creates distinct functions generic with function f(y: Real) return Real; function slope(x1, x2 : Real) return Real; function slope(x1, x2 : Real) return Real is begin if x1 = x2 then return 0; else return (f(x2) f(x1)) / (x2 x1); end slope; function straight_slope is new slope(f => straight); function tan_slope is new slope(f => tan); (c) S. Thompson, M. Winters 46
Methods as Parameters (not in text) In pure object-oriented languages, function pointers aren t enough Can t pass a (non-static) class method as a parameter Requires an instatiated object C++ solves this with member-function pointers float (SomeClass::*my_memfunc_ptr)(int, char *); my_memfunc_ptr = &SomeClass::some_member_func; Similar to function pointers, except they require an object to call it SomeClass *x = new SomeClass; (x->*my_memfunc_ptr)(6, "Another Arbitrary Parameter"); (c) S. Thompson, M. Winters 47
Delegates Special type used in.net language that abstract away the function vs member function problem Your usage shouldn t care which it is Useful for event listeners, general callbacks (c) S. Thompson, M. Winters 48
Delegate Example public delegate void Del(string message); public static void DelegateMethod(string message) { System.Console.WriteLine(message); } public class MethodClass { public void Method1(string message) { } public void Method2(string message) { } } MethodClass obj = new MethodClass(); Del d1 = obj.method1; Del d2 = obj.method2; Del d3 = DelegateMethod; d1( A message ); (c) S. Thompson, M. Winters 49