Re: JEP 186: Collection Literals

Timo Kinnunen timo.kinnunen at
Wed Jan 15 11:50:50 PST 2014


Re: “Array literals (and, array types) are more of an oddity from today's
point of view; we should get rid of them if that were possible,
because their functions can be perfectly achieved with other general
purpose language devices.”

If it is at all possible, it’s possible through providing something that’s simpler and in all respects better than old arrays.

With one magical annotation, you could do:


@interface SyntaxProvider {

@Retention(RetentionPolicy.SOURCE) @Target(ElementType.METHOD) @interface ArrayInitializer {}  

@Retention(RetentionPolicy.SOURCE) @Target(ElementType.METHOD) @interface ArrayGetter {}  

@Retention(RetentionPolicy.SOURCE) @Target(ElementType.METHOD) @interface ArraySetter {}

@Retention(RetentionPolicy.SOURCE) @Target(ElementType.METHOD) @interface ArrayLength {} }

Which allows:

interface ArraySyntaxProviderForMyClass {

// Allows: MyClass it = { myItem1, myItem2 };


static MyClass containing(MyItem... items){

return new MyClass(Arrays.asList(items)); }

// Allows: MyItem there = it[100_000_000_000_000L];


static MyItem getAt(MyClass that, long index){

//TODO: Implement actual long indexing

return that.items.get((int) index); }

// Allows: MyItem another = it[1] = there;
static MyItem setAt(MyClass that, long index, MyItem item){

that.items.set((int) index, item); return item; }

// Allows: long items = it.length;
static long getLengthOfMyClass(MyClass it){

return it.items.size(); }

This covers most of the usual array stuffs already. Lists, ArrayLists are doable. Add interleaved varargs at compile-time and that covers Maps and JSON:

// Allows: MyClass it = { "one", new MyItem(1), "two", new MyItem(2) };


static MyClass createdFrom(String[] keys, MyItem... items){

MyClass myClass = new MyClass(Arrays.asList(items));

for(int i = 0, n = keys.length; i < n; i++) {

myClass.index.put(keys[i], items[i]);


return myClass; }

Faking array[. . .] syntax by making it mean the same as calling somestaticmethod(array, . . .) covers indexing with multiple axis in one call, allowing sparse tables and continuous multi-dimensional arrays:

// Allows: MyItem item = myClass["clubs", 10];


static MyItem getAt(MyClass that, String id, int subId){

return that.items.get(subId).index.get(id); }

// Allows: MyItem old = myClass["clubs", 10] = new MyItem(5);


static MyItem setAt(MyClass that, String id, int subId, MyItem item) {

return that.items.get(subId).index.put(id, item); // returns old item, if any, unlike arrays

} }

class MyItem extends MyClass { int value;

public MyItem(int i) {

super(new ArrayList<>());

this.value=i; } }

class MyClass implements ArraySyntaxProviderForMyClass {

List<MyItem> items; 

Map<String, MyItem> index = new HashMap<>();

public MyClass(List<MyItem> asList) { this.items=asList; } }

If some of the array syntax is to be reused, better reuse all of it to leave no doubt.

Is this the least expansive way of covering all of these cases or is there some other way that has an even smaller impact or footprint?

Have a nice day,

Sent from Windows Mail

From: Zhong Yu
Sent: ‎Wednesday‎, ‎January‎ ‎15‎, ‎2014 ‎21‎:‎19
To: Per Bothner
Cc: lambda-dev at

On Wed, Jan 15, 2014 at 11:04 AM, Per Bothner <per at> wrote:
> On 01/15/2014 03:44 AM, Zhong Yu wrote:
>> On Tue, Jan 14, 2014 at 7:17 PM, Per Bothner <per at> wrote:
>>> For example, one could define:
>>> T v = { e1, ..., en}
>>> as syntactic sugar for:
>>> TB tmp = T.make_builder();
>>> tmp.add(e1); ..; tmp.add(en);
>>> T v =;
>> How is this any better than
>>      T.of(e1, ..., en);
>> ? I don't see how the literal syntax helps code writers or code
>> readers in this case.
> I can think of two reasons:
> (1) Target-typing means you don't have to redundantly specify T:
> T v = { e1, ..., en};
> vs
> T v = T.of(e1, ..., en);
> (2) Using the T.of form requires allocating an array,
> which is then thrown away.
> I don't think (2) is a major justification. (1) may not
> be enough to justify a new language feature by itself,
> though one could argue it's a natural extension of the
> existing syntax for arrays.

There is no need for array literals; method+vararg is just fine

    String[] strings = array("a", "b", "c");

(of course this requires generics/vararg which java1.0 didn't have.)

Array literals (and, array types) are more of an oddity from today's
point of view; we should get rid of them if that were possible,
because their functions can be perfectly achieved with other general
purpose language devices.

List literals, or T literals in your example, have equally little
value. It creates a new burden for programmers - they now have two
very similar ways to do the same thing, and they have to waste their
brain power to make a choice. Two camps will emerge fighting each
other over whose syntax is better.

Zhong Yu

> --
>         --Per Bothner
> per at

More information about the lambda-dev mailing list