Indexing access for Lists and Maps considered harmful?
Joshua Bloch
jjb at google.com
Tue Jun 23 20:40:52 PDT 2009
Reinier,
I don't really understand your post. What's wrong with just agreeing at the
outset that a[i] = b[i] = x; works, and then figuring out what (if any)
interfaces we need to make it work?
Josh
On Tue, Jun 23, 2009 at 6:39 PM, Reinier Zwitserloot <
reinier at zwitserloot.com> wrote:
> I agree to the theory of your post, but, so what?
>
> Java is not going to be perfect unless java is willing to sacrifice
> backwards compatibility, which it isn't. So, perfection can't be the
> goal - because if it is, then no language change is ever going to make
> it in, and paradoxically, that really brings java no closer to
> perfection.
>
> So - so what that it isn't perfect? Let's roll with where I think you
> are trying to go, and create 2 interfaces, where the SetIndex
> semantics are defined as requiring the implementing class to return
> the logical value - e.g. boxing a primitive when assigning it into a
> list, for example.
>
> But now we can't retrofit java.util.List without breaking thousands of
> List implementations out there, so the conclusion would have to be
> that you can not use a List itself; you must use either a specific
> type (such as ArrayList, retrofitted to implement SetIndex), or a
> newly created List2 interface that also implements SetIndex. In this
> scenario, I'm assuming the name of the method isn't set(), as that
> would conflict with java.util.List's set which has different semantics.
>
> So, riddle me this then. There are 3 java7 scenarios:
>
> In the first scenario, m[a] = m[b] = c; does what you want, but only
> if m is an ArrayList, SetIndex, or HashMap. It just doesn't work if m
> is a List or Map type. Even for just "m[b] = c", which I'll bet is
> more prevalent than m[a] = m[b] = c by a factor of 100 or more!
>
> In the second scenario, m[a] = m[b] = c does not do what you want (and
> in my opinion, should express this by failing fast - generating a
> compiler error on the spot stating that m[b] = c is not an expression,
> but that's not relevant to the point I'm trying to make here) - but it
> works with every type you'd expect it to work with: List, Map, arrays,
> and many other types of objects.
>
> In the third scenario, m[a] = c isn't allowed at all.
>
> In the fourth scenario, java complicates the process quite a bit e.g.
> by having a scala-esque conversion semantic where some class in the
> classpath has registered itself as capable of turning any
> java.util.List into a java.lang.SetIndex object. m[a] = m[b] =c does
> what you want, and it works with List, but now the proposal is rather
> complicated.
>
> I'm quite certain the (vast?) majority will go with the second java7.
> If pass-through assignment was more common than it is, it might be
> worth investigating the fourth scenario more thoroughly,
>
> NB: I'd hereby like to repeat my suggestion to choose pragmatism over
> perfection here: Returning void is pragmatic, in that we can always
> change it later without breaking any code. In this case, the pragmatic
> choice may have to be to define explicitly SetIndex behaviour as
> existing for java.util.List and java.util.Map and no other types of
> objects (hard code the types, at least for now - no need to do this to
> GetIndex, as there are no issues there). If these things are sorted
> out in the future, then the restriction can be waived, and any code
> can use it. It may not be /pretty/, but it has the crucial advantage
> of being future-compatible!
>
> --Reinier Zwitserloot
>
>
>
> On 2009/24/06, at 02:47, Neal Gafter wrote:
>
> > These methods are language-support methods. If I create a new array-
> > like
> > API, what should its "put" method return? Four choices are void,
> > null, the
> > input value, or the logical value placed into the data structure.
> >
> > void doesn't work because that's not the return type of the method
> > in these
> > interfaces.
> >
> > null is silly (an API method that should always return nothing
> > should be
> > declared void), and conflicts with the JLS's meaning of an assignment
> > expression (see below).
> >
> > The input value isn't correct; the value resulting from the
> > assignment is
> > supposed to be the NEW value in that variable (JLS3 15.26 paragraph
> > 3). For
> > built-in arrays, that is the value converted to the array element
> > type.
> >
> > For general collection-like APIs, the result of an assignment using
> > the
> > array syntax may be some other "equivalent" value (for example,
> > strings
> > might be interned). To support the JLS semantics, the API needs to
> > have an
> > opportunity to yield this value. So IndexedAccess<V>.put() should be
> > declared to return a value of type V, which should be specified to
> > be *the
> > value of the logical variable after the assignment has occurred*.
> > java.util.List, on the other hand, has a put method that is declared
> > with
> > the right signature (it returns a V), but it returns the wrong value
> > to
> > support the JLS semantics for assignment.
> >
> > Retrofitting interfaces onto existing classes is a poor solution to
> > this
> > language-design problem.
> >
> > Regards,
> > Neal
> >
> > On Tue, Jun 23, 2009 at 4:35 PM, Shams Mahmood <shams.mahmood at gmail.com
> > >wrote:
> >
> >> I don't follow why it won't handle anything other than the
> >> collections api.
> >> The compiler should be able to support any implementations of
> >> IndexedAccess<V> and DictionaryAccess<K, V> just like the for each
> >> loop
> >> handles any implementations of the Iterable interface.
> >>
> >>
> >>
> >> ------------------------------
> >> *From:* Neal Gafter <neal at gafter.com>
> >> *To:* Shams Mahmood <shams.mahmood at gmail.com>
> >> *Cc:* coin-dev at openjdk.java.net
> >> *Sent:* Tuesday, June 23, 2009 4:42:40 PM
> >> *Subject:* Re: Indexing access for Lists and Maps considered harmful?
> >>
> >> On Tue, Jun 23, 2009 at 1:55 PM, Shams Mahmood <shams.mahmood at gmail.com
> >> >wrote:
> >>
> >>> So,
> >>> List<String> list = new ArrayList();
> >>> list[1] = list[0] = "value";
> >>> would get translated to:
> >>> Collections.set(list, 1, Collections.set(list, 0, "value"))
> >>
> >>
> >> The link to methods in Collections is a bit too magical (e.g. it
> >> won't
> >> gracefully handle anything other than the collections API nor will it
> >> gracefully support evolution of the platform).
> >>
> >>
> >>
> >
>
>
>
More information about the coin-dev
mailing list