Proposal: Indexing access syntax for Lists and Maps

Reinier Zwitserloot reinier at zwitserloot.com
Wed Apr 22 16:57:00 PDT 2009


Letting 'foo[x]', where foo is a set, have the asribed specification  
is exactly the kind of circus trick I expect some well-intended bad  
library to use, in languages that support operator overloading.

Hard-coding it into the JLS: Please, don't do that.

Here's the golden rule for doing ANYTHING at all with operators:

If it's not crystal clear for everybody who is going to read your  
code, then, don't do it. Also,

someList[10] = true;

someMap[10] = true;

someSet[10] = true;

would all have entirely different meanings. Overloading [] for lists  
and maps is an acceptable evil because people in general are quite  
used to it (e.g. due to javascript, python, and many other languages).



This list is certainly reinforcing the idea that operator overloading  
accessible to library builders is a bad idea.


  --Reinier Zwitserloot
Like it? Tip it!
http://tipit.to



On Apr 22, 2009, at 06:47, Derek Foster wrote:

> I like your idea of including Set as well. I think it makes  
> intuitive sense with regards to a set as a quality of its members.  
> (e.g. the set "blue" has members which are blue, and thus "blue[x]"  
> represents "is x blue?"
>
> However, if we were to do so, I think that "bool foo = (set[y] =  
> bar)" should always result in 'foo' being equal to 'bar', not in it  
> getting the assigned the return value of set.add() or set.remove()  
> as your desugaring implies.
>
> Derek
>
>
>
> -----Original Message-----
>> From: Tim Keith <tim.keith at gmail.com>
>> Sent: Mar 29, 2009 10:40 PM
>> To: coin-dev at openjdk.java.net
>> Subject: Re: Proposal: Indexing access syntax for Lists and Maps
>>
>> Is it possible to include Set as well?
>>
>> E.g.  "bool = set[x]"  meaning  "bool = set.contains(x)"
>> and "set[x] = bool"  meaning  "bool ? set.add(x) : set.remove(x)"
>>
>> -- Tim
>>
>> On Sun, Mar 29, 2009 at 5:12 PM, Shams Mahmood <shams.mahmood at gmail.com 
>> >wrote:
>>
>>> Indexing access syntax for Lists and Maps
>>>
>>> VERSION
>>> This is version 1.0.
>>>
>>> AUTHOR(S):
>>> Shams Mahmood Imam
>>>
>>> OVERVIEW
>>>
>>> FEATURE SUMMARY:
>>> Collection classes are among the most frequently used in the Java  
>>> SDK.
>>> Currently Lists and Maps do not provide any additional language
>>> feature to access individual elements unlike Arrays. This proposal
>>> aims to provide these Collection citizens of java additional
>>> language support to access elements like Arrays have currently.
>>>
>>> MAJOR ADVANTAGE:
>>> Will provide a consistent syntax for accessing elements of Arrays,
>>> Lists and Maps. In addition, the language grammar will not change
>>> much since the subscript operator is already supported for Arrays.
>>>
>>> MAJOR BENEFIT:
>>> Apart from the consistency mentioned above, implementation fo this
>>> feature will result in fewer characters needed to be typed to  
>>> achieve
>>> simple access to elements in Maps/Lists.
>>>
>>> MAJOR DISADVANTAGE:
>>> Like the for-each loop construct, it will expose the client to
>>> NullPointerException(NPE)s when used with a null List/Map. However,
>>> this shouldn't be such a major issue as NPEs are also generated
>>> by arrays when the operator is used in a null array.
>>>
>>> ALTERNATIVES:
>>> The comparatively more verbose get/set methods for Lists and get/put
>>> methods for Maps.
>>>
>>> EXAMPLES
>>>
>>> SIMPLE EXAMPLE:
>>>
>>> public class Main {
>>> public static void main(String[] arguments) {
>>>   List<String> l1 = Arrays.asList(new String[] {"a", "b", "c"});
>>>   String firstElement = l1[0];
>>>   Map<Integer, String> m1 = new HashMap<Integer, String>(4);
>>>   m1[Integer.valueOf(1)] = "One";
>>> }
>>> }
>>>
>>> ADVANCED EXAMPLE:
>>>
>>> public class Main {
>>> public static void main(String[] arguments) {
>>>   List<String> l1 = Arrays.asList(new String[] {"a", "b", "c"});
>>>   Map<Integer, String> m1 = new HashMap<Integer, String>(4);
>>>   Map<String, Integer> m2 = new HashMap<String, Integer>(4);
>>>
>>>   m2[l1[2]] = m2[m1[1]] = 4; // same as m2.put(l1.get(2),
>>> m2.put(m1.get(1), 4));
>>> }
>>> }
>>>
>>> DETAILS
>>>
>>> SPECIFICATION:
>>> Java Language Specification changes:
>>>
>>> 15.29 (NEW CHAPTER): Collection Access Expressions
>>> A collection access expression contains two subexpressions, the  
>>> List/Map
>>> reference expression (before the left bracket) and the index  
>>> expression
>>> (within the brackets). Note that the List/Map reference expression  
>>> may be a
>>> name or any expression that evaluates to a List/Map. The index  
>>> experssion is
>>> expected to evaluate to an int for Lists and a valid key type for  
>>> Maps.
>>>
>>> CollectionAccess:
>>> Expression [ Expression ]
>>>
>>> 15.8 Primary Expressions
>>> original:
>>> ---------
>>> PrimaryNoNewArray:
>>> Literal
>>> Type . class
>>> void . class
>>> this
>>> ClassName.this
>>> ( Expression )
>>> ClassInstanceCreationExpression
>>> FieldAccess
>>> MethodInvocation
>>> ArrayAccess
>>>
>>> replaced with:
>>> --------------
>>> PrimaryNoNewArray:
>>> Literal
>>> Type . class
>>> void . class
>>> this
>>> ClassName.this
>>> ( Expression )
>>> ClassInstanceCreationExpression
>>> FieldAccess
>>> MethodInvocation
>>> ArrayAccess
>>> CollectionAccess
>>>
>>> 15.26 Assignment Operators
>>> original:
>>> ---------
>>> LeftHandSide:
>>> ExpressionName
>>> FieldAccess
>>> ArrayAccess
>>>
>>> replaced with:
>>> --------------
>>> LeftHandSide:
>>> ExpressionName
>>> FieldAccess
>>> ArrayAccess
>>> CollectionAccess
>>>
>>>
>>> COMPILATION:
>>>
>>> After successful creation of the AST handling the additional  
>>> grammar for
>>> Collection Access expressions, the syntactic sugar will be  
>>> replaced by
>>> JDK1.4 compatible code during the Code Generation phase. This is  
>>> consistent
>>> with how JDK5.0 constructs like the for-each loop is handled by the
>>> compiler.
>>>
>>> e.g.
>>> public class TestConcise {
>>> public static void main(String[] args) {
>>>   java.util.Map<Integer, String> m1 = new java.util.HashMap<Integer,
>>> String>();
>>>   m1[2] = "two";
>>>
>>>   java.util.LinkedList<String> l1 = java.util.Arrays.asList( new  
>>> String[]
>>> {"a", "b", "c" });
>>>   m1[3] = l1[2];
>>>   l1[0] = m1[0];
>>>   l1[1] = "one";
>>> }
>>> }
>>>
>>> is converted to
>>> public class TestConcise {
>>> public TestConcise() {
>>>   super();
>>> }
>>>
>>> public static void main(String[] args) {
>>>   java.util.Map<Integer, String> m1 = new java.util.HashMap<Integer,
>>> String>();
>>>   m1.put(Integer.valueOf(2), "two");
>>>
>>>   java.util.LinkedList<String> l1 = java.util.Arrays.asList( new  
>>> String[]
>>> {"a", "b", "c" });
>>>   m1.put(Integer.valueOf(3), l1.get(2));
>>>   l1.set(0, m1.get(Integer.valueOf(0)));
>>>   l1.set(1, "one");
>>> }
>>> }
>>>
>>>
>>> TESTING:
>>>
>>> LIBRARY SUPPORT:
>>> No additional library support is needed.
>>>
>>> REFLECTIVE APIS:
>>> This proposal does not require any reflective API changes.
>>>
>>> OTHER CHANGES:
>>> No changes required.
>>>
>>> MIGRATION:
>>> No migration is needed.
>>>
>>> COMPATIBILITY
>>>
>>> BREAKING CHANGES:
>>> No breaking changes.
>>>
>>> EXISTING PROGRAMS:
>>> Existing programs are not affected by this change.
>>>
>>> REFERENCES
>>> My Java7 Wishlist regarding Collections,
>>> http://shamsmi.blogspot.com/2008/04/my-java7-wishlist-regarding-collections.html
>>> Implementation of My Java7 Wishlist,
>>> http://shamsmi.blogspot.com/2008/05/implementation-of-my-java7-wishlist.html
>>>
>>> EXISTING BUGS:
>>> None.
>>>
>>> URL FOR PROTOTYPE (optional):
>>> Projects kijaro's concisecollections branch:
>>> https://kijaro.dev.java.net/source/browse/kijaro/branches/concisecollections/
>>>
>>>
>>>
>>>
>>>
>>
>
>




More information about the coin-dev mailing list