Title: Parameter Passing Ch 18
1Parameter Passing (Ch 18)
formal parameters
int plus (int a, int b) return ab int x
plus(1,2)
function body
actual parameters (arguments)
function call
- How are parameters passed?
- Looks simple enough
- We will see seven techniques
27 methods for passing parameters
By value By result By value-result By
reference By macro expansion By name By need
3Whats wrong?
int sum (int a, int b) int sum sum a
b return sum
int sum (int a, int b) a b return
a
int a, b, c a1 b2 c sum(a,b)
int sum (int a, int b) a b return
a
4Who is who Parameter Correspondence
sum(a,b)
- Which actual parameters go to which formal
parameters? - Most common case positional parameters
- Correspondence determined by positions
- nth formal parameter matched with nth actual
5Keyword Parameters
- Determined by matching parameter names
- Ada
- DIVIDE( DIVIDEND gt X, DIVISOR gt Y)
- DIVIDE( DIVISOR gt Y, DIVIDEND gt X)
- Parameter order is irrelevant here
6Mixed Keyword And Positional
- Most languages that support keyword parameters
allow both - Ada, Fortran, Dylan, Python
- The first parameters in a list can be positional,
and the remainder can be keyword parameters
7Optional Parameters
- Default values formal parameter list includes
default values to be used if the corresponding
actual is missing
int f(int a1, int b2, int c3) body
int xf(), yf(0), zf(0,0), hf(0,0,0)
Same as Overloading
int f() f(1,2,3)int f(int a) f(a,2,3)int
f(int a, int b) f(a,b,3)int f(int a, int b,
int c) body
8Unlimited Parameter Lists
- Some languages allow actual parameter lists of
unbounded length C, C, and scripting languages
like JavaScript, Python, and Perl - Library routines must be used to access the
excess actual parameters - A hole in static type systems, since the types of
the excess parameters cannot be checked at
compile time
int printf(char format, ...) body
9Call By Value
For by-value parameter passing, the formal
parameter is just like a local variable in the
activation record of the called method, with one
important difference it is initialized using the
value of the corresponding actual parameter,
before the called method begins executing.
Or not!
- Simplest method
- Widely used
- The only method in Java!!!!
Java is Pass-By-Value, Dammit!
10int plus(int a, int b) a b return a
void f() int x 3 int y 4 int z
plus(x, y)
f()
plus(3,4)
When plus is starting
11By Result
For by-result parameter passing, the formal
parameter is just like a local variable in the
activation record of the called methodit is
uninitialized. After the called method finished
executing, the final value of the formal
parameter is assigned to the corresponding actual
parameter.
- Also called copy-out
- Actual must have an lvalue
- Introduced in Algol 68 sometimes used for Ada
12void plus(int a, int b, by-result int c) c
ab void f() int x 3 int y 4
int z plus(x, y, z)
f()
plus(3,4,z)
When plus is starting
13void plus(int a, int b, by-result int c) c
ab void f() int x 3 int y 4
int z plus(x, y, z)
f()
plus(3,4,z)
When plus is ready to return
14void plus(int a, int b, by-result int c) c
ab void f() int x 3 int y 4
int z plus(x, y, z)
f()
When plus has returned
15By Value-Result
For passing parameters by value-result, the
formal parameter is just like a local variable in
the activation record of the called method. It
is initialized using the value of the
corresponding actual parameter, before the called
method begins executing. Then, after the called
method finishes executing, the final value of the
formal parameter is assigned to the actual
parameter.
- Also called copy-in/copy-out
- Actual must have an lvalue
16void plus(int a, by-value-result int b) b
avoid f() int x 3 plus(4, x)
f()
plus(4,x)
When plus is starting
17void plus(int a, by-value-result int b) b
avoid f() int x 3 plus(4, x)
f()
plus(4,x)
When plus is ready to return
18void plus(int a, by-value-result int b) b
avoid f() int x 3 plus(4, x)
f()
When plus has returned
19Why call by Value-Result?
f() int x 3 fork check_d(4,
x) check_d(5, x)
check_d(int a, int value-result b) b
....
8
7
20By Reference (address)
For passing parameters by reference, the lvalue
of the actual parameter is computed before the
called method executes. Inside the called
method, that lvalue is used as the lvalue of the
corresponding formal parameter. In effect, the
formal parameter is an alias for the actual
parameteranother name for the same memory
location.
- One of the earliest methods Fortran
- Most efficient for large objects
- Still frequently used
21void plus(int a, by-reference int b) b
avoid f() int x 3 plus(4, x)
Can this be 4?
plus(4,x)
f()
When plus is starting
22void plus(int a, by-reference int b) b
a void f() int x 3 plus(4, x)
plus(4,x)
f()
When plus has made the assignment
23Previous example in C
void plus(int a, int b) b a void f()
int x 3 plus(4, x)
This is call by reference
void plus(int a, int b) b a void f()
int x 3 plus(4, x)
This is call by value
24Will array x be modified?
void F( int a) a1a11...
int x5F(x) ....
?
call by reference
call by value
25Tricky
Will array x be modified?
call by value
void F(int a) a new int10...
int x5F(x) ....
call by value
void F(int a) a new int10...
int x5F(x) ....
This is what java does!!
26Aliasing
- When two expressions have the same lvalue, they
are aliases of each other - Obvious cases
ConsCell x new ConsCell(0,null)ConsCell y x
27Aliasing in call by reference
- Aliases expressions that have the same lvalue
void sigsum(by-reference int n,
by-reference int ans) ans 0 int i 1
while (i lt n) ans i
int f() int x,y x 10 sigsum(x,y)
return y
int g() int x x 10 sigsum(x,x)
return x
28Trouble caused by Alias
void sigsum(by-reference int x,
by-reference int bound) while (x lt bound)
x
int a10 sigsum(a,a)
29By Macro Expansion
- The body of the macro is evaluated in the
callers context. - Each actual parameter is evaluated on every use
in the body (in the callers context).
- Like C macros
- Natural implementation textual substitution
before compiling
30Macro Expansions In C
define MIN(X,Y) ((X)lt(Y)?(X)(Y)) .... ....a
MIN(b,c)
source file
.... .... a ((b)lt(c)?(b)(c))
expanded source
31Preprocessing
- Replace each use of the macro with a copy of the
macro body, with actuals substituted for formals - An old technique, used in assemblers before the
days of high-level languages - It has some odd effects
32A little trouble
define M(X,Y) X 2Y .... ....M(a,bc)
source file
.... .... a 2bc
expanded source
33Repeated Evaluation
- Each actual parameter is re-evaluated upon every
use
define MIN(X,Y) ((X)lt(Y)?(X)(Y)) .....a
MIN(f(b),f(c)) ..... a MIN(b,c)
a ((f(b))lt(f(c))?(f(b))(f(c)))
a ((b)lt(c)?(b)(c))
34Capture, used to be a big problem in logic
T ? ?x?y(xycd)
free variables
capture c
H ? ?c T
H ? ? c?x?y(xycd)
free variable
35Capture in actuals (Bad form)
Most PLs macro expansions do that! Bad!!
g(a) ? ? c?x?y(xyca)
free variable
h ? g(c)
capture
h ? c?x?y(xycc)
36Solution to bad capture Conversion
T(c) ? ?x?y(xycd)
?x?x?y(xyxd)
H ? ?x T(x)
x ? a
Conversion
incorrect
T(c) ? ?a?y(aycd)
H ? ? x?a?y(ayxd)
Most PLs macro expansions dont do that
37Capture in PL
- In a program fragment, any occurrence of a
variable that is not statically bound is free - When a fragment is moved to a different context,
its free variables can become bound - This phenomenon is called capture
- Free variables in the actuals can be captured by
definitions in the macro body - Also, free variables in the macro body can be
captured by definitions in the caller
Bad Logic
38Capture Example
define intswap(X,Y) int tempX XY Ytemp
int main() int temp1, b2
intswap(temp,b)
Source code
Expanded code
int main() int temp1, b2 int temp
temp temp b b temp
x is captured by temp
39By Name (a way to avoid previous bad capture)
Each actual parameter is evaluated in the
callers context on every use of the
corresponding formal parameter.
- Like macro expansion without capture
- Algol 60 and others
- Now unpopular
40Implementing By-Name
- The actual parameter is treated like a little
anonymous function - Whenever the called method needs the value of the
formal (either rvalue or lvalue) it calls the
function to get it - The function must be passed with its nesting
link, so it can be evaluated in the callers
context
41Call by name Example
intswap(by-name int X, by-name int Y) int
tempX XY Ytemp
temp()
int main() int temp1, b2
intswap(temp,b)
b()
Main()
intswap(x, y)
Return Address
Return Address
Previous Activation Record
Previous Activation Record
local variable temp1 b2
local variable temp
temp X
X Y
1
?2
?1
Y temp
42void f(by-name int a, by-name int b) b5
ba int g() int i 3 f(i1,i)
return i
6
5
5
i 5 i i1
i 5 i i1
43Comparison
- Like macro expansion, by-name parameters are
re-evaluated every time they are used - (Can be useful, but more often this is merely
wasteful) - Unlike macro expansion, there is no possibility
of capture.
44By Need
Each actual parameter is evaluated in the
callers context, on the first use of the
corresponding formal parameter. The value of the
actual parameter is then cached, so that
subsequent uses of the corresponding formal
parameter do not cause reevaluation.
- Used in lazy functional languages (Haskell)
- Avoids wasteful recomputations of by-name
45void f(by-need int a, by-need int b) ba
ba void g() int i 3 f(i1,i)
return i
4
3
4
/ a i1 / b a b a
46void f(by-name int a, by-name int b) ba
ba void g() int i 3 f(i1,i)
return i
5
4
5
4
3
5
4
i i1 i i1
47Laziness compute only when necessary
boolean andand(by-need boolean a,
by-need boolean b) if (a) return true else
return b
Compute b only when necessary
void f() andand(sometest(),g())
boolean g() while (true) return true
48Specification Issues
- Are these just implementation techniques, or part
of the language specification? - Depends on the language
- Without side-effects, parameter-passing technique
may be undetectable by the programmer - Even with side-effects, some languages specify
the parameter passing technique only partially
49Without Side Effects
- Still have to ask
- Are parameters always evaluated (eager
evaluation), or only if they are really needed
(lazy evaluation)?
50With Side Effects
- A program can detect which parameter-passing
technique is being used by the language system - But it may be an implementation detail that
programs are not supposed to depend onit may not
be part of the specification of the language.
51Conclusion
- The CS corollary of Murphys Law
Inside every little problem there is a big
problem waiting to get out
52Prolog
Install SWI-Prolog on your machines
http//www.swi-prolog.org/