Function type naming conventions (original) (raw)

David Holmes david.holmes at oracle.com
Wed Jan 23 17:41:59 PST 2013


On 24/01/2013 7:20 AM, Brian Goetz wrote:

Will do the first part tomorrow unless someone strongly objects.

Sounds very reasonable to me.

Open issues: - Where multiple rules apply, do we prefer XY or XToY?

XToY

- Do we like the "drop the arity prefix in case all are specialized" rule tweak?

I feel I will need to consult a lexicon regardless so I abstain on this one.

David

On 1/23/2013 3:19 PM, Sam Pullara wrote: Awesome, this is where I hoped we would end up on this.

Thanks, Sam On Jan 23, 2013, at 12:11 PM, Brian Goetz <brian.goetz at oracle.com_ _<mailto:brian.goetz at oracle.com>> wrote:

Returning to this....

Recall that the primary goal in choosing SAM names is user ergonomics. Not only do we want to make things clear, but we want to assign the simple names to the most commonly used configurations. Hence "Function<T,U>" instead of "ObjectToObjectFunction". A secondary goal is for the names to be mechanically derivable from a reasonably small set of rules. To recap where we are: Base types, each with their own natural arity: 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> Plus arity prefixes to modify the natural arity of these: BiFunction<T,U,R> // (T,U) -> R BiPredicate<T,U> // (T,U) -> boolean We have a primitive specialization convention that lets you prefix {Int,Long,Double,Boolean,Obj} on front of one of these (possibly multiple times). In accordance with our ergonomics goal, we want simple specializations for those that specalize return type, since that has been the most common specialization. (Obj is used when you want to specialize later type params.) We first tried ordering the type parameters return-type-first, so that partial specialization could proceed left-to-right. This went over like a lead balloon. So we then adopted the rule that we specialize return type first when the return type is generic, and otherwise left-to-right. This means that IntFunction is a function T -> int. This seemed attractive as T -> int was far, far more common than int -> T. But this special treatment introduces anomalies. For example, this rule would (probably) assign IntDoubleFunction for double -> int, whereas users will probably expect IntDouble function to correspond to int -> double based on left-to-right. There are ways to further complicate the mapping to avoid this but that just moves the anomalies into darker corners. Based on offline discussions with Kevin and Joe, we concluded that backing off slightly from our desire to have the shortest possible name for the most common specialization can yield a more consistent naming scheme while still being acceptably ergonomic. So, new proposal: - When specializing return type, prefix "ToXxx" - Otherwise specializations gobble type arguments left-to-right. So: Function<T,U> // T -> U DoubleFunction // double -> T ToIntFunction // T -> int DoubleToIntFunction // double -> int This also means there is more than one way to represent the same thing in some cases. For example, also consistent with these rules are: DoubleIntFunction // double -> int since this covers all the type arguments. Only Function and Supplier are generic in return, so specializations of Block and Predicate would not be affected by the new "To" rule. This scheme is simpler and has fewer anomalies. The casualty is that IntFunction becomes ToIntFunction -- arguably clearer, and only slightly more verbose -- overall seems a win. Here's how the current SAMs would be affected: IntFunction ToIntFunction IntBiFunction<T,U> ToIntBiFunction<T,U> IntBlock not affected IntBinaryOperator not affected IntPredicate not affected IntSupplier ToIntSupplier alternately, not affected IntUnaryOperator not affected ObjIntBiBlock not affected ObjIntFunction IntToObjFunction alternately, IntObjFunction A possible (orthogonal) tweak to this system would be: - When there are enough specializations to cover all arguments, omit the arity prefix This would turn ObjIntBiBlock into ObjIntBlock. Some more investigation would be required to ensure there are no collisions here.



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