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

Kevin Bourrillion kevinb at google.com
Fri Nov 2 14:04:15 PDT 2012


I think Sink is fine, but would recommend renaming Supplier to Source then.



On Fri, Nov 2, 2012 at 1:58 PM, Brian Goetz <brian.goetz at oracle.com> wrote:

> A few Googlers, myself included, have expressed surprise that Block
>> accepts a value. There's nothing in the word "block" that suggests this
>> to me -- no semantic basis on which to distinguish 'block' from
>> 'runnable'. We call this type Receiver<T>. That name has a more
>> complementary nature with Supplier. Have we considered it?
>>
>
> Is this surprise at the idea that a Block could accept *any* arguments, or
> that the natural arity for Block should be zero rather than one?  If the
> latter, would UnaryBlock / BiBlock still seem weird?
>
> To me, Block connotes "do something via side-effects"; taking arguments
> seems to fit well enough.
>
> We did consider Sink as an alternate name.  Seems OK too.  Anyone else
> have opinions?
>
>
>> On Fri, Nov 2, 2012 at 12:32 PM, Brian Goetz <brian.goetz at oracle.com
>> <mailto: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/>
>>
>>         <http://cr.openjdk.java.net/~**mduigou/8001634/2/webrev/<http://cr.openjdk.java.net/~mduigou/8001634/2/webrev/>
>> >
>>
>>
>>
>>
>> --
>> Kevin Bourrillion | Java Librarian | Google, Inc. |kevinb at google.com
>> <mailto:kevinb at google.com>
>>
>>


-- 
Kevin Bourrillion | Java Librarian | Google, Inc. | kevinb at google.com


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