Closures prototype equivalence between closures and methodrefs
Neal Gafter
neal at gafter.com
Wed Aug 13 08:04:40 PDT 2008
Subtype relationships among reference types must require no conversion code.
For example, converting a List<? extends Number> to a List<? extends Object>
requires no code. If we support more general conversions among function
types I believe it ought to be implemented by putting the underlying
interfaces in some kind of normal form - for example, using Void for the
result type in the interface when the user wrote void in the function type.
All that is possible, but I'm reluctant to take on major changes to the spec
at this stage.
Regards,
Neal
On Wed, Aug 13, 2008 at 3:29 AM, Mark Mahieu <mark at twistedbanana.demon.co.uk
> wrote:
> I must admit that I've come close to reporting similar non-bugs, because
> even though I *know* - having read the spec far too many times - that the
> conversion is only applicable to closures, I've found it's very easy to slip
> into thinking that assignment compatibility works the same way for function
> types. At least for the subtler aspects like boxing or void vs Void.
>
> So I'll ask the question: why is the conversion applicable to closures
> only, and not to function types as well?
>
> Presumably if it were allowed for function types then it would be trivial
> to write a program which appears to have stable performance and memory usage
> but which actually degrades in performance and eventually blows up with an
> OutOfMemoryError or StackOverflowError, but I'm curious to know what the
> real reasons are.
>
> Regards,
>
> Mark
>
>
> On 13 Aug 2008, at 04:44, Neal Gafter wrote:
>
> Alex-
>
> In your code, doN requires its third parameter of type
>
> {int, T => U throws X}
>
> but you've supplied something of type
>
> {int, String => void throws IOException}
>
> In fact, the value you supplied is NOT a closure, it is a variable of
> function type. The closure conversion is not involved at all.
>
> These two function types are unrelated. There is no conversion between
> them. So the call is illegal.
>
> In the first call, you did supply a closure (a method reference is a kind
> of closure), so the closure conversion was applied.
>
> The fact that the diagnostic prints the "required" line in terms of
> javax.lang.function.OIO instead of using the function type syntax is a bug.
>
> Regards,
> Neal
>
> On Tue, Aug 12, 2008 at 2:34 PM, Alex Buckley <Alex.Buckley at sun.com>wrote:
>
>> Trying to stress the equivalence, I get this interesting error on the
>> first line of main but not the second:
>>
>> A.java:13: method doN in class A cannot be applied to given types
>> required: int,T,javax.lang.function.OIO<? extends U,? super T,? extends X>
>> found: int,java.lang.String,{int,java.lang.String => void throws
>> java.io.IOException}
>> doN(1, "hi" , closure);
>> ^
>> 1 error
>>
>> Seems like the wrong proto-function is being selected.
>>
>> --
>> import java.io.*;
>>
>> public class A {
>> static {int, String => void throws IOException} closure = {
>> int i, String s =>
>> if (i==3) throw new IOException(); System.out.println(s);
>> };
>>
>> static void method(int i, String s) throws IOException {
>> if (i==3) throw new IOException(); System.out.println(s);
>> }
>>
>> public static void main(String[] a) {
>> doN(1, "hi" , closure);
>> doN(2, "bye", A#method(int,String));
>> }
>>
>> static <T extends String, U, throws X extends IOException>
>> void doN(int n, T x, {int, T => U throws X} b) {
>> for (int i = 0; i < n; i++) {
>> try {
>> b.invoke(i, x);
>> } catch (IOException e) { System.out.println("o no!"); }
>> }
>> }
>> }
>> --
>>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20080813/8851c0af/attachment.html
More information about the closures-dev
mailing list