Review Request: CR#8001634 : Initial set of lambda functional interfaces
Sam Pullara
sam at sampullara.com
Fri Nov 2 13:25:15 PDT 2012
This sounds like a great way to go. Some comments / questions inline:
On Fri, Nov 2, 2012 at 12:32 PM, Brian Goetz <brian.goetz at oracle.com> wrote:
> Gathering the feedback we've gotten so far:
>
> 1. Factory. People seem comfortable renaming Factory to Supplier; as a
> bonus (or not), IntSupplier specializations make more sense when connected
> to Supplier than Factory (how do you make new ints?)
>
Much better. It also implies that you could be returning the same one, etc.
> 2. Mapper. I agree with Doug's complaint that Mapper is too specialized,
> especially as it is probably the most useful shape of function and will be
> used in places that have nothing to do with mapping. While I've resisted
> "Function" for a long time (and will continue to resist
> Function1..FunctionN), its not clear that there are significantly better
> alternatives.
>
I've never liked the overlap with hash maps. Function is great and though I
shorten it to F when using it with guava/JDK7 I don't think it is a burden
for it to be spelled out in APIs. Call site side you will rarely see it.
> 2a. IMO Fun or Func are *not* better alternatives. The extra few
> characters are not an impediment, and would be inconsistent with the other
> naming conventions we're adding here.
>
+1
>
> 2b. The reason I've resisted Function* is that is kind of gives up one of
> the few benefits of nominal function types. Structural function types are
> clearly "better", except that erased structural function types are clearly
> awful. So nominal function types are the best we can do here. Nominal
> function types have two advantages to offset their many disadvantages:
> - Type names are useful and informative, especially in API signatures
> - The libraries are already full of nominal function types like Runnable
> and Comparator, so adding more does not create a bifurcation between "old
> libraries" and "new libraries".
>
> Going full-hog to Function1..FunctionN (for an ever-increasing N)
> basically says "let's take all the disadvantages of nominal types, and none
> of the advantages." API signatures that have nothing but Function1 and
> Function2 in them are unlikely to be very informative.
>
> Guava managed to get away with only Function and a few other SAMs, and not
> need to go much further, so it is a possible candidate for recasting
> Mapper, though I still don't like the slippery slope. Would like something
> better, but Mapper probably isn't it.
>
I like this compromise. My guess is that if the current nominal function
types don't work well for a particular API, people will just create their
own more semantic function types for their library or application. Not that
big of a deal.
> So if we adopt the above we'd have:
>
> {Int,Long,Double}?Predicate: T -> boolean
> {Int,Long,Double}?Function: T -> U
> {Int,Long,Double}?Block: T -> void
> {Int,Long,Double}?**UnaryOperator: T -> T
> {Int,Long,Double}?Supplier: () -> T
> {Int,Long,Double}?{Binary,**Unary}Operator
>
Looks good to me.
> As to the arity modifiers (which will come in the next round), it seems
> likely we'll want the equivalent of
>
> Bi{Predicate,Function,Block}
>
> Does the Bi/Tri convention scale sufficiently? Is the "inconsistency"
> (which I don't really think is an inconsistency) with BinaryOperator
> excessively bothersome?
Not to me.
Sam
> On 10/31/2012 4:16 PM, Mike Duigou wrote:
>
>> There's a large set of library changes that will be coming with Lambda.
>> We're getting near the end of the runway and there's lots left to do so we
>> want to start the process of getting some of the more stable pieces put
>> back to the JDK8 repositories. We've spent a some time slicing things into
>> manageable chunks. This is the first bunch. We'd like to time-box this
>> review at one week (until Nov. 7th), since there are many more pieces to
>> follow.
>>
>> The first chunk is the basic set of functional interface types. While
>> this set is not complete, it is enough to be able to proceed on some other
>> pieces. This set contains no extension methods (we'll do those separately)
>> and does not contain all the specializations we may eventually need.
>>
>> Doug has also suggested we have some sort of regularized, low-level
>> naming scheme. There's nothing in this bunch that is inconsistent with
>> that; if we had such a thing, the nominal SAMs here could easily implement
>> the horribly named low-level versions. We're still thinking about how that
>> might fit in, so while that's not directly reflected here, it hasn't been
>> forgotten.
>>
>> The specification is limited; most of the interesting restrictions
>> (side-effect-freedom, idempotency, stability) would really be imposed not
>> by the SAM itself by by how the SAM is used in a calculation. However, some
>> common doc for "how to write good SAMs" that we can stick in the package
>> doc would be helpful. Suggestions welcome.
>>
>> Elements of this naming scheme include:
>> - Each SAM type has a unique (arity, method name) pair. This allows SAMs
>> to implement other SAMs without collision.
>> - The argument lists are structured so that specializations act on the
>> first argument(s), so IntMapper<T> is a specialization of Mapper<R,T>, and
>> IntBinaryOperator is a specialization of BinaryOperator<T>.
>> - Multi-arg versions use prefix BiXxx, TriXxx, as suggested by Doug.
>> However, the "natural" arity varies. No good two or three letter prefix
>> for zero or one comes to mind (e.g., UnaryFactory<T> or NilaryBlock (though
>> that's the same as Runnable.) So that could be improved.
>>
>> Please review and comment.
>>
>> http://cr.openjdk.java.net/~**mduigou/8001634/2/webrev/<http://cr.openjdk.java.net/~mduigou/8001634/2/webrev/>
>>
>>
More information about the lambda-libs-spec-observers
mailing list