JEP 186: Collection Literals
Paul Benedict
pbenedict at apache.org
Wed Jan 15 14:19:00 PST 2014
I question the appropriateness of using annotations for this problem. Isn't
there some long standing assertion that annotations shouldn't be used to
drive language features?
On Wed, Jan 15, 2014 at 4:03 PM, Timo Kinnunen <timo.kinnunen at gmail.com>wrote:
> No need for that, just fake the = { <. . .> } syntax to mean calling
> someStaticMethod( <. . .> ) as well, again passing through what arguments
> happened to be given by the caller. Huge-array library developers will take
> care of the rest. That’ll also get you initializer list -like constructors
> as a bonus, in case someone wants to use those in their classes.
>
>
>
>
>
>
>
>
>
>
>
>
> --
> Have a nice day,
> Timo.
>
> Sent from Windows Mail
>
>
>
>
>
> From: Brian Goetz
> Sent: Thursday, January 16, 2014 00:02
> To: Timo Kinnunen, Zhong Yu, Per Bothner
> Cc: lambda-dev at openjdk.java.net
>
>
>
>
>
> If we were to do something like that (BTW, something very similar was in
> one of the Collection Literal proposals from the Coin timeframe), we'd
> also want to upgrade the indexes to long; 2B is just too low a limit for
> the next 20 years. Which also means that using ... in the initializer
> is a no-go.
>
> On 1/15/2014 2:50 PM, Timo Kinnunen 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?
> >
> >
> >
> >
> >
>
>
--
Cheers,
Paul
More information about the lambda-dev
mailing list