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

Raab, Donald Donald.Raab at gs.com
Sat Nov 3 19:33:32 PDT 2012


Just thought I'd add some clarification.  Hate is a strong word as Tim points out (thus the smiley).  I just don't feel Block adds any useful meaning, and for some groups of developers could actually be confusing.  What does Block return?  There is nothing in the name that suggests it will be void.  Procedure says "I have no useful return value, I just do stuff" just like in Pascal or Clipper or Algol60 according to Doug (I never programmed in that).  A Block in Smalltalk will return something.  A Block in Java would not.  Why?

Here are some basic explanations of Blocks and their usage in Smalltalk from James Robertson who is a long time Smalltalk evangelist.

Blocks:
http://www.jarober.com/blog/blogView?entry=3504515703

Collections:
http://www.jarober.com/blog/blogView?entry=3525675601

Blocks are also used in Ruby and Clipper, which both likely had much larger development communities than Smalltalk, and both Blocks in those languages return something.

http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_containers.html
http://www.ghservices.com/gregh/clipper/cbevo.htm

If Java only had one interface it was going to use for all possible lambdas, then perhaps I would consider Block as a useful catch all.  That's why I dislike Block and prefer Procedure in the Java context.  

-Don

> -----Original Message-----
> From: Raab, Donald [Tech]
> Sent: Saturday, November 03, 2012 7:35 PM
> To: 'Brian Goetz'
> Cc: Sam Pullara; lambda-libs-spec-experts at openjdk.java.net
> Subject: RE: Review Request: CR#8001634 : Initial set of lambda
> functional interfaces
> 
> 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