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