no pointer in Java => my problem

R

Roedy Green

I get annoyed when people complain that Java (or any language in fact)
doesn't support the same programming paradigm as another language.

Java won't let you get away with kludges and cheats. In the long run
though, this is a good sacrifice. If I can't to it, nobody else can
either.

Of course *I* would never abuse this, but others would, so I am far
better off being mildly frustrated every once in while, in return for
dealing with much more tractable code from others.

My attitude now is, computers should be doing the housekeeping not
people. Instead of going back to more manual approaches like C++, we
should be going forward to more abstract and automatic approaches
where less and less detail is specified explicitly.

My biggest headache is the sheer volume of code I have to read to
understand somebody else's program just to change one line.
 
R

Roedy Green

A real world analogy would be if I had a piece of paper with an address
of a house on it and someone copied that address onto another piece of
paper that you received.

To us, this is deceptively simple. I wrote a crazy analogy about
references and objects, with every quirk in the story having a mapping
to something about Java objects and references. It is utterly
bizarre. It is far more complicated than it feels once you understand
it. The story does not really help you understand objects that well,
but it may make you more patient with newbies.


see http://mindprod.com/jgloss/reference.html
 
D

Dale King

Timo Kinnunen said:
Please, let me help:

A real world analogy would be if I had a piece of paper with an address
of a house on it and someone copied that address onto another piece of
paper that you received. That piece of paper is not the house at that
address it is only an lvalue to that house. There could of course be
several pieces of paper with that address on it. You could then go to
that house and modify it by painting it blue, but that does not change
the piece of paper you received. If the address isn't written in ink, you
could change the address on your paper, but that does not change the
address on my paper. You cannot change my paper, since we assume that you
don't even know where my paper is or really even the existance of my
paper. That is pass by reference. You received the lvalue on my paper.

Except that is not pass by reference, that is pass by value where the value
passed is a reference.

Pass by reference would be more like where the papers were magic papers that
were linked together. The piece of papers are linked so that what you see on
one is also what you see on the other. If either of us changes what is
written on the paper it is also seen on the other piece of magical paper.
And even weirder is that you can make magical copies of the paper that are
also linked with the other copies. There is nothing in the real world that
works like that so thus it is hard to come up with an analogy.

That is part of what is evil about pass by reference. You essentially give
control of your variables over to the method you are calling. It can do with
it whatever it wants. It could save the reference and change it hours later
if it wanted. Pass by value puts more of a wall between your code and the
code you call. If you want to change your variables then you have to do it
when the method returns.
 
T

Timo Kinnunen

Except that is not pass by reference, that is pass by value where the value
passed is a reference.

You said it.
Pass by reference would be more like where the papers were magic papers that
were linked together. The piece of papers are linked so that what you see on
one is also what you see on the other. If either of us changes what is
written on the paper it is also seen on the other piece of magical paper.
And even weirder is that you can make magical copies of the paper that are
also linked with the other copies. There is nothing in the real world that
works like that so thus it is hard to come up with an analogy.

You have got to be kidding me.

Pass-by-reference is really simple. In pass-by-value you emphasize the
paper and all but ignore the house whose address is on that paper. In
pass-by-reference, you emphasize the house and ignore the paper. In
pass-by-reference, you are a house-painter, you couldn't care less if you
were using PDAs or rock tablets or even your memory. Whether you use a PDA
or a paper has no effect whatsoever on the house, because once you are at
the house you can just start painting.
That is part of what is evil about pass by reference. You essentially give
control of your variables over to the method you are calling. It can do with
it whatever it wants. It could save the reference and change it hours later
if it wanted. Pass by value puts more of a wall between your code and the
code you call. If you want to change your variables then you have to do it
when the method returns.

I hope you're not suggesting that Java is a safer language because it
doesn't have pass-by-reference. Item 24: Make defensive copies when needed
in Joshua Bloch's Effective Java applies equally well whether you are
passing a Date object by reference in C++ or a reference to a Date object
by value in Java.
 
C

Chris Smith

Timo said:
Pass-by-reference is really simple. In pass-by-value you emphasize the
paper and all but ignore the house whose address is on that paper. In
pass-by-reference, you emphasize the house and ignore the paper.

And yet, it's more than that. Pass-by-reference isn't just a lack of
emphasis on the paper, but in fact would make it impossible to refer to
the paper directly. (This is assuming we're passing the house by
reference; Dale's comments apply instead if you're passing the paper by
reference.) Since there are, in Java, operators that directly modify a
formal parameter of a method even when it is a reference, Java doesn't
fit the model of passing objects by reference.

In fact, practically every time someone shows up on a newsgroup to say
that they don't understand why their code isn't working since someone
told them that Java passes objects by reference, it's exactly this; they
are accidentally modifying a reference parameter directly; something
that they've been misled to believe is impossible by the prevalent myth
that Java passes objects by reference.
I hope you're not suggesting that Java is a safer language because it
doesn't have pass-by-reference. Item 24: Make defensive copies when needed
in Joshua Bloch's Effective Java applies equally well whether you are
passing a Date object by reference in C++ or a reference to a Date object
by value in Java.

I would suggest that Java is a safer language due to the lack of pass-
by-reference. Certainly you need to know the language semantics first
(for example, that only references can be directly expressed in Java and
therefore passed as parameters), but once you do, you've got a good idea
of what an API can do. Specifically, it can't modify the value of any
of your actual parameters that you pass to it. That's not true in C++,
and the client has no clear indication of when a method is going to
modify its actual parameters or not.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
D

Dale King

Timo Kinnunen said:
You said it.


You have got to be kidding me.

Not at all, you simply don't understand.
Pass-by-reference is really simple. In pass-by-value you emphasize the
paper and all but ignore the house whose address is on that paper. In
pass-by-reference, you emphasize the house and ignore the paper.

It doesn't make sense to try to contrast something unless you can show how
they differ. To do that we have to have the commonality of what is being
passed. It doesn't make it any clearer to compare passing a paper containing
a reference be value with passing a house by reference. To make a clear
analogy you have to pick something and show what it means to pass that thing
by value and to pass that same thing by reference. But as I said there are
no real world analogies that work that way.

Talking about passing houses by reference is a very weak analogy since we
are talking about variables and variables are something that have values
that can be changed. A house doesn't fit that analogy.
In
pass-by-reference, you are a house-painter, you couldn't care less if you
were using PDAs or rock tablets or even your memory. Whether you use a PDA
or a paper has no effect whatsoever on the house, because once you are at
the house you can just start painting.

No you still don't have a grasp of the concept. Pass by reference implies
that I give you something and I still have something yet they are in reality
the same thing. It appears to both of us that we each have something. Your
analogy is that we each have something that refers us to a common thing.
Under the hood that is basically what occurs, but we are talking about
language semantics not what happens at the assembler level. The whole
purpose of definining semantics like PBR and PBV is to provide an abstract
framework for making meaningful comparisons.
I hope you're not suggesting that Java is a safer language because it
doesn't have pass-by-reference.

Yes, I am. The key part of the is that it is the r at the end. It is safer,
not necessarily completely safe.
Item 24: Make defensive copies when needed
in Joshua Bloch's Effective Java applies equally well whether you are
passing a Date object by reference in C++ or a reference to a Date object
by value in Java.

Yes it does. So while you need to do that in Java sometimes, you essentially
would have to it *all* the time in C++. I didn't say that Java eliminated
all concepts of references nor that it should. You do need the concept of
passing references, but Java is safer because you can only pass references
to objects. With objects you have greater control over the interaction than
with pointers to raw data. You can have much more readable semantics to the
interaction as well.
 
L

Lasse Reichstein Nielsen

Dale King said:
It doesn't make sense to try to contrast something unless you can show how
they differ. To do that we have to have the commonality of what is being
passed. It doesn't make it any clearer to compare passing a paper containing
a reference be value with passing a house by reference. To make a clear
analogy you have to pick something and show what it means to pass that thing
by value and to pass that same thing by reference. But as I said there are
no real world analogies that work that way.

I'd say houses and adresses work fine.

You can't pass an object by value. It simply makes no sense. Just like
a house.
House : object
Address : reference
Talking about passing houses by reference is a very weak analogy since we
are talking about variables and variables are something that have values
that can be changed. A house doesn't fit that analogy.

But you can erase the paper and write another reference there. It's
the same paper, but with a different "value" on it.
Paper : variable
(and here the analogy breaks down, because in Java, a reference does
not allow pointer arithmetic. You can't keep the street of the address
and change the number, the reference is atomic and must be written or
erased completely).
No you still don't have a grasp of the concept. Pass by reference implies
that I give you something and I still have something yet they are in reality
the same thing.

I have a piece of paper with an address on it. I copy it to another
piece of paper. I still have the address, and it's the same address,
referencing the same house. It's just on a different piece of paper.

You can then use the address to send a letter, a message, to the
residents of the house, and you can keep doing that as long as you
have the address.
It appears to both of us that we each have something. Your
analogy is that we each have something that refers us to a common thing.

I'll agree to that.
Under the hood that is basically what occurs, but we are talking about
language semantics not what happens at the assembler level. The whole
purpose of definining semantics like PBR and PBV is to provide an abstract
framework for making meaningful comparisons.

At the assmbler level, you are moving bits. That is not what is happening
here.
With objects you have greater control over the interaction than
with pointers to raw data. You can have much more readable semantics to the
interaction as well.

And that I agree with completely.

/L
 
T

Timo Kinnunen

And yet, it's more than that. Pass-by-reference isn't just a lack of
emphasis on the paper, but in fact would make it impossible to refer to
the paper directly. (This is assuming we're passing the house by
reference; Dale's comments apply instead if you're passing the paper by
reference.) Since there are, in Java, operators that directly modify a
formal parameter of a method even when it is a reference, Java doesn't
fit the model of passing objects by reference.

Well, the few C++ FAQs that I googled have something akin to "How can you
reseat a reference to make it refer to a different object?", so the concept
is there, even if the language doesn't allow it. It is conceivable that a
keyword or new syntax to do that could be added if it garnered enough
support. If it were added, would it mean C++ no longer can pass by
reference?
In fact, practically every time someone shows up on a newsgroup to say
that they don't understand why their code isn't working since someone
told them that Java passes objects by reference, it's exactly this; they
are accidentally modifying a reference parameter directly; something
that they've been misled to believe is impossible by the prevalent myth
that Java passes objects by reference.

That's the second part of the problem. The first part is that they are
relying on = to call an object's assignment operator, which is totally
foreign to Java. If only one of the parts was present, they propably
wouldn't have any problems, because they wouldn't be able compile their
code. It's only the combination, which is problematic. This suggests two
ways to attack the problem: either tell them to notice operator overloading
and not to try to do it in Java or to make all their reference variables
final to simulate nonreseatability.
I would suggest that Java is a safer language due to the lack of pass-
by-reference. Certainly you need to know the language semantics first
(for example, that only references can be directly expressed in Java and
therefore passed as parameters), but once you do, you've got a good idea
of what an API can do. Specifically, it can't modify the value of any
of your actual parameters that you pass to it. That's not true in C++,
and the client has no clear indication of when a method is going to
modify its actual parameters or not.

Passing a reference to non-const versus a reference to const versus a copy
of the value should be a clear indication. You can't reseat a reference
anywhere in C++ anymore than you can change a reference variable in the
caller's stackframe in Java. It comes down APIs that the methods work with.
An int has modifiable and unmodifiable APIs in C++, but that's quite easy
to forget.
 
B

Bryan Castillo

Roedy Green said:
Java won't let you get away with kludges and cheats. In the long run
though, this is a good sacrifice. If I can't to it, nobody else can
either.

It won't? Can java keep a design from being a kludge? I've seen
terrible java kludges and cheats. Usually its a programmer who
doesn't understand what they are working with. I had to debug
someones code where they tried to write a class that could to
asynchronous LDAP operations using a singleton class extending a
thread. They used a static variable to hold a reference to the object
which would receive the newly connected LDAP object, and they forgot
to synchronize the object! What they really wanted was to make sure
it wouldn't take too long to try and connect to the LDAP server, they
were using the Netscape LDAP SDK at the time (quite a few years back).
If they had read the API they would have realized that there were
parameters for setting timeout values for the underlying socket
connection and they wouldn't have had to use a poorly designed thread
class at all.

Programmers will find ways to kludge and cheat in any language. Java
helps encourages people not to use kludges or cheats, however I've
found that the use of JUnit has had more of a significant impact on
reducing kludges and cheats than just the use of Java over C/C++.
 
R

Roedy Green

It won't? Can java keep a design from being a kludge?

No, but it discourages all kinds of common hacks you see in C++. I
gently pushes you to write code in a straightforward way.

Even the worst Java program is easier to understand than an average
C++ one.
 
S

Stanimir Stamenkov

/Roedy Green/:
did you do these by hand, or have you some clever newsreader that
sorts out nested attributions?

Seems like he has posted through Google, so most probably he did
them by hand.
 
C

Chris Smith

Bryan said:
I disagree with the statement from
Chris that java can not modify the value actually passed to it.
Consider the following code:
[...]

Do you have any indication of whether or not the ArrayList will be
modified? Here is the output of me running this program.

You're missing the point. The ArrayList object is not the parameter.
Because it's an object, it can never be a parameter in Java. Yes, you
can use the parameter (which is a reference) to get to some common
shared data, but you still can't modify the parameter.

That may sound picky... but we are talking about language semantics,
after all. It's also important, though, because when I pass an object
that can only be modified through methods, I can know precisely what I
do and don't expect to occur with that object, because it's documented
in the API of the object itself. C++, on the other hand, provides a
single const modifier (which is very helpful and covers most common
cases), but otherwise allows any change to a pass-by-reference
parameter.

Aside from that, a C++ pas-by-reference parameter looks identical to
passing by value, which is its own problem; I don't have an indication
that I'm passing by reference at all, hence I may not expect any change.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
C

Chris Smith

Timo said:
Well, the few C++ FAQs that I googled have something akin to "How can you
reseat a reference to make it refer to a different object?", so the concept
is there, even if the language doesn't allow it. It is conceivable that a
keyword or new syntax to do that could be added if it garnered enough
support. If it were added, would it mean C++ no longer can pass by
reference?

Okay, so I was oversimplifying. The actual definition (which is, I
admit, a bit arbitrary... but is the definition nonetheless) has to do
with the assignment operator. In C++, under the current spec, this
operator acts on the referent in pass-by-reference; not on the
reference. That makes it pass-by-reference, because the lvalue of the
actual parameter is the lvalue of the formal parameter. If a way to
"reseat" a reference were added that did not involve the assignment
operator, then it would be a bastardized pass-by-reference. If the
operation of assignment on reference parameters were changed, then C++
may no longer provide pass-by-reference at all.
Passing a reference to non-const versus a reference to const versus a copy
of the value should be a clear indication. You can't reseat a reference
anywhere in C++ anymore than you can change a reference variable in the
caller's stackframe in Java. It comes down APIs that the methods work with.
An int has modifiable and unmodifiable APIs in C++, but that's quite easy
to forget.

That is, indeed, a way to solve a lot of this problem (though not as
flexible as providing the ability to control the operations on an object
more completely via objects). If you know that you're passing by
reference, it gets you safety. So, I suppose, I really should have said
that hidden pass-by-reference like what exists in C++ is inherently
dangerous. If you know that you're passing by reference, it's less so
with appropriate use of the const modifier.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
B

Bryan Castillo

Chris Smith said:
Bryan said:
I disagree with the statement from
Chris that java can not modify the value actually passed to it.
Consider the following code:
[...]

Do you have any indication of whether or not the ArrayList will be
modified? Here is the output of me running this program.

You're missing the point. The ArrayList object is not the parameter.
Because it's an object, it can never be a parameter in Java. Yes, you
can use the parameter (which is a reference) to get to some common
shared data, but you still can't modify the parameter.

That may sound picky... but we are talking about language semantics,
after all. It's also important, though, because when I pass an object
that can only be modified through methods, I can know precisely what I
do and don't expect to occur with that object, because it's documented
in the API of the object itself. C++, on the other hand, provides a
single const modifier (which is very helpful and covers most common
cases), but otherwise allows any change to a pass-by-reference
parameter.

Its not just picky, its a technicality. To me the ArrayList is the
parameter. Yes you can seperate the concept of an object and its
reference but can you actually use an object without its reference in
java? There is only one way to access the Object and that is through
its reference, to me the reference is the Object. When we start
saying things like "no you aren't really passing something that can be
modified because the thing your passing isn't really the thing your
interested in, its the indirect reference to it", we end up confusing
people.

If we get picky, you can't really modify the parameter passed in C++
either, because you are really only passing the Address of something
not the thing itself. But you will say "Wait, in C++ we have
references thats different". Not really, it will probably be
implemented the same as though you passed an address. To illustrate
this point. Here are 2 C++ files that I output the assembly for. The
assembly is exactly the same, except for a directive saying the name
of the source file.


tuxedo@jabba:/tuxedo/bryanc/testc>cat test1.cpp

extern "C" void modify (int * i) {
*i=0;
}
tuxedo@jabba:/tuxedo/bryanc/testc>cat test2.cpp
extern "C" void modify (int & i) {
i=0;
}
tuxedo@jabba:/tuxedo/bryanc/testc>gcc -S -c *.cpp
tuxedo@jabba:/tuxedo/bryanc/testc>diff test1.s test2.s
1c1
< .file "test1.cpp"
---
.file "test2.cpp"

Ok, now you can say but it is different because of language semantics.
Well the language semantics of java seem exactly the same to me as
passing a reference in C++. If you say that you aren't really passing
some that can be modified in java because its a reference than you
should also say the same about references in C++.
 
D

Dale King

Lasse Reichstein Nielsen said:
I'd say houses and adresses work fine.

You can't pass an object by value. It simply makes no sense. Just like
a house.

Says who? You can't pass an object by value in Java (you can't pass an
object at all in Java). But in C++ you can pass objects by value or by
reference. So in the world of programming langauages passing an object by
value does make sense.
House : object
Address : reference

That was what I was going for with the addition of

Paper : reference variable
But you can erase the paper and write another reference there. It's
the same paper, but with a different "value" on it.
Paper : variable

Exactly why I used it in the analogy.
(and here the analogy breaks down, because in Java, a reference does
not allow pointer arithmetic. You can't keep the street of the address
and change the number, the reference is atomic and must be written or
erased completely).

It is just an analogy. The important point is that the adress on the paper
can be changed. In the real world the address does not have to exist. In
Java it is required that the adress on the paper is always a real address.
This was not a characteristic important to the analogy. So the analogy is
not a perfect analogy, but I wouldn't say it breaks down.
I have a piece of paper with an address on it. I copy it to another
piece of paper. I still have the address, and it's the same address,
referencing the same house. It's just on a different piece of paper.

And that is pass by value if we stick with the Paper representing a variable
and the address being the value of the variable.
You can then use the address to send a letter, a message, to the
residents of the house, and you can keep doing that as long as you
have the address.

But it is still not pass-by-reference.
 
D

Dale King

Bryan Castillo said:
Chris Smith <[email protected]> wrote in message
Bryan said:
I disagree with the statement from
Chris that java can not modify the value actually passed to it.
Consider the following code:
[...]

Do you have any indication of whether or not the ArrayList will be
modified? Here is the output of me running this program.

You're missing the point. The ArrayList object is not the parameter.
Because it's an object, it can never be a parameter in Java. Yes, you
can use the parameter (which is a reference) to get to some common
shared data, but you still can't modify the parameter.

That may sound picky... but we are talking about language semantics,
after all. It's also important, though, because when I pass an object
that can only be modified through methods,

You mean when you pass the value of a a reference to an object... ;-)
Its not just picky, its a technicality.

And pass by reference is a very technical term so requires a technically
precise definition.
To me the ArrayList is the parameter.

It may be to you, but technically it is not. The parameter in your example
is the expression "list".
Yes you can seperate the concept of an object and its
reference but can you actually use an object without its reference in
java? There is only one way to access the Object and that is through
its reference, to me the reference is the Object.

You are focussing on the reference when you should focus on variables. The
variable that contains the reference and the object that it references are
not the same thing. It is not true that the variable and the object are the
same thing in Java. What you passed in your example was a variable, but more
importantly the formal parameter for the method is also a variable. Changing
the value of the variable does not change the object.
When we start
saying things like "no you aren't really passing something that can be
modified because the thing your passing isn't really the thing your
interested in, its the indirect reference to it", we end up confusing
people.

Not in the experience of this group. It usually clarifies it to most people
to understand this difference between object reference variables and the
objects themselves.
If we get picky, you can't really modify the parameter passed in C++
either, because you are really only passing the Address of something
not the thing itself. But you will say "Wait, in C++ we have
references thats different". Not really, it will probably be
implemented the same as though you passed an address. To illustrate
this point. Here are 2 C++ files that I output the assembly for. The
assembly is exactly the same, except for a directive saying the name
of the source file.

extern "C" void modify (int * i) {
*i=0;
}
extern "C" void modify (int & i) {
i=0;
}
Ok, now you can say but it is different because of language semantics.

And because the language semantics are different we give different names for
those semantics. It doesn't make sense to use the same name for different
semantics when your purpose is to describe language semantics.

That is certainly part of what is dangerous about it, but also part of why
we give it different terms. If I have this call in C++

foo( i );

Things are very different depending on whether foo is defined to pass by
reference or by value. If it is by value then the only part of the
expression passed is its R-Value. In PBR what is passed also includes is
L-Value.
 
D

Dale King

Chris Smith said:
Okay, so I was oversimplifying. The actual definition (which is, I
admit, a bit arbitrary... but is the definition nonetheless) has to do
with the assignment operator. In C++, under the current spec, this
operator acts on the referent in pass-by-reference; not on the
reference. That makes it pass-by-reference, because the lvalue of the
actual parameter is the lvalue of the formal parameter.

You have that backwards. The lvalue of the formal parameter is the same as
the lvalue of the actual parameter. The formal parameter is the variable
within the called code. In PBV it has a distinct lvalue from the actual
parameter and in PBR it has the same lvalue as the actual parameter.
That is, indeed, a way to solve a lot of this problem (though not as
flexible as providing the ability to control the operations on an object
more completely via objects). If you know that you're passing by
reference, it gets you safety. So, I suppose, I really should have said
that hidden pass-by-reference like what exists in C++ is inherently
dangerous. If you know that you're passing by reference, it's less so
with appropriate use of the const modifier.

I disagree with this notion of hidden versus non-hidden PBR. It makes no
sense given the definition of PBR.
 
R

Roedy Green

to get to some common
shared data, but you still can't modify the parameter.

Actually you can, but is just your local copy of the parameter. You
can't affect any of your caller's local variables. That is why they
are called LOCAL. Nobody else can confuse you by meddling with them.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,066
Latest member
VytoKetoReviews

Latest Threads

Top