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

Raab, Donald Donald.Raab at gs.com
Sat Nov 3 16:34:40 PDT 2012


Hate it.  :-)

Block is the name of the class used in Smalltalk to represent closures/lambdas.  It represents Predicate, Function and Procedure with all possible variations of arity.

> -----Original Message-----
> From: Brian Goetz [mailto:brian.goetz at oracle.com]
> Sent: Saturday, November 03, 2012 4:05 PM
> To: Raab, Donald [Tech]
> Cc: Sam Pullara; lambda-libs-spec-experts at openjdk.java.net
> Subject: Re: Review Request: CR#8001634 : Initial set of lambda
> functional interfaces
> 
> Ok, everyone seems ok with procedure, but how much do we actually
> *dislike* block?   (I think this one is an "ain't broke, don't fix")
> case, and personally I find procedure buth clunky and more limiting
> than block (just as factory is more limiting than supplier.).
> 
> (Respond only if you *hate* block.)
> 
> Sent from my iPhone
> 
> On Nov 2, 2012, at 6:30 PM, "Raab, Donald" <Donald.Raab at gs.com> wrote:
> 
> > If resistance to Function is lessening, and Predicate is already
> decided, then why not just go for Procedure for forEach to round out
> the trio?  These are the names we settled on in GS Collections and
> match the names Doug used in his collections framework many years ago.
> >
> > http://g.oswego.edu/dl/classes/collections/collections.html
> >
> > Most collections frameworks seem to agree on Predicate and Function.
> A couple at least have chosen Procedure that I have seen.  Trove is one
> example, although their Procedure returns a boolean so it could support
> short-circuiting forEach IIRC.
> >
> >> -----Original Message-----
> >> From: lambda-libs-spec-experts-bounces at openjdk.java.net
> >> [mailto:lambda- libs-spec-experts-bounces at openjdk.java.net] On
> Behalf
> >> Of Brian Goetz
> >> Sent: Friday, November 02, 2012 5:24 PM
> >> To: Sam Pullara
> >> Cc: lambda-libs-spec-experts at openjdk.java.net
> >> Subject: Re: Review Request: CR#8001634 : Initial set of lambda
> >> functional interfaces
> >>
> >> 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