By value or by reference?
Alex Martelli
aleaxit at yahoo.com
Tue Oct 19 02:38:55 EDT 2004
On 2004 Oct 18, at 22:46, Josiah Carlson wrote:
...
>
> I agree with most everything you have said, though consider the pointer
> vs. value of C to define the semantics of the passing. That is, if you
> get a pointer in C, it is by reference. If you don't get a pointer, it
> is by value.
I disagree: you get the value of the pointer. If you assign to the
barename of the pointer, this has no effect on the caller.
void foo(int* x) {
x = 0;
}
the fact that x is a pointer makes no difference whatsoever: the x=0;
within function foo is just assigning to local variable 'x', without
any effect on the caller, just as if the signature was '(int x)'
instead.
"By reference" semantics, in e.g. Fortran, Visual Basic, Pascal, C++,
..., are normally taken to mean that the function can do:
x = 0;
i.e. assign to the barename of an argument, and thereby affect the
caller. In Fortran (traditionally) it's always that way (the language
definition supports both value/return and reference semantics, with
lots of strictures on what is semantically correct in order to ensure
both mechanisms work; in practice, implementations for the last 30+
years have used references, 99% of Fortran programmers are unaware of
the strictures, and get big surprises when an aggressive optimizer,
taking advantage of the constraints the programmers routinely violate,
turns their code into mush;-). In Pascal, defining an argument in the
signature as "x:integer" or "var x:integer" makes all the difference;
in Visual Basic, the adjectives Byval and Byref do; in C++, the
referencemarker ampersand ('int&x' in the signature); etc.
C has nothing like that. You can explicitly take the address of
something, you can pass (by value!) an address ('pointer'), you can
dereference an address -- and these are the mechanisms you can use to
get PAST the lack of byref parameters. The workarounds in Fortran for
the lack of byval parameters are sometimes even funnier: you see X+0
passed as the actual argument, for example, or sometimes X*1, in the
hope that this will make a copy of X and thereby preserve X from
modification (the interested reader can study the Fortran 66 and 77
manuals to see how this tricks have fared, standardswise... compilers
often are more accomodating than the standards, though in the Fortran
world optimization is SO crucial that this need not be so...).
[[similar tricks in Python are using L[:], L+[], or L*1, to get a copy
of L -- less forgivable in Python where list(L) does that cleanly,
explicitly and legibly, of course;-)]]
>
> I also agree that everything is pure and explicit in both languages, it
> took me a few minutes mucking around with the interpreter my first time
> to understand how Python deals with the base types.
>
> I'm trying to point out that if you toss the standard C semantic
> definition of "pass by value" and "pass by reference", by merely
> pretending that the definitions have not been given in the history of
> computer science, and just look at how Python does actual name binding
> in namespaces/scopes, you can understand what Python does much better
> than to get into a "Python does pass by reference" vs. "Python does
> pass
> by value" argument.
I agree. But in C you cannot possibly do better than "C does pass by
value, and assigns by value [with an unfortunate hack regarding arrays
decaying to pointers]". The concept of passing by reference is needed
in other languages, but not in C (nor Python). "Pass by value"
normally (for most languages) implies a copy: once you realize that
Python doesn't do implicit copies (the +[], *1 and [:] hacks
notwithstanding, those ARE computing expressions after all) then 'pass
by value' is in fact just as applicable to Python -- the difference is
not in how arguments are passed, but in the fact that in Python a
name's value is ALWAYS a reference to an object, so the value (that is
passed) IS the reference (to the object), while in C variables are
little boxes with their value inside, so the value that is passed is a
copy of the box's contents (some of those boxes, known as pointers,
hold addresses...).
Alex
More information about the Python-list
mailing list