Call By Value and Call By Reference
Beginning programmers can skip this section. This is a digression
for experienced C and C++ programmers.
Most programming languages have a formal mechanism for determining
if a parameter receives a copy of the argument (call by
value) or a reference to the argument object (call
by name or call by reference). The
distinction is important because programming languages like C++ allow us
to provide a reference to a global variable as input to a function and
have that global variable updated by the function without an obvious
assignment statement.
The following scenario is entirely hypothetical for Python
programmers, but a very real problem for C and C++ programmers. Imagine we
have a function to2, with this kind of definition in
C.
int to2( int *a ) {
/* set parameter a's value to 2 */
*a= 2;
return 0;
}
This function changes the value of the variable a
to 2. This would be termed a side-effect because it
is in addition to any value the function might return normally.
When we do the following in C
int x= 27;
int z= to2( &x );
printf( "x=%i, z=%i", x, z );
We get the unpleasant side-effect that our function
to2 has changed the argument variable,
x, and the variable wasn't in an
assignment
statement! We merely called a function,
using x as an argument. In C, the
&
operator is a hint that a variable might be
changed. Further, the function definition
should
contain the keyword
const
when the reference is
properly read-only. However, these are burdens placed on the programmer to
assure that the program compiles correctly.
Python does not permit this kind of call-by-reference problem in the
first place. The arguments to a function are always references to the
original underlying object, not the variable. In the Python version of the
above example, the variable x is a reference to an
integer object with a value of 27. The parameter variable in the
to2 function is a copy of the reference, and it is
local to the function's scope. The original variable,
x, cannot be changed by the function, and the original
argument object, the integer 27, is immutable, and can't be changed
either.
If an argument value is a mutable object, the parameter is a
reference to that object, and the function has access to methods of that
object. The methods of the object can be called, but the original object
cannot be replaced with a new object.
Programmers intimate with the implementation details behind C know
that manipulating a copy of a value directly can be far more efficient
than working through references. This is true only when the language has
some high-performance data types that would benefit from call by value
processing. Unlike C or Java, Python has no data types that benefit from
this kind of special case handling. All data elements are passed by
reference in a simple, uniform manner.
It also means that, in general, all variable updates must be done
explicitly via an
assignment
statement. This makes
variable changes clear.