MCS-287 Notes for 2006-04-10

To make sure everybody understands the differences between the different argument passing mechanisms, it would be valuable for us to write procedures that produce different results depending on whether their arguments are passed by value, by reference, by value-result, or by name. (As an aside, these are often known as "call by value," "call by reference," etc., even though the procedure calling per se is the same in each case; the difference is in the passing of arguments.)

The definition of passing an argument by name needs to be more careful than the one Tucker and Noonan give. If the actual concrete syntax were copied in, lexical scoping would be violated. Consider the following example:

void foo(int x){
  x = x + 1;
}

void main(){
  int a = 10;
  foo(a);
  print(a);
}

Suppose that the call foo(a) passed its argument by name. If this were literally done by substitution, the assignment statement in foo would become a = a + 1;, which isn't legal, because it is outside the scope of a. If foo were changed to have its own local variable a, then the assignment statement would be legal, but it would be changing foo's a, rather than main's. This is not what call-by-name does. All names remain interpreted in their original environment, so that in this case main's a would increase from 10 to 11 before being printed.

As this example illustrates, call-by-name can sometimes seem to be the same as call-by-reference. This has an interesting tie-in with the history of call-by-name. This argument passing technique originated in Algol 60. The original plan of the Algol 60 committee had been for call-by-reference and call-by-value to be the two options, rather than call-by-name and call-by-value. To the very end, some members of the committee preferred call-by-reference, but they were having difficulty formulating a simple, correct specification of it. Other committee members put forward a specification of call-by-name as an alternative, on the last day of the committee meeting. It isn't clear whether everyone understood that what was being suggested was a different parameter passing mechanism, rather than just a different specification of call-by-reference. The proposal was adopted, in the last hour of the last day, but according to Peter Naur, "it seemingly was understood in a coherent manner only by one member, Alan Perlis." ("The European Side of the Last Phase of the Development of Algol 60," in History of Programming Languages, Richard L. Wexelblat, ed., Academic Press, 1991, pp. 111-112.)

To fully understand the example of how pointers are used in C, there are a couple items that might be worth our discussing. You need to understand the difference between

struct Foo {
  int a;
  struct Bar b;
};

struct Bar {
  int c;
  int d;
}

and

struct Foo {
  int a;
  struct Bar *b;
};

struct Bar {
  int c;
  int d;
}

Also, you need to understand that p->x means the same thing as (*p).x; both refer the the field named x within the structure that the pointer p points to.


Course web site: http://www.gustavus.edu/+max/courses/S2006/MCS-287/
Instructor: Max Hailperin <max@gustavus.edu>