I hate Java pass-by-reference-by-value .

Started by
17 comments, last by rip-off 14 years, 1 month ago
Quote:Original post by cache_hit
For what it's worth, this is one of the many things about Java that make me hate with a passion reserved for few things in life.

How simple is it in practically every other language in the world to write a function that returns multiple values? For example, suppose you have some item cache and for speed you want to write a TryGet function that if successful returns true as well as the item, and if failed simply returns false? Simple in every language in the world except Java. In Java you have to do something crazy like create a new class just for the return value, like:

*** Source Snippet Removed ***


Really??? Just return null - it's just as easy to check for null as for false.
Advertisement
Quote:Original post by cache_hit
For what it's worth, this is one of the many things about Java that make me hate with a passion reserved for few things in life.

...

*** Source Snippet Removed ***


You're being silly. This is what null is for, just like kaffiene said. I hope your other grievances with Java are more substantial :-)
Quote:Original post by lightbringer
Quote:Original post by cache_hit
For what it's worth, this is one of the many things about Java that make me hate with a passion reserved for few things in life.

...

*** Source Snippet Removed ***


You're being silly. This is what null is for, just like kaffiene said. I hope your other grievances with Java are more substantial :-)


Yea, assuming null isn't a valid value for an entry. Point is that you can't easily return multiple values from a function. I don't think that's an insubstantial grievance.
Quote:Original post by cache_hit
Yea, assuming null isn't a valid value for an entry. Point is that you can't easily return multiple values from a function. I don't think that's an insubstantial grievance.


Yeah, you can't return multiple values from C, C++, or C#, either. (which can be considered Java's alternatives, for the most part)

Of course, in C, C++, and C#, you have explicit references/pointers, which can be used to resolve the issue [wink]

public bool TryGetItem(int key, ref T item){    if (...)    {        item = ...;        return true;    }    return false;}


Your specific example in Java would be better written as:
public boolean TryGetItem(int key, T[] item){    if (...)    {        item[0] = ...;        return true;    }    return false;}

It does require you to declare your item in an array, but it's cleaner than creating a whole class for it.
Quote:Original post by cache_hit
Yea, assuming null isn't a valid value for an entry. Point is that you can't easily return multiple values from a function. I don't think that's an insubstantial grievance.


You could throw a checked exception if you really wanted to, but you did say it had to be fast, so I would just leave the interpretation of null to the application developer. This is also the default behavior of the Java Collection classes (at least those that permit mappings to null values). You could also complain about operator overloading... Java trades some shortcuts for safety and simplicity - I consider it beautiful and elegant and clean, but obviously your experience has been different :-) Java is not without shortcomings obviously, but I don't think this is one of them.
Quote:Original post by rip-off
My hint is that if the line "_root = new BTreeNode<T>(obj);" stays inside the helper function _insert(), there are less special cases to handle. My solution is remarkably close to your original attempt.



So I am guessing the base case would be :

if(_root == null){ _root = new BTreeNode<T>(obj); return _root; }
else { ... }

Any more hints. Should I return instead a new BTreeNode ?
Edge cases will show your design flaws in your code!
Visit my site
Visit my FaceBook
Visit my github
how's this rip-off :
private BTreeNode<T> _insert(BTreeNode<T> Node, T val){  if(Node == null){	if(isEmpty()) return (_root = new BTreeNode<T>(val));	else return (Node = new BTreeNode<T>(val));  }  else{	int result = _compare(val,Node.element());		if(result < 0) Node.setLeft( _insert(Node.getLeft(),val) );	else if(result > 0) Node.setRight( _insert(Node.getRight(),val) );  	return Node;  }}
Edge cases will show your design flaws in your code!
Visit my site
Visit my FaceBook
Visit my github
Quote:Original post by cache_hit
For what it's worth, this is one of the many things about Java that make me hate with a passion reserved for few things in life.

How simple is it in practically every other language in the world to write a function that returns multiple values? For example, suppose you have some item cache and for speed you want to write a TryGet function that if successful returns true as well as the item, and if failed simply returns false? Simple in every language in the world except Java. In Java you have to do something crazy like create a new class just for the return value, like:

*** Source Snippet Removed ***


You aren't the only one. In University, my compilers prof's idea of a joke was to get us to generate a partial grammar for Java. Then we generated one for LISP. We were only graded on the second :).

If you find yourself having to work in Java, ever again, Someone wrote a tuple library. I suspect it was because they got tired of having to work around Java's limitations.
Essentially that is what I had come up with, except my code had a bug in it that always replaced the root of the tree [embarrass] That bug made the insert logic look simpler.

Now that I see the complete solution, it is not really an elegant solution at all, despite having a little less code that your intermediate attempt. I don't like it because it involves lots of redundant assignments and the strange logic for handling the root case.

I still think that insert logic belongs inside the BTreeNode type. It is a little longer than the other version, but is both easier to read and easier to reason about (the BTreeNode type can maintain internal invariants on the left and right references). This code would be similar to your intermediate attempt, but without the bug where the function returns null for non-root inserts.

A simple way to see this bug is if you use multiple returns. By having a placeholder return value at the top that returns null, the compiler will not warn you about control paths that fail to logically return a value (because they never write to the "result" variable).

This topic is closed to new replies.

Advertisement