Today was one of those days when I wished Java would support multiple return values. I had to develop a rather CPU-intensive algorithm which would compute a solution for a knotty constraint problem. Having a solution alone is sometimes not enough and you also need to add some parameters which measure the quality of the computed outcome. Most of these accompanying parameters can or have to be computed within the algorithm itself, but Java allows you to return only one value either an object or a primitive type. People working with Lisp, MATLAB or Perl, just to mention a few, don’t have a problem like this at all. Functions supporting multiple return values is already implemented at the language level and frameworks make heavy use of this. But as a Java programmer you are pretty much stuck here and need to consider some other means to come out of this situation. In the following I would like to give some hints on that topic. Hopefully they are of help for anyone having the same problem every now and then.
One very pragmatic solution is claiming to integrate this into the upcoming Java releases. Since Java is open source there is a good chance of a bunch of programmers gathering to implement this. We have had generics, annotations and Java 7 will even support closures. In fact it looks like with closures you can simulate having the ability to return more than one value. So why not add the functionality of multiple return values in, say, Java 8? It wouldn’t add too much semantic sugar. Well, even so I like the way the language evolves — it just gives Java an increased feeling of being bloated. Annotations are a good example for this. Great if you work, for example, with EJB but besides that I scarcely ever use them. Shouldn’t a programming language contain only the things you need for your daily task? Don’t get me wrong, if multiple return values ever make it into the Java specs I will be happy to use them, but if I would be the one to decide, I would leave them out.
Ok, lets assume you don’t want to wait and have a solution right know. Since a method can only return a single object this has to be our wrapper for accessing the different return values. Some people might now claim: “Hey, but then I have to create another object. This is a waste in terms of performance.” I won’t go into further detail about that. Java is object-oriented! If you are afraid of creating single objects then you shouldn’t use Java at all. Events are fired through Objects and many things more. So really there is nothing wrong with creating objects on a very frequent basis. javax.vecmath.Tuple3b is a good example for a simple Wrapper. It contains just three bytes and all it takes is just a single line: return new Tuple3b(aByte, bByte, cByte);
A better objection to dislike wrapper objects is the increase in lines of code that need to be written. The more you code the harder it is to read for others and for yourself in the future. This is a good point. Lets investigate what we can do about this. Take the following class for example. It acts as a wrapper for two objects:
public class TwoReturnValues { private Object first; private Object second; public TwoReturnValues(Object first, Object second) { this.first = first; this.second = second; } public Object getFirst() { return first; } public Object getSecond() { return second; } }
A perfect object-oriented approach for having a wrapper around two objects. And since Java 1.5 supports autoboxing we don’t have to give primitive types a special treatment, right? Well, this will really result in writing ugly code. Lets say some arbitrary methods needs to return a String s and an int n. No problem just write: return new TwoReturnValues(s,n);
For the callee it gets more cumbersome. Both getFirst and getSecond return java.lang.Object. Though the callee knows about the real types, he has to cast first to String and second to int. This is ugly and it is common knowledge that casts spread around your code should be avoided. Lets make things easier and add generics:
public class TwoReturnValues{ private R first; private S second; public TwoReturnValues(R first, S second) { this.first = first; this.second = second; } public R getFirst() { return first; } public S getSecond() { return second; } }
Changing the signature of the method to TwoReturnValues >String,Integer< we not only got rid of those casts, but the code looks much more straightforward. One could argue that Generics itself are bloated fixings, but like I said if it is already in the language go ahead and use it. Wether or not the two accessore methods are needed in this specific case is open to dispute. Since this Object has no other purpose as to deliver values we can ignore encapsulation at least a bid and make first and second public. However then you should declare both fields final as well and regard the whole Object as immutable! This gives you also the advantage of having a thread-safe object (unless the fields itself are mutable).
public final class TwoReturnValues{ public final R first; public final S second; public TwoReturnValues(R first, S second) { this.first = first; this.second = second; } public R getFirst() { return first; } public S getSecond() { return second; } }
The shown approach can easily be broadened to support more than two return values. As long as the callee knows how many objects he has to return and the number won’t exceed lets say 2-4 you will be fine with this solution. And a line like (i,j,r,s,t,u,v,w) = foo() will doubtless convince not anybody to vote for supporting multiple return values in Java.
Finally consider the case mentioned in the last paragraph. Lets say a method returns an unknown, but big number of values. Unfortunately here you really need to write many more lines of code to retrieve and convert all the data. Those who have worked with ResultSet and JDBC before know what I am talking about. An intermediate procedure would be returning an array of Objects, albeit you will end up using casts again if all the elements in the array have different types. But I believe even returning some kind of collection is better than adding support for multiple return statements.
If you would like to see your thoughts or experiences with technology published, please consider writing an article for OSNews.
This approach is usually generalized into tuples, which are useful in a number of situations. Examples would be:
for java: http://javatuple.com/
for c++: http://www.boost.org/doc/libs/1_35_0/libs/tuple/doc/tuple_users_gui…
That java link was nice…thanks. Once you start using tuples in other languages like Python you want to use them in everything. I looked at the code hoping it wouldn’t be a big mess and it seems pretty clean. Its not a hard concept.
I didn’t see a mention of a license in the download though. The site does say
… so it might be public domain?
EDIT: Just saw it on the bottom…. Creative Commons Attribution 3.0 United States License.
Edited 2008-07-17 17:53 UTC
Return object array, object, char separated values? How hard could it be?
but couldn’t you just return an array of pointers to the multiple data values you want to return?
1.) Java doesn’t have pointers.
2.) There’s no type safety in that approach (meaning it’s not a good idea for C++ too)
With C++ you’d just pass multiple values by reference, rather than muck about trying to “return” multiple values.
Then there is no “contract” in the function prototype. It is nice to know by looking at the arguments what can be changed and what can’t be changed. You wind up looking at the code to see what is really going on, or actually reading the documentation which nobody wants to do.
Pointers are an ugly hack. The output variable is an input to the function?
C++ allows you to declare constant references and pointers, just for this purpose.
Cool… a hack around a hack 😉
Er, not really. const is a standard feature in C++ for declaring, well, constants. Same as it is in C, and it’s been that way forever. It’s hardly a hack: certainly no more than inventing silly ways to return multiple values from a function.
Also, who said anything about pointers here? C++ supports proper bona fide pass by reference.
Except that const are not always constants in C++.
I find much more readable to have the input variable on one part of the function and the output variables on another part, of course readability isn’t C++ strong point.
Agree, “const-ness” defines a set of properties and behaviors over our methods and variables.
Let’s say:
const Attribute& GetAttribute() const;
A method marked with “const” says: “I will not modify the object state, I will only provide information”; this feature prevents a lot of errors and undesired access because it is hardly viral (for this example, you cannot invoke to a “non-const” method defined in Attribute).
The “const Attribute& ” returns a reference to an attribute defined inside our object (a really nice approach to avoid object copy or memory management “ambiguity”) If I get a const Attribute& I’m getting a working state and I have not to worry about its memory handling.
“const-ness” should be implemented in other C-like (I knew D implements it partially) languages because provides nice behavior and improves the code readibility too.
Bleah, I don’t like C++’s overloading of keywords for type and method signature..
Not always: if there’s another reference with read-write access to the same object, it can be modified or the const may be casted away.
Yup, but it caused many, many discussions: head vs tail const, const vs invariant.. Const is a concept really hard to design properly.
And the solution retained is ineleguant as for C++ compatibility’s sake, the name const is retained for read-only views (which may not be really constant!), and true constants are named ‘invariant’.
IMHO ‘const’ should be replaced by ‘view’ as in “view but don’t touch (others may do it though)”
and true constant named const.
My first thought in C++ would be to have a templated ReturnTriple struct along the lines of:
template<class A, class B, class C>
struct ReturnTriple
{
A first;
B second;
C third;
};
which is cheap, type-safe and reusable.
EDIT: Or, as another poster pointed out, just pass parameters by reference. Is this not possible in Java?
Edited 2008-07-17 17:37 UTC
Java doesn’t have data structs so it would have to be a class but the same concept works.
In fact it makes sense… if you’re returning multiple values, they have a relationship. Chances are that that relationship will be studied elsewhere in the code. For instance other methods will take as input both of those pieces of data. Or there will be methods that specifically massage that data. What better place to put them than in this return value class? So in the end such a class almost always pays off by making code easier to read and more organized.
Edited 2008-07-17 18:31 UTC
The first poster on here gave a nice link for javatuple which does something very similar. I just looked and it seems real nice. it has classes for Single, Pair, Triple etc. up to Decuple.
I’m not sure if your C++ example retains type safety but this javatuple package does.
Java has Objects and primitives (because back in the day people were bitching about performance). Primitives are pass by value, Objects are passed as a reference. This means that if you pass a Vector to a method, because it is an Object, if you add or remove from that Vector in the method the changes will be visible after the method is called. However, even though Integer is a class, there are no methods to change the value of one. So, a method that needs to return two integers could return a List<Integer> or an Integer[], but things get ugly when you need to return an Integer and a String.
Sure java has pointers. You just can’t manipulate them.
E.g.:
Object a=new Object(), b=a;
Here a and b are pointers to the same object.
To a C++ programmer, a and b look a lot more like references than pointers…
To a C++ programmer, a and b look a lot more like references than pointers… [/q]
No, they are not references, they are pointers. The code above is identical to:
Object* a = new Object(), *b = a;
a and b are pointers to the same object.
References in C++ are stuff defined as:
const Object& a = Object::GetSingleton();
a is a const reference to an instance of a class.
Java works with references and a reference is a typed pointer. So if you use Object you kind of are using pointers…
Exactly: that’s why Java made them type-safe.
Where do you get that assert from???
Everything in Java but the primitive data types are referred via pointers (ok, let’s call them “references”, but in Java they are the same).
When you declare
MyObject obj = new MyObject();
you are creating an instance of class MyObject and you are assigning a pointer to that instance.
The only difference here is that you cannot do pointer arithmetic (as in C).
If Java does not have pointers, why is there a “NullpointerException”? 😉
I’ve commented on this before 😉
http://www.osnews.com/thread?318611
Reading Your last argument in the linked post – not convinced.
As it is stated in the next thread, returning multiply results from function absolute most of the time means bad design.
Applied to the example you gave.
You should spend some time and understand what are these tables used for and for how long. If these hashtables are used often I see no reason why shouldn’t you use a wrapper. This wrapper may have some of the fetch and common processing logic loaded into to break data and computation apart. If they are short lived – why do you need a separate getter for them anyway?
Edited 2008-07-17 18:32 UTC
If you don’t see a reason why I should use a wrapper object, then why don’t you see a reason for multiple return values?
It is doing the exact same thing logically.
It isn’t often that I need to return multiple things. Hardly ever. I just mentioned one case where it made sense.
If I wanted to be “object oriented” using getters I could call one method compute() like so…
public void compute(){
  SomeClass a = someExpensiveDBOperation();
  // h1 and h2 are class members
  h1 = new HashTable<String, List<String>>
  h2 = new HashTable<String, List<String>>
  while(a.hasMoreCrap()){
    Row r = a.next();
    List<String> list = new ArrayList<String>();
    list.add(r.getString(1));
    list.add(r.getString(2));
    list.add(r.getString(3));
    list.add(r.getString(4));
    h1.put(r.getString(1), list);
    h2.put(r.getString(2), list);
  }
}
Then, when I want h1 or h2, I’d have to call a method like…
public HashTable<String, List<String>> getH1(){
  HashTable<String, List<String>> ret = h1;
  // so we’re not hanging onto it forever…
  h1 = null;
  return ret;
}
What an absolute pain in the ass.
Edited 2008-07-17 19:06 UTC
I don’t see your problem, then again I don’t know what you are trying to achieve in your program.
I never had the urge to use a multi-value return and I also came from a C++ environment, I never used it because good OO design never needed it.
Sorry to point this out but the fact that you nullify the class field ‘h1’ before returning the (reference) copy, tells me that you either do not fully understood how Java works or you need some serious OO design classes.
People should also stop using returning implementation types rather than interfaces (in this case HashTable).
Edited 2008-07-17 20:20 UTC
I know it should have returned Map. I just wrote that quick and dirty…there are probably syntax errors too.
You are sooooo right!
It is client server. The client needs the HashTables two different ways. Nullifying it on the server and returning it to the client makes it a candidate for garbage collection on the server where I didn’t want it hanging around.
All I’m saying is that there are places where multiple return values would be nice. It is basically returning a tuple but without creating meaningless wrapper classes.
This this does not explain this piece of code. When there are no references to a object then the garbage collector will reap it. Nullifying an object only helps if you have the only reference to an object but you just passed a copy as return value, hence: there is still a reference.
As for the fact that it is a client-server application, when the protocol you use is done sending the stuff over, the protocol will release it’s reference and it will most likely kick in the garbage collector. Still: an experienced Java programmer would never write code like this. And: an experienced Java programmer would never NEED multiple return values.
No and no. First – no sequence of variables covered in obscure “tuple”. This defy the very basic ideas of OO programming like encapsulation. Second – I’ve suggested not a wrapper object but rather an entity on it’s own aware of how to fetch the data, how is it encoded, how it needs to be pre-processed etc. This will allow you to decouple supplier from consumer.
And the case may point out to a deeper design problem.
I suggest you look once again at each and every case you think you must use more then one return value and try to avoid this at all cost.
in Java, if you need multiple return values in your application “most of the time” it is an indication of bad design.
Yeah…
I do .Net in C# for my job which also doesn’t allow multiple returns and I have never wished that I could return multiple values. I just make a struct.
I suppose I could also use output parameters (not sure if that is in Java), but they always seemed ugly to me.
I think it’s pretty clear from reading this article that you have very little experience in solid object oriented design. No developer worth his salt would implement a generic “two return value” wrapper like that. If you have a set of related information that gets returned, the proper way to handle it is to design a class that represents that object, and contains methods to analyze its data.
The solution you suggest is an arbitrary pairing of potentially unrelated data in a too-generic fashion, from which no meaning can be derived – and is therefor a horrible design.
I may also point out that if you NEED multiple return values (which you don’t, you want them, but noone ever needs them), and another languages supports them, then clealy Java was the wrong choice in the first place.
Right. Classes like Point, PairOfShoes, Triangle, … instead of TwoReturnValues and ThreeReturnValues. And if the values don’t relate the method should get refactored.
Reading the RSS summary I was just going to say write a class that encapsulates all the data you want to return… problem solved. I Guess that’s the solution you were advocating, never mind!
Just introduce a new class.
As you said:
And the next one will come along and demand more horrible things like out parameters, structs and pointers for Java.
I definitely second everybody who suggested that the author needs a better design rather than having the programming language to implement something non-sense.
If you need multiple return values, that means your method is coding too much logic into it and why don’t you code everything in main and if that is the case, you don’t need Java or even OO, just go back to any procedural language and even in those you only need main method.
A method (no matter it’s in object or procedural) is a unit that serves a unique purpose. You code minimum logic into one method and this is why you unit test your method (some suggests you unit test on object, not method). A method is following a simple processing model:
Input->Process->Output
If you identify only one output and you will know what you need from input and process. In this case, if you need more than one return value, I guess you should start again to understand the fundamental of programming.
No offense but just my 2 cents.
🙂
If I understand, your main idea was to have a function return an object as well as some boolean status of success. Here are my alternatives.
1. Pass the object you want manipulated, and return a boolean. Example: boolean populateObject(ObjectRef objectToPopulate)
2. Return an object reference, and test for null. Example: ObjectRef populateObject(). A null return means it failed. This is one reason I rarely use int as a return, but instead use an Integer. Then I can just test for null.
3. The best approach to do what you want (have a function return both a value and some status flag) is to use exceptions. Example: ObjectRef populateObject() throws ObjectPopulationException. Then your external code would use a try/catch to call this function. This is the norm with languages that supports exception handling.
Just my 1/50th of a falling dollar.
I usually try to avoid this, since Java does not codify your intention in the method signature. The obvious danger is that if it happens more than once in a library that you will confuse the library user. If it happens only a few times, you will suprise the user. It’s a solution, but be careful!
Actually, I am happy C++ allows pass by value (where a value can also be a pointer), and pass by reference. If you really want to modify variables or instances provided through a parameter list, you can make this more explicit by using a pointer (without constness).
That’s usually not a good idea for math-intensive code due to all the boxing/unboxing that takes place. At other places this can be a good solution, if documented.
If the return type is a floating point type, and the parameters cause an invalid result, returning NaN is an option.
Be careful there as well. Exceptions are for when… something exceptional happens. The danger is misusing exceptions as a mechanism to return values. Of course, Java does provide some good exceptions for common exceptional occasions. For those cases, prefer one of the exceptions that Java defines.
Edited 2008-07-17 20:21 UTC
From the article:
Having a solution alone is sometimes not enough and you also need to add some parameters which measure the quality of the computed outcome. Most of these accompanying parameters can or have to be computed within the algorithm itself, but Java allows you to return only one value either an object or a primitive type. […] But as a Java programmer you are pretty much stuck here and need to consider some other means to come out of this situation.
Actually, you are mistaking a inherent property of Java and other static-typing languages as a disadvantage. If used properly, it is an advantage: the person implementing the caller code can exactly see by looking up the function or method declaration what to expect. This is a potential downside of dynamic languages, that can usually return anything, as long as it is (usually) a reference to something.
With the proposed solution, there’s a risk of returning something that is potentially meaningless to the caller. Therefore, in such situations it’s normally best to either: use more getters (where appropriate), or if the data in strongly coupled (which appears to be the case in the example mentioned in the article) return it as a class with its own getters.
Sure, there are situations where tuple-like classes can be useful. A good example is std::pair in C++, which is used for data stored within a map. The first element of the pair is used as the key, the second element as the value. Most if not all (since std::map provides ordering guarantees) implementations of std::map store these pairs in a binary tree that is ordered by the key. It’s also convenient for iteration.
But for what my opinion is worth, this article makes a design error, it’s the kind of approach you’ll want to avoid in a static-typing OO language.
Very weak argument.
You want multiple return values? Use an array, then you have as many return values as you like, no objects required.
Making Java as dynamic as JavaScript would be a mistake and it’s this kind of dynamic feature creep that could lead to that.
If you are in the need of returning more than one value by a method, you should probably think about your software design!
Man, do I hate complications.
If you really must have multiple return values, just use a map and return it. Better than that, you can have named values:
Map Foo()
{
Map ret = new Map;
Map[“return1”] = X;
Map[“return2”] = Y;
Map[“return3”] = Z;
return ret;
}
There you go. Problem solved. BTW… I haven’t used java in a while, so that may not be syntactically correct, but the point is the same
If you think this is too slow due to the lookup, you can be annoying and use a Vector instead .
So… why add more crap to a language?
I think what the poster needs is really what’s in Common-Lisp (I don’t know whether something similar exists in other languages too).
Let’s take as an example the standard floor mathematical function, that would return the integer portion (and in Common Lisp it might return additionally the remainder portion).
Normally people are only interested in getting the integer part, so all they are doing is this:
(setf some-var (floor some-other-var))
In “C” this would be:
some_var = floor( some_other_var );
The user is not even aware that floor can actually return two values, because it’s still used as if it was returning one (in such cases the CL compiler might be smart enough and optimize it).
Now if you want 2 values to be returned – the integer part of floor, and the rational (floating in other languages) remainder, here’s what you’ll have to do:
;; Let’s put in some-other-var the rational 3/2
(setf some-other-var 3/2)
;; Now get the two values
(multiple-value-bind (a b)
(floor some-other-var)
(format t “A=~a B=~a” a b))
—> A=1 B=1/2
The long-ish MVB multiple-value-bind form is going to assign local variable ‘a’ to 1 and ‘b’ to 1/2, format is printing them.
Documentation: http://www.lisp.org/HyperSpec/Body/mac_multiple-value-bind.html#mul…
In Common-Lisp there are 4 or 5 such operators specifically for getting multiple return values – some can accumulate the results directly in local variables, others in lists, etc.
I am getting depressed from this discussion. All this “if you want to return multiple values, your design is wrong” nonsense. It’s useful! Try it in Python, at least once.
The reason why Java (and C and it’s predecessors) didn’t support it is historical and comes from mathematics. In mathematics, functions that return multiple objects are useless, because you can just have multiple functions.
However, in programming, you often need to compute something and you get some other useful result as a side-effect of that computation. Classic example is the quotient/remainder example in the integer division. To split it into two functions, you would have to do the division twice, which would be silly. Sure, you can also wrap them into an object or struct or whatever, but compare this to Python, where you just “return them” and it’s completely natural.
So please, stop saying that just because your language of choice doesn’t support it, it’s not useful. Because it is.
I don’t see any problems in creating an object for that. Even if you think it will overhead, when you pass it as an arguments to another method, you’ll find the object very usefull, because you only have manage one variable per result. Additionally I like the idea of not changing method signatures (and thus breaking backward compatibility), just because I need another argument.
Well, Python also creates an object (a tuple), so you can actually retrieve and manipulate the return values together. So this is a solved problem.
Anyway, my point is it’s not always quite useful to define an object. In some cases yes, for example, if you have a point in 3D, then you probably want to have it as an object.
But in some cases, it is pointless to have an object “result of integer division”. So why even bother?
Imagine a language where you can only have functions with one argument. Sounds silly? But it is exactly what you are defending. You could also say, well, you can always construct an object from the arguments, and it will be helpful in many cases. You could also say that it would be good because the function signature would never change.
In fact, I don’t see any reason why it couldn’t be completely symmetric. Thus, why cannot we have multiple return values, default return values, keyword return values and unlimited number of return values. The only reason I see is historic – we are used to notation that doesn’t allow all of this stuff.
At first glance, yes. But let’s think this some further: Normally you just put “something” and “something” into a method and getting a “something” and maybe another “something” back. Like this:
(c,d) = divide(a,b);
If you find this call in a sourcecode: How do you know, what’s the divisor, remainder, etc.? You have to look at the documentation and interpret the call.
Now imagine this example in a one-parameter-,one-return-value-language:
DivideParameter params = new DivideParameter();
params.dividend = a;
params.divisor = b;
DivideResult result = divide(params);
c = result.quotient;
d = result.remainder;
Ok, it’s much more to code, but it’s much easier to understand, without looking at the documentation.
A good solution in the middle of this, would be named parameters/return values, so you can easily see what’s going in and out.
If you just want multiple “somethings” as return values, define the return value as Object[].
So, you basically agree with me that the situation with input and output values is symmetric.
However, I don’t agree that the second example you give is more readable. In a large program, every line and every technicality obscures the high-level structure. To show you the types of parameters of function you are looking at is a job for IDE or some source code browsing tool, and it should not be needed to write it up again and again endlessly in the source itself.
Hi!
I’m in Java programming for 9 years now, but never really seen a problem with multiple return types.
Normally I would prefer the data object style to return multiple values, because the data returned from one method is often related. So the object groups the data and dealing with the related informations is much easier. Changing the information is much easier, too. Think about:
Position calculatePosition(), goTo(Position pos), runFrom(Position pos)…
instead of:
int[] calculationPosition(), goTo(int x, int y, int z), runFrom(int x, int y, int z)…
If the data one method returns is not related, you should double-check your code, because it smells (see “code smells”).
/Nyarla
All those who claim that it’s “useless” have never tried Python. If Java would borrow Python’s multiple return types, it would look like this:
public (String, int) findName(List<whatever> names)
{
String name;
int number;
// do some searching inside the list…
// …
// finally return the name and the amount of
// data that has been searched through (just an example)
return (name, number);
}
String name, int number = getName(someList);
System.out.println(“Found: ” + name);
System.out.println(“I had to search through ” + number + ” items”);
Now tell me that ain’t useful? Of course it’s not something you need everyday (and it might really be bad design in many cases), but there are cases where you want to return two things that are not so closely connected to each other that they really belong into the same class.
I have used it in Python before and it’s very useful. I wish Java had this.
Oh, please.
Sure you can do the same thing. Return an immutable list of ‘Object’s. Because that’s what Python actually does (it returns a tuple). That’s different than allowing for multiple return types (viewed from a static language).
People don’t do this, because it sacrifices type safety. Of course, you will have to cast it back to some class type to make its methods visible again. (And you can’t apply some of the syntactic cleverness that some dynamic languages offer in the calling code.)
If you don’t want to do that, you are picking the wrong language. Java is a statically typed language, Python is dynamically typed. If you want a dynamic language for a particular job, use a dynamic language. Don’t expect a static language to act as a dynamic or vise versa.
Edited 2008-07-18 14:20 UTC
First of all, I would like to give you a very basic exam on how to call a method:
Where did you get that method from when your method defined before was findName(…)?
Besides, you really need to learn what is OO. Even this example is not enough to proof you have enough OO knowledge. Let’s say your example is to show that customer name with total number searched. You create an object that wraps these two values and pass it back to the caller until you reach your “View” and show it. This is value object pattern and if you create Frontend application, this becomes, somehow in web sense, your “Model” in “MVC”. Tell me, if you have 5 layers (caller methods) between this “findName()” method and the frontend. During development cycle your requirement is changed 3 times for return value to include “long searchedInMilliSeconds, int listSize”, you have to change all 5 layers (may be more than 5 caller methods) because they all return multiple values. I don’t think this makes any of sense.
In the end, if you like the way of returning multiple values, why do you want “List” as parameter? You simply extract all values from this list, pass them all as parameters like the following:
public (String, int) findName(String name1, String name2, String name3, String name4, String name5…[until all names are passed]){
…
}
If you really like this way of programming, then I guess you don’t even need/like to use array. If this is the case you may want to find out where your strength is really in instead of programming.
You have never tried Python.
Well, I am SOO sorry that I once wrote getName und once findName – this was an EXAMPLE, it’s likely to make such a mistake if you’re writing this stuff into that comment box here…
And don’t tell me I don’t know about OO. This actually hasn’t got anything to do with OO, it’s just a tiny, tiny EXAMPLE of why multiple return types CAN actually be useful, or – maybe better – how an actual implementation would look like in Java. Cases where it might actually be useful should be made up by everyone themselves, I think every programmer should have just about enough phantasy to do that.
And yes, it’s not useful for EVERY case (remember the sentence: “When you’ve got a shiny new hammer, every problem looks like a nail”). But there ARE some cases where it is indeed useful.
Python implements that feature. What do you think is the justification for this – widely used – feature in this – widely used – language, if it ain’t useful and hasn’t got anything to do with OO and and and…
Also, it hasn’t got anything to do with type safety (not sure if it was you who mentioned that or someone else), because as you can see in my example, it would be actually VERY typesafe indeed. Because the types “String” and “int” are actually written there. And if you would return some other stuff instead, a good compiler _might_ tell you about that. Yes, Python just returns tuples, but they can be immediately assigned to seperate values (JUST like in my Java example) and if it would be included into a statically typed language, who would claim that it would be necessary to use some kind of Tuple<Object, Object> internally? No one, because it would be bullshit. And I didn’t say that either. It would be no problem for static types (JUST like in my Java example).
People should really spend more time with the fundamental parts of computing.
For instance – there is a HUGE cluebyfour in understanding the fundamental parts of LISP (S-expressions).
If someone, for an instance of a second, thought that this was a real problem with Java they should take a break and google up some fundamental LISP-knowledge and be a lot wiser.
As an added benefit you’ll understand why those LISP/Scheme nutters (they are, really) are correct when they say that their language is beautiful.
Maybe I better clearify some parts.. Some claiming it is bad design. Could be, but design is always nice in theory but hard in practice. The intention of this article was for cases when multiple values are needed. I agree when implementing some UI, stuff like this is a bloat. But when using (misue) a language like Java for say number crunching algorithms the algorithms are itself messy and hard to read. There is no good design just from the beginning. Asgard gave a example. Do stuff like linear integer programming, data mining and you want multiple return values. One could argue: Why then Java? – use Matlab or Lisp. Yeah sure, I would like to. But sometimes the decisions are not yours to make and you have to reuse stuff your colleagues worked with.
Multiple return values are fantastic, but Java as a language doesn’t really need them. It’s built in a way that demands their absence.
I’m primarily a Perl hacker but I’ve done some lisp, too. It’s not really about returning two things from a function, it’s about the way your code is structured.
In Java of course you’d just wrap things in an object. Preferably your code would not suck and the things would be related.
In C#.NET you could do…
SomeObject one = new SomeObject();
SomeObject two = new SomeObject();
private void ReturnTwo( out SomeObject objone, out SomeObject objtwo )
{
objone = whatever;
objtwo = whatevertwo;
}
(It’s been a while since i used c# tho… but there was out and ref, out needed the parameter pre-initialized and ref allows you to initialize it inside the meethod)
Or something like that.
I think it is about time OSNews supports Unicode properly.
How about simulating a C pointer with an object? Then you can do it just like the C people do it.
public class Pointer<T> {
public Pointer(T val) {
value=val;
}
public T value;
}
Pointer<Type1> a;
Pointer<Type2> b;
myfun(a, b);
public void myfun(Pointer<Type1> a, Pointer<Type2> b) {
a = null;
b = new Pointer<Type2>(new Type2()));
}
Sorry for replying to myself, but the preview doesn’t seem to work quite right with angle brackets.
Let’s try this again:
public class Pointer<T> {
public Pointer(T val) {
value=val;
}
public T value;
}
Pointer<Type1> a;
Pointer<Type2> b;
myfun(a, b);
public void myfun(Pointer<Type1> a, Pointer<Type2> b) {
a = null;
b = new Pointer<Type2>(new Type2()));
}
Scala solves this in a manner that actually preserves the nice design principle.
Here’s an example:
object MultipleReturnValues extends Application {
// Define a class for the return value
case class RetVal(intPart: Int, fracPart: Double)
// Define a function returning values of that type
def floor(value: Double) : RetVal = new RetVal(value.floor.toInt, value – value.floor)
// Extract the parts of the return value and declare vals to hold them
val RetVal(i,f) = floor(10.4)
// Print the result
Console.println(i + ” ” + f)
}
The nice thing with scala is that it can easily be mixed with Java code.