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

Joe Bowbeer joe.bowbeer at gmail.com
Sat Nov 3 10:39:57 PDT 2012


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 <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?)
>
> 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