Issues in Overloading Why is this form of overloading usually disallowed? Though many languages allow It’s because overload resolution overloading, few allow (deciding which definition to overloaded methods to differ use) becomes much harder. only on their result types. Consider (Neither ++ nor Java allow this class MyClass { kind of overloading, though int f(int i, int j) { ... } Ada does). For example, float f(float i, float j) { ... } class MyClass { float f(int i, int j) { ... } int f() { ... } } float f() { ... } in } int a = f( f(1,2), f(3,4) ); is illegal. This is unfortunate; which definitions of f do we methods with the same name use in each of the three calls? and parameters, but different Getting the correctly answer result types, could be used to can be tricky, though solution automatically convert result algorithms do exist. values to the type demanded by the context of call.

© © CS 538 Spring 2008 70 CS 538 Spring 2008 71

Operator Overloading The expression 10+c is illegal because there is no definition Some languages, like C++ and of + for the types int and C#, allow operators to be MyClass&. We can create one by overloaded. You may add new using C++’s friend mechanism definitions to existing to insert a definition into operators, and use them on MyClass that will have access to your own types. For example, MyClass’s private data: class MyClass { class MyClass { int i; int i; public: public: int operator+(int j) { int operator+(int j) { return i+j; } return i+j; } } friend int operator+ (int j, MyClass& v){ MyClass c; return j+v.i; } int i = c+10; } int j = c.operator+(10); MyClass c; int k = 10+c; // Illegal! int k = 10+c; // Now OK!

© © CS 538 Spring 2008 72 CS 538 Spring 2008 73 C++ limits operator overloading Parameter Binding to existing predefined operators. A few languages, like Algol 68 (a Almost all programming successor to Algol 60, developed languages have some notion of in 1968), allow to binding an actual parameter define brand new operators. (provided at the point of call) to a In addition to defining the formal parameter (used in the operator itself, it is also necessary body of a subprogram). to specify the operator’s There are many different, and precedence (which operator is to inequivalent, methods of be applied first) and its parameter binding. Exactly which associativity (does the operator is used depends upon the associate from left to right, or in right to left, or not at all). Given question. this extra detail, it is possible to Parameter Binding Modes include: specify something like • Value: The formal parameter op +++ prec = 8; represents a local variable int op +++(int& i, int& j) { initialized to the value of the return (i++)+(j++); } corresponding actual parameter. (Why is int& used as the parameter type rather than int?)

© © CS 538 Spring 2008 74 CS 538 Spring 2008 75

• Result: The formal parameter • Name: The formal parameter represents a local variable. Its final represents a block of code value, at the point of return, is (sometimes called a thunk) that is copied into the corresponding evaluated to obtain the value or actual parameter. address of the corresponding • Value/Result: A combination of the actual parameter. Each reference to value and results modes. The the formal parameter causes the formal parameter is a local variable thunk to be reevaluated. initialized to the value of the • Readonly (sometimes called Const): corresponding actual parameter. Only reads of the formal parameter The formal’s final value, at the are allowed. Either a copy of the point of return, is copied into the actual parameter’s value, or its corresponding actual parameter. address, may be used. • Reference: The formal parameter is a pointer to the corresponding actual parameter. All references to the formal parameter indirectly access the corresponding actual parameter through the pointer.

© © CS 538 Spring 2008 76 CS 538 Spring 2008 77 What Parameter Modes do Example Programming Languages Use? void p(value int a, reference int b, • C: Value mode except for arrays which pass a pointer to the start of the array. name int c) { a=1; b=2; print(c) • C++: Allows reference as well as value } modes. E.g., int i=3, j=3, k[10][10]; int f(int a, int& b) p(i,j,k[i][j]); • C#: Allows result (out) as well as reference and value modes. E.g., What element of k is printed? int g(int a, out int b) • The assignment to a does not • Java: Scalar types (int, float, char, affect i, since a is a value etc.) are passed by value; objects are parameter. passed by reference (references to objects are passed by value). • The assignment to b does affect j, since b is a reference parameter. • : Reference (even for constants!) • c is a name parameter, so it is evaluated whenever it is used. In • Ada: Value/result, reference, and the print statement k[i][j] is readonly are used. printed. At that point i=3 and j=2, so k[3][2] is printed.

© © CS 538 Spring 2008 78 CS 538 Spring 2008 79

Why are there so Many • Call by value/result allows actual parameters to change, but treats a Different Parameter Modes? call as a single step (assign Parameter modes reflect parameter values, execute the subprogram’s body, update different views on how parameter values). parameters are to be accessed, as well as different degrees of • Call by name delays evaluation of an actual parameter until it is efficiency in accessing and actually needed (which may be using parameters. never). • Call by value protects the actual parameter value. No matter what the subprogram does, the parameter can’t be changed. • Call by reference allows immediate updates to the actual parameter. • Call by readonly protects the actual parameter and emphasizes the “constant” nature of the formal parameter.

© © CS 538 Spring 2008 80 CS 538 Spring 2008 81 Call by Name Consider the conditional expression found in C, C++, Call by name is a special kind and Java: of parameter passing mode. It (cond ? value1 : value2) allows some calls to complete that otherwise would fail. What if we want to implement Consider this as a function call: f(i,j/0) condExpr(cond,value1,value2) { if (cond) Normally, when j/0 is return value1; evaluated, a divide fault else return value2; terminates execution. If j/0 is } passed by name, the division is With most parameter passing delayed until the parameter is modes this implementation needed, which may be never. won’t work! (Why?) Call by name also allows But if value1 and value2 are programmers to create some passed by name, the interesting solutions to hard implementation is correct. programming problems.

© © CS 538 Spring 2008 82 CS 538 Spring 2008 83

Call by Name and Lazy The obvious computation Evaluation infList(int start) { return list(start, Call by name has much of the infList(start+1)); flavor of lazy evaluation. With } lazy evaluation, you don’t doesn’t work. (Why?) compute a value but rather a suspension—a function that will A less obvious implementation, provide a value when called. using suspensions, does work: infList(int start) { This can be useful when we need return list(start, to control how much of a function() { computation is actually return infList(start+1); performed. }); Consider an infinite list of } integers. Mathematically it is Now, whenever we are given an represented as infinite list, we get two things: the 1, 2, 3, ... first integer in the list and a suspension function. When called, How do we compute a data this function will give you the rest structure that represents an of the infinite list (again, one infinite list? more value and another suspension function).

© © CS 538 Spring 2008 84 CS 538 Spring 2008 85 The whole list is there, but only as Eager Parameter Evaluation much as you care to access is actually computed. Sometimes we want parameters evaluated eagerly—as soon as they are known. Consider a sorting routine that breaks an array in half, sorts each half, and then merges together the two sorted halves (this is a merge sort). In outline form it is: sort(inputArray) { ... merge(sort(leftHalf(inputArray)), sort(rightHalf(inputArray)));} This definition lends itself nicely to parallel evaluation: The two halves of an input array can be sorted in parallel. Each of these two halves can

© © CS 538 Spring 2008 86 CS 538 Spring 2008 87

again be split in two, allowing parallel sorting of four quarter- sized arrays, then leading to 8 sorts of 1/8 sized arrays, etc. But, to make this all work, the two parameters to merge must be evaluated eagerly, rather than in sequence.

© CS 538 Spring 2008 88