Removal of function types

Reinier Zwitserloot reinier at zwitserloot.com
Thu Jul 8 12:04:40 PDT 2010


On Thu, Jul 8, 2010 at 8:20 PM, Rémi Forax <forax at univ-mlv.fr> wrote:

> Function types have several advantages over SAMs.
> (remember that to be useful SAMs must be generified, see my point below).
> - no need to be have to understand long error message because
>   you forget a ? extends or a ? super somewhere.
>


I do not understand this complaint. type parameters are as much a part of
the abandoned function type concept as they are for SAM types. In fact,
function types use _MORE_ generics than SAM types; #int(String, String) is
translated to FunctionIOO<String, String> internally, which is extra
generics. This implementation detail leaks, for example because an array of
#int(String, String) types doesn't work very well, whereas an array of a SAM
type will work just fine. I expect that most SAM types will have some type
parameters of their own making this point moot, but if either of these two
proposals needs to be faulted for causing confusion based around generics,
shouldn't it be function types?


> - no need to box/unbox things.
>

SAM fitting isn't "boxing" or "unboxing". Specifically, any lambda literal
is not first treated as an unnamed/untyped function, then boxed into the
appropriate SAM depending on how you use it. Instead, the use site of the
lambda literal is inspected to figure out what is required, and the lambda
literal is then read by the compiler with this target type in mind. That's
entirely different from boxing/unboxing. The old function type based
proposal that had the ability to automatically box them into SAM types was
appropriate usage of the 'box' term I'd say, but this is quite different.
For example, by figuring out the target SAM type _before_ attempting to
understand the signature of the lambda literal, parameter types become
optional.



> - no need to find a creative name for a god damn function.
>

Not sure if the hyperbole is warranted here. Names are a good thing far more
often than they are a bad thing. At least, it seems to be that way if I look
at Parallel Arrays, where, if we assume for a moment the
primitives-and-generics issue is fixed, there are 9 named SAM types, which
each can carry useful javadoc: Op, BinaryOp, Reducer, Generator, Procedure,
Comparator, Predicate, BinaryPredicate, and Action.

I admit there are rare situations where naming the SAM type is superfluous,
but even in this situations, it's only a burden to the library developer,
not the user of the library. The word "Comparator" can't be found anywhere
in the following snippet:

Collections.sort(stringList, {x, y -> x.length() - y.length()});



> By example, you can count the number of filter/predicate SAM
> you have in the JDK:
>

And none of those can go away; java must remain backwards compatible. It's
absolutely true that these are a problem, but I don't see how you can fault
the SAM based proposal for these any more than you can the strawman
proposal. It was never the intention in the strawman proposal that one could
treat a javax.swing.RowFilter as a java.io.FileFilter. A #boolean(T) might
box to either depending on the circumstance, but I don't see how that solves
the problem of so many copies of filter.

Perhaps you meant that forcing to SAM type results in further duplicates in
the future. Maybe. But I can't think any other examples of duplication other
than Filter and Runnable / Executable. Once predicates and ops arrive in
rt.jar via either Parallel Arrays or new filter and map methods for
collections, I'd expect no further duplication.

The same argument can also be used to call a Camera and a Gun not being
interoperable as problematic, as they both have a shoot() method. It may be
true that in practice Camera/Gun occurs less often than 2 incompatible
classes whose structure nevertheless does match, which do represent the same
semantical concept, but that's not how java works today, and I rather doubt
turning java into a structurally typed language is in scope for project
lambda, let alone desired.

>
> JDK already contains bifurcations, it has more than 10 ways to represent
> a function that takes an object and returns a boolean.
>

Yes. Let's not make it worse.


> Function type can't be reified like SAMs can't be reified because
> argument of type variable aren't available at runtime.
> That's it.
>

SAMs are already reified. I'm not sure what you mean when you say they
cannot be:

Runnable r = {-> System.out.println("Hello, World!");}

one can introspect at runtime that r's type is in fact "Runnable".

--Reinier Zwitserloot


More information about the lambda-dev mailing list