• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Bear Bibeault
  • Tim Cooke
  • Junilu Lacar
Sheriffs:
  • Paul Clapham
  • Devaka Cooray
  • Knute Snortum
Saloon Keepers:
  • Ron McLeod
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • Frits Walraven
Bartenders:
  • Carey Brown
  • salvin francis
  • Claude Moore

2-Tuple... Or something to stand in as a 2-Tuple  RSS feed

 
Ranch Hand
Posts: 103
Java Linux Monad
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

The tuple or more specifically the 2-tuple, is a data structure that I sorely miss while poking around with Java but I think I found a stand in. The AbstractMap.SimpleEntry<K, V>. Its not a 2-tuple but its close enough and convenient enough and present in the standard library.. Does Java call it a standard library?

 
Marshal
Posts: 64089
215
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That sounds like a implementation of Map.Entry<K, V>.
Please look at this post of Stephan van Hulst's about why he wouldn't be happy with a plain simple Tuple. What is wrong with your creating a CustomPair<T, U> class? Map.Entry<K, V> isn't intended for such generalised use.
 
Gerard Gauthier
Ranch Hand
Posts: 103
Java Linux Monad
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
But that complaint is from a OOP position and most languages are trending towards blending the best of all paradigms. I see Java implementing some form of tuples in the near future.
 
Saloon Keeper
Posts: 10104
212
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
People think they miss a Pair class, but that's only because they're usually too lazy to make a class that's appropriate for the particular use-case.

For instance, say that for a given collection of countries, you want to get their largest cities by population and by area, and then calculate some score based on the two. This is just a silly example but bear with me:

Now, you could get away with using SimpleImmutableEntry<City, City>, but then you'd have to use the methods getKey() and getValue() instead of the fields largestByArea and largestByPopulation. Which of the two is more expressive?
 
Stephan van Hulst
Saloon Keeper
Posts: 10104
212
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Gerard Gauthier wrote:I see Java implementing some form of tuples in the near future.


Built-in tuples that you can deconstruct into well named variables are a plus in my book. General purpose tuple types with generic member names are not.
 
Gerard Gauthier
Ranch Hand
Posts: 103
Java Linux Monad
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:People think they miss a Pair class, but that's only because they're usually too lazy....



I hate to tell you this, all high level abstractions are there because people are too lazy.

What is it about Java programmers and OOP? Just about every other language enthusiast will embrace new language features that explore other paradigms but not Java enthusiast.. Just look what happened to Java's popularity when it embraced lambdas and streams. Java was on a slow and steady downward trend in popularity until it adopted lambdas and streams... It obvious people want these features in Java.
 
Saloon Keeper
Posts: 2504
321
Android Angular Framework Eclipse IDE Java Linux MySQL Database Redhat TypeScript
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Gerard Gauthier wrote:Java was on a slow and steady downward trend in popularity until it adopted lambdas and streams...


Is that your opinion or is there a source for that?
 
Stephan van Hulst
Saloon Keeper
Posts: 10104
212
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is the second topic where you assume that Java enthusiasts favour OO above all else. It's simply not true. I'm a huge fan of functional programming and an early adopter of the Streams API, as are many other experienced programmers here.

We object (hehehe) to the abuse of objects to write poor code. An analogy would be to create an algebraic Pair type constructor in Haskell. Why? It makes the code ugly, hard to maintain and it's inferior in every way to just using a built-in tuple.

I don't see how your statement that Java programmers denounce new language features in the has any bearing on the discussion in the first place. Like I already mentioned, I'll be the first to cheer when Java introduces built-in tuples. That's not what your original post was about. Your original post was about generic tuple types. Generic tuples are deficient and hurt more than they help.

Also, the argument that a certain feature is popular is not an argument that speaks for the quality of a feature. If the whole world says a stupid thing, it's still a stupid thing. Such an argument is a logical fallacy.

Finally, I expect that a lot of your criticisms regarding our approach to object oriented programming stems from that you haven't learned some of the lessons that we've learned over the years. Not all of what we're saying is just parroting what others have said. We've been in the business for years and learned from our mistakes.
 
Gerard Gauthier
Ranch Hand
Posts: 103
Java Linux Monad
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Do I really have to point out Campbell Ritchie's link in the above post?
 
Stephan van Hulst
Saloon Keeper
Posts: 10104
212
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, what's there to point out? That topic is about generic tuple types. Not built-in tuples as a language feature.
 
Saloon Keeper
Posts: 20635
122
Android Eclipse IDE Java Linux Redhat Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm going to swim against the stream and argue that having a language-defined abstract template for tuples would be a good thing. Specifically, it would probably be desirable to have an abstract Tuple class, an abstract Pair class and maybe even an abstract Triple class (all subclasses of Tuple).

There are 3 reasons why I advocate this.

First, having something in the core of a language enviroment definition draws attention to the concept. You don't have to explain what a Pair is to the unlearned if it's in the JavaDocs (well, you do,  but at least you can growl at them). You can talk abstract design in terms of concretely-realizable objects.

Secondly, it allows for a standard base implementation. Instead of a mish-mash of individual Pair classes where some contain 2-element arrays, some contain unique members and the member functions can vary per-class, you have a common standard. Less to worry about when designing, less to argue about when you're ordered to implement.

And finally, simply having a common base class has its own advantages. Sure, a HashPair might normally be something buried in the innards of HashMap, but sometimes you might want to work with it as an abstract Pair - after all, you can have one returned to you via the standard HashMap methods. With free-for-all pair class implementations, you have to spend time coding -- and debugging -- stuff to access the pair's elements and possibly to forward the pair to some unspecified distant mechanism. With a common abstract base class for Pair, you are most likely to have to do some casting at worst. And while I really, really hate casting, thanks to years in the C/C++ realm, I still prefer it to uglier alternatives.


As for popular opinion, yeah. Just because more people get their news from the Ministry of Truth, that doesn't mean that MiniTrue is actually telling the truth, the whole truth, and nothing but the truth.
 
Stephan van Hulst
Saloon Keeper
Posts: 10104
212
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm afraid there's not a single base implementation that will work for all. Some pairs need to be immutable. Others don't. Some may allow null elements and others need to reject them. Some pairs need to be thread-safe. Some might need to be Serializable or Cloneable.

You can't provide base implementations for equals() and hashCode(), and you can't implement Comparable, because then you would not be able to override those methods in sub-types without breaking the general contract.

The only things that a widely usable Pair class could implement are the toString() method and the fields that hold the elements, and the fields must have protected access so that sub-classes can implement accessors. The accessors can not be declared in the abstract base class, because then you're once again stuck with meaningless identifiers such as item1() and item2().

A general purpose Tuple class would be even worse. What information could such a class possibly contain? The only thing I can think of is the size of the tuple. Either you don't know what kind of tuple you're dealing with and the only thing you can do with it is get the size, or you do know what kind of tuple you're dealing with and the size is useless.
 
Sheriff
Posts: 5917
155
Chrome Eclipse IDE Java Postgres Database Ubuntu VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Ron McLeod wrote:

Gerard Gauthier wrote:Java was on a slow and steady downward trend in popularity until it adopted lambdas and streams...


Is that your opinion or is there a source for that?


If you look at this article by TIOBE, about half way down is a graph of Java popularity over time.  The language is in decline until 2014 when Java 8 is released, then it has a big growth spurt. After that is varies greatly but I think you could interpret the data as a steady downward trend until Java 8.
 
Tim Holloway
Saloon Keeper
Posts: 20635
122
Android Eclipse IDE Java Linux Redhat Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:I'm afraid there's not a single base implementation that will work for all. Some pairs need to be immutable. Others don't. Some may allow null elements and others need to reject them. Some pairs need to be thread-safe. Some might need to be Serializable or Cloneable.



Maybe I'm thinking Java can do abstractions better than it actually can, but it seems to me that a conceptual Abstract Pair is not a class that should be worrying about any of these. They're all things that should be in derived subclasses or even in derived abstract subclasses. A Pair basically needs to standardize the template for construction and define left and right accesssors (CAR and CDR, if you're into LiSP). That's it. Java's Collection classes have dealt with these problems before and managed to resolve most of them. And by definition, all Tuples are collections.

Stephan van Hulst wrote:
You can't provide base implementations for equals() and hashCode(), and you can't implement Comparable, because then you would not be able to override those methods in sub-types without breaking the general contract.



I can but repeat the previous statement and ask for examples of why it isn't possible.

Stephan van Hulst wrote:
The only things that a widely usable Pair class could implement are the toString() method and the fields that hold the elements, and the fields must have protected access so that sub-classes can implement accessors. The accessors can not be declared in the abstract base class, because then you're once again stuck with meaningless identifiers such as item1() and item2().



And here, I'll take the opposite view. That toString() isn't something that a conceptual Pair can safely implement. Depending on needs, it might simply defer to Object.toString, Or, regardless of whether the pair components are stored as named members or in an array or something weirder, there are a ton of ways to output invocations on their own toString methods, plus in how you'd separate the values (command, semi/colons, pipes. etc., etc.). That's best done by more specific sub-classes of the general case.

Stephan van Hulst wrote:
A general purpose Tuple class would be even worse. What information could such a class possibly contain? The only thing I can think of is the size of the tuple. Either you don't know what kind of tuple you're dealing with and the only thing you can do with it is get the size, or you do know what kind of tuple you're dealing with and the size is useless.



Tell that to the Perl and Python people, who throw around indeterminate-sized tuples right and left. On the contrary, if you know something is a Tuple, you know it's an ordered collection. Very similar to, if not identical to the equally abstract concept of the Java List. You know that it's sequentially enumerable in an idempotent way. If it's the base for Pair or Triple, you can convert from the general to the specific or vice versa in a simpler and safer way. And you remove some of the "magic" that special-case implementations carries, allowing the whole project to be viewed in a more abstract and flexible way.
 
Stephan van Hulst
Saloon Keeper
Posts: 10104
212
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Tim Holloway wrote:Maybe I'm thinking Java can do abstractions better than it actually can, but it seems to me that a conceptual Abstract Pair is not a class that should be worrying about any of these.


Agreed. My point was there is so little it can do that it's not worth creating such a type at all.

After writing this post, I've slightly come back from this position, because you could implement equals() and hashCode() as long as they're final. A Pair base class might be worth it as long as it's abstract and it doesn't expose generic accessors.

Java's Collection classes have dealt with these problems before and managed to resolve most of them. And by definition, all Tuples are collections.


You're mixing up Java's definition of a collection and the mathematical definition of a collection, if there even is one universally accepted definition. Java collections and tuples are very different. Collections are homogeneous. You can do a lot with them that you can't do with tuples, such as accessing elements dynamically in a type-safe way.

I can but repeat the previous statement and ask for examples of why it isn't possible.



This is how I would imagine such a class. The equals() and hashCode() methods must be final, otherwise Pair can't guarantee that there are no instances that break the method contracts. For instance, if there is a sub-class that includes a third field in the equation, then the symmetric and transitive properties of equals() won't hold. I guess this would be fine, because you don't expect pairs to compare by anything else than their two elements.

No accessors are provided. Sub-classes must provide well-named getters. The fields are not final, because sub-types must be able to implement Cloneable and Serializable in a way that requires them to assign new values to these fields. Supplying setters is NOT recommended.

That toString() isn't something that a conceptual Pair can safely implement. Depending on needs, it might simply defer to Object.toString, Or, regardless of whether the pair components are stored as named members or in an array or something weirder, there are a ton of ways to output invocations on their own toString methods, plus in how you'd separate the values (command, semi/colons, pipes. etc., etc.). That's best done by more specific sub-classes of the general case.


Yes, but you can still give a default implementation, as I've done above.

Tell that to the Perl and Python people, who throw around indeterminate-sized tuples right and left.


I don't think Perl is a language to emulate. Python tuples are actually more like an Object[].

If it's the base for Pair or Triple, you can convert from the general to the specific or vice versa in a simpler and safer way.


How would you convert a Tuple to a Pair<A, B>? And if casting a Pair<A, B> to a Tuple, what could you do with it that you couldn't do better with a List<Object> or an Object[]?

And you remove some of the "magic" that special-case implementations carries, allowing the whole project to be viewed in a more abstract and flexible way.


I think the entire point here is that this level of generalization is counter-productive. It makes code harder to read and maintain. Tuples aren't there to provide flexibility. They're there to provide static type-safety.
 
Stephan van Hulst
Saloon Keeper
Posts: 10104
212
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Given such an abstract base class, my earlier example could be written like this:

As you can see, not much difference, except that code using this class could be tempted to use the non-semantic item1 and item2 fields instead of the largestByArea() and largestByPopulation() accessors. So using such a Pair class would only be useful if the sub-class needs to override equals().
 
Stephan van Hulst
Saloon Keeper
Posts: 10104
212
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Conversely, if Java supported built-in tuples, my earlier example could look like this:

This is absolutely fine by me, as it preserves the ability to give the elements descriptive names.
 
Master Rancher
Posts: 3177
119
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This topic is a little Shakespearian: much ado about nothing. For me, my Pair<K, V> class is just a convenience class, nothing more, nothing less. That convenience is for me much more important than some unconvincing theoretical objections. But we've discussed that a few times before, the twain still haven't met.

For the very lazy among us: you can simply use the javaFX Pair class.
 
please buy this thing and then I get a fat cut of the action:
Create Edit Print & Convert PDF Using Free API with Java
https://coderanch.com/wiki/703735/Create-Convert-PDF-Free-Spire
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!