Drag and Drop in GWT - The How-To Know your streams
Dec 05

We all know the Java Collections Framework - Collection, List, Set, Map are used in almost every Java application. We also know that operator overloading in not available in Java, something that has caused a huge debate over the years, especially after C# came out and had it as a feature.

In fact, just today Daniel Pitts posted something about it under his “almost useful” tag. In that, he obviously mentions the convenient square brackets operator map[“key”] or list[1] where map is a Map instance and list is a List instance, of course.

Some history about EoD

When Java 5 came out, many ease of development (EoD in short) features were introduced. One of them was the “foreach” loop - a syntax for iterating over arrays and collections from the collections framework easily and, as an extra effect, in a standard way. This was accomplished by extracting the iteration interface out of the Collection interface, now named Iterable. Everything that implements the Iterable interface could be used in a “foreach” loop (which is, by no coincidence, the implemented interface by my Yielder class, which is a virtual collection).

It makes sense for another EoD interface to come out: the Indexer interface. This interface could be a simple interface which would allow for [ ] operators to be used through code. This shouldn’t be an issue for the operator overloading debate: The square brackets interface can hardly be used for operator abuse (with the exception of functor objects, but without the ability to have multiple parameters it would be a pretty lame usage), and if operator overloading does infiltrate the Java language, the compiler feature could be replaced with something that uses that language feature.

The details about Indexer

The Indexer interface could be as simple as:

public interface Indexer<K, V> {
  void put(K key, V value);
  V get(K key);
}

And now, together with the EoD compiler feature, every call such as indexer[key] = value could be compiled to indexer.put(key, value), and value = indexer[key] could be compiled to value = indexer.get(key). This shouldn’t and couldn’t be hard to do in compile time, especially seeing that the [ ] operator is currently reserved only for array instances.

This feature could obviously be used for some interesting new classes, but it would be even more relevant with current collections’ interfaces, such as Map<K, V> implements Indexer<K, V>, and perhaps the less obvious but as important List<T> implements Indexer<Integer, T>, allowing us to use collections the way they were meant to be used (and are indeed used already in many other languages).

As always, I’m interested in hearing your opinion about it!

Other posts of interest

8 Responses to “Who wants Indexer as the next EoD feature?”

  1. Stephen Colebourne Says:

    You will need two interfaces, as List cannot extend Indexer (an implementation of List could, but not the interface). This isn’t a big deal - just have Indexable and Mappable.

    If you would like to implement this, take a look at the Kijaro project. We are gathering together lots of proposed language changes, and an implementation really help convince those in power. Just drop me an email if you’d like to create a branch at Kijaro for this (or any other language change).

  2. Avah Says:

    Are you saying it can’t because of the get(int) defined in List, or some other reason?

    Also, it is unfortunate but might be necessary to create to interfaces, just to not create redundant methods (set vs. put in List, for example).

  3. Stephen Colebourne Says:

    Due to backwards compatability, you can’t add any new methods to List (or any other JDK interface). List doesn’t have a put(K,V) or get(K) method at present, so can’t in the future.

    So,
    public interface Indexable {
    E get(int index);
    E set(int index, E newValue);
    }

  4. Daniel Pitts Says:

    I agree with Stephen, you need at least two interfaces. I’m not sure I agree with the names he choose though.

    Iterable makes sense, Indexable suggest that it can be indexed, not that it contains indexes.

    It might also be useful to separate out storing from retrieving. They’re often related but not always.

    IndexedGetter, IndexedSetter, KeyedGetter KeyedPutter.

  5. Daniel Pitts’ Tech Blog » Blog Archive » More Discussion On Operator Overloading Says:

    […] I was surprised to see that within one day of posting my previous entry on Operator Overloading, I received several comments. Avaid Ben Dov from Chaotic Java even took my idea and ran with it. Ricky Clarkson suggested using Haskels approach of allowing anything that is of the “Num” type to define +,-,/,*, etc…. I have a few things to add to this discussion. […]

  6. Neal Gafter Says:

    If you want to be able to retrofit Map without breaking compatibility, the get method needs to take an Object as its parameter, not a K.

  7. Avah Says:

    Neal: You’re right, now that I think of that. I always wondered why, when generics was added, the get method didn’t become get(K)… Doesn’t it also help type safety in a way?

  8. Daniel Pitts Says:

    In a way, it might improve type safety, but the really get(wrongObjectType) will always return null, since the map won’t (can’t) contain that key.

    My guess on why they decided to keep get(Object), was because some code may rely on that behavior (instead of having to do explicit type-checks/casting before calling get)

Leave a Reply

Chaotic Java is Digg proof thanks to caching by WP Super Cache!