|
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 valueIn 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 referenceIn 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 nameIn 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 belowg(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 needPass-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
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 Read section 7.4 |
|