Function type naming conventions (original) (raw)

Remi Forax forax at univ-mlv.fr
Thu Jan 3 05:16:22 PST 2013


On 01/03/2013 12:32 AM, Tim Peierls wrote:

Unvarnished reactions: I still hate "Block" -- doesn't mean anything to me -- and I'm sure I'll never remember whether IntFunction is int -> int, T -> int, or int -> T, so it'll trip me up a little each time I read it. I don't love the Binary-/Bi- inconsistency, either, but I think it won't be hard to remember which goes where in that case.

Yesterday, I tried to replace a Function by 'Operator', and double-check my repository configuration/Eclipse configuration, etc. before I do an ls in java/util/function to find that the current name is 'UnaryOperator' and not 'Operator'. Ok, I had not fully recover from the excess of day before but I little more consistency should be good here.

For me, UnaryOperator should be Operator or Function should be UnaryFunction.

IndexedSupplier isn't too bad. I'd understand Indexed more readily.

the main issue is that int can be an index or the element (of an IntStream).

--tim

Rémi

On Wed, Jan 2, 2013 at 2:23 PM, Brian Goetz <brian.goetz at oracle.com_ _<mailto:brian.goetz at oracle.com>> wrote: Just to recap where we are in function type naming, we've got a few base types: Block T -> void Function<T,R> T -> R Predicate T -> boolean Supplier () -> T Plus some derived convenience types: UnaryOperator extends Function<T,T> BinaryOperator extends BiFunction<T,T,T> We have arity prefixes to modify the natural arity of these: BiFunction<T,U,R> (T,U) -> R BiPredicate<T,U> (T,U) -> boolean Presumably we'll be forced into TriXxx and worse at some point, but so far we've been able to avoid that. We have a primitive specialization convention that lets you prefix {Int,Long,Double,Boolean} on front of one of these (possibly multiple times), and this gobbles the type argument that appears in the return position, or, if the return is not generic, the first type argument: IntFunction T -> int IntSupplier () -> int IntBiFunction<T,U> (T,U) -> int IntBinaryOperator (int,int) -> int IntBlock int -> void So far we've got about 30 defined SAMs, and this has been mostly enough to implement our libraries, including primitive specializations. This convention is an uneasy compromise that is part and parcel of the compromise/commitment we made to nominal function types. Its a bit annoying in places, but the rules above are consistent, and the names read mostly reasonably in APIs, and better than most of the alternatives proposed, especially the fully general Function$FromIntAndDouble$ToDouble. In fact, the only type we've come across repeatedly that wants a "nice" name that doesn't fit into the above scheme is: int -> T which shows up in quite a few places. There are probably a few others but this is the biggest. (We also came across a desire for (T,int)->T in the reducer work, but that shows up in only one place.) We could treat int -> R as a specialization of Function<T,R>, and extend the naming convention to handle it, or we could try to come up with a new top-level name for it. In the latter category, IndexedSupplier would work for some of the use cases (Arrays.fill, array suppliers) but not terribly well for IntStream.map(int -> T). Other ideas?



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