Indexing access syntax for Lists and Maps

Reinier Zwitserloot reinier at zwitserloot.com
Mon Jul 20 18:03:56 PDT 2009


Greg, reread some older threads. We've held an extremely extensive  
back-and-forth about implementing map/list index operators. A summary  
of the findings:

1. Whatever we come up with, it has to work with java.util.Map and  
java.util.List, otherwise, why bother? Map and List are both  
interfaces, so they cannot gain any new methods. Therefore, either (A)  
we 'hardcode' support in for those data types, or (B) we come up with  
an interface that mirrors a strict subset of the methods in those types.

2. Mirroring List's "T get(int)" is just fine, but "boolean set(int,  
T)" is problematic because of that 'boolean' return value. What should  
this:

  Object x = someArrayList[0] = "Hello";
  System.out.println(x);

print? People will expect 'Hello'. But if we just 'desugar' "list[idx]  
= foo" to "list.set(idx, foo)", then this will print "true", which is  
an instant java puzzler. Turning the return type to 'void' solves the  
problem, but won't be compatible with java.util.List, as "boolean  
set(int, T)" is just not compatible with "void set(int, T"). There are  
two fixes for this. The first is complex and has ramifications for the  
JVM: (A) add to the JLS that you can override a method that returns  
void, and change the void return type to something else (just like you  
can pick a more specific subtype if you want), but that's not enough,  
because you also need to add: (B) *UNLIKE* how specific subtype is  
implemented (a wrapper method at compile time), because there are  
existing Map implementations out there in class form, the class loader/ 
JVM needs to create and inject these wrapper methods on-the-fly, as  
the classes are loaded. The second fix is simpler but feels hackish:  
Declare java.util.List and java.util.Map 'magic', and while they DONT  
extend SetByKey/SetByIndex, they DO work with the map[foo] = val /  
list[idx] = val syntax.

3. Same situation (but worse) with Map: "V get(K)" is fine, but "V  
set(K, V)" is problematic, as it returns the OLD value associated with  
the key (usually null, in other words). So:  
System.out.println(map[key] = "Hello"); will print 'null', not  
'Hello'. Puzzler. Bad.

4. Technically, the result of the "a = b" expression in the JLS is  
defined as not just "b", but "b, converted to fit into a". So:

long foo;
Object x = foo = 1;
System.out.println(x.getClass());

will print "java.lang.Long" and not "java.lang.Integer" as you might  
expect. Trying to port this nuance to map/list is so complicated that  
no one to date has come up with a strategy that isn't going to confuse  
half of the java programmers out there. Nevertheless, my continued  
insistence that the only way forward is decide on making the map/list  
assignment sugar have the void type, and working out a way to  
implement this nicely, has been made with majority opposition.

5. Even though I consider the value of this proposal very low (who  
indexes into lists? You .add(), and you iterate), Joe Darcy continues  
to mention this proposal in coin posts, so apparently it isn't dead yet.

  --Reinier Zwitserloot



On 2009/20/07, at 23:39, Greg Brown wrote:

> I'd like to separate the previous discussion into two threads, so the
> conversation regarding the merits of collection literals doesn't
> completely overshadow the other topic:
>
>> 1) Indexing access syntax for Lists and Maps
>>
>> It would be nice to see this feature extended to any class, not just
>> List and Map. Groovy supports this by mapping the index operator to
>> getAt() and putAt() - a similar approach (possibly one that maps to
>> get(int)/set(int, E) and get(K)/put(K, V)) would be more flexible and
>> would still work for List and Map.
>
>
> How viable might this be?
>
>
>




More information about the coin-dev mailing list