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

Brian Goetz brian.goetz at oracle.com
Fri Nov 2 14:23:32 PDT 2012


Are those really the names of what you'd want as the target for forEach?

On 11/2/2012 5:21 PM, Sam Pullara wrote:
> Wouldn't it be more like Runnable, UnaryRunnable and BiRunnable?
>
> Sam
>
> On 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/>
>>>
>>>
>>>
>>>
>>> --
>>> Kevin Bourrillion | Java Librarian | Google, Inc. |kevinb at google.com
>>> <mailto:kevinb at google.com>
>>>
>


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