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