Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

experts disagree on "call-by-reference"

2 views
Skip to first unread message

(Greg Weeks)

unread,
Jul 30, 2000, 3:00:00 AM7/30/00
to
Lisp, CLU, Java, and Python implement objects, assign objects, and pass
objects to functions similarly. [Although Jave differs regarding its
"primitive" types.] So I was curious about how various Lisp, CLU, and Java
texts dealt with the issue of "references" and "call-by-whatever". I
examined my bookshelf. Some texts used phasing I like; others didn't:

"Lisp" (by Winston and Horn):

The text makes no distinction between objects and references to objects,
and it states that Lisp is call-by-value.

"Common Lisp" (by Steele):

The text makes no distinction between objects and references to objects.
The text implies that objects are addresses: "(eq x y) is true iff x and y
are the same identical object. (Implementationally, x and y are usually eq
iff they address the same identical memory location.)" No mention is made
of call-by-whatever.

Structure and Interpretation of Computer Programs (by Abelson and Sussman):

The text implies that objects are addresses: "In this representation, which
is called box-and-pointer notation, each object is shown as a pointer to a
box". The text then partially reverses itself with: "The box for a pair is
actually a double box, the left part containing (a pointer to) the CAR of
the pair and the right part containing the CDR." For consistency, "(a
pointer to)" should have been omitted. The text states that Lisp is
call-by-value.

CLU Reference Manual (by Liskov and others):

The text doesn't say quite what an object is, but it seems to say that an
object is not an address. It also states that CLU argument passing is not
call-by-value or call-by-reference. but is instead "call-by-sharing".

The Java Language Specification (by Gosling, Joy, and Steele):

The text distinguishes between objects and references. No mention is made
of call-by-whatever.

All of the passages mentioned above could just as well apply to Python.
The experts are in explicit disagreement.

Regards,
Greg

David Goodger

unread,
Jul 30, 2000, 3:00:00 AM7/30/00
to
on 2000-07-30 18:20, Greg Weeks (we...@golden.dtc.hp.com) wrote:
> All of the passages mentioned above could just as well apply to Python.
> The experts are in explicit disagreement.

You're comparing apples with oranges. Of course they're "in disagreement",
because they're describing different things.

In compiled low-level languages, a variable is a symbol representing an
address in memory, and you can have read-write access to that address. For
local variables, the "address in memory" is actually an offset from the top
of the stack. In languages like C, the variable name doesn't survive the
compilation process; it is replaced by the address or stack offset directly.

In some high-level languages, like Python, the variable name survives to
runtime. In Python, a variable is a name in a namespace, implemented as a
dictionary. The name is a dictionary key to what evaluates internally to an
address of some sort (it doesn't matter what sort). For immutable objects,
you *don't* have write access to this address, just to the name itself. So
if you assign to a name/variable, you replace the address with a new one
(and the object at the old address may go away, if no other name is
referring to it). Mutable objects contain referemces of their own. Modifying
a list in-place means inserting, removing, or replacing references with new
ones. The referred-to objects themselves aren't changed in any way.

When passing a name to a function, you are simply assigning the "reference"
to a new name in the function's local namespace. Whatever you could do with
the old name before calling the function, you can do with the new name
inside the function. But the new name doesn't know anything about the old
one; assigning to the new name does *nothing* to the old name. Modifying an
object in-place will of course survive the function as a side-effect, but
the original *name* was not affected in any way.

Terms like "pass by reference" don't really apply to Python in the
traditional sense, because we're dealing with a higher order of
variables/names. (Of course, there are a few gotchas, as with any variable
or parameter passing scheme.) The language takes care of all the
housekeeping, freeing the programmer from having to deal with the details.
Once you understand the process and get over the need to keep track of all
the details, once you stop insisting that Python be explicable in terms of
some other language, once you trust the language to know what it's doing,
Python is very liberating. If you're a micromanaging control freak, then
perhaps Python isn't for you. But if you're willing to delegate the
drudgework, Python is great.

That's what's cool about different programming languages, just as with
natural languages: learning a new language shows you a new way of thinking.
Learning the syntax isn't enough; you have to embrace the deeper meaning.
And trying to apply some other language's semantics to a new language means
you'll speak haltingly, not fluently.

I hope this explanation helps, and I hope that this discussion fizzles out.
Life is too short!

--
David Goodger dgoo...@bigfoot.com Open-source projects:
- The Go Tools Project: http://gotools.sourceforge.net
(more to come!)


Jeremy Hylton

unread,
Jul 30, 2000, 3:00:00 AM7/30/00
to
Here are two other examples that may illuminate Python's parameter
passing mechanism.

The C++ Programming Language (Stroustrup), 3rd ed:

The section of references (5.5, p. 97-100) has a simple example of
parameter passing with references.

void increment(int& aa) { aa++; }

void f()
{
int x = 1;
increment(x); // x = 2
}

There is clearly no feature in Python to accomplish the same thing.
The call-by-reference allows the variable aa in increment to serve as
an alternate name for x in f. A change to aa results in a change to
x.

"A History of Clu" (Liskov) in History of Programming Languages
(Bergin & Gibson, eds.), p. 483-4:

"In fact, CLU procedures do not share variables at all. In addition to
there being no free variables, there is no call-by-reference. Instead
arguments are passed 'by object'; the (pointer to the) object
resulting from evaluating the actual argument expresssion is assigned
to the formal. (Thus pasing a parameter is just doing an assignment to
the formal.) Similarly, a pointer to a result object is returned to
the caller. We have found that ruling out shared variables seems to
make it easier to reason about programs.

A CLU procedure can have side effects only if the argument objects can
be modified (because it cannot access the caller's variables). This
lead to the concept of 'mutable' objects. Every CLU object has a
state. The sate of some objects, such as integers and strings, cannot
change; these objects are 'immutable.' Mutable objects (e.g., records
and arrays) can have a succession of states. [Discussion of whether
CLU should have opted for only immutable objects ala pure Lisp
omitted.]

CLU assignment causes sharing: after executing 'x := y,' variables x
and y both refer to the same object. If this object is immutable,
programs cannot detect the sharing, but they can if the shared object
is mutable, because a modification made via one variable will be
visible via the other one."

Given this extend description of CLU parameter passing, I believe it
would be fair to say that Python is also a call-by-object language.

Jeremy

-- Jeremy Hylton <http://www.python.org/~jeremy/>

Martijn Faassen

unread,
Jul 31, 2000, 3:00:00 AM7/31/00
to
(Greg Weeks) <we...@golden.dtc.hp.com> wrote:
> Lisp, CLU, Java, and Python implement objects, assign objects, and pass
> objects to functions similarly. [Although Jave differs regarding its
> "primitive" types.] So I was curious about how various Lisp, CLU, and Java
> texts dealt with the issue of "references" and "call-by-whatever". I
> examined my bookshelf. Some texts used phasing I like; others didn't:

> "Lisp" (by Winston and Horn):

[snip]
> "Common Lisp" (by Steele):
[snip]


> Structure and Interpretation of Computer Programs (by Abelson and Sussman):

[also Lisp]

Note that if you use Lisp to do functional programming, 'reference' and
'value' loses meaning in practice as all objects are treated as immutable.
Just like in Python the immutable objects behave with 'value' semantics.

> CLU Reference Manual (by Liskov and others):

[snip]

> The Java Language Specification (by Gosling, Joy, and Steele):

> The text distinguishes between objects and references. No mention is made
> of call-by-whatever.

In Java for non-primitive types all variables contain references to objects,
so it's the references that are passed (but no explicit reference taking
happens during the call). This is similar to Python.

> All of the passages mentioned above could just as well apply to Python.
> The experts are in explicit disagreement.

I think it's important to note that 'reference' versus 'value' tends to
becomes an implementation detail if you do pure functional programming.

Regards,

Martijn
--
History of the 20th Century: WW1, WW2, WW3?
No, WWW -- Could we be going in the right direction?

Martijn Faassen

unread,
Jul 31, 2000, 3:00:00 AM7/31/00
to
Jeremy Hylton <jer...@beopen.com> wrote:
> Here are two other examples that may illuminate Python's parameter
> passing mechanism.

> The C++ Programming Language (Stroustrup), 3rd ed:

> The section of references (5.5, p. 97-100) has a simple example of
> parameter passing with references.

> void increment(int& aa) { aa++; }

> void f()
> {
> int x = 1;
> increment(x); // x = 2
> }

> There is clearly no feature in Python to accomplish the same thing.
> The call-by-reference allows the variable aa in increment to serve as
> an alternate name for x in f. A change to aa results in a change to
> x.

I think this example is misleading, as you used an integer, which
is immutable in Python. For mutable variables you can accomplish much
the same thing; the difference with this C++ example is that the underlying
value can be changed directly (integers are mutable in C++!).

Another difference is that in Python, *all* variables behave as if they
were C++ 'references' (or C pointers with implicit dereferencing).

In the C++ example there is a reference-taking going on as soon as the
increment() function is called; in Python no reference needs to be taken
as it's already a reference, always.

> "A History of Clu" (Liskov) in History of Programming Languages
> (Bergin & Gibson, eds.), p. 483-4:

[snip]

> Given this extend description of CLU parameter passing, I believe it
> would be fair to say that Python is also a call-by-object language.

Yes, the description seems near-identical to the way Python works.

I think the confusion arises in the 'call/pass by' part of the expression
'call/pass by reference'. 'call by reference' at least for many seems
to imply that a reference is taken as soon as the call happens
(as in the C++ example, for instance, and I believe also in Perl from
what I've seen). In Python, this never happens; everything is a reference
(to an object) already, so the references are simply passed along.

So you could say that Python has reference semantics, and that references
are the things that always are used and passed. But 'call by reference'
definitely seems to carry unwanted connotations (the taking of a reference),
and 'pass by reference' seems to have this trouble as well (though I'd
say less so). Even so, references are the things that are passed.

If the 'call-by-object' terminology is standard, then I'd agree Python
is call by object. But that doesn't mean talking about references isn't
useful; it would be in CLU too I presume from this description.

Gordon McMillan

unread,
Jul 31, 2000, 3:00:00 AM7/31/00
to
Greg Weeks wrote:

>Lisp, CLU, Java, and Python implement objects, assign objects, and pass
>objects to functions similarly. [Although Jave differs regarding its
>"primitive" types.] So I was curious about how various Lisp, CLU, and
>Java texts dealt with the issue of "references" and "call-by-whatever".

...

Back in '96 or so, I had a knock-down, drag-out fight on c.l.j.? (they call
it a "discussion" there) with a well known Java book author and Sun
employee. He would tell posters "Java is pass by value". I got him to
reform that to: "Java is pass by value: for primitives, it's the value of
the primitive, for references, it's the value of the reference."

I wasn't particularly happy with that either (he should've at least added
"...*not* the referenced object"), but it's technically true, and it should
ring warning bells in the heads of people who have been brainwashed by Herr
Wirth into thinking that "by value" and "by reference" are magical things
the language does for you, without ever stopping to consider how it works.

My experience with these folks is that most of them can grasp what a
pointer is, but less than half ever get "pointer to a pointer".

Pascal-causes-brain-damage-ly y'rs

- Gordon

(Greg Weeks)

unread,
Aug 1, 2000, 3:00:00 AM8/1/00
to
Paul Foley (see@below) wrote:
: Greg Weeks has consistently failed to understand that the meaning he
: wants to apply to the terms "call by value" and "call by reference"
: seems to be somewhat at odds with what everyone else means by those
: terms; I'm sure the authors he quoted wouldn't actually disagree at
: all if you asked them (i.e., I'm quite confident that each and every
: one of them understands what's actually going on)

Of course. We *all* know how the various programming languages behave.
(Well, most of us anyway.) My main point was that what some people call
one thing (eg, "call by reference") is called by others something else (eg,
"call by reference").

: Yes, exactly. "Pass by whatever" has never really applied to
: Lisp-like call semantics, Greg Weeks' protestations about "the old way
: of speaking" notwithstanding.

Again, these are words that you like to use. Winston and Sussman like
different words (eg, that Lisp is call by value). Are you saying that they
are flat-out wrong to use those words?


Greg

Greg Ewing

unread,
Aug 3, 2000, 3:00:00 AM8/3/00
to
Martijn Faassen wrote:
>
> I think the confusion arises in the 'call/pass by' part of the expression
> 'call/pass by reference'.

I think the confusion arises when people say things like
"python uses pass-by-reference" without making it clear
*what* is being passed. To accurately describe Python
parameter passing in Algol terms, you can't just say
"x is passed by reference", because that implies that
a reference the *variable* x is being passed.

Instead, you have to say something like "the object
referred to by x is passed by reference". Or alternatively,
"x is passed by value, and that value is a reference
to an object". Just calling it "pass by reference" or
"pass by value" are both half true and half false.

--
Greg Ewing, Computer Science Dept, University of Canterbury,
Christchurch, New Zealand
To get my email address, please visit my web page:
http://www.cosc.canterbury.ac.nz/~greg

Courageous

unread,
Aug 3, 2000, 3:00:00 AM8/3/00
to

> I think the confusion arises when...

Confusion, I suspect, arises very rarely.

C//

0 new messages