Indexing access syntax for Lists and Maps

Reinier Zwitserloot reinier at zwitserloot.com
Wed Jul 22 05:01:36 PDT 2009


Your suggestion has been discussed quite a bit, IIRC. It's not a clear  
winner by any means. To wit:

1. For people who consider x[y] = z as syntax sugar for x.set(y, z),  
this is going to catch them out. In particular, they may just run a  
blanket search/replace for the "list.set(idx, val)" pattern and  
replace it with list[idx] = val, and thus produce code which is buggy,  
but the bug is not at all obvious.

2. You now have an interface powering a language feature where you  
HAVE TO return something, but whatever you return is ALWAYS ignored.  
That's rather silly, not to mention actively confusing in that it  
strongly suggests the value of the expression is what you return from  
this method. It may have to be acceptable collateral damage to be  
compatible with java.util.Map/List, but making this deliberation seems  
impossible given the limited timespan between now and java7's release.

3. You still have to deal with the notion that the value of any  
assignment expression is currently defined as a rough analogue to 'the  
actual value of the thing you're assigning to, post-assignment'. The  
idea behind this, no doubt, is that you can use 'tunnel vision' and  
consider only "A = B" when reading "A = B = C = D = E = F" if you are  
so inclined. This indeed holds for all current assignments, but for  
lists and maps, this will not hold unless a subsequent get call is  
generated. Who knows - maybe that List takes only integers and will  
increment each integer by 1 prior to storing it for some reason.


I will make one last plea for sanity here and reiterate my belief that  
the only right answer (if there is one) is that a[b] = z MUST NOT be  
an expression, but a statement. There are at least 5 reasonable but  
mutually exclusive interpretations of what it ought to be, as covered  
in this review of the issues:

  1) the old object at the given index / the old value associated with  
the given key, as per Map.put and List.set.

  2) The RHS, unmodified (wrong on all accounts, but nevertheless, if  
you go out on the street and interview Joe Q. Random Java Programmer  
about the value of "a = x", this one will win hands down, and is  
therefore de facto a reasonable answer, unless we want to consider the  
majority of java programmers as unreasonable, which seems like a  
rather ill informed plan).

  3) The RHS, but converted so that it fits (in this case,  
essentially: box first if the RHS is a primitive).

  4) a = b[c] = d; is equal to b[c] = d; a = b[c]; (the tunnel vision  
argument: A = B = C is, as far as A is concerned, equal to A = B).

  5) Assignments aren't expressions, so, no value. (wrong, but a  
popular style rule).

The problem with 4 out of those 5 is: If you get the answer wrong,  
your code will do subtly different things that's going to take you a  
long time to debug.

Therefore, #5 wins, because when you pick the wrong answer, the  
resulting error in your code is:

  A) generated at compile time (in IDEs, as you write it, instant red- 
line). For all others, it would be a run-time problem.
  B) generated in the right place (at the place where you write the  
assignment-as-expression, and not in some other place, which is where  
you're going to get your surprise in the other 4 options)
  C) generated with a concise and obvious error message: "List/Map  
index/key assignment may not be used an expression." For all others,  
you won't even get an exception, you'll just end up with a value you  
weren't at all suspecting.


Hence, I rate the man-hour cost of getting the answer wrong as over an  
hour for #1-#4, but more like 10 seconds for #5. The fact that its a  
popular style rule (e.g. people who will even try to use an assignment  
as an expression is low) is just gravy.

#5 is therefore the only right answer, Unless consistency is of  
tantamount importance, in which case there is no right answer, and  
this proposal must not go forward.


  --Reinier Zwitserloot



On 2009/22/07, at 11:40, Eamonn McManus wrote:

> Reinier Zwitserloot <reinier at zwitserloot.com> writes:
>> 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.
>
> In addition to the options you mention later in your message, it  
> seems to me
> that a reasonable option would be to say that the value of
>
> someArrayList[0] = "Hello"
>
> is the value assigned.  The fact that list.set returns something  
> else doesn't
> have to be relevant.  The JLS currently says that "the result of the  
> assignment
> expression is the value of the variable after assignment has  
> occurred", and it
> is obvious how this should be extended for lists and maps.
>
> Éamonn McManus · JMX Spec Lead · http://weblogs.java.net/blog/ 
> emcmanus/
>
>




More information about the coin-dev mailing list