Pass by reference ?
Robert W. Cunningham
rcunning at acm.org
Wed Apr 5 19:37:06 EDT 2000
Gordon McMillan wrote:
> Robert W. Cunningham wrote:
>
> > The CS models of "Pass By Reference" and "Pass By Value" are fairly well understood,
> > but they do not seem to map simply and directly to Python.
>
> Grrr. Pascal causes brain damage. Python is exactly like Java
> (with the exception of having no primitive types).
>
> These notions should state *what* is being passed. In Pascal,
> that's "value of a slot" or "reference to a slot". To be precise,
> in Python it is *always* "value of a reference", (think "pointer
> value", not "value of that which is pointed to").
<sigh> Let's go back to CS101 and start with at least a MINIMAL set of
common words, definitions and concepts.
1. Computers contain and operate upon REPRESENTATIONS only.
That is to say, there is no such thing as the "integer number five" in a
computer, only that which we CHOOSE to REPRESENT the VALUE of the purely
math-theoretical notion of "5".
In this case, any pattern of bits of which the lower three have the
value "101" (base 2) with all higher bits being zero is commonly
accepted as a proper representation of the "integer number five" within
a computer.
2. REPRESENTATIONS exist in various forms. (Or, more simply, there is
more than one way to skin a cat.)
If a RAM location or a CPU register or data on a hard disk contains the
bit pattern representing the integer number five (hereafter referred to
by the symbol "5"), we commonly refer to the VALUE of the specific
REPRESENTATION as being 5.
3. Various implementations of various programming languages variously
manipulate various VALUES and their various REPRESENTATIONS in various
ways. (Except when they vary too much.)
In our particular context (the storage and communication of information
within the Python language), some non-trivial representations are
employed to store and communicate values.
Within this context, the PHYSICAL representations themselves are almost
immaterial: They could be changed at will and we'd still have Python.
No matter the word width, no matter the endian-ness, no matter what.
What is more relevant, and more to the point, are the rules used to
manipulate the various representations, and the results of applying
those rules.
In common usage, "Pass By Value" implies that the original value is
copied from it's identified representation within the caller's "space"
into another (possibly similar, but physically different) representation
when passed to a function. The actual "re-representation" is performed
before the called function accesses the item, but the actual action may
be performed within the code space of either the caller or the callee,
and is determined as a language implementation decision. The called
function, however, can still only operate upon the re-representation,
and has no access to the caller's original representation.
"Pass By Reference", as it is normally used, instead implies that the
original representation is not "re-represented" in any way, and that
direct access to that representation is provided to the called function.
This access may be direct or indirect, so long as the final result is
that any change made to the item by the called function is visible to
the caller after the function returns. There are many implementation
strategies for this, including "Copy & Copy Back", "Pointers", etc. The
implementation is often selected to meet other needs within the
language, such as having the ability to pass by reference to functions
across thread or machine boundaries.
Now, what does Python do? First, we must acknowledge that Python
REPRESENTATIONS are significantly more complex than those of C and
Pascal, and have different properties than those of Java or Perl. Which
is to be expected: Python is a different language.
How are specific Python representations passed to functions?
[I am a newbie and this is probably not even correct Python. So correct
my details, but please try to follow my logic.]
Let's pick some representations:
a=5
b=(5)
c=[5]
d={"five":5}
And let's create some functions to manipulate them. In this case I
chose an extremely generic Python function, though I SHOULD choose a
separate function for each representation to illustrate that the
function doesn't matter: The passing does.
def Nuke(w):
print w,
w=None
print w
Let's call each of these functions:
Nuke(a)
Nuke(b)
Nuke(c)
Nuke(d)
Look at the output:
5 None
5 None
[5] None
{"five":5} None
And then look at the original values:
print a,b,c,d
5 5 [5] {"five":5}
None changed! Therefore, representations the functions modified were
DIFFERENT from those passed, though it is clear that the correct VALUE
was passed.
This behavior meets the classical definition of "Pass By Value".
What other tests have I omitted, and what do they yield?
-BobC
More information about the Python-list
mailing list