views:

8561

answers:

20

This question got me re-thinking about something that always bothered me:

Does Java need tuples?

Do you feel the lack of them in your day-to-day work? Do you think tuples would simplify otherwise complex data structures you find yourself implementing?

+2  A: 

Isn't a data-only class with public fields effectively just a tuple?

Alnitak
It's not convenient. Look, if I want to return a pair of two coordinates x and y, and that translates to typing: ^x@y, then that's ok. The other hand: ArrayList a=new ArrayList();a.add(x);a.add(y);return a; - plus: /** This method returns a list that always has length 2. first entry is x, second y.
nes1983
Yes, but "return new Pair(x,y);" or even better "return new CartesianCoords(x,y);" is much better than abusing List for this purpose.
Andrzej Doyle
yes, that's my point. If I want a pair of coordinates, I'll pass back a Point(x, y) object. No need for getters or setters, etc, just use it like a struct in 'C'.
Alnitak
+10  A: 

I think it definitely does. But tuples are just one of many language features that Java lacks, including closures and basic type inference. It's interesting to see how Scala will do in the future, as this is a JVM-language that implements a lot of the sexy language features that Java lacks.

EDIT: Of course, for tuples to be effective in Java as a native language feature, some sort of pattern matching is also required.

Ulrik Rasmussen
To be fair, Java does have basic type inference (in relation to generics), though crude might be a better description. This is one feature .NET has added of which I am **really** jealous.
Hank Gay
+1  A: 

Anyone who has used JPA and Object arrays to return multiple items for a JPQL query will tell you Java needs an equivalent of the C# var type.

cletus
Actually, the var "type" in C# is not allowed as return or parameter type; it is for inferring types only on local variables.
Rafa Castaneda
A: 

What I really miss is some type of list that's not mind-numbingly annoying to work with. If I could declare and use an ArrayList of different types of objects without a metric ass-ton of casting I'd be much happier.

I don't think tuples (in the Python, same-as-lists-but-immutable sense) are really critical though.

Steve Losh
can't you use the generic ArrayList<type> to avoid casting issues?
bobwah
What if I want an ArrayList of some Integers and some Strings? I can use an ArrayList<Object> but then I need to cast on the way out.
Steve Losh
The solution is to not use a statically typed language like Java of course. But even then I'm hard pressed to find an example where it would be a good idea to store strings and integers in the same list!
Wim Coenen
Maybe a HashMap would be a better example. In Python I can say: person = { 'name': 'Steve', 'last_login': datetime.datetime.now(), 'karma': 722 }; print person['name'], person['last_login'].day, person['karma']*10; That'd be a *lot* of casts in Java.
Steve Losh
`Person p = new Person("Steve", System.currentTimeMillis(), 722); System.out.println(p.getName(), p.getLastLogin(), p.getKarma() * 10);` - I don’t see no casts here! :)
Bombe
@Bombe You forgot to include the contents of Person.java, but that might not fit in one of these comments.
Steve Losh
The comment by @Steve Losh is not in any way, shape or form OO. There is no really good way to interact with person--no way to know what the contents could be. The one by @Bombe is completely clear and obvious, however it wouldn't be very easy to use in a scripting scenario where you are just throwing out a little spat of one-off code for a shell script. Java has a usage scenario that is different from most of the dynamic languages... It's made to be readable, usable and maintainable, not minimalistic.
Bill K
+20  A: 

I don't think that Java needs tuples, but they would certainly be nice to have in certain situations.

It's not much work to write a generic Pair<A, B> class, or a Triple<A, B, C> class, which gets you most of the benefits of tuples, but the approach does not generalise to n-tuples.

Dan Dyer
The Java Posse podcast often asks about Pair: if everyone is writing one, why isn't it provided?
Michael Easter
To quote @James Iry, "Should Java standard lib have a Pair class? I say no. Every Java developer should just grow a Pair."
pelotom
+1  A: 

No, it doesn’t. In my class library here at work I do have a class Pair but I don’t use it very often and only for internal purposes, i.e. it’s never exposed in a public interface.

Bombe
A: 

To my standpoint, no, Java does not need tuples. Wait, let me refine it. It would be a BAD idea to implement tuples in Java.

Why? Because of Java way of thinking. Nearly everything in Java is there to prevent runtime errors: statically strong typing, explicit variable declaration, single inheritance, generics, exceptions and so on.
This is the strongest point of Java (with its huge library), and that's why java gains so much popularity in the industry world.

Tuples means implicitly adding dynamic typing and inference, which is completely at the oposite of Java's philosophy.

Not that tuples are bad, I use them happily in other languages, they're just inappropriate for Java.

EDIT: To explain my point about dynamic typing, as said in the comment, I was thinking about an unknown set of return elements.
Anyway, how would we grab the tuple? Using a

val1, val2 = obj.method()

could be fine, but what if you want to use the result as a parameter of another method?

gizmo
A don't see why tuples imply dynamic typing.
Tom Hawtin - tackline
You're right, it depends to how far you want to go with tuple as return. I was thinking about an unknown set of elements in the return type. But if you restrict it to a given set, you remove that issue.
gizmo
-1: Statically typed n-tuples are already part of the standard library of F#, Haskell, Scala, and OCaml. Its trivial to implement as a Tuple<t, u> or Tuple<t, u, v> class in Java, however its not very pretty given Java doesn't support type inference or variable decomposition.
Juliet
I disagree. Why would tuples have to be dynamic?
Uri
You ask "but what if you want to use the result as a parameter of another method". Clearly, you should be able to do "val = obj.mehod()" as well, with "val" now having a (static and generic) Tuple type. Then you can write "anotherMethod(obj.method())" if "anotherMethod" accepts a parameter that can be unified with the return type of "obj.method()". IMO, you should look at F#, Haskell and OCaml for a good idiom of tuple values, not at Python.
harms
What would be wrong with Tuple<K, K, V>?
Thorbjørn Ravn Andersen
+4  A: 

Multiple (statically-typed) return values would be useful in some circumstances (although my guess most uses would be abuses). However, a generalised tuple would, I think, be counter to the feel of Java (and would be used almost exclusively for abuse).

Tom Hawtin - tackline
+1  A: 

I might be on the wrong track here, but isn't Map.Entry a tuple?

Creating a single Entry is fairly ugly, though:

public Map.Entry<String, String> tuple(String key, String value) {
    Map<String, String> map = new HashMap<String, String>();
    map.put(key, value);
    return map.entrySet().iterator().next();
}
neu242
This is a pair. My guess is that the question intended N-tuples.
Michael Easter
+3  A: 

Good question. No.

I regularly write in Java and Python, and this is exactly the sort of thing I miss when writing Java. However, what you have to remember is those two languages represent two vastly different programming paradigms. Sequences are first-class in python, and they're just another object in Java. Language-level tuples wouldn't fit in with this.

I like Python for what it is, and I like Java for what it is. While I miss features from one while programming in the other, I wouldn't want them to try to emulate each other.

Draemon
Do you think that language-level tuples can't fit in Java paradigm? What's the problem?
Dmitry
+2  A: 

I've been in the same situation often enough, and I admit that in some cases I have initially done the ugly thing of using a pair or a trip. However, I generally strive to refactor these into a real object.

I don't think tuples would add much that you can't achieve with existing mechanisms (especially now that we have generics).

If Java supported Lambdas, then that would be a different thing... :)

Uri
+1 for using a real object... that's what OO is about
sleske
+1  A: 

What is the benefit of having tuples without introducing pattern matching on invocation?

Therefore, the question become: «Does Java need tuples and pattern-matching on invocations?»

And subsequently, is it even possible for java to support pattern matching?

+16  A: 

I think it does, but only in the context of supporting multiple return values. I'd like to see a method like that pike, python, perl etc copied for supporting creating a form of hidden data-structure as a return-type and linking an assignment to the invocation of said return type...as follows:

a, b = method();

And with the following, strangely obvious, return syntax:

return a, b;

And similarly it should be paired with the ability to create an array from said values, assuming there is no type mismatch. This type mismatch could easily be caught and enforced at compile time with a runtime classcastexception for when type-safety is circumvented, much like it would be today in other contexts.

Object[] results = method();

Similarly, since coersion into an array is as straight-forward as having a tuple who's all values are only a single type, it makes rather logical sense that the converse would be possible as well:

a, b = results;

Of course, this would be type-safe. Under the covers, the tuple could just be an array of Object[] much how generics are largely compile-time enforced now, and the syntax of method invocation with multiple return values could simple be translated into corresponding op-codes to take an array of object back and copy the values into the identifiers specified as capturing the result. Type-safety could be a compile-time-only enforcement, and this would avoid adding a real new language concept to the JVM and remain that multiple return values are simply syntactic sugar, and backward/forward compatibility could be upheld since the runtime byte-code would be tuple-unaware. Everything would just look like a really annoying array of object, to all those Java 6 programmers.

Scott S. McCoy
A: 

Here's a pretty stupid N-tuple:

class Tuple {
    Object[] list;
    Tuple(Object... value) {
        list = value;
    }
    Object[] get() {
        return list;
    }
}
neu242
But not type safe
Quantum7
I wrote that it was pretty stupid, didn't I? :)
neu242
you can make it typesafe using type-specific getters e.g. getInt.
Seun Osewa
+2  A: 

Yes it does! I am convinced that Java needs tuples and if it does not have it, we can define them for ourselves.

If a problem is functional, you need to program in a functional style. Object oriented style makes things unnecessarily complicated. If a function returns more than one value or structure, you need a tuple. Tuples should be immutable (as in other functional languages) to provide safe programming.

Here is a simple example of a 2-dimensional tuple class:

// pair

public class Tuple2 { public final A item1; public final B item2;

// Constructor from components
public Tuple2(A item1Init, B item2Init)
{
 item1 = item1Init;
 item2 = item2Init;
}

// Constructor from another Tuple2 with the same types:
public Tuple2(Tuple2 <A, B> anotherTuple2)
{
 item1 = anotherTuple2.item1;
 item2 = anotherTuple2.item2;
}

// No getters/setters are needed/possible because the components are public/final.

}

obiwankenobi
Of course, for triples you need to define Tuple3 in a similar way etc, unless you figure out a more generic way.If you want a more elegant functional AND object oriented programming on JVM, look at Scala.obiwankenobi
obiwankenobi
you should implement hashCode() and equals() too
Hugo
A: 

Does java need to actually be python instead?

Yes it does, big time.

Lo'oris
Umm, why not just use python? I prefer Java the way it is, but I probably have different use cases than you do.
Bill K
Yep. android sdk forces you to use java. (ASE is pointless, since it does not produce applications)
Lo'oris
Couldn't you use JPython with the Android SDK?
tylermac
Actually, no. Android doesn't use the JVM, so that is not possible. :(
tylermac
+1  A: 

Very simply not necessary for an OO language--in fact, detracts from design.

If you have a method that returns two values, either they should be closely related or your method is doing more work than it should.

If they are closely related, they should be parts of an object (like a tuple). But if you are going to do that, why not create a first-class object that can have methods?

If you had tuples, you'd have to have external code to manipulate those tuples. You also wouldn't have any place to put range checking or other validations.

I've often started with a temporary class (structure) with two public variables and before the day was out had a full-fledged class with private members and methods that I missed in my original design.

I've never just left it at a pair of variables, A class seems to always be required--it just tends to work out that way.

If Java had tuples, I may not have been driven to find these design flaws and my code would be worse in every single case.

(Counterexamples welcome)

Bill K
+1  A: 

You can implement most functionality of tuples with an object (nested class), but that is a bit cumbersome for one-shot usage.

A frequent reason for tuples is needing to return multiple values from a given method call. Here again, a specialized class can substitute.

Also note that you can use an array object from within a method and set its value and use that as a "return many value" holder.

Thorbjørn Ravn Andersen
Agreed, Java is not intended for one-shot usage (Scripting)--it's intended to be readable and maintainable, it prefers explicit over implicit--visible over hidden. There are scripting languages based (both loosely and closely) on Java if brevity is your goal.
Bill K
A: 

Well, I found this question by Googling "tuples Java" because I needed them. I like the tuple-less solution I coded up far less than what I could have done had they been present.

Jekke
A: 

I'd rather see Case Classes (from Scala) in Java than tuples. Case class is something like

public class MyClass {

    private Integer intField;
    private String stringField;
    private Date dateField;

    public MyClass(Integer intField, String stringField, Date dateField) {
        this.intField = intField;
        this.stringField = stringField;
        this.dateField = dateField;
    }

    public Date getDateField() {
        return dateField;
    }

    public void setDateField(Date dateField) {
        this.dateField = dateField;
    }

    public Integer getIntField() {
        return intField;
    }

    public void setIntField(Integer intField) {
        this.intField = intField;
    }

    public String getStringField() {
        return stringField;
    }

    public void setStringField(String stringField) {
        this.stringField = stringField;
    }

}

but you'd write it like this

public case class Myclass(Integer intField, String stringField, Date dateField);

Additionally in Scala pattern matching is done on case classes : http://www.scala-lang.org/node/107

peperg
I think we need both. The problem with only having case classes is that you attach more information to the type than necessary (the constructor name), when what you really need is just a tuple. This destroys generality, and makes it more difficult to implement, for instance, polymorphic zip/unzip methods. Syntactic sugar for tuples that converted them to a conventional set of predefined polymorphic case class constructors could probably solve this.
Ulrik Rasmussen