CSE 505 Lecture Notes:

Parameter Passing

October 12, 1994


Introduction

techniques used for argument passing: call by value: copy going into the procedure

call by result: copy going out of the procedure

call by value result: copy going in, and again going out

call by reference: pass a pointer to the actual parameter, and indirect through the pointer

call by name: re-evaluate the actual parameter on every use. For actual parameters that are simple variables, this is the same as call by reference. For actual parameters that are expressions, the expression is re-evaluated on each access. It should be a runtime error to assign into a formal parameter passed by name, if the actual parameter is an expression. Implementation: use anonymous function ("thunk") for call by name expressions

efficiency of call by reference -- large arrays

Fortran uses call by reference
insecurities in early FORTRANs -- passing a constant

Algol 60 has call by name, call by value

Ada uses different designations: IN, OUT, IN OUT:

Lisp and Smalltalk use call-by-value with pointer semantics

An important related concept: aliasing. Two variables are aliased if they refer to the same storage location. A common way that aliasing can arise is using call by reference. A formal parameter can be aliased to a nonlocal variable, or two formal parameters can be aliased.

In a functional programming language, call by value is equivalent to applicative order evaluation. Call by name is equivalent to normal order evaluation. (It always gives the same results as lazy evaluation, but lazy evaluation may be faster.)


Example 1: Call by value and Call by name

begin ! Simula program to demonstrate call by value and call by name; ! (Algol-60 would be similar); integer a,b; integer procedure IncrementByValue (x); integer x; begin x := x+2; IncrementByValue := x; end; integer procedure IncrementByName (x); name x; integer x; begin x := x+2; IncrementByName := x; end; integer procedure AddByValue (x); integer x; begin AddByValue := x+x; end; integer procedure AddByName (x); name x; integer x; begin AddByName := x+x; end; a := 3; b := AddByValue(IncrementByValue(a)); outint(a,5); outint(b,5); outimage; a := 3; b := AddByValue(IncrementByName(a)); outint(a,5); outint(b,5); outimage; a := 3; b := AddByName(IncrementByValue(a)); outint(a,5); outint(b,5); outimage; a := 3; b := AddByName(IncrementByName(a)); outint(a,5); outint(b,5); outimage; end; Output: AddByValue IncrementByValue a=3 b=10 AddByValue IncrementByName a=5 b=10 AddByName IncrementByValue a=3 b=10 AddByName IncrementByName a=7 b=12

Example 2: illustrates call by value, value-result, reference

begin integer n; procedure p(k: integer); begin n := n+1; k := k+4; print(n); end; n := 0; p(n); print(n); end; Note that when using call by reference, n and k are aliased.

Output:

call by value: 1 1 call by value-result: 1 4 call by reference: 5 5

Example 3: Non-local references

procedure clam(n: integer); begin procedure squid; begin print("in procedure squid -- n="); print(n); end; if n<10 then clam(n+1) else squid; end; clam(1); Output: in procedure squid -- n=10

Example 4: Procedures as parameters

To pass a procedure as a parameter, the system passes a closure: a reference to the procedure body along with a pointer to the environment of definition of the procedure. begin procedure test(n: integer, p: procedure); begin procedure rose; begin print("in procedure rose -- n="); print(n); end; print("in procedure test -- n="); print(n); p; if n<10 then begin if n=3 then test(n+1,rose) else test(n+1,p) end end; procedure violet; begin print("in procedure violet"); end; test(1,violet); end; Output: in procedure test -- n=1 in procedure violet in procedure test -- n=2 in procedure violet in procedure test -- n=3 in procedure violet in procedure test -- n=4 in procedure rose -- n=3 in procedure test -- n=5 in procedure rose -- n=3 in procedure test -- n=6 in procedure rose -- n=3 in procedure test -- n=7 in procedure rose -- n=3 in procedure test -- n=8 in procedure rose -- n=3 in procedure test -- n=9 in procedure rose -- n=3 in procedure test -- n=10 in procedure rose -- n=3 Similar effects can be achieved by passing labels as parameters.