Fwd: Closures: converting closures returning void, and interfaces vs. one-abstract-method abstract classes

Neal Gafter neal at gafter.com
Sun May 11 20:21:40 PDT 2008


Forwarded FYI

---------- Forwarded message ----------
From: Neal Gafter <neal at gafter.com>
Date: Sun, May 11, 2008 at 7:17 PM
Subject: Re: Closures: converting closures returning void, and interfaces
vs. one-abstract-method abstract classes
To: pholser at alumni.rice.edu
Cc: Alexander Buckley <Alex.Buckley at sun.com>, Maurizio Cimadamore <
Maurizio.Cimadamore at sun.com>, James Gosling <james.gosling at sun.com>, Gilad
Bracha <gilad at bracha.org>, Peter Ahé <peter at ahe.dk>


On Sun, May 11, 2008 at 2:54 PM, Paul Holser <pholser at gmail.com> wrote:

> ...  I have an existing Java library that uses
> "function types", and wanted to see whether closure conversion would
> work with it "out of the box", so to speak.
>
> Attached are source for a Range class, a UnaryFunction interface, and
> a Main that uses both.
>
> 1) When the signature of Range#forEachDo is:
>
>    void forEachDo( UnaryFunction<? super Integer, ?> operation )
>
> Main fails compilation with:
>
>  Main.java:3: forEachDo(UnaryFunction<java.lang.Integer,?>) in Range
> cannot be applied to ({int => void})
>        Range.fromTo( 1, 4 ).forEachDo( System.out#println(int) );
>                                    ^
> 1 error
>
> When I change the signature to:
>
>    <R> void forEachDo( UnaryFunction<? super Integer, ? extends R>
> operation )
>
> Main compiles and runs fine.
>
> What is it about the second signature that allows a void-return-type
> closure in as a parameter to forEachDo(), whereas such a closure is
> denied entry to the method with the first signature?
>

OK, given

Function<T> {
     T f();
 }

the closure

{ => }

is assignable by subtyping to a variable of type

Function<? extends Void>

which is assignable by subtyping to a variable of type

Function<?>

The subtype relation should be transitive, so the closure should be directly
assignable.  I've made this change in the prototype, thus resolving your
issue.

A side-effect of this change is that, with function types, the closure is
assignable to a variable of type

{ => Object }

Regards,
Neal
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20080511/8e1b0fe5/attachment.html 


More information about the closures-dev mailing list