JEP 186: Collection Literals
Zhong Yu
zhong.j.yu at gmail.com
Wed Jan 15 14:59:28 PST 2014
I don't see why array syntax is so appealing, and why we want to
expand it to other things. I would rather get rid of arrays, use
instead an Array<T> type with plain construcutor, getter,and setter.
On Wed, Jan 15, 2014 at 1:50 PM, Timo Kinnunen <timo.kinnunen at gmail.com> wrote:
> Hi,
>
> 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:
>
>
> @Retention(RetentionPolicy.SOURCE)
> @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 };
> @SyntaxProvider.ArrayInitializer
> static MyClass containing(MyItem... items){
> return new MyClass(Arrays.asList(items)); }
>
> // Allows: MyItem there = it[100_000_000_000_000L];
> @SyntaxProvider.ArrayGetter
> static MyItem getAt(MyClass that, long index){
> //TODO: Implement actual long indexing
> return that.items.get((int) index); }
>
> // Allows: MyItem another = it[1] = there;
> @SyntaxProvider.ArraySetter
> static MyItem setAt(MyClass that, long index, MyItem item){
> that.items.set((int) index, item); return item; }
>
> // Allows: long items = it.length;
> @SyntaxProvider.ArrayLength
> 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) };
> @SyntaxProvider.ArrayInitializer
> 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];
> @SyntaxProvider.ArrayGetter
> 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);
> @SyntaxProvider.ArraySetter
> 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,
> Timo.
>
> Sent from Windows Mail
>
> From: Zhong Yu
> Sent: Wednesday, January 15, 2014 21:19
> To: Per Bothner
> Cc: lambda-dev at openjdk.java.net
>
> On Wed, Jan 15, 2014 at 11:04 AM, Per Bothner <per at bothner.com> wrote:
>> On 01/15/2014 03:44 AM, Zhong Yu wrote:
>>>
>>> On Tue, Jan 14, 2014 at 7:17 PM, Per Bothner <per at bothner.com> 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 = tmp.build();
>>>
>>>
>>> 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 bothner.com http://per.bothner.com/
>
More information about the lambda-dev
mailing list