Foo.Of{Int,Long,Double} naming convention

Brian Goetz brian.goetz at oracle.com
Sun Dec 23 09:44:48 PST 2012


For types that have primitive specializations that are subtypes of the 
base type (e.g., MutableReducer), we've been converging on a naming 
convention that puts the subtypes as nested interfaces.  For example:

interface MutableReducer<T,R> {

    // reducer methods

    interface OfInt<R> extends MutableReducer<Integer,R> { ... }
    interface OfLong<R> extends MutableReducer<Integer,R> { ... }
}

The motivation here is (a) reduce the javadoc surface area, (b) groups 
related abstractions together, (c) makes it clear that these are 
subsidiary abstractions, and (d) keep the cut-and-paste stuff together 
in the code.  The use site also looks pretty reasonable:

   class Foo implements MutableReducer.OfInt { ... }

This shows up in Sink, IntermediateOp, TerminalOp, MutableReducer, 
NodeBuilder, Node, Spliterator, etc.  (It also shows up in concrete 
implementation classes like ForEachOp, MatchOp, and FindOp, though these 
will not be public and so (a) doesn't really apply to these.)

Are we OK with this convention?  It seems to have a tidying effect on 
the codebase, the documentation, and client usage, and mitigates the 
pain of the primitive specializations.  (There will be grey areas where 
its applicability is questionable; we can discuss those individually, 
but there are a lot of things that it works for.)


More information about the lambda-libs-spec-observers mailing list