Subprograms • Fundamentals of subprograms • Design issues for subprograms – – – – – – – Parameter-passing methods Type checking of parameters Static or dynamic storage Local referencing environments Nesting of subprogram definitions Overloaded subprograms Generic subprograms • Design issues for functions • Subprograms as parameters • User-defined overloaded operators 1 Subprograms Levels of Control Flow: 1. Among program units (this lecture) – Ch. 9 2. Among program statements – Ch. 8 3. Within expressions – Ch. 7 Two fundamental abstraction facilities 1. Process abstraction – Ch. 9 2. Data abstraction – Ch. 11 2 Fundamentals of Subprograms General characteristics of subprograms: 1. has a single entry point 2. caller is suspended during execution of the called subprogram 3. control always returns to the caller when the called subprogram’s execution terminates Note: 2. does not apply to concurrent programs 3 Definitions • Subprogram – Description of the subprogram's actions • Subprogram call – Explicit request to execute the subprogram • Subprogram header – the 1st part of subprogram's definition: its name, type, and formal parameters • Parameter profile – the number, order, and types of the formal parameters • Subprogram protocol – its parameter profile plus, if it is a function, its return type • Subprogram declaration – its name and its protocol, but not the body • Formal parameter – “dummy” variable listed in the parameter profile and used in the subprogram body • Actual parameter – value or address used in the subprogram call statement 4 Actual/Formal Parameter Correspondence 1. Positional (most common) 2. With keyword – e.g. • SORT(LIST => A, LENGTH => N); – Advantage: order is irrelevant – Disadvantages • user must know the formal parameter’s names • less readable and writeable 3. Default values e.g. procedure SORT(LIST: LIST_TYPE; LENGTH: INTEGER := 100); ... SORT(LIST => A); 5 Subprograms (Functions and Procedures) • • • Formal parameter (names) Actual parameters Passing – – – In Out In/Out Subprogram Result/ Return Value In In/Out Formal parameters In/Out Out Actual Parameters Input/Output Side Effects 6 Design Issues for Subprograms 1. Parameter passing – 2. Type checking of parameters – 3. how strict? Static or dynamic – 4. can subprograms be used? local variable allocation Nesting – 5. can subprogram be defined in another subprogram definition? Referencing environment – 6. what can be accessed within the caller (sub)program? Overloading – 7. is it allowed? Generic – can subprogram be generic? 7 Parameter Passing Methods • How can parameters be transmitted to and/or from the caller and the called subprogram? 1. 2. 3. 4. 5. Pass-by-value (in mode) Pass-by-result (out mode) Pass-by-value-result (in/out mode) Pass-by-reference (in/out mode) Pass-by-name 8 Parameter Passing with Physical Moves (Copy) Caller (sub(a, b, c)) Call 1 a x Return In mode 2 b Callee (void sub (int x, int y, int z)) y Call Out mode c z In/out mode 3 Return 9 Design Choices for Parameter Passing • Efficiency vs. style and reliability • One-way or two-way parameters? – Good programming style • limited access to variables, e.g. one-way whenever possible – Efficiency • pass by reference is the fastest way to pass big structures, however the access is then a bit slower – Note the conflict! – Also style • functions should minimize pass by reference parameters 10 Pass-by-value (In Mode) a. Physical move (copy) – Advantages • No need to write-protect in the called subprogram • Accesses cost lower (no indirect addressing) – Disadvantages • Requires more storage (duplicated space) • Cost of the moves (if the parameter is large) b. Access path (reference) – Advantages & Disadvantages • Opposite of above 11 Pass-by-result (Out Mode) • • No value is transmitted to the subprogram Local’s value is passed back to the caller – • Physical move is usually used Disadvantages: – If value is passed, time and space – Order dependence may be a problem • e.g. procedure sub(y: int, z: int); ... sub(x, x); • Value of x depends on order of assignments in the callee!!! 12 Pass-by-value-result (In/Out Mode) • Combination of pass-by-value and pass-by-result – Also called pass-by-copy • Formal parameters have local storage • Physical move both ways • Advantages/Disadvantages: – Same as for pass-by-result – Same as for pass-by-value 13 Pass-by-Reference (In/Out Mode) • Pass an access path (reference) – Also called pass-by-sharing • Advantage – Efficient - no copying and no duplicated storage • Disadvantages – Slower accesses to formal parameters (than in passby value) – Potential for unwanted side effects – Allows aliasing • See next slide 14 Pass-by-Reference Aliasing • Actual parameter collisions: e.g. procedure sub(a: int, b: int); ... sub(x, x); • Array element collisions: e.g. • sub(a[i], a[j]); /* if i = j */ – Also, • sub2(a, a[i]); /* (different one) */ • Collision between formal parameters and global variables 15 Pass-by-Reference Problems • Root cause – Subprogram has more access to non-locals than necessary – Reference to the memory location allows side effects • Pass-by-value-result solves this – It does not allow these aliases – has other problems 16 Pass-by-Name (In/Out Mode) • By textual substitution • Formal parameters are bound to an access method at the time of the call • Actual binding to a value or address takes place at the time of a reference or assignment • Advantage – Flexibility in late binding • Disadvantages – Reliability: weird semantics 17 Pass-by-name Semantics • If actual is a scalar variable, it is pass-by-reference • If actual is a constant expression, it is pass-by-value • If actual is an array element, it is like nothing else – e.g. procedure sub1(x: int; y: int); begin x := 1; y := 2; x := 2; y := 3; end; sub1(i, a[i]); 18 Multidimensional Arrays as Parameters • If a multidimensional array is passed-byvalue in a separately compiled subprogram • The compiler needs to know the declared size of that array to build the storage mapping function 19 Parameter Passing Methods of Major Languages • Fortran – Always used the in/out semantics model – Before Fortran 77: pass-by-reference – Fortran 77 and later: scalar variables are often passed by value result • C – Pass-by-value – Pass-by-reference is achieved by using pointers as parameters • C++ – A special pointer type called reference type for pass-by-reference • Java – All primitive type parameters are passed by value – Object parameters are passed by reference 20 Parameter Passing Methods in PLs (cont.) • Ada – Three semantics parameter modes – in • can be referenced but not assigned – out • can be assigned but not referenced – in/out • can be referenced and assigned – in is the default mode • C# – Pass-by-value is default – Pass-by-reference • ref must precede both the formal and its actual parameter 21 Parameter Passing Methods in PLs • PHP – very similar to C# • Perl – all actual parameters are implicitly placed in a predefined array named @_ 22 Type Checking of Parameters • Very important for reliability – Which errors are caught by type checking? • FORTRAN 77 and original C – No type checking • Pascal, FORTRAN 90, Java, and Ada – Type checking is always done • ANSI C and C++, Lisp – User can avoid type checking 23 Subprograms As Parameters • Are subprograms allowed as parameters? – if so, are types checked? • Early Pascal and FORTRAN 77 – no • Later versions of Pascal and FORTRAN 90 – yes • C and C++ – pass pointers to functions – parameters can be type checked • Java, Ada, Perl – no 24 Referencing Environments • What is the correct referencing environment of a subprogram that is passed as a parameter? • Possibilities: 1. It is that of the subprogram that declared it • Deep binding • Most natural for static-scoped PLs 2. It is that of the subprogram that enacted it • Shallow binding • Most natural for dynamic-scoped PLs 3. It is that of the subprogram that passed it • Ad hoc binding (Has never been used) 25 Referencing Environments (cont.) Example: function sub1() { var x; function sub2() { alert(x); } function sub3() { var x=3; call sub4(sub2); } function sub4(subx) { var x=4; call subx(); } x=1; call sub3; } • What is the referencing environment of sub2 when it is called in sub4? – – – Shallow binding => sub2 <- sub4 <- sub3 <- sub1 Deep binding => sub2 <- sub1 Ad-hoc binding => sub3 local x [output = 4] [output = 1] [output = 3] 26 Nested Subprogram Definitions • Does the language allow them? • Are there limits on nesting depth? • How are non-local variables handled? – Static scope – Dynamic scope 27 Design Issues Specific to Functions 1. Are side effects allowed? • Two-way parameters • • Ada does not allow them Non-local references • Allowed in all PLs 2. What types of return values are allowed? 28 Return Types of Functions in PLs • FORTRAN, Pascal – • C – • any type (but subprograms are not types) C++ and Java – • any type except functions and arrays Ada – • only simple types like C, but also allow classes to be returned Common Lisp – any type, function, class, object, structure, closure, etc. 29 Accessing Non-local Environments • Non-local variables – variables that are visible but not declared in the subprogram • Global variables – variables that are visible in all subprograms 30 Nonlocal Environments in PL • FORTRAN COMMON blocks – The only way in pre-90 FORTRAN to access nonlocal variables – Can be used to share data or share storage • Static scoping – • discussed already External declarations - C – Subprograms are not nested – Globals are created by external declarations • they are simply defined outside any function – Access is by either implicit or explicit declaration – Declarations give types to externally defined variables • External modules - Ada – More in Chapter 11 • 5. Dynamic Scope – Common Lisp 31 Overloaded Subprograms • Overloaded subprogram – has the same name as another subprogram in the same referencing environment • C++, Java and Ada – have built-in subprogram overloading – users can write their own overloaded subprograms 32 Generic Subprograms • A generic or polymorphic subprogram – takes parameters of different types on different activations, or – executes different code on different activations • Overloaded subprograms offer – ad hoc polymorphism • A subprogram where the type of a parameter is described by a type expression with a generic parameter – parametric polymorphism 33 Generic Subprograms in Ada • Ada – types, subscript ranges, constant values, etc., can be generic in subprograms, packages – e.g. generic type element is private; type vector is array (INTEGER range <>) of element; procedure Generic_Sort (list: in out vector); 34 Generic Subprograms in Ada (cont.) procedure Generic_Sort (list : in out vector) is temp: element; begin for i in list'FIRST.. i'PRED(list'LAST) loop for j in i'SUCC(i)..list'LAST loop if list(i) > list(j) then temp := list(i); list(i) := list(j); list(j) := temp; end if; end loop; -- for j end loop; --for i End Generic_Sort procedure Integer_Sort is new Generic_Sort (element => INTEGER; vector => INTEGER_ARRAY); 35 Generic Subprograms Parameters in Ada • Ada generics can be used for parameters that are subprograms – Note: the generic part is a subprogram • Example: generic with function fun(x: FLOAT) return FLOAT; procedure integrate (from: in FLOAT; to: in FLOAT; result: out FLOAT) is x: FLOAT; begin ... x := fun(from); ... end; integrate_fun is new integrate(fun => my_fun); 36 Parametric Polymorphism in C++ • C++ – Template functions – e.g. template <class Type> Type max(Type first, Type second) { return first > second ? first : second; } 37 C++ Template Functions • Template functions are instantiated implicitly when – the function is named in a call, or – its address is taken with the & operator • Example: template <class Type> void generic_sort(Type list[], int len) { int i, j; Type temp; for (i = 0; i < len - 2; i++) for (j = i + 1; j < len - 1; j++) { if (list[i] > list[j]) { temp = list [i]; list[i] = list[j]; list[j] = temp; } //** end if } //** end for j } //** end for i } //** end of generic_sort … float number_list[100]; generic_sort(number_list, 100); // Implicit instantiation 38 Generics in Java • Java provides generic types – Syntax: • class_name<generic_class {, generic_class}*> e.g.: class MyList<Element> extends ArrayList<Element> {…} e.g.: class MyMap<Key,Value> extends HashMap<Key,Value> {…} – Types substituted when used: e.g.: MyList<String> courses = new MyList<String>(); e.g.: MyMap<String,String> table = new MyMap<String,String>(); • Type-checking works! courses.add("ics313"); // ok courses.add(313); // incorrect, 313 is not String • No casts needed! String course = courses.get(0); //(String)courses.get(0)?? 39 Generics in Java (cont.) • Generic types can be restricted to subclasses class UrlList<Element extends URL> {…} • Generic types can be used in "for-each" clause for (String course : courses) { System.out.println (course.toUpperCase()); } • Generic types are used in standard libraries – Collections: • List, ArrayList, Map, Set • Primitive types can be substituted for generic types class MyList<Element> extends ArrayList<Element> {…} MyList<Integer> numbers = new MyList<Integer>() numbers.add(313); int sum = 0; for (int number : numbers) {sum += number;} 40 Generics in Java: Parameters, Return Type • Generic types can be used – as formal parameters class MyList<Element> extends ArrayList<Element> { int occurences(Element element) { … if (element.equals(this)) sum++; … } } – even as return type class MyList<Element> extends ArrayList<Element> { Element[] toArray() { Element[] array = new Element[this.size()]; … return array; } } 41 Generic Methods in Java • Method can be made depend on a generic type – Generic type precedes method's return type – Generic type can be used to • As the return type • To declare formal parameters • To declare local variables – E.g. <T> T succ(T value, T [] array) { T element = null; ... return element; } • Actual type is inferred from the call Integer [] array = {1, 2, 3, 4, 5, 6}; int successor = succ(3, array); 42