Indexing access for Lists and Maps considered harmful?
Joseph D. Darcy
Joe.Darcy at Sun.COM
Tue Jun 23 22:33:03 PDT 2009
A less than ideal option would be to just support [] access for getting
and not setting, but I think we can work out something acceptable for
setting as well.
-Joe
Joshua Bloch wrote:
> 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