Pass by reference ?

Quinn Dunkan quinn at auto.ugcs.caltech.edu
Wed Apr 5 22:00:33 CEST 2000


On Wed, 05 Apr 2000 18:21:36 GMT, Robert W. Cunningham <rcunning at acm.org> wrote:
>Jacek Generowicz wrote:
>
>> Michael Hudson wrote:
>>
>> > The code you posted only confuses if you have a flawed understanding of
>> > assignment in Python
>>
>> That is exactly the point. My original confusion arose precisely because I

>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.
>Rather than say "Give up on theory, just learn Python", I'd rather EXTEND (or
>clarify) the theory to account for Python!  Then, I'm certain, I will learn
>Python better and faster.

Hmm, that's funny, because under my understanding of "pass by reference",
python fits it exactly.  And all languages I use except C acts like python
(but C does too if you pass by pointer).  I was initially a bit confused
because most languages I use don't have mutation, but it cleared up pretty
fast.

python:
def pass_by_ref(lst):
    lst[0] = 'baz'
    return lst

def pass_by_ref2(a):
    a = a + 1
    return a

x = []
print pass_by_ref(x)
x = 5
print pass_by_ref2(x)
print x

pseudo-C:
char **pass_by_ref(char **lst)
{
    lst[0] = "baz";
    return lst;
}
char *x[1];
printf("%s\n", *pass_by_ref(x)[0]);

int *pass_by_ref2(int *a)
{
    int a[1];
    *a = *a + 5;
    return a;
}
int x[1] = { 5 };
printf("%d\n", *pass_by_ref2(x));
printf("%d\n", *x);

perl:
sub pass_by_ref {
    my $lst = shift;
    $$lst[0] = "baz";
    return $lst;
}
$x = [];
print @{pass_by_ref($x)}, "\n";

sub pass_by_ref2 {
    my $a = shift;
    $a = \($$a + 1);
    return $a;
}
$x = \5;
print ${pass_by_ref2($x)}, "\n";
print $$x, "\n";  # gah, it's worse than C, how does anyone put up with perl?

As you noticed, the important thing is to realize how python's assignment
differs from C's, and that's simply because python doesn't have declarations,
so it assumes when you say 'foo = bar' you are binding to a *local* name,
unless you explicitly say 'global foo' (python also doesn't have C's confusing
magic pointer decay, but that's different).  How I see it, it has *nothing* to
do with references and everything to do with declarations vs. no declarations.
I think any explanation of the concept to confused C people should focus on
that.  And if you really understand it, you'll know why

a = 5
def kaboom():
    a = a + 1

throws a NameError, which is such a common confusion they changed it to
UnboundLocalError or something like that in 1.6.  It's the same reason:

int a[1] = { 5 };
int *kaboom(void)
{
    int a[1];
    *a = *a + 1;
    return a
}

won't give you what you want (at least I assume it won't, I'm too lazy to
see).

>There is not the "World Of All Other Computing Languages" and "Python" off by
>itself.

Exactly.  Python's behaviour is very standard.  The norm, rather than the
rule, IMHO.



More information about the Python-list mailing list