Why are most eclipse collections types Serializable?

eclipse-collections, java, serializable

Solution

This question was asked quite a few years ago. I will explain the design rationale behind making all of the functional interfaces in Eclipse Collections extend `Serializable`, as best as I can recall it. The decision was made over 15 years ago. Note: I am the creator of Eclipse Collections.

Eclipse Collections has been in development since 2004. It started out its development lifecycle in JDK 1.4. Eclipse Collections had functional interfaces and a functional API, ten years before there were lambdas and Streams available in Java 8. In order to use the functional API of Eclipse Collections with the functional interfaces before Java 8, we often had to create anonymous inner classes.

We had a need to serialize the functional interfaces between caches in a proprietary distributed caching architecture and also to occasionally serialize them to disk. Intersection types were added to the Java language in Java 8 to support serialization of lambdas. Prior to Java 8, we had to choose a single interface or class to implement an anonymous inner class. If a functional interface we used for an anonymous inner class was not `Serializable`, we had no way to make it `Serializable` without creating a named class that extended both the functional interface and `Serializable`.

One possibility we considered would have been to have a parallel hierarchy of functional interfaces. We could have had a `Function` interface, which did not extend `Serializable`, and then add a second `SerializableFunction` interface which would extend both `Function` and `Serializable`. There are some examples in the distributed caching space that took this approach of having parallel hierarchies. For instance Oracle Coherence and Hazelcast have functional interfaces which extend JDK equivalent interfaces and `Serializable`. If we had done this in Eclipse Collections it would have resulted in doubling our total functional interface types (today around 500) to almost 1K functional interface types.

Ultimately, we decided the best approach for Eclipse Collections was to make all of our functional interfaces simply extend `Serializable`.

After Java 8 was released, we added `@FunctionalInterface` to our functional interfaces, and changed them to extend the equivalent functional interfaces in the JDK. This resulted in us having `Serializable` versions of the JDK interfaces that we could use with Eclipse Collections and Java Streams APIs.

Here are links to all of the object and primitive functional interfaces included in Eclipse Collections. As can be seen, the functional interfaces are voluminous because of the support for a functional API on primitive collections.

- Functions

- Primitive Functions

- Predicates

- Primitive Predicates

- Procedures

- Primitive Procedures

When Project Valhalla is delivered and generics support for primitives is included in a LTS (Long Term Support) Java Release, we will eventually upgrade Eclipse Collections and possibly remove most of our current primitive functional interfaces as they will no longer be necessary. I say possibly, as this would be a breaking change resulting in a substantial amount of work and require a major release of Eclipse Collections. More importantly, it would impact all of the current clients.

Problem

I'm looking for design rationale here. I can understand making collection classes Serializable as a matter of course, although JCF doesn't do that. Nevertheless, the `Procedure`, `IntProcedure`, etc. interfaces in particular are prime candidates for not being `Serializable` since they will often be anonymous anyway. Making those interfaces `Serializable` goes against Josh Bloch's advice that interfaces should rarely extend `Serializable`[1]. I may need to update my Eclipse preferences not to emit serial uid warnings for every anonymous `Procedure`. [1] Effective Java 2nd Ed. pg 291

Original source

Related problems