#229: The Pair class

37 views
Skip to first unread message

marcelomo...@gmail.com

unread,
Feb 8, 2009, 8:12:52 AM2/8/09
to The Java Posse
This is the first time I've felt the need to change the language. I
guess everybody else here wants other changes. I've got this class in
every project I've worked on for the last 2 years. Anybody has a
better one?

public class Par<P extends Serializable, Q extends Serializable>
implements Serializable {

static final long serialVersionUID = 9L;

private P car;
private Q cdr;

public Par(P car, Q cdr) {
this.car = car;
this.cdr = cdr;
}

public P getCar() {
return car;
}

public Q getCdr() {
return cdr;
}

@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
@SuppressWarnings("unchecked")
final Par<P, Q> other = (Par<P, Q>) obj;
if (this.car != other.car && (this.car == null || !
this.car.equals(other.car))) {
return false;
}
if (this.cdr != other.cdr && (this.cdr == null || !
this.cdr.equals(other.cdr))) {
return false;
}
return true;
}

@Override
public int hashCode() {
int hash = 9;
hash += 97 * hash + (this.car != null ? this.car.hashCode() :
0);
hash += 97 * hash + (this.cdr != null ? this.cdr.hashCode() :
0);
return hash;
}
}

Weiqi Gao

unread,
Feb 8, 2009, 8:40:58 AM2/8/09
to java...@googlegroups.com
marcelomo...@gmail.com wrote:
> This is the first time I've felt the need to change the language. I
> guess everybody else here wants other changes. I've got this class in
> every project I've worked on for the last 2 years. Anybody has a
> better one?

public class Pair {
public Object first;
public Object second;
--
Weiqi Gao
weiq...@gmail.com
http://www.weiqigao.com/blog/

Viktor Klang

unread,
Feb 8, 2009, 10:12:44 AM2/8/09
to java...@googlegroups.com


On Sun, Feb 8, 2009 at 2:40 PM, Weiqi Gao <weiq...@gmail.com> wrote:


marcelomorales.name@gmail.com wrote:
> This is the first time I've felt the need to change the language. I
> guess everybody else here wants other changes. I've got this class in
> every project I've worked on for the last 2 years. Anybody has a
> better one?

public class Pair {
  public Object first;
  public Object second;
}

public final class Pair<T,Z>
{
    public final T _1;
    public final Z _2;

    public Pair(final T _1,final Z _2)
    {
          this._1 = _1;
          this._2 = _2;
    }
}
 



--
Viktor Klang
Senior Systems Analyst

Mark Derricutt

unread,
Feb 8, 2009, 1:55:48 PM2/8/09
to java...@googlegroups.com
We have Tuple2, Tuple3, Tuple4 in our utils package, rather handy.  Wish this was avaialable directly in the language, probably as form of generic/typed "array", maybe something like:

public [Integer,String] doSomething() {
  return new [Integer,String] {5, "Hello"};
}

...
Integer foo = doSomething()[0];

This reuses the style of an array, but specifying a type signature for each element.  Anyone know if this would be a viable suggestion?

...and then Buffy staked Edward.  The End.

Reinier Zwitserloot

unread,
Feb 8, 2009, 8:58:18 PM2/8/09
to The Java Posse
What's with the serializable? What's with the typo from pair to par?

You can make Pair serializable and then make P and Q not explicitly
serializable. If you pass in serializables, it'll work. If you don't,
it won't. That seems like a better solution than forcing. A powerful
type system should be able to fix this (make the pair serializable if
and only if both of its generics parameter types are serializable),
but java's isn't quite that powerful. It can be argued, because of the
generic nature of the Pair class, that it creates nicer code if the
fields are made public (and final), instead of having getters. The
lack of a toString() is rather inexcusable, too.

If you've been adding it to every project, why not make a jar out of
it?

On Feb 8, 2:12 pm, "marcelomorales.n...@gmail.com"

Weiqi Gao

unread,
Feb 8, 2009, 9:08:42 PM2/8/09
to java...@googlegroups.com
Reinier Zwitserloot wrote:
>
> If you've been adding it to every project, why not make a jar out of
> it?

Because that would be more work than writing the class.

Marcelo Morales

unread,
Feb 8, 2009, 9:36:59 PM2/8/09
to java...@googlegroups.com
Thank you for your comments.
Par is spanish for Pair. It seems close enough. Also, the name pops up
in third pary code from time to time.
car and cdr are names on the back of my head, from being lisped a few years ago.
I don't like returning non-serializable pairs, so I decided it would
be better to force it in compile-time. Most of the time is BigDecimal,
Date, Long, String or ArrayList. When something different appeared...
well... it smelled.
I also don't like to know when something is not serializable even if
declared serializable. Serializable interface shows its age in code
like this, but I don't think there is something terribly wrong the way
it is.
The getters are needed for the JavaBeans nonsense. but I agree on public final.
You are totally right on lacking toString. I guess I never needed it.
--
Marcelo Morales

Jason Waring

unread,
Feb 8, 2009, 9:52:35 PM2/8/09
to The Java Posse
Hi Mark,

Smells similar to how Matlab passes multiple return arguments. The []
give the feeling that it is an array, which I like, but I'm not too
keen on accessing the elements by index. Following is an alternate
suggestion for how to use the return arguments:

[Integer foo, String bar] = doSomething();

Better yet, if we could infer types then:

var [foo, bar] = doSomething();

also, one could ignore return arguments if not required. For example:

[null, String bar] = doSomething();
or [, String bar] = doSomething();

I think it's important to package the return arguments, for clarity
sake. As such, I would be uncomfortable with:

Integer foo, String bar = doSomething();

Cheers,
Jason

On Feb 9, 3:55 am, Mark Derricutt <m...@talios.com> wrote:
> We have Tuple2, Tuple3, Tuple4 in our utils package, rather handy.  Wish
> this was avaialable directly in the language, probably as form of
> generic/typed "array", maybe something like:
>
> public [Integer,String] doSomething() {
>   return new [Integer,String] {5, "Hello"};
>
> }
>
> ...
> Integer foo = doSomething()[0];
>
> This reuses the style of an array, but specifying a type signature for each
> element.  Anyone know if this would be a viable suggestion?
>
> ...and then Buffy staked Edward.  The End.
>
> On Mon, Feb 9, 2009 at 2:12 AM, marcelomorales.n...@gmail.com <

Keith Haber

unread,
Feb 8, 2009, 10:41:11 PM2/8/09
to The Java Posse
Our team's Pair class has a few extra methods in it that make it non-
trivial enough to justify putting it into a reusable jar file (with
other utility classes we've come up with, of course).

Our Pair implements java.lang.Comparable. It compares first element
to first element, then second element to second element. If either
element is itself Comparable, it uses its compareTo method for that
comparison; otherwise it compares against the toString() of the
elements. Nulls are considered less than any non-null value.

Here are some of the other methods in our Pair class:

public Pair<B, A> getReverse()

public static <X, Y> List<Pair<Y, X>> reversePairs(Collection<Pair<X,
Y>> pairs)

public static <X, Y> Map<X, Y> toMap(Collection<Pair<X, Y>> pairs)

public static <X, Y> List<Pair<X, Y>> fromMap(Map<X, Y> map)

public static <T, X, Y> List<Pair<X, Y>> convertBeansToPairs
(Collection<T> beanList,
String firstPropertyName, String secondPropertyName)


And in defense of using getters, they're pretty much a must in cases
where you need to use JavaBean properties to access the values.
Examples would be use in JSPs (with JSTL), or with utilities like the
Jakarta Commons PropertyUtils classes.

For what it's worth...

Keith


On Feb 8, 9:08 pm, Weiqi Gao <weiqi...@gmail.com> wrote:
> Reinier Zwitserloot wrote:
>
> > If you've been adding it to every project, why not make a jar out of
> > it?
>
> Because that would be more work than writing the class.
>
> --
> Weiqi Gao
> weiqi...@gmail.comhttp://www.weiqigao.com/blog/

Mark Derricutt

unread,
Feb 8, 2009, 10:47:49 PM2/8/09
to java...@googlegroups.com
One reason I was thinking of the array style return, is that means we're not actually replacing javas "single return type" idiom, we're just changing the type system slightly to allow us syntactic sugar around that single return value (I'm thinking this would easier than the alternatives, maybe).

What we really want is something like .NETs new anonymous type, which make LINQ possible:

  var productsAnonymous =
        from p in products2
             select new { p.Name, p.LaunchDate, p.Price };

productsAnonymous contains instances of an anonymous type, with 3 fields based off the names of the parameters passed into the constructor (my understanding anyway).

You can read more about them at http://www.developer.com/net/csharp/article.php/3589916


...and then Buffy staked Edward.  The End.


Joel

unread,
Feb 8, 2009, 10:52:36 PM2/8/09
to The Java Posse
I've found this library quite handy: http://javatuple.com/

Marco Zühlke

unread,
Feb 9, 2009, 3:37:27 AM2/9/09
to The Java Posse
John Rose had some time ago written up whats required to have tuples
on the JVM:
http://blogs.sun.com/jrose/entry/tuples_in_the_vm

-Marco

On 8 Feb., 14:12, "marcelomorales.n...@gmail.com"

Reinier Zwitserloot

unread,
Feb 9, 2009, 8:27:42 AM2/9/09
to The Java Posse
Given that he customized this to being called 'Par', omitting the
toString, and having the awkward Serializable requirement, it seems
like it would be considerably LESS work in the long run to do it right
once. It also seems obvious, given those mistakes, that he may have to
make updates, so copy/pasting the class into every new project is also
a bad idea, as then he couldn't easily make updates to this class.

Here are some more problems with your pair class:

1. By using a constructor, you don't get type inference. Use a static
method, like so:

public static <P, Q> Pair<P, Q> create(P a, P b) {
return new Pair<P, Q>(a, b);
}

and then make the actual constructor private.

2. While you're at it, you can also fix your serializable issue, by
making two constructors:

public static <P extends Serializable, Q extends Serializable> Pair<P,
Q> create(P a, P b) {
return new Pair<P, Q>(a, b);
}

public static <P, Q> Pair<P, Q> createNonSerializable(P a, P b) {
return new Pair<P, Q>(a, b);
}


so, now by default things have to be serializable, but you can get
around the issue if you want without having to bother with raw types
and @SuppressWarnings("unchecked").

(If you're really anal about it, you can create a Pair class and a
SerializablePair subclass, and have the create() method return a
SerializablePair, but I'd have to question your sanity).

Also, your insistence on Serializable is itself a code smell; because,
as Keith Haber suggested: If serializable 'seems like a good idea',
then so does Comparable, and then why not Runnable (for if both pairs
are Runnables and you want to run both of them, or some such). Where
do you draw the line? Sure, serializable needs special treatment
because its such a bad design, but that's actually a good reason to
work around it as best you can.

NB: Here's something I might submit to Project Coin: Make all entities
serializable regardless of whether or not they implement Serializable,
but run every attempt to serialize a non-serializable through the
securitymanager.

On Feb 9, 3:08 am, Weiqi Gao <weiqi...@gmail.com> wrote:
> Reinier Zwitserloot wrote:
>
> > If you've been adding it to every project, why not make a jar out of
> > it?
>
> Because that would be more work than writing the class.
>
> --
> Weiqi Gao
> weiqi...@gmail.comhttp://www.weiqigao.com/blog/

Marcelo Morales

unread,
Feb 9, 2009, 10:14:16 AM2/9/09
to java...@googlegroups.com
On Mon, Feb 9, 2009 at 9:27 AM, Reinier Zwitserloot <rein...@gmail.com> wrote:
>
> Given that he customized this to being called 'Par', omitting the
> toString, and having the awkward Serializable requirement, it seems
> like it would be considerably LESS work in the long run to do it right
> once. It also seems obvious, given those mistakes, that he may have to
> make updates, so copy/pasting the class into every new project is also
> a bad idea, as then he couldn't easily make updates to this class.
>

minor pains for such a small utility I'll say. Haven't need the
change, as flawed as it is. Didn't even look it a second time again
until I posted this. No work was ever required to maintain it.

> Here are some more problems with your pair class:
>
> 1. By using a constructor, you don't get type inference. Use a static
> method, like so:
>
> public static <P, Q> Pair<P, Q> create(P a, P b) {
> return new Pair<P, Q>(a, b);
> }
>
> and then make the actual constructor private.
>
> 2. While you're at it, you can also fix your serializable issue, by
> making two constructors:
>
> public static <P extends Serializable, Q extends Serializable> Pair<P,
> Q> create(P a, P b) {
> return new Pair<P, Q>(a, b);
> }
>
> public static <P, Q> Pair<P, Q> createNonSerializable(P a, P b) {
> return new Pair<P, Q>(a, b);
> }
>

Understood and agreed.

>
> so, now by default things have to be serializable, but you can get
> around the issue if you want without having to bother with raw types
> and @SuppressWarnings("unchecked").
>
> (If you're really anal about it, you can create a Pair class and a
> SerializablePair subclass, and have the create() method return a
> SerializablePair, but I'd have to question your sanity).
>
> Also, your insistence on Serializable is itself a code smell; because,
> as Keith Haber suggested: If serializable 'seems like a good idea',
> then so does Comparable, and then why not Runnable (for if both pairs
> are Runnables and you want to run both of them, or some such). Where
> do you draw the line? Sure, serializable needs special treatment
> because its such a bad design, but that's actually a good reason to
> work around it as best you can.
>

You talk as if implementing serializable was a whim. It was not. Don't
take it so seriously ;)

> NB: Here's something I might submit to Project Coin: Make all entities
> serializable regardless of whether or not they implement Serializable,
> but run every attempt to serialize a non-serializable through the
> securitymanager.
>
> On Feb 9, 3:08 am, Weiqi Gao <weiqi...@gmail.com> wrote:
>> Reinier Zwitserloot wrote:
>>
>> > If you've been adding it to every project, why not make a jar out of
>> > it?
>>
>> Because that would be more work than writing the class.
>>
>> --
>> Weiqi Gao
>> weiqi...@gmail.comhttp://www.weiqigao.com/blog/
> >
>

Just for fun, I googled Pair.java. There are HUNDREDS of them. Even in
the official distribution, the compiler contains one:
http://www.google.com/codesearch/p?hl=en#zBm1I2MD8bU/src/share/classes/com/sun/tools/javac/util/Pair.java

--
Marcelo Morales

Reinier Zwitserloot

unread,
Feb 9, 2009, 11:07:06 AM2/9/09
to The Java Posse
If you feel this strongly about it, feel free to submit it to project
coin:

http://blogs.sun.com/darcy/entry/project_coin

On Feb 9, 4:14 pm, Marcelo Morales <marcelomorales.n...@gmail.com>
wrote:
> the official distribution, the compiler contains one:http://www.google.com/codesearch/p?hl=en#zBm1I2MD8bU/src/share/classe...
>
> --
> Marcelo Morales

Dominic Mitchell

unread,
Feb 9, 2009, 12:26:47 PM2/9/09
to java...@googlegroups.com
On Mon, Feb 09, 2009 at 05:27:42AM -0800, Reinier Zwitserloot wrote:
> 1. By using a constructor, you don't get type inference. Use a static
> method, like so:
>
> public static <P, Q> Pair<P, Q> create(P a, P b) {
> return new Pair<P, Q>(a, b);
> }
>
> and then make the actual constructor private.

Hear, hear! Although, I'd call it "of" rather than create, as that's
what the google collections library does. The type inference leads to a
really nice API.

public Pair<String, Integer> doStuff() {
// …
return Pair.of("answer", 42);
}

As to the issues of getters / setters:

* Don't have setters, pairs should be immutable.
* Do you really need to get at pairs from within JavaBeans? I'd guess
probably not. Most of the time, the components of a pair will be
extracted within a line or two of the call site.

A nice discussion, anyways. I wish my iPod hadn't run out of juice half
way through. :)

-Dom

Reinier Zwitserloot

unread,
Feb 9, 2009, 2:30:56 PM2/9/09
to The Java Posse
.of instead of .create?

I likey.

Viktor Klang

unread,
Feb 9, 2009, 3:05:23 PM2/9/09
to java...@googlegroups.com
I'd recommend putting a static factory method named "pair" aswell,

with a bit of static import magicks:

final Pair<String,String> values = pair("foo","bar");

instead of

final Pair<String,String> values = Pair.of("foo","bar");

because

final Pair<String,String> values = of("foo","bar"); //doesn't really make sense...

Michael Neale

unread,
Feb 9, 2009, 6:34:06 PM2/9/09
to The Java Posse
So how would you do it in scala ;) ?

(sorry I always find it crushing how easy everything is in scala, when
I have to look at java).

Of course you can just do:

def foo() : (String, Int) = ("Hello", 42)

never looking into what scala *actually* does with tuples, if its
something nasty or not... (someone else I am sure knows if it is a
good or bad thing).


On Feb 10, 7:05 am, Viktor Klang <viktor.kl...@gmail.com> wrote:
> I'd recommend putting a static factory method named "pair" aswell,
>
> with a bit of static import magicks:
>
> final Pair<String,String> values = pair("foo","bar");
>
> instead of
>
> final Pair<String,String> values = Pair.of("foo","bar");
>
> because
>
> final Pair<String,String> values = of("foo","bar"); //doesn't really make
> sense...
>

David Chuhay

unread,
Feb 9, 2009, 7:51:47 PM2/9/09
to java...@googlegroups.com
Scala has tuple classes up to size 22 included in the base langauge
package. The (var1, var2, ...) syntax gets compiled into an
instantiation of the properly sized Tuple class.

Michael Neale

unread,
Feb 9, 2009, 8:48:49 PM2/9/09
to The Java Posse
Thanks David !

22... interesting...
How did they do the syntactic support for ( and ) to mean Tuple? Is it
special or like anything else, just defs?

Reinier Zwitserloot

unread,
Feb 9, 2009, 9:45:38 PM2/9/09
to The Java Posse
The way scala has 22 tuples is a big scala smell actually. At least,
to me. Anytime I look at scala's javadoc, you see 22 TupleX's fly by.
Meh.

Josh Suereth

unread,
Feb 9, 2009, 9:20:06 PM2/9/09
to The Java Posse
They're actually unifying Function arguments and Tuples so you can use
them interchangeably (I believe in 2.8). In java this looks
ridiculuous, as you don't have scala's style of type-inference. My
guess would be that if tuple support isn't native to the language
currently, it will be in the future.

Scala sometimes gets the syntactic-sugar wrong where you have to do
things like someFunction((x,y)), but in general it "just works".
It also supports extracting tuples using pattern matching like so:
val (x,y) = someFunction()

which may look a lot uglier in java:

(String x, int y) = someFunction();

but is still rather nice for a "pair" class.

Also, as a Side note, Tony Morris's project "Functional Java" has a
Tuple class hidden in its bowels of Monads and Theory. It's actually
called a "Product" (the classes are named PN where N is a number from
1-8)
Here's the docs
http://functionaljava.googlecode.com/svn/artifacts/2.17/javadoc/index.html

Reinier Zwitserloot

unread,
Feb 9, 2009, 10:50:38 PM2/9/09
to The Java Posse
If you have inference, you can create TupleXes by chaining tuples.

So a (String, Integer, Double) tuple would be:

Pair<String, Pair<Integer, Double>>.

Then you add a light sprinkling of syntax sugar to make it not look
ridiculous.

I don't understand why scala doesn't work this way. It would avoid
littering the namespace with a tonne of these and having an arbitrary
limit of 22.

A 'Pair' could then support asking how big it is (it would check if
it's second element is a Pair, and if so, return that pair's size +1,
and if not, return 2, or better yet, have a BGGA-esque Nothing/Void/
Undefined type and don't count those either).

On Feb 10, 3:20 am, Josh Suereth <Joshua.Suer...@gmail.com> wrote:
> They're actually unifying Function arguments and Tuples so you can use
> them interchangeably (I believe in 2.8).  In java this looks
> ridiculuous, as you don't have scala's style of type-inference.  My
> guess would be that if tuple support isn't native to the language
> currently, it will be in the future.
>
> Scala sometimes gets the syntactic-sugar wrong where you have to do
> things like someFunction((x,y)), but in general it "just works".
> It also supports extracting tuples using pattern matching like so:
> val (x,y) = someFunction()
>
> which may look a lot uglier in java:
>
> (String x, int y) = someFunction();
>
> but is still rather nice for a "pair" class.
>
> Also, as a Side note, Tony Morris's project "Functional Java" has a
> Tuple class hidden in its bowels of Monads and Theory.  It's actually
> called a "Product" (the classes are named PN where N is a number from
> 1-8)
> Here's the docshttp://functionaljava.googlecode.com/svn/artifacts/2.17/javadoc/index...

Christian Catchpole

unread,
Feb 9, 2009, 11:00:25 PM2/9/09
to The Java Posse
This link cliams..

22 is the number of partitions of 8, and 8 is the largest cube in the
Fibonacci sequence, and the Fibonacci sequence is the most popular FP
example.

http://www.nabble.com/Why-tuples-only-to-22--td19962995.html

But my brain isn't big enough to know if its a serious answer or
not. :)

Josh Suereth

unread,
Feb 10, 2009, 2:40:31 AM2/10/09
to java...@googlegroups.com
I think perhaps as Scala is academic, speed takes more of a focus for some decisions.  Although what you're describing with nested pairs works perfectly well, the performance of grabbing item N off the Tuple is N-1 lookups on Pair.   Call it what you will, but Scala tries to strike a balance between elegance and speed.   As you add these higher-level abstractions it can be tough to keep them fast enough for "general-purpose" (or better yet, specific purpose) computing.

Note that Scala takes the approach for sizes you outline in it's "Seq" abstract Trait.   It is recommended against calling the length method for performance reasons.  If you want fast length calculations, use a List. 

It seems if you'd like to support an arbitrary number of Tuples, you literally should return Arrays of Objects or some form of Collection, then have javac auto-cast results for you in bytecode.   The difference here would be some form of bytecode flag that says: "This return value isn't a list, it's actually a Tuple of these other types".  Either that, or have the JVM support tuples directly

-Josh

Viktor Klang

unread,
Feb 10, 2009, 5:36:19 AM2/10/09
to java...@googlegroups.com
On Tue, Feb 10, 2009 at 12:34 AM, Michael Neale <michae...@gmail.com> wrote:

So how would you do it in scala ;) ?

*laugh*

Well, the Scalaposse isn't really broadcasting yet ;)
 

Reinier Zwitserloot

unread,
Feb 10, 2009, 6:04:39 AM2/10/09
to The Java Posse
That was a joke.

On Feb 10, 5:00 am, Christian Catchpole <christ...@catchpole.net>
wrote:

Reinier Zwitserloot

unread,
Feb 10, 2009, 7:02:28 AM2/10/09
to The Java Posse
Even if you use a list instead of a tuple, lists don't support
heterogenous typing; you can have a tuple of type <String, Integer>,
but you can't have a list that is defined to contain alternating
String/Integer. I agree that it would be great if somehow the actual
underlying object is the same thing between a tuple and a list, and
the only difference is that a tuple has a set size and a listed type
for each element, whereas a list has a single type for all elements
and can be any size. I guess you could theoretically employ a nested
pairs structure just for the sake of the compiler, and actually do a
relatively quick list lookup + cast at runtime, using copious amounts
of unsafes. Without more sugar you can't make this work in the JVM
(You'd define a tuple as a Tuple<H, T>, so how do you extract the H of
the Tuple that is the T? Or the H of the Tuple that is the T of the
tuple that is the T of this tuple? The generics type system has the
info, there's just no syntax (in java 1.6) to liberate the right type.
Scala has higher kinded types but I'm not sure it can solve this
problem either, by the way.

I get that scala's current solution was the easiest given the
constraints, but littering the top-level namespace with 22 instances
of FoobarX, and having an arbitrary limit at all, can't be the right
answer. If java is to get arbitrary-length tuples I'd prefer a less
hacky solution.

On Feb 10, 8:40 am, Josh Suereth <joshua.suer...@gmail.com> wrote:
> I think perhaps as Scala is academic, speed takes more of a focus for some
> decisions.  Although what you're describing with nested pairs works
> perfectly well, the performance of grabbing item N off the Tuple is N-1
> lookups on Pair.   Call it what you will, but Scala tries to strike a
> balance between elegance and speed.   As you add these higher-level
> abstractions it can be tough to keep them fast enough for "general-purpose"
> (or better yet, specific purpose) computing.
>
> Note that Scala takes the approach for sizes you outline in it's "Seq"
> abstract Trait.   It is recommended against calling the length method for
> performance reasons.  If you want fast length calculations, use a List.
>
> It seems if you'd like to support an arbitrary number of Tuples, you
> literally should return Arrays of Objects or some form of Collection, then
> have javac auto-cast results for you in bytecode.   The difference here
> would be some form of bytecode flag that says: "This return value isn't a
> list, it's actually a Tuple of these other types".  Either that, or have the
> JVM support tuples directly
>
> -Josh
>

Robert Fischer

unread,
Feb 10, 2009, 9:02:07 AM2/10/09
to java...@googlegroups.com
As your third paragraph states, if you're grabbing the Nth element out of an N-tuple that way,
you're doing something wrong. Probably confusing "tuple" with "list".

In some other languages, a method that takes a tuple transparently unpacks the tuple into local
variables, so accessing the Nth element out of the tuple is just a local variable access. This is
done on the assumption that you're asking for a tuple because you know what you're doing, and at
least the majority of elements are meaningful. Similarly, the most common way to unpack returned
tuples is through a case statement or multiple assignment, either of which is basically the same
stunt as unpacking into local variables.

The reason Scala has 22 "Tuple" types is because they need some way to hook type information onto
(1,"foo") in a way that's coherent to the Java-based generics model they've got.

~~ Robert.
> <mailto:Joshua.Suer...@gmail.com>> wrote:
> > They're actually unifying Function arguments and Tuples so you
> can use
> > them interchangeably (I believe in 2.8). In java this looks
> > ridiculuous, as you don't have scala's style of type-inference. My
> > guess would be that if tuple support isn't native to the language
> > currently, it will be in the future.
> >
> > Scala sometimes gets the syntactic-sugar wrong where you have to do
> > things like someFunction((x,y)), but in general it "just works".
> > It also supports extracting tuples using pattern matching like so:
> > val (x,y) = someFunction()
> >
> > which may look a lot uglier in java:
> >
> > (String x, int y) = someFunction();
> >
> > but is still rather nice for a "pair" class.
> >
> > Also, as a Side note, Tony Morris's project "Functional Java" has a
> > Tuple class hidden in its bowels of Monads and Theory. It's actually
> > called a "Product" (the classes are named PN where N is a number from
> > 1-8)
> > Here's the
> docshttp://functionaljava.googlecode.com/svn/artifacts/2.17/javadoc/index.
> <http://functionaljava.googlecode.com/svn/artifacts/2.17/javadoc/index.>..
> >
> > On Feb 9, 8:48 pm, Michael Neale <michael.ne...@gmail.com
> <mailto:michael.ne...@gmail.com>> wrote:
> >
> > > Thanks David !
> >
> > > 22... interesting...
> > > How did they do the syntactic support for ( and ) to mean
> Tuple? Is it
> > > special or like anything else, just defs?
> >
> > > On Feb 10, 11:51 am, David Chuhay <dchu...@gmail.com
> <mailto:dchu...@gmail.com>> wrote:
> >
> > > > Scala has tuple classes up to size 22 included in the base
> langauge
> > > > package. The (var1, var2, ...) syntax gets compiled into an
> > > > instantiation of the properly sized Tuple class.
> >
> > > > Michael Neale wrote:
> > > > > So how would you do it in scala ;) ?
> >
> > > > > (sorry I always find it crushing how easy everything is in
> scala, when
> > > > > I have to look at java).
> >
> > > > > Of course you can just do:
> >
> > > > > def foo() : (String, Int) = ("Hello", 42)
> >
> > > > > never looking into what scala *actually* does with tuples,
> if its
> > > > > something nasty or not... (someone else I am sure knows if
> it is a
> > > > > good or bad thing).
>
>
>
> >

--
~~ Robert Fischer.
Grails Trainining http://GroovyMag.com/training
Smokejumper Consulting http://SmokejumperIT.com
Enfranchised Mind Blog http://EnfranchisedMind.com/blog

Check out my book, "Grails Persistence with GORM and GSQL"!
http://www.smokejumperit.com/redirect.html

Robert Fischer

unread,
Feb 10, 2009, 9:03:02 AM2/10/09
to java...@googlegroups.com
Why would it be good for a Tuple to be a List?

~~ Robert.

James Iry

unread,
Feb 10, 2009, 9:45:36 AM2/10/09
to The Java Posse
Scala doesn't work that way because Tuples have O(1) access to all
elements where what you propose would have O(n) access. Having 22
Tuple classes is definitely a code smell. Same with having 22
Function classes. But those are code smells forced by the JVM. On
"machines" with a less strict stack discipline than the JVM, e.g. the
x86, there are other ways to encode tuples that are much more
flexible.

An alternative on the JVM is to use runtime byte code generation and
classloader-fu to generate TupleN classes as needed. But Scala has
avoided that kind of magic as it tends to not play well with other
things that want to do classloader-fu.

What you've proposed is called a Heterogeneous Linked List, or HList
for short. It's exactly the kind of list you get from Lisps. Most
statically typed languages can't do them, or at least not usefully.
HLists are very tricky to type correctly and still make pleasant to
use. Scala can do it, but only just barely using a currently
experimental compiler flag. When that feature stabilizes you can
probably expect HLists to be in the standard library.

Finally, related to your last point re: BGGA, Scala does have a type
for undefined called "Nothing." BGGA's undefined type was renamed
from "Unreachable" to "Nothing" in order to follow Scala's example:
http://gafter.blogspot.com/2008/08/java-closures-prototype-feature.html.
Both names make sense in context.

The BGGA Void type means something else. Void is the type of a
closure that returns normally but doesn't return any useful data.
Scala has an equivalent (again, before BGGA did), but Scala calls it
Unit to differentiate from the non-first class nature of Java's void
and to help further distinguish it from Nothing.

Reinier Zwitserloot

unread,
Feb 10, 2009, 11:40:16 AM2/10/09
to The Java Posse
There's 'synthetic', which is a flag on class members that indicates
that they aren't intentional (by the code author), just a side-effect
of the compiler making it all work right. A side-effect is that most
IDEs suppress them in auto-complete models, which is overkill, but
another flag that means: This is a system type thing, so, auto-
complete, sure, but definitely don't generate javadocs, or offer it
when extending classes, etcetera. I don't like structural typing in a
java closure proposal, but if it does happen, The FunctionIII stuff
can also use such a flag. Adding flags to members is backwards
compatible. Just an idea.

NB: For a closure proposal I was cooking up I'm going to need a bunch
of synthetic publics, which fortunately works as intended; javac will
refuse to compile access to synthetics in .java source, and eclipse
does not list them in auto-completes etc, but the JVM completely
ignores the synthetic flag. (allows any call to a synthetic same as a
call to a non-synthetic). Nice feature.

Peter Becker

unread,
Feb 11, 2009, 6:16:36 AM2/11/09
to java...@googlegroups.com
Re 22: consider the empty product/tuple and suddenly you are in the
realm of conspiracy theories. With the functions you actually see the
true number -- they explicitly start with 0.

How far is it from the EPFL to Lake Totenkopf? Does either really exist?
Who's reality is this anyway?

Peter


PS: no, we are probably not doomed, it's just the type of comments
people deserve for arbitrary cut-offs :-)

Bill Wohler

unread,
Feb 11, 2009, 5:01:14 PM2/11/09
to The Java Posse
On Feb 9, 9:26 am, d...@happygiraffe.net (Dominic Mitchell) wrote:
> Hear, hear!  Although, I'd call it "of" rather than create, as that's
> what the google collections library does.  The type inference leads to a
> really nice API.

Thanks, Dominic. I used your message as an incentive to replace our
Pair constructor with an "of" factory method. And yes, it does a great
job of cleaning things up! I hit one snag. Is there a way around the
following compilation problem?

public class PairTest {
/*
* The Pair.of() call below yields the following compilation
error: Type
* mismatch: cannot convert from Pair<Class<capture#1-of ? extends
* Exception>,Class<capture#2-of ? extends Exception>> to
Pair<Class<?
* extends Exception>,Class<? extends Exception>>
*/
public static void main(String[] args) {
Class<? extends Exception> foo;
Class<? extends Exception> bar;

// Original line with constructor.
Pair<Class<? extends Exception>, Class<? extends Exception>>
compiles = new Pair<Class<? extends Exception>, Class<? extends
Exception>>(
foo, bar);

// Failed attempt at using of.
Pair<Class<? extends Exception>, Class<? extends Exception>>
doesntCompile = Pair.of(
foo, bar);
}
}

Reinier Zwitserloot

unread,
Feb 12, 2009, 5:57:42 AM2/12/09
to The Java Posse
Yes, write it like so:

Pair.<? extends Exception, ? extends Exception>of(foo, bar);

Not pretty, but it works.

though, I'm somehat confounded as to why java wouldn't compile it as
is. Generics still surprise me sometimes.

Bill Wohler

unread,
Feb 12, 2009, 12:10:41 PM2/12/09
to The Java Posse
On Feb 12, 2:57 am, Reinier Zwitserloot <reini...@gmail.com> wrote:
> Yes, write it like so:
>
> Pair.<? extends Exception, ? extends Exception>of(foo, bar);
>
> Not pretty, but it works.

Thanks, Reinier. Weird, but true!

joel.neely

unread,
Feb 17, 2009, 9:03:34 AM2/17/09
to The Java Posse
<ROTFL>Thanks for posting that!

(no closing tag... I'm still chuckling silently!)

-jn-

On Feb 9, 10:00 pm, Christian Catchpole <christ...@catchpole.net>
wrote:
Reply all
Reply to author
Forward
0 new messages