Image goes here
Calling Functions
CptS 355 - Programming Language Design
Washington State University

Parameter Passing

Formal parameters:

   fun f  x = ----- x -----

x, is a formal parameter, which is the name by which the parameter is known inside the function.

   f 3

3 is an actual parameter

Recall ~ when a function is called an activation record (AR) is created. In the AR, there is a slot for each formal parameter.

| return |

|    SL  |

|    DL  |

|     …  |     --- params

| locals |

Pass by value

In pass by value each formal parameter is bound to the evaluated actual

For example, if we have
   function f(x) =
      {x := x+1; return x }
in a language with variables and pass by value

it could be translated to ML, using an ML ref to represent a variable, as

   fun f(z : int)
      = let x = ref z in x := !x+1; !x end

Pass by reference

In pass by reference each formal parameter is bound to the address of the actual parameter which must be a variable.

Suppose we have function

   f(x) =
      { x := x+1; return x }                 in a language with variables and PBR
This would translate to
   fun f(x : int ref) = (x:= !x+1; !x)
in ML. Aliasing: suppose same variable is passed as the actual parameter to 2 formal parameters. Result can be unpredictable.

Pass by name

In pass by name, the actual argument expression is not evaluated until it is used in the called function

Suppose we have function g() and call it as below
   g(x) = return x+7;                               PBName
   g(y)
This would could be translated to ML:
   fun g(th : unit -> int) = (th() + 7)
   g(fn() => y)
The parameter th of g is called a thunk and is called each time the formal parameter is used in the body of the function g.

Pass by name was introduced in Algol 60 and has more-or-less disappeared from modern languages; however, in languages like ML, LISP and Python it is sometimes a useful idiom to know. You can use it to avoid evaluating an expensive expression (even a potentially non-terminating expression) until you know you need its value  (or you know it will terminate).

Pass by need

Pass-by-need is similar to Pass-by-name except the value is only computed once. It is then saved for later use if needed again for the computation.

Pass by Value-result:

In pass-by-value-result a function computes with a local copy as in PBV. But when the function returns the current value of the local  variable is copied back to original actual original variable.

Tail recursion (or more generally tail calls)

Problem: recursive functions consume stack space for ARs with each recursive call.

It is not always necessary for this space to be consumed. We can apply the tail call optimization.

Def: A call to f in the body of g is a tail call if g returns the result of f without any further computation.

   fun g x = if x=0 then (f x) else x*(f x)
                          |            |
                          |            not a tail call
                          tail call

In above example to evaluate the tail call, we could replace the AR for (g 0) with that for
(f 0) instead of pushing a new AR for (f 0) onto the stack. We cannot do the same for the second (non-tail call).

Read section 7.4

(c) 2003 Curtis Dyreson, (c) 2004-2006 Carl H. Hauser           E-mail questions or comments to Prof. Carl Hauser