Proposal: Indexing access syntax for Lists and Maps
Stephen Colebourne
jodastephen at gmail.com
Mon Mar 30 16:40:20 PDT 2009
I'm surprised annotation solutions are being considered given the
general approach taken to annotations affecting the language.
For this feature, if it went ahead, I would strongly request having four
new interfaces
IndexedGet
IndexedSet
MappedGet
MappedPut
Each with one method.
The existing Collection and Map classes would then be retofitted.
It might be a good time to retrofit a Sized interface too, defining the
size() method.
Finally, arrays must "implement" the new indexed interfaces. This is
critical to allow code like this to work:
public void process(IndexedGet getter) { .. }
This would take in any List or array, or used defined implementation of
IndexedGet.
I would note that arrays should also "implement" Sized and Iterable
(were remove on the iterator would throw UOE). I should really write up
the Coin proposal for making arrays implement more interfaces, but its
almost 2am, and it wouldn't make much sense. Suffice it to say that I've
had to code this since Java 5 on more than one occasion:
public void process(Iterable it) { ... }
public void process(Object[] array) { ... }
Stephen
Joseph D. Darcy wrote:
> I was going to type up a proposal along these lines from scratch, but
> I'm happy you sent in your proposal first, especially since there is a
> prototype already :-)
>
> While collections are certainly very widely used and should have this
> indexing support IMO, I think it is also important that indexing support
> not be strictly limited to just classes implementing java.util.{List,
> Map}. For example, if this kind of capability is added, I'd like enough
> flexibility to give library developers the ability to in effect write a
> 64-bit array class. (Semantically, a Java array today is basically just
> a map from int to some other type.)
>
> The mechanism to indicate indexing is supported on a class must at least
> support Lists and Maps:
>
> java.util.List<E>
> read: E get(int)
> write: E set(int, E)
>
> java.util.Map<K, V>
> read: V get(Object)
> write: V put(K, V)
>
> So variation in both the names of the methods must be accommodated as
> well as the typing of the methods.
>
> The compiler needs a few pieces of information to perform the indexing
> translating including "Should this type get indexing support?" and "If
> this type gets indexing support, what methods do read and write
> operations get mapped to?"
>
> The most magical way to indicate the indexing support bit is to have a
> marker interface (or even an annotation) and then to have the names of
> the get/set methods indicated as annotation values. As a strawman
> something like
>
> public interface java.lang.Indexable {}
>
> @Documented
> @Target(TYPE)
> @Retention(RUNTIME)
> @Inherited
> public @interface java.lang.IndexableNames {
> String reader() default "get";
> String writer();
> }
>
> where then, say, java.util.List would be changed from
>
> public interface List<E> extends Collection<E>
>
> to
>
> @IndexableNames(writer="set")
> public interface List<E> extends Collection<E> extends Indexable
>
> However, this feels a bit too magical and there would be complications
> about getting the indexable method names since annotation inheritance
> only works along superclasses, not superinterfaces.
>
> A better approach is probably to create at least two new superinterfaces
> in java.lang for the List and Map signatures. However, some care and
> analysis will be needed to ensure a migration compatibility issue is not
> introduced. (In support of the enhanced for loop in JDK 5, a
> superintface of java.util.Iterator, java.lang.Iterator (lacking a remove
> method), was introduced being being subsequently removed for migration
> compatibility conflicts.)
>
> -Joe
>
>
>
More information about the coin-dev
mailing list