Nobody *ever* uses map, et. al… (example 3)
Continuing my nobody *ever* uses series, here’s a Java example.
Consider the following horrible piece of Java code taken from Instinct which finds specifications to run:
private Collection<LifecycleMethod> findMethods(final MarkingScheme markingScheme) {
final Collection<LifecycleMethod> lifecycleMethodSet = new HashSet<LifecycleMethod>();
final Collection<Method> methods = methodLocator.locateAll(contextType, markingScheme);
for (final Method method : methods) {
lifecycleMethodSet.add(new LifecycleMethodImpl(method, contextType));
}
return lifecycleMethodSet;
}
Here’s the same method rewritten using Functional Java, with the conversion function pulled out for clarity:
private Collection<LifecycleMethod> findMethods(final MarkingScheme markingScheme) {
final F<Method, LifecycleMethod> conversion = new F<Method, LifecycleMethod>() {
public LifecycleMethod f(final Method a) {
return new LifecycleMethodImpl(a, contextType);
}
};
final Collection<Method> methods = methodLocator.locateAll(contextType, markingScheme);
return toFjList(methods).map(conversion).toCollection();
}
The good thing about the above is it expresses succinctly what we’re doing; find the methods we’re interested in and map across them to convert them into another type. The unfortunate things are that we have to convert from a Java collection to a FJ collection (toFjList) and we need to use the clunky Java anonymous inner class as a pseudo first class function.
For comparison, here’s a rough stab (i.e. probably won’t compile) at what it’d look like in Scala, notice that implicits will take care of the conversion for us:
def findMethods(markingScheme: MarkingScheme) = methodLocator.locateAll(contextType, markingScheme).map(new LifecycleMethodImpl(_, contextType))
Now isn’t that better?