I just took a quiz for my programming languages class and came across this question:
Assuming call by name, what are the results of following code:
public class MyClass {
static int i = 1;
static float f(int x, int i){
int s = 0;
for(i = 0; i <3; i++){
s = s + x;
}
return s;
}
static void g(){
int[] a= {10,30,50};
int[] b = {20,40,60};
System.out.println(f(i, i));
i = 1;
System.out.println(f(a[i],i));
i = 1;
System.out.println(f((a[i] *b[i]), i));
}
public static void main(String[]args){
g();
}
}
The above code is exactly as presented on my quiz, but it was on paper at the time so I did the calculations manually and got the results 3.0, 90.0, and 3600.0
. After running the code on my own computer, the results are the same as what I calculated.
However, the question was multiple choice and the closest option available was 3.0, 90.0, and 4400.0
. This leads me to assume that the words "Call by name" change how the function f
is called on the line System.out.println(f((a[i] *b[i]), i));
Can someone please explain how 4400.0 is possible in Java or C++?
In call-by-name, the expressions used as arguments are substituted directly in the called function. They are not evaluated before calling the function, but are substituted at each place the parameter occurs in the function.
This means the last call to f
is equivalent to this:
int s = 0;
for(i = 0; i <3; i++){
s = s + (a[i] * b[i]);
}
return s;
Here is the full sequence of steps inside the last call to f
(I hope this is clear):
s = 0
i = 0
s = s + (a[i] * b[i])
= 0 + (a[0] * b[0])
= 0 + (10 * 20)
= 200
i = 1
s = s + (a[i] * b[i])
= 200 + (a[1] * b[1])
= 200 + (30 * 40)
= 200 + 1200
= 1400
i = 2
s = s + (a[i] * b[i])
= 1400 + (a[2] * b[2])
= 1400 + (50 * 60)
= 1400 + 3000
= 4400
So you can see that s
is 4400
when f
returns.