251 comments

[ 2.8 ms ] story [ 316 ms ] thread
In short: Java has pointers and is strictly pass-by-value.

It's a well know fact that Java has pointers given that you have NullPointerException as an exception.

The confusion around whether or not Java has pointers comes from people comparing it with C or C++. In Java, you can't dereference a pointer to an Object and get some sort of Object value. Similarly, you can't perform an "address of" operation on a primitive value and get a pointer to that value. Similarly, you can't pass-by-reference (in the sense of the parent article) or do pointer arithmetic in Java.

While Java technically has pointers (in the sense that it has pointer types), it has dulled them so that you can't hurt yourself with them the same way that C (and C++) permit.

(comment deleted)
Correct me if I'm wrong (my Java's rusty), but isn't the most common NPE scenario when a class has a member variable that's a class and has to be initialized in the ctor or elsewhere, but the programmer forgets to.

The alternative to this seems to be to require every class to have a no-arg ctor in order to be a member variable of another class. C++ takes this route, and it has the irritating effect of making iostreams, for example, hard to work with.

The best way to deal with this by a substantial margin is to simply not have uninitialized variables, ever, which means you don't need null in the first place (you can replace the functionality with optionals if you really want to, but usually it's not necessary). When I write Java, I declare fields final wherever possible for this and other reasons.
Final is a useful keyword -- a way to make the compiler flag up risky code. :)

The problem (the rest of the time), though, is that if you're writing object-oriented code, some values are simply null. Some data points are unknown, or some properties won't have values for some instances.

If you create an new object but it hasn't been persisted yet, it has a null ID.

If you're working with Categories (of something), some may have a parentCategory and some may not (null).

You can set a placeholder of some kind -- e.g., "-1" means no ID, NO_PARENT is a special Category to return from getParentCategory() if there's no parent, etc.. But then you still need extra code to handle these not-actually-valid values, and when your code is bad, instead of fast-failing with a NullPointerException... things will work, but weirdly. You'll get more confusing errors, further away from the actual bad code.

The Apache Commons way to deal with null is something of a hack, but it works -- library methods for common actions with built-in null handling.

E.g., StringUtils.isBlank(s) is true if s is null, or empty, or only whitespace.

ObjectUtils.isEquals(o1, o2) is true if both are null, false if only one is null, or true if o1.equals(o2).

CollectionUtils.isEmpty(c) returns true if the collection is null, or empty.

I haven't much explored other OO-based approaches to null that are less annoying than Java's handling -- so I'm always curious to hear about smarter approaches.

OP mentioned one of the other approaches..."Optional". An `Optional<String>` will be a non-null reference to either a present value, or an absent value. It's really just modelling null at a non-syntax level, and encourages checking whether there is a value explicitly (i.e. it's self documenting that you need to check if the value is present before using it).

Proponents of Optional will then say that every non-Optional reference must never be null, through static/runtime assertions (like @Nonnull, checkNotNull(), etc)

FWIW, in .NET land, we tend to say "pass-by-reference-by-value".
I call this "pass by pointer copy". Does anyone know if that's a term people use, or did I just invent it? I can only find one other person mentioning it when I google for "pass by pointer copy" (in quotation marks for the exact match).
No,that's completely natural (if verbose). This is from someone coming from a C background, FWIW.
Shouldn't it be: pass-reference-by-value
>Java is strictly pass-by-value, exactly as in C

In C you can pass a pointer, and a pointer to a pointer. I understand both cases are usually called "pass-by-reference". If you call "pass-by-value" to passing a pointer, then the notion of "pass-by-value" and "pass-by-reference" are not very useful.

IMHO "pass-by-reference" means you can mutate the attributes of the thing passed (as in java when you pass an object) and also means you can be operating on a "volatile" area of memory, meaning another thread can CHANGE the data while the function is executing.

OTOH "pass-by-value" means you get a "snapshot" of the value at the point of the function-call, the copy is normally on the stack, and no other thread will change the data while the function is running. Also you can mutate the area with gusto without worrying of data-races, side-effects or altering the calling function variables.

This two "definitions" of pass-by-value and pass-by-reference are the ones I find useful regarding concurrency and side-effects.

If you tell me that passing an integer and passing an object are both the same thing (pass-by-value) in Java, then I will tell you that pass-by-value and pass-by-reference are not very useful concepts.

It is a useful concept because there are languages with pass-by-reference constructs. C++, Swift (sort of, with inout parameters), are two examples that come to mind. Java and C are simply not those languages.
You can pass double pointers in C so functions can change the original pointer's address value. You can't do that in Java.
Yes, you can do that in C, but that is still not pass by reference. In C you are not passing the variable you are trying to change, you are passing a pointer to it. You cannot write

  swap(a, b);
You have to write

  swap(&a, &b);
The problem is that you will label both cases as an example of "pass-by-value", while they're fundamentally different.

That's why people call "pass-by-reference" the second example.

They're not fundamentally different. The passing semantics are the same in both cases, the variable bound within the body of swap will not be the same variables we are passing it. The difference is that the value being passed is a pointer in the second case.
They are both labelled pass-by-value because they are both pass-by-value. Yes, they are different, but that doesn't mean one is pass-by-reference and the other is pass-by-value.

The C example is equivalent to

  pa = &a;
  pb = &b;
  swap(pa, pb);
When swap returns, the values of pa and pb are unchanged. Only the values or a and b are changed. But a and b were not passed to swap. Therefore this is not pass-by-reference, but rather passing a pointer to a variable by value.
I fully understand the difference, and I know that you're technically correct.

What I'm saying is that people tend to abbreviate "pass-a-reference-by-value" to "pass-by-reference" because the differences between passing a value (value snapshot) and passing a reference-value (passing the address-of) are way more important* than if the language syntax allows you to pass an "implicit" variable reference or not. (the swap example)

*"more important" for code-reading, code-analysis, code-safety analysis, and also even more important in a concurrent environment because of side-effects and data-races.

Maybe the feature should be called "pass an implicit reference", which describes better what Java does, instead of saying "everything is pass-by-value" which is correct but, as the evidence shows (the mere existence of the article), it is very confusing for "folks".

>I'm really tired of hearing folks (incorrectly) state "primitives are passed by value, objects are passed by reference".

(comment deleted)
In Java, you stick the pointer into a one element array and pass that. Given some flexibility about the definition of the "original pointer", it can be done, although there's no special syntax for it. Or maybe "array syntax" is "pass by reference" syntax.
I'm remembering at least some versions of basic were pass by reference for all types.
Early variants simply "passed by reference" by virtue of not having local variables or functions at all. A "function" would be implemented by the programmer as a subroutine that used a specific set of the global variables available for its input and output values.
Call/pass by reference means you can write a function that swaps the values of two variables such that the caller will see the values swapped. See the examples in the posted article for Pascal and C++. This cannot be done in Java or C, which is why they are not pass by reference.
> IMHO "pass-by-reference" means you can mutate the attributes of the thing passed (as in java when you pass an object) and also means you can be operating on a "volatile" area of memory, meaning another thread can CHANGE the data while the function is executing.

Sorry, but having an 'opinion' about such definitions doesn't help. Just [use the definition](http://en.wikipedia.org/wiki/Evaluation_strategy#cite_note-1). This clearly states what the article tried to explain with helpful examples.

> If you tell me that passing an integer and passing an object are both the same thing (pass-by-value) in Java, then I will tell you that pass-by-value and pass-by-reference are not very useful concepts.

They are useful, just not in the way that you think of them. You could use these definitions to have a meaning in terms of side-effects, but only if you design your objects accordingly, i.e. there are no exposed methods to do an in-place change of your object's data, instead you only have class functions that return a new object and read-only accessor methods. Combining this with a language that is strictly pass-by-value (such as Java and a subset of C++ without reference parameters) should make your program side-effect free.

> Sorry, but having an 'opinion' about such definitions doesn't help. Just [use the definition](http://en.wikipedia.org/wiki/Evaluation_strategy#cite_note-1). This clearly states what the article tried to explain with helpful examples.

I don't think that's a very strong argument.

For one, it's not really useful to be totally prescriptivist, especially when talking about just-birthed fields like computing.

Also, consider the usage on that page of "data structure" where it's implied that you can't have a stack-allocated data structure (namely that data structures aren't value types, even those containing pointers). Such a distinction seems remarkably unusual to me, indicating that it's best not to take that page as gospel.

Personally I prefer to avoid these terms altogether because on the rare case that it would be useful to use the words, it's rarely worth the inevitable argument.

I didn't mean to use that wiki as gospel, but the book citation I linked seems to hold up. And for a concept like pass-by-value vs. pass-by-reference, I don't think it's a good idea to go and come up with your own definitions if you don't have a very good reason to do so. While I agree that computing is a still a young field, and lots of stones are still rolling, it's still important to establish some common language and models just in order to communicate ideas. This includes not overloading terms that have been clearly established by now. If you find a well-known source[1] that would disagree with the terminology as cited, I'd be happy to revise my opinion.

[1] such as Kay, Ritchie, Dijkstra, Engelbart or even Matsumoto, Van Rossum, Eich, Crockford.

> terms that have been clearly established by now

Evidently this is not one of those, though, since its colloquial use is all over the map.

PHP unfortunately has the same issue because it copied Java's terminology to describe object reference values (introduced in PHP 5), yet it has always also had "references" which are actually pass-by-reference.

To demonstrate, object references/pointers/whatever:

  $foo = new Foo(); // $foo
  $foo2 = $foo;
  $foo2->x = 3;
  // $foo->x is also 3 now, $foo and $foo2 point to the same Foo object
  // that is, $foo and $foo2 both contain an object handle/pointer/reference/whatever that points to the same Foo object
PHP references:

  function swap(&$a, &$b) {
      $temp = $a;
      $a = $b;
      $b = $temp;
  }
  $a = 3;
  $b = 2;
  swap($a, $b);
  // $a is now 2, $b is now 3
(comment deleted)
The only reason I use @-refs anymore is because of PHP copying arrays on assignment (shallowly, lazily.) In addition--unless you do everything in a super-functional way--you need to unset() each &-ref to prevent latent bugs later in the same scope.

It's an unfortunate situation, and it gets worse when you add array-like-objects into the mix, which look exactly like "normal" arrays up until the moment everything explodes into WTFs.

The terms are not precisely enough to give meaning to cross-language comparisons. Within a single language like C++, you can usefully differentiate the various ways to pass references and data.
I disagree. The question of whether or not you can write a swap function as described in the article is fairly precise.
(comment deleted)
(comment deleted)
I don't see how the article you linked to contradicts the original post.
The author doesn't seem to understand how parameters work.
No, the Java language specification makes it as clear cut as anything can get.
(comment deleted)
Well the way I've always thought of it is that Java passes "references by value". Meaning the target method receives a _copy_ of the pointer, not the actual pointer. So the result of newing up the parameter inside the target method doesn't affect the original, because you're just making the pointer point to a NEW memory address. On the other hand, mutating the parameter WILL affect the original object, because a copy of a pointer still points to that object from the caller.
What Java does is pretty much equivalent to putting an asterisk in your C/C++ typedefs:

    typedef struct _foo* Foo;
I'm guessing this is why you have to call "new" to create new objects in Java?
Java's new is similar to C++'s new as I understand it, yes. It allocates memory, initialises an object, and produces a pointer.
The article says almost exactly that:

"However, Objects are not passed by reference. A correct statement would be Object references are passed by value."

Yeah, it says that in one sentence while its the central point of confusion if you even want to call it that.

Instead it rants at length to somehow save definitions that are clearly not particularly helpful in a language like Java.

This article just reeks of this certain kind of socially inept, completely unhelpful attitude and technical pedantry that has infected mailinglists and IRC channels over the world. Actively trying to misunderstand people in an effort to expose their ignorance or unfamiliarity with intricacies of whatever language or tool they are trying to navigate.

Its a terrible habit up there with feigned surprise.

This is a very unjustified and overly harsh criticism. The article clearly presents real world confusion that can arise from not understanding that Java is not pass by reference. This can easily lead to wrong code. So it's not just pedantically insisting on some specific terminology, but highlighting the semantically differences between passing a reference (more precisely pointer) by value vs. 'real' pass by reference.
I've never seen actual bugs due to a misunderstanding of the concept though. It seem to be mostly a terminology difference between c++ and Java cultures. It is correct to say that Java passes objects as references, but it is technically wrong to say that Java is pass-by-reference. But since Java has only one way of passing objects, this terminology confusion does not lead to actual problems.
Except they are different things, and others (me included) have seen bugs related to the confusion.

Technical correctness is always best. Java is pass by value, and even variables holding object references are passed by value.

I think the confusion was largely created by the author. When he asserts that nothing in Java is passed by reference, he's using "reference" in the C++ sense. Then he says things like "references are passed by value", which uses "reference" in the Java sense.

We should be consistent in terminology. If we accept Sun's terminology, then objects are indeed passed by reference. If we're insisting on the more traditional C++ terminology, then Java has no references, only pointers.

The author recognizes the two meanings of "reference", but isn't sufficiently clear about which meaning he's using at a given time.

If we're using the "reference type" meaning of reference, then the phrase "objects are passed by reference" is grammatical nonsense. At best it becomes a tautology - "reference types are passed as reference types". What does that even mean? That reference types don't magically become value types when you pass them in as arguments? That doesn't actually say anything useful about the evaluation strategy.
It would mean that the invoked method gets a reference to the original object rather than its own copy of the object.

It's only obvious if we assume some knowledge of Java's semantics.

You appear to be saying 'we can call it pass-by-reference if we use a special definition of the term when speaking about Java.'

"A word means what I want it to mean, nothing more, nothing less." - Humpty Dumpty, 'Through The Looking Glass and What Alice Found There'.

There should be a variant of Occam's Razor specifically against unnecessary semantic splitting and proliferation.

If you already know Java, you have no need to have Java's parameter passing mechanism explained to you.

If you don't know Java, and need an explanation, then you need one based on terminology that exists outside Java. Pass by value and pass by reference are concepts that predate and exist outside of Java, describing programming language semantics in a way where statements about different languages can be compared and contrasted, because they're not phrased in vocabulary specific to the language the statement is about.

Java passes all arguments by value.

The idea of overloading the term 'reference' to mean 'pointer', but without all the power you get from pointers in languages like C, has at this point grown far beyond Java. I don't think it's a logical muddying of the waters to use it in a phrase like "references are passed by value" when describing Java using terminology that exists outside of Java.

Yeah I don't agree on two fronts:

1) To say that Java "passes all arguments by value" implies astonishing behavior if one passes an object and calls a mutator on that object changes it everywhere else that reference is used. If it were truly passed by value, the target would get a _copy_ of the original. Which is NOT the case in Java. So this terminology is misleading!

2) An admittedly weaker argument you imply that a given Java developer has never looked at any other language that doesn't use Java's approach to parameter passing. That's a tiny, tiny audience, my friend.

Java does pass all arguments by value. The issue is that you don't understand that the value of a Java object reference is the same as a C++ pointer, which means passing it by value into a function means simply that you've copied the pointer, nor the object, and mutating that object inside the function is simply following the pointer copy to the same pointed-to object, so the caller also sees the change.

Note that it you change the pointer (object reference) directly, instead of following it and mutating the pointed-to object, the caller would NOT see the change. Like "x = new Foo()" inside a routine would not change what was passed in at all.

But if Java was pass by reference, then things would act differently.

Please learn Java. It's not about not knowing other languages. It's about not knowing Java. This is all in the JLS.

Dude. I've been using Java since 1.0. You're talking about Java from the perspective of C++, which is confusing to someone who is actually programming in the Java language.
Read the JLS. This is Java as defined by its creators, absent of C++.
"The issue is that you don't understand that the value of a Java object reference is the same as a C++ pointer"

A C++ pointer is a simple thing: an address within the program's address space. In an earlier response to a similar claim of yours, RayleyField pointed out that "In HotSpot references are double pointers (useful for moving GC), but in general it's up to JVM implementation." Certainly, if you dig into a Java reference, you will find an address that is analogous to a C++ pointer, but the same can be said of a C++ reference. Java references are not exactly equivalent to either C++ references or C++ pointers, and the statement that Java passes by value is not dependent on an arguable claim that Java references are more like C++ pointers than C++ references. This line of argument has just added to the confusion in these threads.

We are talking logically, not implementation details.

Logically, a C++ pointer and a Java object reference are nearly identical, as described and defined by their respective language standards. Independent of the implementation chosen.

This is not the same as a C++ reference, which is logically an alias (and may be implemented via pointers, but that's irrelevant).

The confusion in this thread stems from people confusing many things, indeed.

If "we" are talking logically, then "we" should not be using the expression "C++ pointer" in the statement I quoted earlier. Doing so can only lead to confusion in the minds of people struggling to understand Java argument-passing.
Why not? A C++ pointer is a logical construct that exists in the language (as per the language standard) independent of any given implementation.

Same with "Java object reference" and "Java pointer" (synonyms).

If we can't discuss this topic using those well-defined things, what can we use?

'If we can't discuss this topic using those well-defined things, what can we use?'

I am told you will find all the things you need well-defined in the JLE, and in doing so you will avoid positing a plurality without necessity, as Billy Ockham may or may not have put it.

JLE? Or JLS? If you mean the spec (JLS) then I agree, you can find everything there. Including what I wrote above - that "Java object references" are the same thing as "Java pointers" (both in the JLS). The JLS also describes parameter passing in excruciating detail, and it matches the definition of "pass-by-value" (not "pass-by-reference") exactly.

But if people in this thread could read and understand the JLS, this thread wouldn't exist. Since it does, some of us feel like we should contribute and correct the false statements we see.

You are right, JLS. With regard to whether these comparisons with C++ have led to the desired results, see elsewhere.
The well-definedness of 'C++ pointer' is a non sequitur - it is not a sufficient condition to justify its use in this context. 'Backwardation' is well-defined, yet I doubt it can contribute anything to this discussion.
If you consider the context of my statement, and not my statement as it stands in isolation, then you are mistaken.
Java objects are not value types; they're reference types. You're confusing your concepts. Specifically, you're conflating parameter passing semantics with reference type semantics. The problem with this conflation is that reference type semantics cover more situations than merely parameter passing, so when you conflate the two concepts, you miss out on the remaining bits. Consider this:

    Foo x = new Foo();
    x.setBar(42);
    Foo y = x;
    y.setBar(0);
    assert(x.getBar() == 42); // fails! astonishing behaviour!
If the value of x was assigned to y, surely modifying y shouldn't affect x, right? That's what assignment does, it takes the value on the right and puts it in the location on the left, correct? So why on earth was x modified when we only called a mutator method on y?

To understand this, you need to know that Java objects are reference types. And this has nothing to do with parameter passing.

And once you understand reference type semantics, you don't need anything extra to understand parameter passing, because parameter passing in Java uses the same semantics as assignment: that is, the value of the actual parameter is copied into the formal parameter, just like values on the right of an assignment are copied into the locations on the left. It's pass by copy.

It is not the author causing confusion here between the term 'reference' in C++ and Java. For the purposes of this discussion, there is no difference.
There are differences. References in C++ are aliases. References in Java are pointers. C++ lets you pass-by-reference (meaning aliasing) or pass-by-value (including objects, pointers, ints, etc). Java only lets you pass-by-value (object references, ints, etc. There are no object values in Java, so those can't be passed at all).

Correctness is important.

Correctness is indeed important, which is why I wrote 'for the purposes of this discussion.' The topic of the original article is what Java does, and additional capabilities in C++ are not pertinent. Dlubarov posited that the author has sown confusion by using the term 'reference' in a C++-specific way, but I believe that confusion arises from a misreading of the article.
The phrases "pass-by-reference" and "object reference" need to be (and are) well-defined for the purposes of this discussion and for Java as it stands alone separate from C++.

But also, for the purposes of this discussion, it is very useful and illustrative to equate pass-by-reference to C++ references, and object references to C++ pointers, because the languages are similar and the concepts match up very well, and because these things are more explicit in C++.

Sure, one could have defined everything without comparing to C++ (in fact that is what the JLS does) but, for the purposes of this discussion, many of us assumed that wasn't good enough for many posters here, because if it was, this discussion wouldn't exist.

You are, of course, entitled to your opinion that the best way to clear this up is by making comparisons to C++, but the problem is that in defending your comparisons, you have brought in various issues, such as that C++ references cannot be rebound and the differences between the meaning of 'pointer' in the two contexts, that can be dispensed with if you do not take this approach. Personally, I think that those people who are both confused and looking at this from a C++ perspective would be better advised to stop making comparisons and look at Java for what it is.
Clearly reading the JLS wasn't good enough for most people. So what do you turn to when people take a well-established programming term like "pass-by-reference" and apply it where it doesn't belong?

Seems to me like a good place is a modern, widely-used language which is similar to Java but also has both pass-by-value and pass-by-reference so one can illustrate what those terms actually mean and how they differ.

Seems like C++ is as good a choice as any Feel free to use another language if you can do better.

Explaining pass-by-reference using Java, which can't express pass-by-reference, is one of the sources of the confusion people here are experiencing (the other is Java using reference to mean something different from established meanings).

"Clearly reading the JLS wasn't good enough for most people. So what do you turn to when people take a well-established programming term like "pass-by-reference" and apply it where it doesn't belong?"

Clearly, one should turn to computer science fundamentals. Considering the totality of your posts under this article and the responses to them, picking the language with arguably the most complex panoply of ways to denote values, of any language in common use, hasn't worked out as a pedagogical device.

Clearly, others in this thread need something more accessible than computer science fundamentals. I believe, if that were enough, they would have understood the terms correctly from the start (because the terms are rooted in computer science fundamentals - the confusion only arises once you confuse them with Java terminology).

So do not conflate what you consider clear with what the thread is reflecting as clear. They are quite different.

What the threads reflect is that you have repeatedly abandoned this approach:

'Please learn Java. It's not about not knowing other languages. It's about not knowing Java. This is all in the JLS.'

'Read the JLS. This is Java as defined by its creators, absent of C++.'

I think you are being particularly clear in that last one.

I think you are being naive if you think people who don't understand the definitions of "pass-by-value" and "pass-by-reference" (terms well-defined and well-understood in programming language theory and computer science fundamentals), and then go on to further misunderstand an article about Java and C++, will get any benefit from discussion on the topic that avoids Java, C++, or any other concrete examples, and instead tries to use the very definitions themselves (which are not understood, remember?) to try to provide clarity.

As I said before, if people understood the fundamentals, or if the fundamentals were good enough, then this entire thread wouldn't exist. This stuff is child's play. Anyone who is confused by this needs more help than shrugging and saying "stop trying, just point them at more fundamentals"...

You appear to have put this post in the wrong place, as it says nothing that relates to the observation presented in the parent, which is that elsewhere, you ultimately abandoned your C++-analogy approach in favor of one that discusses Java in Java terms -e.g. 'Read the JLS. This is Java as defined by its creators, absent of C++.'

Which is not to say that there is anywhere this post belongs, as you attempt to use a couple of tired old rhetorical ploys: insinuating a position that has not been stated, and the insertion of a specific item into a list of disjunctions in the hope of insinuating that it is necessary.

Your argument here depends on the misunderstanding that all explanations in computer science are abstract, and specifically that they are inevitably more abstract than a discussion of the same topic in C++. That is not so; a discussion of argument-passing can be (and is) done in terms of addresses and stack frames. That's more concrete than 'abstract pointers', and also more straightforward than making qualified analogies between elements of Java and C++, which are of no help to anyone who doesn't have a solid understanding of C++, anyway.

This is just as well, or how else would anyone have understood this stuff before they had C++?

What in the world are you talking about?

> you attempt to use a couple of tired old rhetorical ploys

I do no such thing.

> Your argument here depends on the misunderstanding that all explanations in computer science are abstract

Not at all.

> That is not so; a discussion of argument-passing can be (and is) done in terms of addresses and stack frames.

Sure you could do it that way. But it becomes exponentially more complicated because you need to either stick to one specific implementation of one specific language runtime, or you have to deal with explaining them all. Neither is ideal.

> are of no help to anyone who doesn't have a solid understanding of C++, anyway

You just need a basic understanding. This isn't advanced stuff here. People learn Java's object references the very first time they

    Thing x = y; y->something(); // Why has x changed?
and they learn C++ references and pointers ... well from the start.

These are week-one concepts for anyone learning the languages.

> This is just as well, or how else would anyone have understood this stuff before they had C++?

Most people have no trouble understanding the concept in week one of Java, or C++, or whatever other language they are learning. And the rest get it from the fundamentals. But those aren't the people in this thread who continue to confuse the issue.

If someone can't take the phrase "pass-by-reference" and the phrase "Java object reference" and understand that the two uses of the word "reference" mean different things, even after reading the simple-to-understand definitions of each, then they really need above-and-beyond help. This isn't "dive into CS theory" or "show them the machine-level stack frames and register contents", this is "try whatever you can that might help them". C++ is a very valid place to go for these folks.

Good day to you, too! You haven't disappointed in the latest of your daily diatribes!

'What in the world are you talking about?'

Here we have another common rhetorical ploy, the attempt to insinuate that the other party is not making sense, without actually refuting her arguments. If not used carefully, however, it has the unfortunate side-effect of giving the impression that you alone cannot figure it out.

But do keep the snide asides coming (not that I think you are likely to stop). If it were not for them, I would have left this thread long ago, satisfied that we had reached an amicable agreement to disagree.

You follow with a few flat denials of things I wrote. You can do that until the cows come home, but unless you can offer actual refutations of the arguments I presented in support of those claims, you are just blowing hot air.

'Sure you could do it that way. But it becomes exponentially more complicated because you need to either stick to one specific implementation of one specific language runtime, or you have to deal with explaining them all.'

Now we come to something that has the verisimilitude of a rational argument, and we can immediately see why you were reluctant to go there, despite the manifest failings of the alternatives you tried. The first question that comes to mind is, exponential in what? What, precisely, leads to an exponential growth in complexity? Note that the sentence quoted here claims exponentially more complication even if you stick to one specific implementation of one specific language runtime, so make sure that your explanation covers that case, or I will have to return to it. Also make sure that your explanation somehow avoids applying to C++, and covers how we ever managed to figure this all out before we had C++.

Furthermore, the implication that it has to be presented using one extant runtime or another is fallacious. One can discuss argument passing using stack frames and addresses without getting into how C++ or any other specific language implements it, and the empirical proof of that can be found in any number of elementary comp. sci. textbooks.

Your 'its so simple' argument is a non-sequitur, as you are making the fallacy that if the concept is simple, then any explanation will be simple. In reality people can, and do, tie themselves in knots over simple issues - Zeno's paradoxes are a case in point. In fact, the simplicity argument goes against you - it's so simple, yet you ended up retroactively qualifying your use of pointer as 'abstract pointer' and spend time in drawing analogies between C++ pointers and Java references.

And if its so simple, how come that there are people who are just not getting it? Maybe, just maybe, the problem is in how it is presented.

The question of whether an approach via C++ is helpful, and whether your particular approach (using qualified analogies between C++ and Java) helps, are separate issues. I could go into how well your approach worked in practice, though I don't think that is necessary at this point (unless you choose to go there), except to point out that you repeatedly abandoned this approach in favor of a purely Java one, telling people to 'read the JLS.'

I didn't even bring up C++ - the article did, dlubarov commented about it, and you asserted that C++ references and Java references were the same. That's where I joined - to correct your fallacy.

Perhaps it really is simple, and you are afraid to admit that maybe you didn't get a simple concept either, until your eyes were opened by the very posts you spend walls of text refuting. I know it is not a pleasant feeling, but it's acceptable to own up to it. No amount of text or thesaurus consultation will fix your mistake.

Or, if that's too much pride for you to abandon, then you can continue to stand behind your original claim that references in C++ and Java are the same for this discussion (or any other - but I posit that there is no discussion, except for maybe "the word reference in both phrases has the same spelling"), then I feel for you. I really do.

Good day!

You were correct on the references issue (which was not as you present it here, which is typical), but mistaken over the cause of length of this thread, which comes from an unbroken series of faulty arguments you presented in an attempt to support the notion that using C++ was the only option in explaining the issue. The last one was a risible claim about the literally exponential complexity of the alternatives.

So here's a difference between us: I freely acknowledge correct arguments, while you silently slink away from your mistakes, and try to pretend you never made them. I am happy to have third parties figure out who is being immature here.

Top O' the morning to you!

Every one of my corrections was accurate.

I also don't believe I ever claimed that C++ was the option.

I own up to my mistakes the instant they are apparent. If you believe I should be owning up to something but I haven't yet, it is because either I wasn't wrong, or the argument against me wasn't coherent.

But at least you finally capitulated. I didn't think you would, so you at least proved me wrong there.

I am hugely amused that you just could not resist making a statement that proves it is you who suffers from the obsession you accuse me of (not that there was any real doubt.) You remind me of the child who just cannot resist the marshmallow: https://www.youtube.com/watch?v=0mWc1Y2dpmY
Are you claiming that if I hadn't corrected your false statements quickly, and instead I had waited a short while, that you would have made additional false statements that you wouldn't otherwise have made? So that I could have enjoyed correcting you even more?

If that's true then I wish you would have said that up front like the experimenter in the video. Unlike the subjects, I would have had no problem delaying that gratification. My prize would have beaten a marshmallow any day.

Most people figure out as children that claiming the truth of something that is demonstrably false is a losing strategy. It doesn't even count as a rhetorical ploy; 'Go directly to fail' would be a more appropriate characterization.

A simple reading of this thread shows that I have merely been responding to specific claims of yours, in which the comparison of references was neither here nor there, once you chose to make an issue of whether your C++-comparison based explanation was the only feasible one remaining. When you could have left it as an amicable difference of opinions, you chose to double-down and insist that anything other than your opinion was flat-out wrong, which led you to make a series of increasingly poor arguments, culminating in the ridiculous claim that the alternatives would literally be exponentially more complex.

In each case (including the last), after I pointed out the flaws in your claims, you have neither accepted the point, nor offered any counter-argument. Instead, you circled around and tried to make a different argument for the same claim, as if there was not already a growing pile of refutations stacking up against it. If there was any doubt before that you suffer from the obsession you accuse me of, you effectively removed it by this behavior.

There is not much point in discussing anything with someone like you, but your sanctimonious rudeness to me and others makes it worthwhile.

'My prize would have beaten a marshmallow any day.' No surprise there - your juvenile motivations are plain for anyone to see.

> Most people figure out as children that claiming the truth of something that is demonstrably false is a losing strategy.

So the video had no point then? Because the video I saw was about delayed gratification, not the strategy of truths and falsehoods.

And I still await a clear idea of where I made a claim of truth and was mistaken. As I've said in the past, if you can show me that clearly, I'll capitulate. I've been patiently waiting through all of your long-winded responses for this, and have been disappointed so far.

In fact, you now have changed your characterization of my posts from "truths and claims" to "opinions", which most of them were all along (the only claim I believe I made that could be considered fact instead of opinion was the refutation of your C++ references-and-pointers equation, which you agreed I was correct on).

> A simple reading of this thread shows that I have merely been responding to specific claims of yours

I don't see that anywhere, actually.

> once you chose to make an issue of whether your C++-comparison based explanation was the only feasible one remaining

I also don't see this anywhere. What I do see is my claim that C++ is a useful comparison - but nowhere do I see myself claiming it is the "only" one, or the "only feasible" one.

Some of my quotes have been: "for the purposes of this discussion, it is very useful and illustrative to equate pass-by-reference to C++ references, and object references to C++ pointers, because the languages are similar and the concepts match up very well, and because these things are more explicit in C++" and "Seems like C++ is as good a choice as any" and "one could have defined everything without comparing to C++"...

> after I pointed out the flaws in your claims, you have neither accepted the point, nor offered any counter-argument

But you haven't actually pointed out any flaws in any of my claims.

> as if there was not already a growing pile of refutations stacking up against it

Please, point out the pile of refutations to the claim that C++ is useful in this discussion (not "only", just "useful)... especially since, refuting the notion that it is useful to someone means finding everyone who read it and getting them to admit that they found no use in it. If you do that, I'll certainly admit I was wrong.

> your sanctimonious rudeness

I see very little rudeness - the only clear cut case was in response to someone else who basically asked me what rudeness would look like and I gave an example referencing proggit. Care to quote any specific rudeness toward you? Be careful not to equate an unpleasant discussion with rudeness.

> your juvenile motivations

If you think truth is a juvenile motivation then I finally understand everything you've written.

Your attempt to deny what you wrote is as revealing as it is pathetic. The record stands for itself.
I was going to write the same thing.
Instead of replying in a manner I haven't heard since middle school, you could be writing a much-delayed explanation of your claim that a stack-frames-and-addresses explanation of pass-by-value would necessarily be "exponentially more complicated" than your C++-based approach.
I guess I am the middle schooler here because I'm going to point out that "you started it".

I won't even dwell on the hypocrisy of you trying to call me out for my rudeness right before you post this middle school nonsense.

If you don't think stack frames and addresses are far more complex a learning tool for this than references and pointers, that's your opinion. I disagree, and I think many would, but there's no factual claim here for you to refute, no matter how much you are grasping for one in this thread.

Go ahead and explain it your way to folks. See if it finally sinks in for those who didn't get it from the JLS or from the article. I'd be happy to watch the attempt. I don't think it'll work. Prove me wrong.

If it were just a matter of opinion, you could have left it like that a long time ago, but instead you have presented a long series of factual claims intended to show that yours is the only reasonable opinion, and I am merely responding to them. For example, your claim of exponential complexity was not just a matter of hyperbole, you backed it up with an explanation: "...because you need to either stick to one specific implementation of one specific language runtime, or you have to deal with explaining them all." If that is no longer your position, say so, and we can move on.

Another recurring factual claim is that there is a set of people that will understand this issue only if it is presented in a very specific way. Putting aside, for the moment, the question of how well that worked out in practice, let's look at what characteristics you have ascribed to your target: 1) They didn't get it as presented in the original article; 2) They have read what the JLS says about it, but did not understand it there; 3) They could not be led, through a suitable explanation, to follow what the JLS says; 4) Any explanation based on computing basics would be beyond their grasp; 5) Despite all this, they understand (and not just think they understand) the more complex issue of argument-passing in C++. It seems unlikely there is anyone in this set. In particular, while there seem to be people in group 3, I doubt any of them have made it into group 5.

As for an alternative explanation, we have, for example, eslaught's post: https://news.ycombinator.com/item?id=9249285 The first paragraph gets to the essential point with admirable directness, without using any comparison to a language that has a particularly complex array of argument-passing cases.

It's always been a matter of opinion. Most people don't take conversational prose literally and argue against it as if it was a fact that needed refuting.

For example, it is your opinion that C++ argument-passing is more complex; it is mine that it is more explicit and easier to reason about. Notice how I don't take your claim and call it a fact and write pages about how you must back up your claim with some more evidence before I'll buy it.

I think many people would agree that, since you challenged me to present an example, and I did, then it is quite reasonable for me to ask if it has changed your opinion that any alternative to your approach would be infeasibly more complicated, and if not, why not.
I'm sorry, where did I say that "any alternative to my approach would be infeasibly more complicated"?
It is true that while you have tried repeatedly to imply there is no viable alternative, you have not explicitly ruled out some so-far unmentioned alternative. Nevertheless, you were very explicit when you made this argument against one class of alternatives:

"Sure you could do it that way. But it becomes exponentially more complicated because you need to either stick to one specific implementation of one specific language runtime, or you have to deal with explaining them all. Neither is ideal."

So it is reasonable for me to ask if the example you asked for changes your mind on this issue.

I asked you to write up an example using stack frames and addresses independent of any language. You have yet to do it.

The comment you linked to is much more reasonable than that and only introduces a little more complexity. But it is still more complex in my opinion because it uses both stacks/locals and heaps/objects as well as referencing C++, and I don't think someone who confuses Java for a pass-by-reference language will understand that any better.

If your goal in all of this is to try to change my opinion, you will need to keep trying. Why you would spend all this time on it is beyond me, but since I enjoy correcting your fallacies and you seem to enjoy grasping for ways to appear like you've accomplished something with all of your replies, we could be doing this for quite a while.

Keep it coming.

To paraphrase Ian Fleming: No, Mr. Noakes [, I don't expect you to admit to even changing your mind], I expect you to continue to offer evasions, misrepresentations, irrelevancies and self-contradictions in an attempt to rewrite the record.

Your response is exactly what we could predict: after a couple of posts in which you try to ignore the first paragraph of eslaught's post, you attempt to rewrite the issue by bringing in his following two paragraphs, which are about a different topic (ironically, their topic is the unsuitability of C++ for this discussion!) The first paragraph stands on its own and is not dependent on, or even supported by, on the following two paragraphs.

So you really would like us to believe that your judgement is such that you find this straight-to-the-point ("you still have no way to modify the variable binding on the caller's stack") argument slightly more complicated than yours, which includes a couple of other long, snide-remarks-laden threads (something you obviously have a predilection for), and a couple in which you finally abandoned your approach, telling people to read the JLS instead?

Tobani, for one, found eslaught's post helpful: "I get what you are saying."

Furthermore, the most you are claiming now is only that eslaughts's post (even in its entirety, including the parts not relevant to this discussion) is just a little more complicated than yours. This is very different from your initial claim (despite your attempt to mis-characterize it as "conversational prose" when it contains an explicit argument attempting to establish a fact - see my recent post above.) Even if we consider the use of 'exponential' as misleading hyperbole, it is still a claim that any such alternative would be inordinately more complex. Therefore, the fact that you are now arguing for only a little more complexity is a tacit admission that you now realize your initial claim was mistaken.

Until you are ready to demonstrate some level of courage in your convictions, there is no point in me posting an alternative explanation here, only to have you willfully misrepresent it in the same way as you did for eslaught's post. If, however, some genuine third party joins in the discussion and requests it, I will be happy to present an alternative.

> after a couple of posts in which you try to ignore the first paragraph of eslaught's post

I wasn't ignoring it - it was irrelevant.

> This is very different from your initial claim

No it isn't - I never claimed anything about eslaught's post, directly or indirectly, before that.

> 'exponential' [...] it is still a claim that any such alternative would be inordinately more complex

You repeat this as often as you can, like it's somehow your only real point here. And every time, I point out that I made no such claim. The only claim I made was that your specific explanation (which you never actually wrote), which you said would include stack frames, machine addresses, and the like, would be much more complex than referring to C++, in my opinion.

You haven't refuted that, even though I am amused that you keep trying.

You also haven't changed my opinion, and as you can guess, I'm equally amused that you keep trying there too.

Continue, please.

No problem - these replies practically write themselves. I usually have a good idea what I am going to write even before I read your next evasion, and you keep giving me new material to work with.

A case in point: your attempt to claim that eslaught's explanation is irrelevant. Of course, it is not - characteristically, you have offered no counter to my explanation of how it gets directly to the point - and of course you were not thinking it was irrelevant when you tried to argue that it is marginally more complicated than your approach. Only after I pointed out that by doing so, you had tacitly admitted to a complete reversal of your position, did it occur to you that it was a mistake, and decided that you would have been better off claiming that the explanation is irrelevant, even though that claim won't stand up. So instead of expunging one of your inconsistencies, you have added another case where you contradict yourself in attempting to rewrite the record.

You also claim that this isn't what you were thinking of. Well, if you didn't think through the full scope and implications of what you were writing, that would be yet another mistake on your part, wouldn't it? We are, however, now entitled to wonder why, precisely, you think you can retrospectively rule this explanation out. As I wrote before, until you can demonstrate the integrity of committing to something definite that you will not attempt to rewrite later, there's no reason for me to post an explanation here.

You seem to start your posts with a lot of rhetoric, and then you repeatedly fall flat on your face with substance.

> you had tacitly admitted to a complete reversal of your position

> until you can demonstrate the integrity of committing to something definite

My position has never changed, nor has my opinion. I still believe C++ was a useful analogy to the problem at hand (people misunderstanding Java references and pass-by-reference), and I still believe that any explanation involving machine addresses and stack frames that you could write (which you continue to refuse to do) would be more complex than comparing to C++.

If you care to take your umpteenth failed swing at that, go right ahead. I already know what's going to happen though. "Failed attempt at rhetoric, misrepresenting of opponent's position, arguing against the failed position".

I should advise you, though, that if you are going to keep wasting your own time flailing around in this thread, you should try to have a modicum of self-respect by sticking to what I say in your replies. Arguing against positions that don't exist may make you feel like you are getting somewhere, but really all you are doing is entertaining me.

But if that's your goal, and I'm misunderstanding you, then ignore the previous paragraph, and keep it coming :)

So I have been advised by jj not to continue. Coincidentally, in what I think was an unrelated yet eerily similar experience, a squirrel hissed at me from its tree while I was running today.

Once again, you attempt to rewrite the record, this time with a bland statement that you might now wish you had limited yourself to, but so long as you insist that you have not changed your mind on anything, then then I have the option to mention the various arguments you have offered for what was a much more emphatic position - to give just one example: "Sure you could do it that way. But it becomes exponentially more complicated because you need to either stick to one specific implementation of one specific language runtime, or you have to deal with explaining them all. Neither is ideal." That is not just "more complex", and it is not just an opinion, it contains an argument (an apparently faulty one, but an argument nevertheless.)

So long as you continue to deceptively misrepresent your former opinions and statements, there is no point in me posting an alternative here for it to be similarly misrepresented, but I will repeat my offer to do so if a third party gets involved.

As most of your last post was devoted, once again, to claiming (without any attempt at justification) that I don't have a leg to stand on, it seems negligent of you to omit making an attempt at a refutation of even one of the many points I have raised in the course of this thread - anyone would think that it is yourself who you are actually describing. I am sure it is just an oversight, so here's one example for you to tackle, left unanswered from the very post you were replying to: what do you think is wrong with eslaught's explanation?

> what do you think is wrong with eslaught's explanation?

Who said anything was wrong with it? All I ever said about it was this:

https://news.ycombinator.com/item?id=9393447

Which says nothing about it being wrong.

In fact, to back up my opinion that his post is slightly more complex, and perhaps harder to understand, here's a thread where I in fact use an even simpler explanation than eslaught's, and the person I was explaining this to still didn't get it. Even they brought up C++ to try to clarify their position, and it turns out that by doing so they actually ended up proving themselves wrong.

So in at least one concrete case, using C++ was actually better (more precise with fewer words and examples).

https://news.ycombinator.com/item?id=9248590

But I really did mean that I was entertained by watching you make stuff up and repeatedly fail at whatever your goal is, so by all means, don't stop now :)

It is said that for a goldfish, each turn around its bowl is a new experience, because it remembers nothing of its previous circuits. You appear to be in the same situation, unaware that each claim you make is contradicted by something you wrote earlier.

Take, for example, "all I ever said about it was this". What you actually did was first make the claim you are now repeating, and then, when I pointed out that doing so completely contradicted your original position, you changed your mind and decided that Eslaught's explanation was irrelevant (https://news.ycombinator.com/item?id=9433742). Now that I have asked on what grounds you consider it to be irrelevant, you have circled back around to your original position, creating a lose-lose situation in which you have contradicted yourself regardless of what your actual opinion is.

You have reached the point of creating epicycles of contradictions within contradictions, as all this is going on within your larger contradiction of first claiming inordinate complexity of any alternative to your approach and then trying to rewrite that as being merely a claim that there is necessarily some slight increment in complexity in avoiding C++. Let's look again at what you actually wrote:

"Sure you could do it that way. But it becomes exponentially more complicated because you need to either stick to one specific implementation of one specific language runtime, or you have to deal with explaining them all." https://news.ycombinator.com/item?id=9266387

That is not a claim of just slightly more complexity, and the phrase following 'because' is an attempt to offer some sort of explanation for this claim. It is obvious to anyone that you have changed your mind on this, and you have never attempted to offer any justification for the 'because' phrase, but so long as you insist that you have not changed your mind, it is not unreasonable for me to point out that you are still wrong even after one more turn around the bowl.

Furthermore, in attempting to present an example, you are having a problem with logical quantifiers. Putting aside the absurdity of claiming to believe that this sorry dialog is simpler and more straightforward than Eslaught' straight-to-the-point paragraph (the first one in https://news.ycombinator.com/item?id=9249285), one example cannot establish the general claim you originally stated, and your attempt to do so is simply an error in logic.

I see that my goldfish analogy is not quite complete - your revolutions are getting faster and tighter. This is not so much the trajectory of a goldfish in a bowl as one being flushed down the toilet.

Two goldfish swim around a bowl. One follows the other, preaching about how sad it is to swim in circles all day...

> I pointed out that doing so completely contradicted your original position

And I pointed out to you that I haven't contradicted myself.

Since you seem to have lost the thread, I'll help you out.

    https://news.ycombinator.com/item?id=9486220
Do you think you can find your way? Or should I link to the rest of it?

> It is obvious to anyone that you have changed your mind on this

I haven't changed my mind at all. Where did I say I have? Can you link to it for me please?

> I have asked on what grounds you consider it to be irrelevant

You didn't ask that. You asked "what do you think is wrong with eslaught's explanation?" I'll link you there too...

    https://news.ycombinator.com/item?id=9549017
> in which you have contradicted yourself regardless of what your actual opinion is

You keep using that word. I do not think it means what you think it means.

Looks like I was right about my prediction:

    https://news.ycombinator.com/item?id=9486220
Please come up with something new to entertain me. Don't get me wrong... this "contradiction" and "your opinion is wrong" quest was fun, but if it's all you've got, let me know - I'm only interested in wasting my time on such a vapid conversation if I continue to get a kick out of it. To do that, though, I need some new crazy from you. Old crazy doesn't cut it any more.

And try not to take so long to do it. I do so look forward to reading your ridiculous replies; you took so long on this past one that I thought you might have finally gotten some sense somewhere.

I'm glad I was wrong :)

It seems that every time I say something, you feel the need to parrot it back, except that you often get it wrong in a way that shows you just don't get it. For example, after I described a couple of your bogus arguments as rhetorical tricks, you decided to call some of my words rhetoric, when they were simply ridicule. Now that I have found occasion to make a goldfish analogy, for some reason you seem compelled to also mention goldfish, but you do so in a way that quite obviously applies slightly (or exponentially, as you would put it) more to you than me.

This form of discourse, in which one party simply repeats back the claims of the other, as if they were applicable without having anything to support the reversal of attribution, might be called the "no, you are" style, on account of this being a phrase that is commonly used by its main adopters. As it happens, there is a video on that subject, and as you have repeatedly said how much amusement you get out of these exchanges, we can expect this will probably have you rolling on the floor: https://www.youtube.com/watch?v=ZRx8PFdurgo

With regard to more substantive matters, I think you should know that if you post a link to a claim that was made without any supporting evidence or justification, it does not magically gain those things in consequence. On the other hand, links that did have those things originally retain them, so we can see that your earlier statement

"Sure you could do it that way. But it becomes exponentially more complicated because you need to either stick to one specific implementation of one specific language runtime, or you have to deal with explaining them all." (https://news.ycombinator.com/item?id=9266387)

stands in contradiction to your later attempted rewrite

"The only claim I made was that your specific explanation (which you never actually wrote), which you said would include stack frames, machine addresses, and the like, would be much more complex than referring to C++, in my opinion." (https://news.ycombinator.com/item?id=9433742)

Just to be clear, you didn't try limiting it to a statement by me until after you had made the first statement and I pointed out its problems (https://news.ycombinator.com/item?id=9269186), and not even then, immediately. Only after I showed that you couldn't explain it away as 'conversation' did you try to rewrite it as in the second quote above.

more significantly, you have refused to offer any justification for the phrase "because you need to either stick to one specific implementation of one specific language runtime, or you have to deal with explaining them all", which Eslaught demonstrated to be false, while you are apparently still claiming never to have been wrong.

I repeat my statement that I will present an explanation once you show the courage of your convictions by saying what, in your opinion, is wrong with Eslaught's straight-to-the-point explanation:

"Except you still have no way to modify the variable binding on the caller's stack. This is what all of us in the "Java is call-by-value" camp keep yammering on about: changing a value on the heap (an array or object in Java) is not the same as changing a variable on the stack (a local variable in Java). In Java, you can never touch local variables on parent functions' stacks, therefore, Java cannot be considered pass-by-reference."

You are trying to wriggle out of dealing with this one by making a distinction between "wrong" and "invalid", an act of desperation which underscores that you have run out of ...

I got so excited when I saw the wall of text! I thought, "I will surely be entertained, for there must be some new crazy somewhere in there".

But I was wrong.

You are still going on about old crazy. You still think you can tell someone what their opinion should be, or that they shouldn't use phrases like "exponentially more complex" and "much more complex" without them being incorrectly and repeatedly accused of being contradictory.

And you still think that the confused folks in this thread understand the distinction between "local variable object references" and "the objects they reference", even though you yourself are referring to Solipsism's thread in which he does not understand that even after translating it to a language he is more familiar with?

Sorry mate. But don't despair, I'll give you one more shot. But bring some new crazy please, and shorten up your ramblings a bit.

Or I'm afraid I'm going to lose interest :(

It's good to have the old JJ back! - the one who wasn't afraid to display his impotent apoplexy. It's so much more entertaining (and probably honest) than the faux bonhomie that you rather heavy-handedly affected in your last few responses. I could tell, somehow, that you were still there.

And you return bearing a gift, in the form of your paragraph about Solipsism's comments. Firstly, you are making the logical error of trying to affirm a general claim with a specific instance. This means that the example cannot possibly settle the matter in your favor, but it can still do damage: your best example of the helpfulness of C++ in explaining Java argument-passing is a case where someone used C++ and got it wrong. This is risible, and your statement about Solipsism's familiarity with C++ only makes it more so. Thanks, JJ! While your act of self-implosion makes my opinion moot, I personally would advise Solipsism to read Eslaught's explanation, with special attention to the first paragraph of his last post (https://news.ycombinator.com/item?id=9249285)

Beyond that, I see you are again trying to rewrite this thread by repeating a couple of excuses that have already been effectively refuted: "it's just my opinion" and "it's just conversation."

You seem to think that calling a statement an opinion immunizes it from being wrong, but it doesn't work that way. An opinion (or set of them) that is self-contradictory is wrong, and similarly, so is an opinion that is contrary to established fact. These opinions are not even worth giving any further consideration; notable examples include flat- and hollow-earth theories, and creationism.

So, putting aside for the moment your self-serving attempt to have everything except your mistakes taken literally, even a 'conversational' reading of "Sure you could do it that way. But it becomes exponentially more complicated because you need to either stick to one specific implementation of one specific language runtime, or you have to deal with explaining them all" finds that you are claiming a stack-frame based explanation will necessarily be inordinately complicated, and even more so when read in its original context (including your precursor posts.) So when you judged (in what is surely a minority self-serving opinion) that Eslaught's explanation was only "slightly" more complex than a C++-based one, you tacitly admitted that your original 'opinion' doesn't hold water. As soon as I pointed out that you had done this, you changed your opinion of Eslaught's explanation, now claiming that it was invalid in some way. Not only was this itself a change in your stated opinion (and a dead giveaway that you knew this to be so), but you created a contradiction with your first evaluation of Eslaught's explanation: if it is being judged as slightly more complicated than the one you prefer, then it is has already passed muster (and nobody but you would question that, anyway.) This is just one more example of how your attempt to claim you have made no mistakes has led you into making more.

But the idea that you are merely presenting your opinion is itself an attempt to rewrite the record. Your original claim was to have made no mistakes, and you only tried to pass your mistakes off as opinion, and thereby claim for them an imaginary immunity from being evaluated, once you realized your factual claims did not stand up. For example, take the clause following "because" in the first quote above. In the context of its use (i.e, following "because"), it has only one purpose: you are presenting this as a basis in fact for your claim of complexity (and also perhaps that you meant 'exponentially' literally, even though it doesn't work as such; whether you are a reliable reporter of your opinions is an issue we will get to later (hint: you are not...

The entertainment value asymptotically approaches zero for me when your updates are this sporadic, verbose, and vapid.

I'll assume you are done dancing, given the continued weakening of your performance. But if I am mistaken, and you do abandon your current trajectory for something new and interesting, perhaps I'll come watch again.

It's a shame, because I did so enjoy your early work. Seeing someone adopt such an arrogant position, only to flail about for this long in a spectacular display of nothing at all... well schadenfreude is the word I would choose for it.

Don't give up.

How sweet of you! No sooner did I mention how enjoyable it was to see your impotent apoplexy return, than you let loose another volley (I hope this doesn't come across as churlish, but I have to say that while the impotence is unparalleled, the apoplexy is not quite at the level it reached before you realized you were signalling your frustration at having your every argument refuted.)

On the subject of arguments, I see that this is the first time in I-can't-be-bothered-to-count that you have you have not tried to insinuate (without an actual argument) that the points I made in my preceding post are invalid (IIRC, the last time you tried an actual argument, it was the fiasco in which you ended up attempting to pass off 'slightly' as a conversational synonym for 'exponential'.) Could it be that you have finally realized what Mark Twain was going on about in his well-known aphorism about keeping quiet or removing doubt? Or, after having taken another turn around the bowl (https://news.ycombinator.com/item?id=9610430), will you once again repeat the same old insinuations that failed before? My money is on the latter.

If you are unsure where to start, may I suggest (once again) that you attempt an actual explanation (as opposed to either merely insinuating that there is an explanation to be found somewhere, or attempting to rewrite your original claims as something completely different) as to why you think Eslaught's explanation does not refute your original claim about the complexity of all stack-frame-based explanations?

Most people would recognize that "...because you need to either stick to one specific implementation of one specific language runtime, or you have to deal with explaining them all" is not just "conversational prose", it was intended to to look like a factual argument for a proposition (notice the use of "because".) If it doesn't need refuting, that is only because it is so obviously wrong.
> References in Java are pointers

In HotSpot references are double pointers (useful for moving GC), but in general it's up to JVM implementation. Pointers are one form of references, which are usually understood as machine addresses, but not all references have to be pointers.

We aren't taking about implementation details when we talk about object references being pointers in Java. It is actually the language level terminology that is correct to use absent of any specific implementation. See the JLS.
(comment deleted)
I agree it's bad habit, but I don't see it in the article.

The article goes to great length to argue why Java should use the same terminology as other languages. I would not say that the statements:

Sun wanted to push Java as a secure language, and one of Java's advantages was that it does not allow pointer arithmetic as C++ does.

They went so far as to try a different name for the concept, formally calling them "references". A big mistake and it's caused even more confusion in the process.

can be called "actively trying to misunderstand people". In fact it shows an understanding with the position he's arguing against.

One amusing artifact of that leaky abstraction is "java.lang.NullPointerException". How is that even possible, if Java doesn't have pointers under the hood?
There are no claims that Java doesn't use pointers. You just don't have direct access to them. Also i don't. Think the entire purpose was to hide pointers for correctness sake but to make the memory model consistent across plarforms.
You don't have to "actively try to misunderstand people" who confuse the meaning of the word "as" with the meaning of the word "by". They are confused about the precisely defined, widely understood meaning of words, and they already actively misunderstand the English language, as well as the Java language specification.

If I drove your grandmother BY a car, it would be totally different than driving her AS a car (logically: if your grandmother had wheels, then she'd be a car). In the same sense, passing the value of an object BY reference is totally different than passing a reference to an object AS a value.

Nobody's "actively trying to misunderstand people," because those people are already actively confused and insist on clinging to and spreading their shallow, incorrect definitions that directly contradict the Java language specification itself.

No matter how many times how many people patiently explain it to them in clear unambiguous terms, they still insist they're right and everyone else including the Java spec and James Gosling himself are wrong. Just look at all the ignorant postings in this thread by people like Mark Stock, Mark Hedley and Kevin Ryan, who just can't get it through their heads that they're wrong.

http://www.theserverside.com/discussions/thread.tss?thread_i...

Also up there with taking a technically correct article personally and flaming the author instead of fixing your own misunderstandings.
> Java passes "references by value". Meaning the target method receives a _copy_ of the pointer, not the actual pointer.

Which is exactly how C does it. I don't see how this is a difficult enough concept to grasp that we need an article explicitly pointing out how Java is just like C in this respect.

Because in C you have to specifically ask for something to be a pointer. "pass by reference" is an incorrect phrasing, but at least it's an attempt. There is a crucial distinction between Java and C.

And C++ shows actual reference passing.

> "pass by reference" is an incorrect phrasing

No, it isn't.

In C, a pointer is a reference. It supports arithmetic, but it works like a reference as well, so the name applies.

What might confuse people is that in C, you do have to specifically ask for a reference to something, whereas in Java, everything which isn't a primitive type is already a reference.

It's true your code can't dereference those references such that it gets access to all of the data in a List object, for example. C works the same way, again: It's entirely possible to say something like 'typedef struct foo mfoo;' and then declare all of your functions to take pointers to type mfoo, and client code will never be able to get its hands on a struct foo object. FILE pointers work just like this, for example.

I don't think a pointer in C is really a reference though?

If you pass a pointer to a function, then you are saying, hey allocate a new variable to put on the stack which is a pointer. If you pass a reference, then at the language level, you are saying hey I want that function to use THIS variable that I already have. While the implementation may certainly be free to use a pointer, they are not fundamentally the same concepts.

Or so I think.

What something IS is independent of how you PASS it. An integer isn't a reference, but you can pass a reference to an integer in C++ (to implement swap, for example), while you can't do that in Java.
A pointer in C is a reference (see ISO 9899:1999 § 6.2.5) under siege by nasal demons (see § 6.3.2.3). The implementation isn't really required to do many of the things people assume it is.

(It's ironic, by the way, that in seeking to be more pedantic, you reference stacks. Stacks are not part of C.)

A C pointer is not a reference in the way we are using the word reference in this discussion (as in pass-by-reference, as in an alias for another value without applying any operators).

Sure, the C standard uses the English word "reference", as in "refers to" and "referred to", but letting that confuse you without understanding the meaning of the word in context is what lead to this Java mess in the first place. Don't bring C into it too.

I'm not confused at all, thank you. I'm of the long-standing and well-informed opinion that "pass-by-reference" and "pass-by-value" are worthless terms that need to die, and that this entire conversation is an exercise in useless academic pedantry.
Based on your previous reply, you are indeed confused. Reference is a long-established term, and using it to refer to C pointers is typically considered incorrect.

In addition, pass-by-reference and pass-by-value are very useful terms for anyone interested in accurately speaking about and understanding what will happen when they run the program they write.

There are people who consider accuracy and understanding to be pedantry. More often than not, in my experience, they are a larger source of bugs than those who strive to truly understand how their tools work.

> Reference is a long-established term, and using it to refer to C pointers is typically considered incorrect.

I am not confused, I disagree.

> In addition, pass-by-reference and pass-by-value are very useful terms for anyone interested in accurately speaking about and understanding what will happen when they run the program they write.

The terms would be useful if people agreed on their meaning (they do not) and if languages actually followed one way or the other consistently (they do not). That is the very reason this thread exists.

If you wish to accurately speak about what will happen, then speak about it. Describe what actually happens, instead of spending your time arguing about which round hole the square peg fits in better.

> There are people who consider accuracy and understanding to be pedantry.

In practice, pass-by-value and pass-by-reference provide neither accuracy nor understanding. Stop using them, and these arguments instantly vanish.

> More often than not, in my experience, they are a larger source of bugs than those who strive to truly understand how their tools work.

That I strive to truly understand how my tools work is the very reason I reject these terms as worthless.

> The terms would be useful if people agreed on their meaning (they do not)

Most people agree on the meaning (read the JSL - it says Java is pass-by-value. Read Wikipedia too. Or really any other real reference that isn't some confused people in a forum.)

> If you wish to accurately speak about what will happen, then speak about it

That's what the article does. That's what the JSL does. People in these forums who still don't get it need something more. That's what I'm giving them.

> Most people agree on the meaning (read the JSL - it says Java is pass-by-value.

I assume you mean the JLS, in which case it -- very wisely -- does not use the term "pass-by-value" (or any similar term I've seen) to label its semantics. It simply describes its semantics.

> Read Wikipedia too. Or really any other real reference that isn't some confused people in a forum.)

So is it "most people" or a reference that, if anything, supports my point (JLS), an un-encyclopedia, and unspecified "real references" that aren't from people you enjoy insulting?

> That's what the article does.

That's one thing the article does, yes. Why is it you think you need to point that out?

> People in these forums who still don't get it need something more. That's what I'm giving them.

I agree you are giving people in this forum "something more". I suspect we disagree as to what that "something" is.

> The JLS doesn't use pass-by-value

Well, maybe not the exact letters "p-a-s-s-b-y-v-a-l-u-e" in a row like that, but sometimes you have to read and comprehend.

The JLS does define exactly what happens when parameters are passed...

http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html... http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#...

And that happens to match the definition of pass-by-value/call-by-value exactly (even Java is listed as an example language for pass-by-value)

http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_val...

> people you enjoy insulting

I haven't insulted anyone, have I? At least, not intentionally. No name-calling, sticking to the facts... I'm sorry if that somehow offends you. Some of us appreciate correctness and don't attribute the chase of it as ad hominem when it isn't.

> sometimes you have to read and comprehend

If you don't understand how you're being insulting here, I can't help you.

> The JLS does define exactly what happens when parameters are passed...

Yes, it's very nice in that respect.

> And that happens to match the definition of pass-by-value/call-by-value exactly (even Java is listed as an example language for pass-by-value)

It happens to match the definition of "call-by-value" used by whoever wrote that blurb on Wikipedia you seem to love so much. The irony here, of course, is that people who like to use these terms don't even agree on how they're spelled...

None of this makes the terms useful.

If you google "pass-by-value" vs "pass-by-reference" and understand what they mean, in a language-agnostic way, and you understand what Java is doing when you pass parameters, then you too will come to the same conclusion and I have, and the people who wrote the wikipedia article, and everyone else.

If you like, though, feel free to provide your plethora of references and documentation that supports your claim that pass-by-reference is meaningless, and is also what Java does.

> If you don't understand how you're being insulting here, I can't help you.

There's no help needed. Asking someone to read and comprehend is no more insulting than pointing out where they are wrong. If being wrong insults you, then I suggest you refrain from posting misguided opinions in technical forums and standing by your incorrect position even in the face of overwhelming opposition from numerous sources.

If I was being insulting, I'd link you to the proggit thread and say "look, even proggit got it after a short discussion, why are the hacker news folks taking so long to get this simple concept"... but I haven't. Instead I would like to try to correct those who are mistaken. I feel like anyone who comes and reads the incorrect statements in threads like this should be able to then read the corrections so they too don't fall into the same traps you have.

> If you google "pass-by-value" vs "pass-by-reference" and understand what they mean, in a language-agnostic way, and you understand what Java is doing when you pass parameters, then you too will come to the same conclusion and I have, and the people who wrote the wikipedia article, and everyone else.

What conclusion would that be, exactly?

> your claim that pass-by-reference is meaningless

I didn't make that claim.

> and is also what Java does

I didn't make that claim, either. Nor would I ever. Stop putting words in my mouth.

You did though. You claimed the terms were meaningless.

But if you study, you find out they they have very specific meanings.

Calling C pointers "references" is just the tip of the misunderstanding iceberg.

But if you prefer to wander around in ignorance, by all means. Just don't be surprised when your incorrect comments are constantly corrected.

> You did though. You claimed the terms were meaningless.

Just to be sure I didn't comment in my sleep, I went back and looked, and I see the word "meaningless" nowhere in my comments.

> But if you study, you find out they they have very specific meanings.

Some people have defined them in very specific ways. The description in the originally linked article is actually one of the ones I hate the least. That doesn't make it good, and doesn't make the terms useful.

> Calling C pointers "references" is just the tip of the misunderstanding iceberg.

What, precisely, will it take to convince you that I understand your position and simply disagree with it?

> But if you prefer to wander around in ignorance

Please stop being insulting.

> I'm of the long-standing and well-informed opinion that "pass-by-reference" and "pass-by-value" are worthless terms that need to die

> The terms would be useful if people agreed on their meaning (they do not) and if languages actually followed one way or the other consistently (they do not).

Go read some actual literature about programming languages so you can get these ignorant notions out if your head.

The terms pass-by-value and pass-by-reference are well defined and have specific meanings both in the context of specific programming languages and independent of any specific programming language.

Pass by value means the value of the caller expression is logically copied in to the parameters, and direct mutations to the parameter itself are not reflected back to the caller.

Pass by reference means the opposite... The parameter is an alias for the caller's expression, and direct mutations are reflected back to the caller.

C pointers are not called references, except in an informal description of how they relate to what they refer to, by any authority on the topic.

I don't know if you are doing it intentionally or not but I'm done feeding your trolling. If you change your mind and want to learn anything else, my door is always open. But if you want to keep up this charade, whatever it is, go troll someone else. No one is going to read this thread this far down, so I feel no more obligation to correct your unfortunate misguided claims in the spirit of helping someone else who is actually looking for the right answer.

> If you change your mind and want to learn anything else, my door is always open.

I can't imagine what could lead you to think I'd be interested in "learning" from someone who clearly doesn't even understand what my claims/opinions are, but insists they're "ignorant" and "trolling".

What you've accomplished here is not to teach, but to harden my existing biases.

Even the best of us can't help the unhelpable. There has to be at least a basic willingness to listen and change.

But it's no skin of my back. My motivation was less about helping you (it was clear from the start that was probably futile) but to instead leave the right answers where you left wrong ones so others who are willing to learn can find what they need to succeed.

This far down, as I said, that no longer applies.

Good day.

You may be amused to learn that Mr. Noakes' sanctimonious rudeness has got him into a spot of trouble in another thread here.
Ah good point about the stacks. However, I think the point still stands.. an argument being a pointer just defines its type, while an argument being a reference does not define its type, but that it's an alias to another variable.

Again, I think the issue is with terminology as someone else pointed out. Certainly a C pointer can be considered a reference when using the normal English definition of a reference, but "pass by reference" has a specific meaning, and in C you can't "pass by reference"

Pass by reference has a specific meaning and specific consequences.

In C to be able to simulate some aspects of pas-by-reference you need a double pointer.

Well, he also has articles on tips for using Visual Age for Java, and a copyright notice starting in 1996, so perhaps this is yet another blast from the past that made it to HN's front page.

Because that particular argument used to be a thing.

Not everyone knows C. A large percentage (maybe even the majority) of programmers who graduate from Java schools don't know C very well at all. For them, "it works just like C" is an insufficient explanation.
"It works just like Python"
I don't know if that'd help or hurt, I've definitely seen people also say Python is pass by reference. It seems like they have the same problem.
Storically, python devs says the python language use "pass-by-name"
How so? Reading [1] on pass-by-name, I don't see how it applies to Python, which evaluates the function arguments before passing them.

The example given would be, in Python,

  def double(x):
    x *= 2
  a = [4]
  double(a[0])
If Python was pass-by-name, a would now be [8], but it's actually still [4].

[1] http://www.cs.sfu.ca/~cameron/Teaching/383/PassByName.html

Exactly. Objects in Java work just like objects in Python: pointers passed by value. The difference is that everything in Python is an object, whereas Java additionally has primitive types where the value itself is passed by value.
Or Asm, for that matter (likely even fewer programmers); at that level, basic concepts like memory addressing and pointers become almost "obvious facts of life".

As someone who started in Asm, I think pass-by-value/pass-by-reference are also intuitive there in the true "understood without needing any explanation" sense, since basically everything you'd pass to a procedure is a value of some sort, and it only depends on whether you are to interpret that value as a memory address.

> Or Asm, for that matter (likely even fewer programmers); at that level, basic concepts like memory addressing and pointers become almost "obvious facts of life".

In my intro-to-java-class, indirection was one of the first things we learnt when we learnt about objects: variables hold a reference to an object, not the object itself. I don't understand why pointers are somehow a great insight that is exclusive to lower-level programmers.

And if a java person ended up trying to make a method that swaps two primitive values, they'd have to learn about the distinction between passing a primitive value into a method as opposed to passing a reference to an object.

The problem is that most introductions stick with the primitives are pass by value, objects are pass by reference. Based on that introduction, they'd know you can't swap two primitives, but they'd think that you could swap two objects.

>I don't understand why pointers are somehow a great insight that is exclusive to lower-level programmers.

They're not. You don't need to be a lower level programmer to understand pointers, but it helps immensely if you know at least a bit of a low level language.

When you're getting into details like call-by-reference vs call-by-value, it really helps to have a mental model what the computer is doing. You don't need to be an assembly programmer, but it does help if you spend a little time studying assembly language.

I think the confusion comes from one main place.

C has the address-of operator (&). So you can pass the address of a pointer, change what that points to in a function, and then the variable outside the function has indeed changed to point to a new chunk of memory. Java only has primitives and pointers to objects, and it only allows you to pass those by value to functions. You can't take the address of a primitive or object and pass that.

So basically in C you can pass an object (struct) or even primitive by reference... or at least you can fake it with trivial syntax. In Java you just cannot do that, and I think Java's use of the term "reference" to mean "pointer" makes some people (understandably) confused.

>You can't take the address of a primitive or object and pass that.

Not correct.

In Java, if you have an object you take the address and pass it. If you have a primitive, you pass a copy of the value. Both things are called "pass-by-value" (something that confuses a lot of people).

Java has no notion of "taking the address of an object" because you never have an expression that refers to an object directly. You only have the addresses, so there's no need (or way) to convert objects to their address.

And it's all pass by value (for all values you could have - numbers, addresses, booleans, whatever).

Heh, see why this is so confusing? That is of course what I meant -- it's really that Java, passing-wise, just has primitives and addresses to objects.
The number of people who don't get it, or don't realize it is different from actual pass-by-reference and that the difference has actual consequences, is reason enough for an article.

In my experience, imprecise semantics and the misunderstandings that arise from them are a/the major cause of error, in both the requirements and implementation domains.

I work full-time in JavaScript and I've always thought of JavaScript as a pass-by-reference but this article made it clear that JavaScript is pass-reference-by-value. The `swap` function from the article doesn't swap the variables outside of the function.
javaScript != java...
The behaviour of JavaScript is equivalent for references. (Call by sharing)
Yes, but the way function parameters are passed is the same. I wrote the swap function in JavaScript and it behaves exactly like the Java version, as opposed to the true "pass by reference" examples.
This topic (I do not know why) raises some serious emotion-based responses on coders. The other topic I know will cause almost a religious flame-war is the philosophical meaning of "null" in the SQL arena.

I've tried to add some insight why the OP hears (so many) >folks (incorrectly) state "primitives are passed by value, objects are passed by reference"

What I believe was my constructive addition to the topic, seems to deserve only downvotes. I'll make a reminder to not participate again in this kind of topics.

Could be worse: could be one of the debates about Python, where people who don't work in Python insist that it must follow one or the other paradigm (when trying to shoehorn either a consistent pass-by-value or a consistent pass-by-reference interpretation on Python's behavior will lead you to write code with bugs).
How is Python not pass-pointer-by-value?
The main issue, as I noted, is people who come from other languages and have preconceived notions about what "pass by value" and "pass by reference" mean and preconceived expectations about language behavior as a result.

In Python, worrying about whether it's "pass-by-X" paradigm is practically worthless; instead, what you want to know in Python is which types are mutable.

> This topic (I do not know why) raises some serious emotion-based responses on coders.

I saw the title on HN, and was like "uhhh, no shit, why is this here?". Then surprisingly, it all of a sudden it has 80 points and almost 50 comments debating the details. I don't think there's any actually real debate on how Java actually works, this must be a purely linguistic. Or as you say, "emotional".

SQL NULLs, on the other hand, is a real philosophical war. One which the wrong size is clearly wrong and need to be crushed into ashes underneath our boots. We are not debating jargon, we are defining databases which could certainly outlive our sons and daughters!!!! .. Ok, sorry. But I just don't think it's good comparison with students who just don't really get Java. Database design is largely a matter of opinion, Java method calls are not.

It is definitely emotional for me: I remember reading yet another of these "java is not pass by reference" posts, and the title stuck for some reason. So next time I wrote a Java function (long afterwards), I modified a list received as an argument inside a function, and could not understand why my original list was modified.

I honestly feel that these posts titles are just trying to pull my leg. "Java passes everything by value!" "Really? And which value is being passed?" "The reference, of course!".

I'm on the same page as you, that's why I'm getting the downvotes.
So instead of programming based on vague recollections of blog titles, you should strive to understand the language you are writing in, so that you don't make those mistakes.

Reading the content of the articles, doing some research, and actually understanding what is happening in the language are all good steps to consider taking.

Dear author: webhostinggeeks did not actually translate your article into Serbo-Croatian for free. They just ran a shitty automatic translation and added in links that boost their black hat SEO empire.

They target many people who host highly linked articles this way. They picked Serbo-Croatian because you're unlikely to verify it.

Do not post translations unless you trust the translator (perhaps because you paid them to do good work) or know the language.

I gave up on this... It's explicitly said in the Java standard that the language is pass-by-value. On one occasion I've been told that the standard must be wrong then. Some people just don't want to accept reality if it doesn't match their interpretation of definitions. :-(
Calling it "pass by value" without qualifying that, for objects, it passes the reference by value, is very confusing.
But these are completely separate things. You can have any mix of those (c# actually has all):

- Pass by value, values hold object references. (java, c# objects)

- Pass by value, values hold objects. (c# structs)

- Pass by reference, values hold object references. (c# inout parameter, passing object)

- Pass by reference, values hold objects. (c# inout parameter, passing struct)

I'm not really sure what point you are trying to make here.

In general, the whole thing about passing a reference by value is just BS. What you need to ask is, "What am I passing to the function?"

If you are passing an object, and Java (or whatever language you are using) determines a reference (memory address or whatever), then passes that reference to the function, then you are, by definition, passing an object by reference. The important thing to focus on in this argument is, "What am I passing?" The answer for this scenario is that the programmer is trying to pass the object itself. Who cares about the address / location of the object.

If you decide to pass the reference explicitly, then you are passing a reference, not the object. This would be like explicitly passing a pointer in c++, and is apparently a controversial topic when it comes to Java. A reference will nearly always (I can't actually think of a case where it isn't) be a primitive, and therefore, be passed by value.

For argument sake, say I'm wrong about all this. My question would be, "What would it look like to pass an object by reference, and how does that differ from what is currently happening?"

The point was, that there is a language close to java which can pass objects by value or by reference. (It passes object references by value or by reference if you want to call it like that)

To pass an object by reference, it looks exactly like C#'s out/ref parameter.

    void function(ref SomeClass arg) {
        arg=null;
    }

    var a=new SomeClass();
    function(a);
    // now a is null
Which is different from what happens without ref. (or by default in Java)
Well, the standard doesn't use "pass by reference" or "pass by value" terminology. It just uses the term "value" to refer to the result of evaluating an expression.

The spec also says

> there must be a standard way for the compiler of the creation expression to pass a reference ... to the member class's constructor

So it seems perfectly correct to say that "objects are passed by reference", and that those references could also be referred to as values.

The whole fragment is actually about why non-private inner classes have an implicit constructor parameter. It talks about compiler "passing a reference". Sure - that reference/pointer is passed - but it's passed by value.

That last sentence is a bit backwards compared to the quote. The references are passed by value if one must put it like that. But nothing gets passed by reference in Java.

The confused terminology isn't related to function calls. In Java, objects are not values.

The confused terminology originates before you get to function calls -- you can't ask "are objects passed by value?" without first considering objects as values. Objects can't be stored in variables and objects cannot be the result of an expression. x = y does not copy an object y into an object x because objects are not values -- x and y are variables and they can only hold values, which objects are not.

Of course it is. It says so in the language spec, and even in the official tutorial here: http://docs.oracle.com/javase/tutorial/java/javaOO/arguments...

Swap is a nice litmus test.

To people who claim that Java doesn't have pointers, I counter-argument by the fact that you can make a circular doubly-linked list in Java. Thus, a reference is a pointer though with lesser capabilities than in C++. In contrast, you cannot make a circular doubly-linked list with C++ references which are object aliases.

Actually, I have the following analogy: pointer ~ symbolic link; reference ~ hard link.

Java's references are misnamed.

> Java's references are misnamed.

That's silly. Why should every other language adhere exactly to C++'s definition of a reference? 'Reference' as a concept exists outside of computer programming and Java isn't wrong to repurpose the term in a different way than C++.

Consider also that C++ has 'dependent types', despite pretty much no relationship to the more well-known definition of dependent types. There are only so many ways to name something.

There are also two uses of “dependent” in C++: the resolution of a name can depend on a type parameter, so you have to specify whether you want to treat it as a type name; and a type can depend on (compile-time) values. The former has nothing to do with dependent typing, but the latter does!
> That's silly. Why should every other language adhere exactly to C++'s definition of a reference?

It would be silly if NullPointerException were named something else.

Here’s an awesome thing: you actually can make a cyclic doubly linked list in C++ with references, in a manner defined by the standard!

    #include <iostream>

    struct node {
      node(node& previous, node& next, int value)
        : previous(previous), next(next), value(value) {}
      node& previous;
      node& next;
      int value;
    };

    int main(int argc, char** argv) {
      char buffer[2 * sizeof(node)];
      node* a = reinterpret_cast<node*>(buffer);
      node* b = a + 1;
      node nil(nil, nil, 0);
      new(a) node(nil, nil, 0);
      new(b) node(nil, nil, 0);
      new(a) node(*b, *b, 1);
      new(b) node(*a, *a, 2);
      std::cout << a->next.next.next.value << '\n';
    }
§3.8¶4 says:

“A program may end the lifetime of any object by reusing the storage which the object occupies or by explicitly calling the destructor for an object of a class type with a non-trivial destructor.”

We don’t need to call the destructor because we have a POD type and we don’t depend on the side effects of the destructor—there aren’t any—so we can simply reinitialise the objects. However, we have to bootstrap these with valid objects in the first place, because we have to be able to dereference “b” and “a” in order to construct the references.

Nice example! I think that can be simplified:

  node a(nil, nil, 0);
  node b(a, a, 2);
  new(&a) node(b, b, 1);
One thing I am not 100% sure about is whether the standard guarantees that those references to the old 'a' are valid references to the new 'a'.

Also, the above works in the general case where there is a nontrivial destructor or when the runtime checks the validity of those references or traverses them at destruction time (might happen when running under a tool looking for memory leaks, for instance, or when using a reference-counting garbage collector under the hood)

The standard doesn’t seem to specify it directly, but I think your simplification is also correct.
I don't think that node is a POD type because it holds two reference members. More on this here: http://stackoverflow.com/questions/4178175/what-are-aggregat...

In particular, node does not have a trivial copy-assignment operator. Further below it seems that classes/structs containing references do not have a standard layout. Hence, it is not a POD.

Also, the standard does not guarantee anything about your usage of reinterpret_cast.

Maybe the code you provided works on your particular implementation, but I'm willing to bet that it violates the standard in several ways.

EDIT: cool trick though. I forgot that a name is in scope and refers to itself just after it is declared, i.e., that you can refer to nil while constructing nil.

Ah, you’re right, it’s not POD, but it should still be safe to reuse the storage in this way. You’re also right about the reinterpret_cast, but it’s not necessary for this example because placement new takes a “void” pointer—I just did it to get the convenience of “+ 1” instead of “+ sizeof(node)”.
You can't do arithmetic on Java references, which to my mind is the most important distinction between a reference and a pointer.
Java hides the pointer, which is what confuses people.

Maybe we shouldn't be shitty about that, since it doesn't really matter too much.

Just a thought.

Java is Pass-By-Value for values and Pass-By-Copy-Reference for objects.
You absolutely CAN write swap in Java:

    void <T> swap(T a, T b) {
        // use the Unsafe to copy a's memory to a temp buffer
        // then copy b's memory to a
        // then copy a's memory to b
        // Caution: Don't pass Integers or anything, okay
    }
Or, if the objects are Beans, just iterate the properties and swap them one by one. In fact, if you know you're dealing with beans, the two don't even have to be the same class, as long as their properties and types are the same.
Not by using that signature, no you can't.
No, it's not the same.

    X a = new X("foo");
    X b = new X("bar");
    X c = a;
    swap(a, b);
    // after this, a points to X("bar") and b points to
    // X("foo"), but c should remain pointing to X("foo"). 
If you swap the contents of the object, c would point to X("bar").
The C++ implementation of swap given is wrong.

SomeType temp = arg1;

This would do a deep copy of the object pointed to by the ref arg1. What is intended is probably

SomeType& temp = arg1;

No, the article was right.

You can't do a generic swap without 3 deep copies.

If you change temp to be a reference, then once you do "arg1 = arg2", you just lost any way to get arg1's value back.

  From: James Gosling
  Date: 1/13/11

  Don Hopkins wrote:

  >Hey I know it's 2011 and we're living in the future and all that, but
  >there still seems to be some confusion and debate about a matter I
  >thought was perfectly clear: Is Java pass by value or pass by
  >reference? 

  Depends on your terminology.  But it's kinda both.  It's pass-by-value for
  everything, with the twist that for class instances, the thing that's 
  passed-by-value is the pointer to the object, so it behaves like 
  pass-by-reference.

  From: Don Hopkins
  Date: 1/13/11

  Reminds me of the controversy about Niklaus Wirth's name:

  "Whereas Europeans generally pronounce his name the right way
  ('Nick-louse Veert'), Americans invariably mangle it into 'Nickel's
  Worth.' This is to say that Europeans call him by name, but Americans
  call him by value." - Introduction by Adriaan van Wijngaarden at the
  IFIP Congress (1965).

  It seems to be a consequence of pretending pointers don't exist -- you
  also have to pretend you have variables with object values and
  references, but you still can't write a swap(a, b) function. If you
  think of Java object values as pointers, then it's obviously passing
  references by value. But if you don't believe in pointers and think of
  variables as containing objects, then it's obviously passing objects
  by reference, but your view of the world is an illusion, because it's
  really implemented with pointers.

  Or is it??? Someone suggested a Magic Elves theory, which helps a lot
  of other stuff to make more sense.
Here's the discussion from 2011 about this issue that prompted me to ask James Gosling for a clarification. You can see that many people were VERY confused, and extremely fanatical about maintaining and spreading their confusion, in spite of the fact that it directly contradicted the Java spec and the inventor of Java himself.

Java is PASS BY VALUE.

http://www.theserverside.com/discussions/thread.tss?thread_i...

The man says:

>But it's kinda both. It's pass-by-value for everything, with the twist that for class instances, the thing that's passed-by-value is the pointer to the object, so it behaves like pass-by-reference.

So he's saying: We call them all "chickens", but some of them walk like a duck and quack like a duck, so they're basically ducks.

You can't extract from that quote "THEY ARE CHICKENS" (all in caps)

When he says "kinda both" and "it behaves like pass-by-reference" I read some "subtle" hints saying that he thinks that basically class instances are passed-by-reference.

Except they don't completely behave like they are passed by reference (see swap in the article). It is only ever correct to say "they behave like they are pointers which were passed by value".

Continuing to say "they act like references" is wrong and how this mess keeps perpetuating.

"It's pass-by-value for everything" is a pretty clear, unambiguous definition that we can all agree with.

I think he goes on to use weasel words like "kinda both" and "the twist" to mean that it's true in a more abstract sense, if you don't use the precise definition of "call by value", and you're fuzzy about exactly what you're referring to (conflating the object with a reference to the object), and vague about how many times you de-reference the pointer that you're passing as a value parameter.

That's an unfortunate shortcut that many Java books and teachers take to teach Java to people who have no prior experience with any other programming language, to avoid teaching about pointers and other implementation details.

That leads to a superficial understanding of the language, and a blind spot in their misunderstandings, which you can see on display in Mark Stock's, Mark Hedley's and Kevin Ryan's stubborn postings to this thread: http://www.theserverside.com/discussions/thread.tss?thread_i...

Java passes pointers to objects by value, which can be used to emulate some but not all aspects of passing objects by reference (i.e. swap).

What your argument comes down to is that you prefer to think of the reference to the object you're passing by value as being the same thing as the object itself, which is not the case. The high level behavioral effect of passing a pointer to an object by value is that you are passing the object itself by reference. But it's impossible for a Java variable to actually contain an object itself, only a reference to an object, and there's no such thing as a reference to a variable or anything other than an object in Java.

Parameter passing by reference requires being able to express a reference to a local variable of any type, including primitive types, not just an object, and you must be able to pass that reference to a function in a way that makes it possible to implement "swap(ref a, ref b)".

Unlike Java, C# does have reference parameters, and it uses the "ref" keyword to distinguish them. Since normal C# parameters are passed exactly the same way as Java parameters, and C# has a "ref" feature that Java doesn't (you can implement swap in C# but not in Java), and you argue for calling Java parameters "pass by reference", then your argument applies to normal C# parameters too, so what do you call C# "ref" parameters if not references? Or do you carry your argument to its logical conclusion, and call both C# normal and "ref" parameters "references"?

Conflating passing a reference to an object by value with passing an object or any other value by reference does not magically give you the power to implement swap, so it's not passing parameter variables by reference, it's only passing the objects that the objects that parameter variables point to by reference.

The map is not the territory.

if you want pass a reference to a reference do

Dog dog[] = { new Dog };

void method( Dog dog[] ) { dog[0] = new Dog(); }

Having this of side effect as a default would be an insane idea ofc., so I am not sure what you are complaining about :-)

No, that's passing by value a reference to an object (Dog array) that contains a reference to another object (Dog). The variable "dog" that is the parameter to "method" is passed by VALUE, not by reference. Passing something by reference is NOT the same as passing a reference to something by value.
I remember this being a hot topic on usenet back in the '90s. It's great to see it getting an outing today, and inciting equally as vigorous argument!
Is there any useful argument to be had around this, for pragmatic purposes?

No one disagrees about what Java is doing here (that I know of).

Naming is a problem if people are writing bugs due to the poor explanation.

But I can't think of the last time I've actually seen bugs caused because anyone who thought that, for example, a swap() method would work in Java.

It's something that brand-new developers might muddle up, but usually they'll learn how it works within the first year, no? If they keep track of how to treat primitives vs. objects in methods by saying "Java passes primitives by value, Objects by reference", and that works for them, that's okay. I think a senior dev should know a bit more about what's really going on, but I'm not waste the time of a mid-level programmer because, even though this code is correct, I want to talk for 20 minutes about the reason why it's correct wasn't worded quite right.

I'm far more likely to see bugs caused by people misunderstanding Java's auto-boxing/unboxing of primitives for method calls ("how the devil is this line throwing a NullPointerException?").

Novice Java programmer reads title, mutates Java object inside function, later notices side-effects, and curses author of the title.

Second novice Java programmer reads title, wants to pass objects into functions, wants to avoid expensive stack copy and writes &myObject, gets compiler error, Googles "Java pointer," and curses author of the title.

Lesson learned: author of title is either unaware of the consequences such an interpretation will cause or seeks cursing as a source of attention.

Novice Java programmer doesn't read title attempts to assign a new object to a variable inside a function, doesn't work, curses Java tutorial that said objects are pass by reference.
When in C, Python, Java, JS, or anything else does reassigning a variable from the function sig ever work? The symbol is in-scope. Even when overwriting the pointer location in C, you don't just assign; you de-reference and copy over the memory that was there. A novice programmer would make this mistake, not a novice Java programmer.
This entire thread makes me want to die. Please, do not speak of this again.
So to summarize, you have a Java function:

  public void f(Foo bar) { ... }
Which is the equivalent C++ function?

  void f(Foo bar) { ... }
  void f(Foo& bar) { ... }
  void f(Foo* bar) { ... }
It's the last one. Java passes everything by value, but non-primitive objects in Java are actually pointers (which Java inaccurately calls references), and the pointer is passed by value.
This! People say java passes by reference sometimes, but in C++ the references can't be null whereas in java they can.
Cpp and c also call things volatile for entirely different reasons than Java.

These are two distinct ecosystems. They use the same terminology with different meaning. That perhaps is confusing, but definitely doesn't make one or the other incorrect.

I think this is the big thing. Maybe java references arent cpp refs. Is there a proper name for an abstract construct that refers to something else? Maybe reference?
Why is it inaccurate to call it a reference in Java?

You don't dereference a variable in Java to access it, so that would make me think reference, not pointer.

By you do deference object variables in Java. What do you think the "." operator does?
Ah, true... so what is the difference between a reference and a pointer then?
It depends on which definition of "reference" you are talking about.

Pass-by-reference and C++ references are basically the same - aliasing without requiring dereferencing via an operator.

Java object references are like C++ pointers.

Java is pass-by-value (no aliasing) for all values (ints, bools, object references etc). Java has no object values.

'a.b()' dereferences 'a' to call its 'b' method. If 'a' is null you'll get a NullPointerException.
Alternatively, the NullPointerException could be viewed as a simple leakage of implementation details, which is a common issue with exceptions.
Actually it is somewhere between the last two. I cant do pointer math but i can pass a null reference.
But you can't write into the pointer variable itself from inside the callee:

    static void f(Foo x) {
      x = ...;
    }

    // somewhere
    Foo y = ...;
    f(y);
The pointer value of y cannot be changed from inside f. Therefore Java is pass-by-value.

Java also has restricted semantics on pointers, but that has nothing to do with the calling convention.

(Edit: Note that the object which y/x points to can be changed, but that's not the question.)

So would you assert this is not pass-by-reference?

    void f(const Foo& x){
    ...
    }
My point is the semantics don't map 1:1. If you're going to say Java's references are pointers with different semantics how is that semantically different from saying Java's references are references with slightly different semantics?

    void f(const Foo&_x){
      Foo& x=const_cast<Foo&> (_x);
      …
    }
What do you think is going on here?
> What do you think is going on here?

I think you're adding code that doesn't address my point. This is pointer manipulation, not function call semantics. If you have raw pointers you can do a lot of magic. I think your code actually demonstrates how not-pointer like Java's references actually are.

Making the referenced object const doesn't change anything. Fill in the '?':

  void f(Foo* x) { Foo y; *x = y; }
  void f(Foo& x) { Foo y; x = y; }

  void f(const Foo* x) { const Foo y; x = &y; }
  void f(const Foo& x) { const Foo y; ?; }
my cpp foo is much out of date admittedly. I believe my comment explicilty deals with its parent comment. I believe your example you are setting the contents of a specific memory address. This is nonsensical in a java context. Again another example of how semantics dont map 1:1.
They do map 1:1, that's the point:

  void f(Foo* x) { Foo* y = new Foo(); x = y; } // C++
  public void f(Foo x) { Foo y = new Foo(); x = y; } // Java
If 'x' was a reference then you couldn't do that.
Except x could be an array
Except you still have no way to modify the variable binding on the caller's stack. This is what all of us in the "Java is call-by-value" camp keep yammering on about: changing a value on the heap (an array or object in Java) is not the same as changing a variable on the stack (a local variable in Java). In Java, you can never touch local variables on parent functions' stacks, therefore, Java cannot be considered pass-by-reference.

The rest of it (const, const_cast, arrays-are-kinda-pointers in C++, taking the address of stack variables, etc.) are just weird quirks in the language semantics. (Honestly, C++ is already a quirky enough language on its own to make detailed comparisons inherently problematic.)

At the most fundamental level, C++ supports both call-by-value and call-by-reference, while Java only supports call-by-value.

I get what you're saying.

I'm just saying philosophically if you're going to say it is pass-by-pointer w/ castrated pointers is that any different than pass-by-reference with castrated references?

To blur the lines: If escape analysis is enabled its entirely possible for an object to allocated on the stack. In this situation a callee could manipulate the parent stack. Granted it can't overwrite the entire region wholesale, but you could functionally overwrite it all, but java doesn't have any way of doing that semantically anyway.

Semantics don't have to map 1:1 to still have a meaningful relationship.

Java object references are mostly like C++ pointers. Even though you can't do arithmetic on them, the way they behave during assignment and parameter passing is identical. The primary qualities of a pointer are that it points to something, copies of it are shallow (and cheap) and point to the same thing, equality of pointers implies equality of the objects (but not vice versa), etc. All the same in both languages.

Nothing in Java is like C++ references (except the word reference) because the primary qualities of references are that they alias the objects that they refer to, they can not be rebound, and operations on them act exactly the same as operations on the aliased objects, with no dereferencing operators necessary, including assignment.

Once you understand that, you can begin to grasp how Java can be fully pass-by-value and yet your function can modify a list and the caller will see the change.

C(++) may not be the best choice for elucidating this issue, given the way arrays decay to pointers.

Instead of comparing Java to any other language, would it not be simpler to just say what Java does?