Review Request: CR#8001634 : Initial set of lambda functional interfaces

Brian Goetz brian.goetz at oracle.com
Sat Nov 3 13:00:22 PDT 2012


I think the opposite is better -- let them each have a unique name.  Otherwise, we can run into overload problems where we want one Sam to implement or extend another -- which I don't think is dumb.  

Sent from my iPhone

On Nov 3, 2012, at 2:51 PM, Doug Lea <dl at cs.oswego.edu> wrote:

> On 11/03/12 14:03, Joe Bowbeer wrote:
>> By the way, don't the method names matter?  If so, shouldn't naming proposals
>> include the corresponding method names?
> 
> I like using "apply" for all of them. Avoids guesswork and
> prevents dumb errors, and prevents crazy ideas to try to create
> an interface implementing more than one of them.
> 
> -Doug
> 
> 
>> 
>> I assume the following are correct:
>> 
>> Operator::operate
>> Predicate::test
>> Procedure::apply
>> Supplier::supply
>> 
>> But what does a Function do?  (What method corresponds to Function?)
>> 
>> Function::fun ?
>> 
>> --Joe
>> 
>> On Sat, Nov 3, 2012 at 10:39 AM, Joe Bowbeer wrote:
>> 
>>    Comments on Brian's update and later comments related to it:
>> 
>>    1. I like Supplier (or Locator?) better than Factory.  Both are compatible
>>    with reuse.
>> 
>>    But what is the method called?  Doesn't 'make' have the same problem as
>>    Factory?  If the method remains 'make' then why not call the class "Maker"?
>> 
>>    2. I'm OK with Function, Predicate, Procedure
>> 
>>    Procedure must have void return
>> 
>> 
>> 
>>    On Fri, Nov 2, 2012 at 12:32 PM, Brian Goetz 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?)
>> 
>>        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.
>> 
>>        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.
>> 
>>        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.
>> 
>> 
>>        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
>> 
>> 
>>        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?
>> 
>> 
>> 
>>        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