Re: programming concepts > specific languages



In article <Pine.LNX.4.60-041.0511101749070.5375@xxxxxxxxxxxxxxxxxxxxx>,
Arthur J. O'Dwyer <ajo@xxxxxxxxxxxxxxxxxxxxx> wrote:
>
> (It might help to read the last part of this first.)
>
>On Thu, 10 Nov 2005, Oliver Wong wrote:
>>
>> "Arthur J. O'Dwyer" <ajo@xxxxxxxxxxxxxxxxxxxxx> wrote...
>>> On Thu, 10 Nov 2005, Oliver Wong wrote:
>>>> "Gerry Quinn" <gerryq@xxxxxxxxxxxxxxxxxxx> wrote...
>>>>>
>>>>> The claim "Java always passes by value" is trivially true but
>>>>> meaningless. Every ordinary language passes parameters on a stack that
>>>>> contains things that can be called values.
>>>>>
>>>>> When you pass a reference, you are "passing by reference", if the term
>>>>> is to have any meaning at all.
>[...]
>> I'm not very familiar with C++, so I can't comment on the the above,
>> except to say that it seems to me that Gerry Quinn posted up C++ code that
>> does something (I'm calling it "pass by reference"), which you cannot do in
>> Java. Here's my understanding of the semantics of C++. Maybe it's wrong:
>>
>> <C++ code?>
>> void function1() {
>> int i = 5;
>> function2(&i);
>> cout << i;
>> }
>>
>> void function2(int &i) {
>> &i = 10;
>
> The above line has invalid syntax --- it should be 'i = 10;'. This does
>indeed modify the value of 'i' back in 'function1', as well as in
>'function2' --- because both names refer to the same object.
>
>> }
>> </C++ code?>
>
>[... the Java "equivalent"]
>> void function2(MyObject i) {
>> i = new Object(10);
>> }
>> </Java code>
>>
>> Here, the output will again be "5" and not "10".
>
> Right. This is because Java's object model treats assignment differently
>from other operations. If you did the logical thing and modified the
>"value" of 'i' like this:
>
> i.myValue = 10; /* pretend 'myValue' is public in this example */
>
>then you'd see the change back in 'function1', because 'i' /is/ passed
>by reference --- the function call 'function2(i)' passes a reference to
>the object named 'i', rather than its value.
>
> But Java's object model is unintuitive: the assignment 'i.myValue=10'
>changes the original object, but the assignment 'i=new Object(10)'
>actually changes the target of the reference passed to 'function2'.
>C++ disallows changing references in this way --- quite sensibly, I
>think!

I claim that how Java treats non-primitive variables is only
"unintuitive" if (1) you are a C programmer, or (2) you learned
Java from a source that was not precise about terminology.

In C++, if I have a class MyObject and write

MyObject i;

then i is *an instance of the class MyObject*, is it not?
while if I write the same line in Java, i is *a reference that
can point to an instance of MyObject*. No instances of MyObject
are created unless/until one writes something such as

i = new MyObject();

(ignoring for now the ways in which you can create objects with
"reflection", e.g., newInstance() in class Class).

In C++, you could (I believe -- my C++ is more than a little rusty)
get the same effect by writing

MyObject * i;

So, when in Java one writes

i.myValue = 10;

the nearest C++ equivalent is not

i.myValue = 10; (where i is a myObject)

but

i->myValue 10; (where is a pointer to a myObject)

Similarly, when in Java one writes

MyObject i;
MyObject j = new MyObject();
i = j;

the effect is to create one MyObject object, with two references
to it. If you wrote this is C++, exactly what would happen would
depend on whether MyObject had overloaded the "=" operator and how.
Now *that* is a potential source of confusion, IMO, though it does
provide some flexibility Java lacks. To get the same effect as
the above lines in Java, in C++, you would write

MyObject *i;
MyObject *j = new MyObject();
i = j;

(Or so I think -- rusty C++, as I said.)

Anyway. So if you are a C++ programmer, I can understand why
the way things work in Java might seem odd and unintuitive.

People who come to Java without a background in C++ to possibly
lead them astray .... I think some confusion may result from
the fact that people are apt to say that the variable i above
"is a MyObject", when it would be more correct to say that i
"is a reference to a MyObject".

The distinction is, IMO, critical. Once you start viewing Java in
terms of "all variables of non-primitive types are *references to
objects* (not objects themselves)", then everything starts to seem
consistent and reasonable. Well, that was my experience anyway.
I guess YMMV.

>
>> In fact, short of using reflection, there is nothing function2
>> can do to change the fact that function1 is going to print out 5.
>
> Yes, I believe we all agree on that point. It's just that I claim
>that that fact is counterintuitive and indicative of bad language design,
>while you claim it's consistent and (presumably) indicative of good
>language design.
>

Another vote here for "consistent, once you understand how things
work".

As for "counterintuitive" -- I would claim that what "intuitive"
means depends on a lot on one's background. GUIs are said to be
very intuitive, but I still remember how baffling I found Windows
at first, after many years working in mostly-CLI environments.
Eventually I sorted out enough of the basic ideas to get past some
of my initial misconceptions, but it took some, um, interesting
learning experiences.

>
>>> I (mostly) agree with Gerry: Java's pointer model is inconsistent,
>>> because some things (ints, doubles) behave one way, and some things
>>> (objects) behave another. And apparently some things (Strings) behave
>>> a third way; I hadn't known that before.
>>
>> Strings DO behave differently from other types of objects which behave
>> differently from primitives. It would be quite a useless class library if
>> every object in it behaved in exactly the same way! But the way in which
>> they are passed between method calls follows the exact same rule: everything
>> (whether it be a primitive or a reference to an object) is passed by value.
>
> I must have misunderstood what Gerry said earlier, then.
>

It's possible, too, that Gerry was confused. I think he's wrong
about under-the-hood copying when one passes immutable objects,
for example.

>
>
>>> Certainly it's not sensible to say Java "passes by value," except
>>> for ints, doubles, and other primitive types. Objects in Java are passed
>>> by reference, but with unintuitive semantics with respect to assignment.
>>
>> You lost me here. I thought primitive types in particular behave in the
>> way that C++ programmers would readily call "pass by value".
>
> Yes. Java passes primitive types by value, and objects by reference.
>That is, 'f(i)' passes a new copy of the value of 'i' if 'i' is a
>primitive, but it passes a reference to 'i' itself if 'i' is an object.
>

Well -- no. Java has no ability to pass objects at all. What it
does have is the ability to pass *references to objects*. So f(i)
passes a new copy of i -- whether i is a primitive type or a reference
type. "What if i is neither one? What if it's an object?" AFAIK,
not possible in Java. This may be the critical point.

>
>> I'm starting to realize we have a terminology problem here. There are 4
>> ways I can see Objects being passed from one method to another:
>>
>> 1) The objects themselves are passed by value.
>> 2) The objects themselves are passed by reference.
>> 3) The reference to the objects are passed by value.
>> 4) The reference to the objects are passed by reference.
>>
>> Add to this, 2 ways in which primitive types can be passed from one
>> method to another:
>>
>> 5) The value of the primitive is passed (I call this "pass by value".)
>> 6) A reference to the primitive is passed (I call this "pass by
>> reference".)
>>
>> I think we are in agreement with the terminology for passing primitives.
>>
>> I believe that 2 and 3 are essentially indistinguishable in their end
>> result. I claim that Java does 3 and 5, both of which I call "passing by
>> value". You claim that Java does 2 and 5, thus sometimes passing by
>> reference, sometimes passing by value.
>
> Okay, using this terminology, I agree that Java does 3 and 5, but since
>3 involves silently passing a reference, I call it "pass-by-reference."
>Therefore Java sometimes passes by reference, and sometimes by value.

Only if you think a variable in Java can be an object. But it can't.

>
> The "weirdness" of Java's handling of assignment comes from the fact
>that it does 3 and not 2. C++ does 2, so that
>
> foo.value = 42;
>and
> foo = 42;
>
>behave the same way (both modify the original 'foo' in some way). Java
>does 3, so that the two lines produce radically different effects.
>I call this a bad thing.
>

Only if you think C++ and Java should behave the same way.

C++ allows variables to *be* objects, and to *point to* objects.
Java only allows variables to *point to* objects, and it calls
such variables "references" rather than "pointers", perhaps so
people understand that they aren't exactly like C/C++ pointers.
But in some respects they're similar, since in both cases there's
a distinction between the pointer (reference) and the object it
points to.

Maybe it would have been clearer if Java referenced fields and
methods with the "->" operator rather than the "." operator, since
then I think things might be less confusing for C++ programmers.
Maybe if the designers of Java had foreseen this confusion ....?
Or maybe not. <shrug>

--
| B. L. Massingill
| ObDisclaimer: I don't speak for my employers; they return the favor.
.



Relevant Pages

  • Re: newbie lost in strings......
    ... When you do int i = 0; you're declaring a variable i that holds the integer ... holds a reference to an Integer object which holds the integer value 0. ... In some cases, the variable is one of the primitive types (byte, char, int, ... The reason Java includes ...
    (comp.lang.java.help)
  • Re: newbie lost in strings......
    ... not the Java sense) is usually an 8 bit ... > holds a reference to an Integer object which holds the integer value 0. ... > In some cases, the variable is one of the primitive types (byte, char, int, ... > i" both declare variables. ...
    (comp.lang.java.help)
  • Re: How do i get a reference count of a object in java ?
    ... How do i get a reference count of a object in java? ... Suppose i have a Object called MyObject .. ... ref = MyObject.getReference; ...
    (comp.lang.java.programmer)
  • Re: Separation of gui and business layer: Duplication of data necessary?
    ... > reference (except for primitive types), ... This semms to be true but the other things are "by reference". ... > using Java you have 650MB. ...
    (comp.object)
  • Re: Pass by reference / pass by value
    ... > - All parameters in Java are passed by value. ... > - Parameters may be either references or primitive types. ... you must pass a reference that ... > Chris Smith - Lead Software Developer/Technical Trainer ...
    (comp.lang.java.programmer)