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