commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Gary Gregory <garydgreg...@gmail.com>
Subject Re: [lang3] Pair
Date Fri, 04 Mar 2011 21:10:02 GMT
On Fri, Mar 4, 2011 at 3:31 PM, Matt Benson <gudnabrsam@gmail.com> wrote:

> On Fri, Mar 4, 2011 at 2:29 PM, Matt Benson <gudnabrsam@gmail.com> wrote:
> [SNIP]
> > From http://en.wikipedia.org/wiki/Tuple:  "a 2-tuple is called a
> > pair".  Not necessarily authoritative, but amusing nevertheless.
> >
> > Another interesting concept mentioned in this article is the
> > summarized by the statement "Another way of formalizing tuples is as
> > nested ordered pairs."  I would argue that this is the only efficient
> > way to formally represent an n-tuple using Java generics without
> > writing one class per value of n.
>
> Well, perhaps not "efficient," but still the only way to represent an
> arbitrary number of type parameters.
>

In this case, we need a 2-tuple, nothing more. We can more later of course,
a la .NET or not.

Gary


>
> Matt
>
> >
> > Call it a pair, call it an association, but let's call it done.
> >
> > Matt
> >
> >> Gary
> >>
> >>
> >>>
> >>> -Adrian
> >>>
> >>> On 3/4/2011 11:24 AM, Gary Gregory wrote:
> >>>
> >>>> Can we talk about the class name and use cases?
> >>>>
> >>>> For me a pair evokes similarity: a pair of shoes, a pair of hands, a
> pair
> >>>> of
> >>>> coordinates. You get the idea. Having a Pair.of(name, dog) reads like
> >>>> nonsense to me. A Map.Entry.of(name, dog) I understand, same for an
> >>>> Association.of(name, dog) (I cannot escape from my Smalltalk
> heritage.)
> >>>>
> >>>> In most cases, I deal with key-value "pairs", let's play:
> >>>>
> >>>> new Pair(name, dog)
> >>>> new KeyValue(name, dog)
> >>>> new Association(name, dog)
> >>>> new MapEntry(name, dog)
> >>>>
> >>>> If we want to accommodate "real" pairs like a Point2D(x,y), which we
> >>>> should,
> >>>> then the Pair name makes perfect sense IF it is a Pair<T>  where
the x
> and
> >>>> y
> >>>> are both Ts.
> >>>>
> >>>> There are two uses cases: pairs and key-value associations.
> >>>>
> >>>> It would then be interesting for the Pair<T>  and KeyValue(K,V)
> interfaces
> >>>> to
> >>>> share a common implementing base class, a something that holds two
> objects
> >>>> (a TwoTuple, yikes?)
> >>>>
> >>>> Let's play (these are immutable for brevity):
> >>>>
> >>>> public interface TwoTuple<E1,E2>  {
> >>>>     E1 getFirst();
> >>>>     E2 getSecond();
> >>>> }
> >>>>
> >>>> public interface Pair<T>  extends TwoTuple<T, T>  {
> >>>> }
> >>>>
> >>>> public interface Association<K, V>  extends TwoTuple<K, V>
 {
> >>>>     K getKey();
> >>>>     V getValue();
> >>>> }
> >>>>
> >>>> Thoughts?
> >>>>
> >>>> Gary
> >>>>
> >>>>
> >>>> On Fri, Mar 4, 2011 at 1:35 PM, Matt Benson<gudnabrsam@gmail.com>
>  wrote:
> >>>>
> >>>>  On Fri, Mar 4, 2011 at 5:41 AM, Stephen Colebourne<
> scolebourne@joda.org>
> >>>>> wrote:
> >>>>>
> >>>>>> I now have authoristion from OpenGamma to discuss adding a Pair
> class
> >>>>>> to [lang] based on our internal classes. If necessary a CCLA
can be
> >>>>>> signed, although since we are not necessarily importing the
> OpenGamma
> >>>>>> classes as is and I'd be writing code in [lang3] with my Apache
hat
> >>>>>> on, the CCLA might not be needed. I can also code it in work
time
> :-)
> >>>>>>
> >>>>>> The main goal would be either an abstract class or an interface
for
> >>>>>> Pair. We chose an abstract class so that it could have factory
> >>>>>> methods:
> >>>>>>
> >>>>>>  Pair<String, Number>  p = Pair.of("Foo", 6);
> >>>>>>
> >>>>>> It also allowed more control over the immutability of Pair (although
> >>>>>> because its abstract and holds references to any object,
> immutability
> >>>>>> cannot be guaranteed).
> >>>>>>
> >>>>>> We then have other concrete classes:
> >>>>>> - ObjectsPair - two generified objects
> >>>>>> - DoublePair - two double
> >>>>>> - IntDoublePair - int and double
> >>>>>> - LongDoublePair - long and double
> >>>>>> - IntObjectPair - int and generified object
> >>>>>> - LongObjectPair - long and generified object
> >>>>>>
> >>>>>> Clearly there are many more possible combinations, but some
make
> less
> >>>>>> sense than others. (Booleans don't waste space, as they are
a
> >>>>>> singleton reference, short/float are rarely used)
> >>>>>>
> >>>>>> Beyond this, there are some standard comparators.
> >>>>>>
> >>>>>> Design wise, we implement Map.Entry (makes sense). The primitive
> >>>>>> classes implement primitive map entry interfaces from another
> library,
> >>>>>> but that wouldn't make sense here. They are comparable and
> >>>>>> serializable (again, one reason for an abstract class).
> >>>>>>
> >>>>>> We name our elements "first" and "second".
> >>>>>>
> >>>>>> The elements are available by methods (for generics) or as public
> >>>>>> final variables from the concrete classes (not the abstract
one).
> The
> >>>>>> methods are getFirst(), getSecond() plus getKey() and getValue()
for
> >>>>>> Map compatibility.
> >>>>>>
> >>>>>> The pairs are implemented as immutable. I saw someone mention
the
> >>>>>> possibility of a mutable pair, so perhaps we consider that.
> >>>>>>
> >>>>>> I don't want this to be a long process of design or implementation!
> If
> >>>>>> there isn't rapid consensus, I'd suggest either shipping [lang3]
> with
> >>>>>> or without the existing class.
> >>>>>>
> >>>>>> Opinions?
> >>>>>>
> >>>>> I agree that it would be nice to do whatever we're going to do
> >>>>> quickly, and ship with *something*.  On the other hand, I don't
want
> >>>>> to ship the existing class without consensus on design, only to
give
> >>>>> ourselves (and users) headaches trying to replace it in a subsequent
> >>>>> release.
> >>>>>
> >>>>> I also had the thought that the abstract class would be necessary
for
> >>>>> the factory methods.  It doesn't seem important, but I'd really
like
> >>>>> to be able to say Pair.of(X, Y).  Semantically it'd also be nice
to
> be
> >>>>> able to use fields on the immutable variety of Pair (it's perhaps
> >>>>> debatable in light of JIT whether the final field access yields
> better
> >>>>> performance, so I won't address it--but it *looks* faster :P ),
while
> >>>>> still requiring the client to know as little as possible about the
RT
> >>>>> type of the Pair.  Is it possible to accomplish all these things?
> >>>>>
> >>>>> abstract class Pair<L, R>  implements Map.Entry<L, R>
 {
> >>>>>  abstract L getLeft();
> >>>>>  abstract R getRight();
> >>>>>  final L getKey() { return getLeft(); }
> >>>>>  final R getValue() { return getRight(); }
> >>>>>  static<L, R>  ImmutablePair<L, R>  of(L, R) {}
> >>>>> }
> >>>>>
> >>>>> class ImmutablePair<L, R>  extends Pair<L, R>  {
> >>>>>  final L left;
> >>>>>  final R right;
> >>>>>  ImmutablePair(L left, R right) { this.left = left; this.right =
> right; }
> >>>>>  L getLeft() { return left; }
> >>>>>  R getRight() { return right; }
> >>>>>  static<L, R>  ImmutablePair<L, R>  of(L, R) {}
> >>>>> }
> >>>>>
> >>>>> class MutablePair<L, R>  extends Pair<L, R>  {
> >>>>>  private L left;
> >>>>>  private R right;
> >>>>>
> >>>>>  MutablePair(L left, R right) { setLeft(left); setRight(right);
}
> >>>>>  L getLeft() { return left; }
> >>>>>  setLeft(L left) { this.left = left; }
> >>>>>  R getRight() { return right; }
> >>>>>  setRight(R right) { this.right = right; }
> >>>>>  static<L, R>  MutablePair<L, R>  of(L, R) {}
> >>>>> }
> >>>>>
> >>>>> In the examples above I continue to use the left/right idiom for
> >>>>> reasons of inertia; in the end, I don't *really* care.  It seems
> >>>>> examples abound of the various proposed paired names in other
> >>>>> programming contexts, so this becomes a simple matter of taste and/or
> >>>>> majority rules.  Personally I prefer left/right as there is less
> >>>>> connotation of priority given either member of the pair as (IMO)
in
> >>>>> the case of first/second.
> >>>>>
> >>>>> If we want to extend ImmutablePair for the wrapper types (it wouldn't
> >>>>> seem to make sense to provide access to the primitive equivalent
> >>>>> values in the MutablePair variety), where does it end?  If we provide
> >>>>> any such pair types, IMO we should use some predictable rule to
> >>>>> define, for a given wrapper type, what combinations are available,
> >>>>> e.g.:
> >>>>>
> >>>>> * X Double
> >>>>> * X Boolean
> >>>>> * X Object
> >>>>> * X self
> >>>>> * X * ?
> >>>>>
> >>>>> I'm sure I don't have to tell any of my fellow Commons committers
> that
> >>>>> our components may well have to provide more implementations, or
none
> >>>>> at all, compared to equivalent proprietary code, for reasons of
> >>>>> perceived "completeness."  If anything this is even more so in the
> >>>>> case of [lang] than perhaps some other Commons components.
> >>>>>
> >>>>> Matt
> >>>>>
> >>>>>  Stephen
> >>>>>>
> >>>>>>
> ---------------------------------------------------------------------
> >>>>>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> >>>>>> For additional commands, e-mail: dev-help@commons.apache.org
> >>>>>>
> >>>>>>
> >>>>>>
>  ---------------------------------------------------------------------
> >>>>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> >>>>> For additional commands, e-mail: dev-help@commons.apache.org
> >>>>>
> >>>>>
> >>>>>
> >>>>
> >>> ---------------------------------------------------------------------
> >>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> >>> For additional commands, e-mail: dev-help@commons.apache.org
> >>>
> >>>
> >>
> >>
> >> --
> >> Thank you,
> >> Gary
> >>
> >> http://garygregory.wordpress.com/
> >> http://garygregory.com/
> >> http://people.apache.org/~ggregory/
> >> http://twitter.com/GaryGregory
> >>
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
>
>


-- 
Thank you,
Gary

http://garygregory.wordpress.com/
http://garygregory.com/
http://people.apache.org/~ggregory/
http://twitter.com/GaryGregory

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message