From peter.levart at marand.si Mon Aug 2 04:03:55 2010 From: peter.levart at marand.si (Peter Levart) Date: Mon, 2 Aug 2010 13:03:55 +0200 Subject: SAM conversion and overload resolution In-Reply-To: <4C5416C5.4070800@univ-mlv.fr> References: <20100730144905.D3B2347DB2@hg.openjdk.java.net> <4C531E4E.3020905@oracle.com> <4C5416C5.4070800@univ-mlv.fr> Message-ID: <201008021303.55783.peter.levart@marand.si> Although the exact algorithm is currently only specified in the javac sources of lambda prototype, it does quite a good job when experimenting with simple usecases. I was thinking that a refinement might even be better... The following program does not compile: public class Closures { public interface ComparableF { Comparable invoke(); } public interface StringF { String invoke(); } public static void say(StringF stringFunc) { System.out.println("stringFunc says: " + stringFunc.invoke()); } public static void say(ComparableF comparableFunc) { System.out.println("comparableFunc says: " + comparableFunc.invoke()); } public static void main(String[] args) { say(#{ "Hello" }); } } ... javac complains that: Closures.java:19: reference to say is ambiguous, both method say(StringF) in Closures and method say(ComparableF) in Closures match say(#{ "Hello" }); ^ 1 error With a simple change to the source from: public interface StringF { String invoke(); } to: public interface StringF extends ComparableF { String invoke(); } ... the program compiles and prints: stringFunc says: Hello ... because the standard overload resolution can choose the most specific method. Now if we defined some kind of "soft-subtype" relationship among SAM types that worked on covariance of SAM return type and contravariance of SAM parameter types, then overload resolution could use this relationship as a last resort to try to disambiguate method resolution. You see that I didn't mention the lambda expression - just the target SAM types. How initial selection of "possible method candidates" is performed can be totaly independent of this "soft-subtype" relationship. Regards, Peter From alex.buckley at oracle.com Mon Aug 2 16:43:01 2010 From: alex.buckley at oracle.com (Alex Buckley) Date: Mon, 02 Aug 2010 16:43:01 -0700 Subject: SAM conversion and overload resolution In-Reply-To: <201008021303.55783.peter.levart@marand.si> References: <20100730144905.D3B2347DB2@hg.openjdk.java.net> <4C531E4E.3020905@oracle.com> <4C5416C5.4070800@univ-mlv.fr> <201008021303.55783.peter.levart@marand.si> Message-ID: <4C575805.9050705@oracle.com> Clever idea, we'll look into it. Of course, the pairs of SAM types related by soft-subtyping (because the "underlying" function types are related by function-subtyping) actually forms quite a small set in comparison with the Cartesian product of the set of SAM types with itself. Many legal overloadings are ambiguous for a given call site, whether the formal parameter(s) is a SAM type or not: interface SO { void invoke(String x, Object y); } interface OS { void invoke(Object x, String y); } class SOOS implements SO, OS { // Legal public void invoke(String x, Object y) {} public void invoke(Object x, String y) {} } new SOOS().invoke("hello", "world"); // Ambiguous void say(SO x) {..} void say(OS x) {..} // Legal say( #(String s1, String s2){..} ); // Ambiguous Alex On 8/2/2010 4:03 AM, Peter Levart wrote: > Although the exact algorithm is currently only specified in the javac sources of lambda prototype, it does quite a good job when experimenting with simple usecases. I was thinking that a refinement might even be better... > > The following program does not compile: > > > public class Closures > { > public interface ComparableF { Comparable invoke(); } > public interface StringF { String invoke(); } > > public static void say(StringF stringFunc) { > System.out.println("stringFunc says: " + stringFunc.invoke()); > } > > public static void say(ComparableF comparableFunc) { > System.out.println("comparableFunc says: " + comparableFunc.invoke()); > } > > public static void main(String[] args) > { > say(#{ "Hello" }); > } > } > > > ... javac complains that: > > Closures.java:19: reference to say is ambiguous, both method say(StringF) in Closures and method say(ComparableF) in Closures match > say(#{ "Hello" }); > ^ > 1 error > > > With a simple change to the source from: > > public interface StringF { String invoke(); } > > to: > > public interface StringF extends ComparableF { String invoke(); } > > > ... the program compiles and prints: > > stringFunc says: Hello > > > ... because the standard overload resolution can choose the most specific method. > > > Now if we defined some kind of "soft-subtype" relationship among SAM types that worked on covariance of SAM return type and contravariance of SAM parameter types, then overload resolution could use this relationship as a last resort to try to disambiguate method resolution. You see that I didn't mention the lambda expression - just the target SAM types. How initial selection of "possible method candidates" is performed can be totaly independent of this "soft-subtype" relationship. > > > Regards, Peter > From neal at gafter.com Mon Aug 2 18:07:44 2010 From: neal at gafter.com (Neal Gafter) Date: Mon, 2 Aug 2010 18:07:44 -0700 Subject: SAM conversion and overload resolution In-Reply-To: <201008021303.55783.peter.levart@marand.si> References: <20100730144905.D3B2347DB2@hg.openjdk.java.net> <4C531E4E.3020905@oracle.com> <4C5416C5.4070800@univ-mlv.fr> <201008021303.55783.peter.levart@marand.si> Message-ID: I think the compiler is doing you a service by rejecting the first example. Overloading like this is questionable to begin with. If the two overloadings have the "same" behavior on the same lambda, then it doesn't matter which is selected, and if they have different behavior, you probably don't want the compiler selecting from among the choices on your behalf. In short, don't complain to your language designer. Instead complain to your API designer. On Mon, Aug 2, 2010 at 4:03 AM, Peter Levart wrote: > Although the exact algorithm is currently only specified in the javac > sources of lambda prototype, it does quite a good job when experimenting > with simple usecases. I was thinking that a refinement might even be > better... > > The following program does not compile: > > > public class Closures > { > public interface ComparableF { Comparable invoke(); } > public interface StringF { String invoke(); } > > public static void say(StringF stringFunc) { > System.out.println("stringFunc says: " + stringFunc.invoke()); > } > > public static void say(ComparableF comparableFunc) { > System.out.println("comparableFunc says: " + comparableFunc.invoke()); > } > > public static void main(String[] args) > { > say(#{ "Hello" }); > } > } > > > ... javac complains that: > > Closures.java:19: reference to say is ambiguous, both method say(StringF) > in Closures and method say(ComparableF) in Closures match > say(#{ "Hello" }); > ^ > 1 error > > > With a simple change to the source from: > > public interface StringF { String invoke(); } > > to: > > public interface StringF extends ComparableF { String invoke(); } > > > ... the program compiles and prints: > > stringFunc says: Hello > > > ... because the standard overload resolution can choose the most specific > method. > > > Now if we defined some kind of "soft-subtype" relationship among SAM types > that worked on covariance of SAM return type and contravariance of SAM > parameter types, then overload resolution could use this relationship as a > last resort to try to disambiguate method resolution. You see that I didn't > mention the lambda expression - just the target SAM types. How initial > selection of "possible method candidates" is performed can be totaly > independent of this "soft-subtype" relationship. > > > Regards, Peter > > From peter.levart at marand.si Tue Aug 3 00:46:01 2010 From: peter.levart at marand.si (Peter Levart) Date: Tue, 3 Aug 2010 09:46:01 +0200 Subject: SAM conversion and overload resolution In-Reply-To: References: <20100730144905.D3B2347DB2@hg.openjdk.java.net> <201008021303.55783.peter.levart@marand.si> Message-ID: <201008030946.01587.peter.levart@marand.si> On a second thought, yes it all boils down to API design. So if one intentionaly wanted to design an API with overloaded methods so that the "most specific" of all candidates was choosen, he/she would just have to make sure that SAM typed method parameters would be related with "real" subtype relationships - which is doable. Regards, Peter On 08/03/10, Neal Gafter wrote: > I think the compiler is doing you a service by rejecting the first example. > Overloading like this is questionable to begin with. If the two > overloadings have the "same" behavior on the same lambda, then it doesn't > matter which is selected, and if they have different behavior, you probably > don't want the compiler selecting from among the choices on your behalf. > > In short, don't complain to your language designer. Instead complain to > your API designer. > > On Mon, Aug 2, 2010 at 4:03 AM, Peter Levart wrote: > > > Although the exact algorithm is currently only specified in the javac > > sources of lambda prototype, it does quite a good job when experimenting > > with simple usecases. I was thinking that a refinement might even be > > better... > > > > The following program does not compile: > > > > > > public class Closures > > { > > public interface ComparableF { Comparable invoke(); } > > public interface StringF { String invoke(); } > > > > public static void say(StringF stringFunc) { > > System.out.println("stringFunc says: " + stringFunc.invoke()); > > } > > > > public static void say(ComparableF comparableFunc) { > > System.out.println("comparableFunc says: " + comparableFunc.invoke()); > > } > > > > public static void main(String[] args) > > { > > say(#{ "Hello" }); > > } > > } > > > > > > ... javac complains that: > > > > Closures.java:19: reference to say is ambiguous, both method say(StringF) > > in Closures and method say(ComparableF) in Closures match > > say(#{ "Hello" }); > > ^ > > 1 error > > > > > > With a simple change to the source from: > > > > public interface StringF { String invoke(); } > > > > to: > > > > public interface StringF extends ComparableF { String invoke(); } > > > > > > ... the program compiles and prints: > > > > stringFunc says: Hello > > > > > > ... because the standard overload resolution can choose the most specific > > method. > > > > > > Now if we defined some kind of "soft-subtype" relationship among SAM types > > that worked on covariance of SAM return type and contravariance of SAM > > parameter types, then overload resolution could use this relationship as a > > last resort to try to disambiguate method resolution. You see that I didn't > > mention the lambda expression - just the target SAM types. How initial > > selection of "possible method candidates" is performed can be totaly > > independent of this "soft-subtype" relationship. > > > > > > Regards, Peter > > > > > From maurizio.cimadamore at oracle.com Wed Aug 4 07:13:25 2010 From: maurizio.cimadamore at oracle.com (maurizio.cimadamore at oracle.com) Date: Wed, 04 Aug 2010 14:13:25 +0000 Subject: hg: lambda/lambda/langtools: Handle non-static method references from static context. More specifically, if f is an instance method of Z whose signature is A, B->C, then #obj.f is of type A, B->C and #Z.f is of type Z, A, B->C. Message-ID: <20100804141331.E804747EDB@hg.openjdk.java.net> Changeset: 443eb1d3b96c Author: mcimadamore Date: 2010-08-04 15:10 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/443eb1d3b96c Handle non-static method references from static context. More specifically, if f is an instance method of Z whose signature is A,B->C, then #obj.f is of type A,B->C and #Z.f is of type Z,A,B->C. ! src/share/classes/com/sun/tools/javac/comp/Attr.java ! src/share/classes/com/sun/tools/javac/parser/JavacParser.java ! test/tools/javac/lambda/MethodReference05.java - test/tools/javac/lambda/MethodReference05.out + test/tools/javac/lambda/MethodReference07.java + test/tools/javac/lambda/MethodReference08.java + test/tools/javac/lambda/MethodReference08.out + test/tools/javac/lambda/MethodReference09.java + test/tools/javac/lambda/MethodReference09.out From forax at univ-mlv.fr Wed Aug 4 07:39:38 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Wed, 04 Aug 2010 16:39:38 +0200 Subject: hg: lambda/lambda/langtools: Handle non-static method references from static context. More specifically, if f is an instance method of Z whose signature is A, B->C, then #obj.f is of type A, B->C and #Z.f is of type Z, A, B->C. In-Reply-To: <20100804141331.E804747EDB@hg.openjdk.java.net> References: <20100804141331.E804747EDB@hg.openjdk.java.net> Message-ID: <4C597BAA.2040008@univ-mlv.fr> Le 04/08/2010 16:13, maurizio.cimadamore at oracle.com a ?crit : > Changeset: 443eb1d3b96c > Author: mcimadamore > Date: 2010-08-04 15:10 +0100 > URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/443eb1d3b96c > > Handle non-static method references from static context. More specifically, if f is an instance method of Z whose signature is A,B->C, then #obj.f is of type A,B->C and #Z.f is of type Z,A,B->C. > > ! src/share/classes/com/sun/tools/javac/comp/Attr.java > ! src/share/classes/com/sun/tools/javac/parser/JavacParser.java > ! test/tools/javac/lambda/MethodReference05.java > - test/tools/javac/lambda/MethodReference05.out > + test/tools/javac/lambda/MethodReference07.java > + test/tools/javac/lambda/MethodReference08.java > + test/tools/javac/lambda/MethodReference08.out > + test/tools/javac/lambda/MethodReference09.java > + test/tools/javac/lambda/MethodReference09.out > > > Hi Maurizio, sorry for being nit-pickky but I think makeMethodReferenceType should be private. R?mi From kevinb at google.com Wed Aug 4 07:36:19 2010 From: kevinb at google.com (Kevin Bourrillion) Date: Wed, 4 Aug 2010 07:36:19 -0700 Subject: hg: lambda/lambda/langtools: Handle non-static method references from static context. More specifically, if f is an instance method of Z whose signature is A, B->C, then #obj.f is of type A, B->C and #Z.f is of type Z, A, B->C. In-Reply-To: <20100804141331.E804747EDB@hg.openjdk.java.net> References: <20100804141331.E804747EDB@hg.openjdk.java.net> Message-ID: Hello, Does this mean that we could replace Predicate p = { e -> e.isPartTime() }; with Predicate p = #Employee.isPartTime; ? If so, very cool. On Wed, Aug 4, 2010 at 7:13 AM, wrote: > Changeset: 443eb1d3b96c > Author: mcimadamore > Date: 2010-08-04 15:10 +0100 > URL: > http://hg.openjdk.java.net/lambda/lambda/langtools/rev/443eb1d3b96c > > Handle non-static method references from static context. More specifically, > if f is an instance method of Z whose signature is A,B->C, then #obj.f is of > type A,B->C and #Z.f is of type Z,A,B->C. > > ! src/share/classes/com/sun/tools/javac/comp/Attr.java > ! src/share/classes/com/sun/tools/javac/parser/JavacParser.java > ! test/tools/javac/lambda/MethodReference05.java > - test/tools/javac/lambda/MethodReference05.out > + test/tools/javac/lambda/MethodReference07.java > + test/tools/javac/lambda/MethodReference08.java > + test/tools/javac/lambda/MethodReference08.out > + test/tools/javac/lambda/MethodReference09.java > + test/tools/javac/lambda/MethodReference09.out > > > -- Kevin Bourrillion @ Google http://guava-libraries.googlecode.com From brian.goetz at oracle.com Wed Aug 4 07:54:21 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 04 Aug 2010 10:54:21 -0400 Subject: hg: lambda/lambda/langtools: Handle non-static method references from static context. More specifically, if f is an instance method of Z whose signature is A, B->C, then #obj.f is of type A, B->C and #Z.f is of type Z, A, B->C. In-Reply-To: References: <20100804141331.E804747EDB@hg.openjdk.java.net> Message-ID: <4C597F1D.7020006@oracle.com> Yes, that is exactly the point! Stay tuned for some cool examples which I was going to post later today. On 8/4/2010 10:36 AM, Kevin Bourrillion wrote: > Hello, > > Does this mean that we could replace > > Predicate p = { e -> e.isPartTime() }; > > with > > Predicate p = #Employee.isPartTime; > > ? If so, very cool. > > > > > On Wed, Aug 4, 2010 at 7:13 AM, wrote: > >> Changeset: 443eb1d3b96c >> Author: mcimadamore >> Date: 2010-08-04 15:10 +0100 >> URL: >> http://hg.openjdk.java.net/lambda/lambda/langtools/rev/443eb1d3b96c >> >> Handle non-static method references from static context. More specifically, >> if f is an instance method of Z whose signature is A,B->C, then #obj.f is of >> type A,B->C and #Z.f is of type Z,A,B->C. >> >> ! src/share/classes/com/sun/tools/javac/comp/Attr.java >> ! src/share/classes/com/sun/tools/javac/parser/JavacParser.java >> ! test/tools/javac/lambda/MethodReference05.java >> - test/tools/javac/lambda/MethodReference05.out >> + test/tools/javac/lambda/MethodReference07.java >> + test/tools/javac/lambda/MethodReference08.java >> + test/tools/javac/lambda/MethodReference08.out >> + test/tools/javac/lambda/MethodReference09.java >> + test/tools/javac/lambda/MethodReference09.out >> >> >> > > From maurizio.cimadamore at oracle.com Wed Aug 4 07:54:40 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 04 Aug 2010 15:54:40 +0100 Subject: hg: lambda/lambda/langtools: Handle non-static method references from static context. More specifically, if f is an instance method of Z whose signature is A, B->C, then #obj.f is of type A, B->C and #Z.f is of type Z, A, B->C. In-Reply-To: References: <20100804141331.E804747EDB@hg.openjdk.java.net> Message-ID: <4C597F30.7070200@oracle.com> On 04/08/10 15:36, Kevin Bourrillion wrote: > Hello, > > Does this mean that we could replace > > Predicate p = { e -> e.isPartTime() }; > > with > > Predicate p = #Employee.isPartTime; > > ? If so, very cool. Yes, the two are the same :-) Maurizio > > > > > On Wed, Aug 4, 2010 at 7:13 AM, > wrote: > > Changeset: 443eb1d3b96c > Author: mcimadamore > Date: 2010-08-04 15:10 +0100 > URL: > http://hg.openjdk.java.net/lambda/lambda/langtools/rev/443eb1d3b96c > > Handle non-static method references from static context. More > specifically, if f is an instance method of Z whose signature is > A,B->C, then #obj.f is of type A,B->C and #Z.f is of type Z,A,B->C. > > ! src/share/classes/com/sun/tools/javac/comp/Attr.java > ! src/share/classes/com/sun/tools/javac/parser/JavacParser.java > ! test/tools/javac/lambda/MethodReference05.java > - test/tools/javac/lambda/MethodReference05.out > + test/tools/javac/lambda/MethodReference07.java > + test/tools/javac/lambda/MethodReference08.java > + test/tools/javac/lambda/MethodReference08.out > + test/tools/javac/lambda/MethodReference09.java > + test/tools/javac/lambda/MethodReference09.out > > > > > > -- > Kevin Bourrillion @ Google > http://guava-libraries.googlecode.com > From maurizio.cimadamore at oracle.com Wed Aug 4 07:56:43 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 04 Aug 2010 15:56:43 +0100 Subject: hg: lambda/lambda/langtools: Handle non-static method references from static context. More specifically, if f is an instance method of Z whose signature is A, B->C, then #obj.f is of type A, B->C and #Z.f is of type Z, A, B->C. In-Reply-To: <4C597BAA.2040008@univ-mlv.fr> References: <20100804141331.E804747EDB@hg.openjdk.java.net> <4C597BAA.2040008@univ-mlv.fr> Message-ID: <4C597FAB.10303@oracle.com> On 04/08/10 15:39, R?mi Forax wrote: > Le 04/08/2010 16:13, maurizio.cimadamore at oracle.com a ?crit : > >> Changeset: 443eb1d3b96c >> Author: mcimadamore >> Date: 2010-08-04 15:10 +0100 >> URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/443eb1d3b96c >> >> Handle non-static method references from static context. More specifically, if f is an instance method of Z whose signature is A,B->C, then #obj.f is of type A,B->C and #Z.f is of type Z,A,B->C. >> >> ! src/share/classes/com/sun/tools/javac/comp/Attr.java >> ! src/share/classes/com/sun/tools/javac/parser/JavacParser.java >> ! test/tools/javac/lambda/MethodReference05.java >> - test/tools/javac/lambda/MethodReference05.out >> + test/tools/javac/lambda/MethodReference07.java >> + test/tools/javac/lambda/MethodReference08.java >> + test/tools/javac/lambda/MethodReference08.out >> + test/tools/javac/lambda/MethodReference09.java >> + test/tools/javac/lambda/MethodReference09.out >> >> >> >> > Hi Maurizio, > sorry for being nit-pickky but I think makeMethodReferenceType should be > private. > > R?mi > > Thanks Remi, I agree it should be private... I will correct it in the next sweep. Maurizio From forax at univ-mlv.fr Wed Aug 4 08:17:59 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Wed, 04 Aug 2010 17:17:59 +0200 Subject: hg: lambda/lambda/langtools: Handle non-static method references from static context. More specifically, if f is an instance method of Z whose signature is A, B->C, then #obj.f is of type A, B->C and #Z.f is of type Z, A, B->C. In-Reply-To: <4C597F30.7070200@oracle.com> References: <20100804141331.E804747EDB@hg.openjdk.java.net> <4C597F30.7070200@oracle.com> Message-ID: <4C5984A7.1080401@univ-mlv.fr> Le 04/08/2010 16:54, Maurizio Cimadamore a ?crit : > On 04/08/10 15:36, Kevin Bourrillion wrote: > >> Hello, >> >> Does this mean that we could replace >> >> Predicate p = { e -> e.isPartTime() }; >> >> with >> >> Predicate p = #Employee.isPartTime; >> >> ? If so, very cool. >> > Yes, the two are the same :-) > > Maurizio > And the coolest thing is that #Employee.isPartTime is just a LDC. Predicate p = #Employee.isPartTime; will be compiled to ldc #Employee.isPartTime ldc Predicate.class invokestatic MethodHandles.asSam (Ljava/lang/MethodHandle;Ljava/lang/Class;)LObject; checkcast LPredicate; knowing that asSam() should always return an instance of the same class for the same SAM. R?mi >> >> >> >> On Wed, Aug 4, 2010 at 7:13 AM,> > wrote: >> >> Changeset: 443eb1d3b96c >> Author: mcimadamore >> Date: 2010-08-04 15:10 +0100 >> URL: >> http://hg.openjdk.java.net/lambda/lambda/langtools/rev/443eb1d3b96c >> >> Handle non-static method references from static context. More >> specifically, if f is an instance method of Z whose signature is >> A,B->C, then #obj.f is of type A,B->C and #Z.f is of type Z,A,B->C. >> >> ! src/share/classes/com/sun/tools/javac/comp/Attr.java >> ! src/share/classes/com/sun/tools/javac/parser/JavacParser.java >> ! test/tools/javac/lambda/MethodReference05.java >> - test/tools/javac/lambda/MethodReference05.out >> + test/tools/javac/lambda/MethodReference07.java >> + test/tools/javac/lambda/MethodReference08.java >> + test/tools/javac/lambda/MethodReference08.out >> + test/tools/javac/lambda/MethodReference09.java >> + test/tools/javac/lambda/MethodReference09.out >> >> >> >> >> >> -- >> Kevin Bourrillion @ Google >> http://guava-libraries.googlecode.com >> >> > > From brian.goetz at oracle.com Wed Aug 4 08:22:09 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 04 Aug 2010 11:22:09 -0400 Subject: hg: lambda/lambda/langtools: Handle non-static method references from static context. More specifically, if f is an instance method of Z whose signature is A, B->C, then #obj.f is of type A, B->C and #Z.f is of type Z, A, B->C. In-Reply-To: <4C5984A7.1080401@univ-mlv.fr> References: <20100804141331.E804747EDB@hg.openjdk.java.net> <4C597F30.7070200@oracle.com> <4C5984A7.1080401@univ-mlv.fr> Message-ID: <4C5985A1.1080806@oracle.com> > And the coolest thing is that #Employee.isPartTime is just a LDC. Yep! Tastes great AND less filling! > Predicate p = #Employee.isPartTime; > > will be compiled to > > ldc #Employee.isPartTime > ldc Predicate.class > invokestatic MethodHandles.asSam > (Ljava/lang/MethodHandle;Ljava/lang/Class;)LObject; > checkcast LPredicate; > > knowing that asSam() should always return an instance of the same class > for the same SAM. Has the 292 EG made any progress in defining the semantics and nonfunctional behavior (i.e., performance) of asSam()? I am curious to hear. Will MethodHandles.asSam(methodHandle, clazz) allocate a fresh MH on each invocation, or will they be cached somehow so that the above is allocation-free (and subsequent invocation is indirection-free)? From kevinb at google.com Wed Aug 4 08:27:53 2010 From: kevinb at google.com (Kevin Bourrillion) Date: Wed, 4 Aug 2010 08:27:53 -0700 Subject: hg: lambda/lambda/langtools: Handle non-static method references from static context. More specifically, if f is an instance method of Z whose signature is A, B->C, then #obj.f is of type A, B->C and #Z.f is of type Z, A, B->C. In-Reply-To: <4C597F1D.7020006@oracle.com> References: <20100804141331.E804747EDB@hg.openjdk.java.net> <4C597F1D.7020006@oracle.com> Message-ID: Fantastic. Discarding my draft email to lambda-dev in which I was going to ask if you could please support this. :-) On Wed, Aug 4, 2010 at 7:54 AM, Brian Goetz wrote: > Yes, that is exactly the point! > > Stay tuned for some cool examples which I was going to post later today. > > > On 8/4/2010 10:36 AM, Kevin Bourrillion wrote: > >> Hello, >> >> Does this mean that we could replace >> >> Predicate p = { e -> e.isPartTime() }; >> >> with >> >> Predicate p = #Employee.isPartTime; >> >> ? If so, very cool. >> >> >> >> >> On Wed, Aug 4, 2010 at 7:13 AM, wrote: >> >> Changeset: 443eb1d3b96c >>> Author: mcimadamore >>> Date: 2010-08-04 15:10 +0100 >>> URL: >>> http://hg.openjdk.java.net/lambda/lambda/langtools/rev/443eb1d3b96c >>> >>> Handle non-static method references from static context. More >>> specifically, >>> if f is an instance method of Z whose signature is A,B->C, then #obj.f is >>> of >>> type A,B->C and #Z.f is of type Z,A,B->C. >>> >>> ! src/share/classes/com/sun/tools/javac/comp/Attr.java >>> ! src/share/classes/com/sun/tools/javac/parser/JavacParser.java >>> ! test/tools/javac/lambda/MethodReference05.java >>> - test/tools/javac/lambda/MethodReference05.out >>> + test/tools/javac/lambda/MethodReference07.java >>> + test/tools/javac/lambda/MethodReference08.java >>> + test/tools/javac/lambda/MethodReference08.out >>> + test/tools/javac/lambda/MethodReference09.java >>> + test/tools/javac/lambda/MethodReference09.out >>> >>> >>> >>> >> >> -- Kevin Bourrillion @ Google http://guava-libraries.googlecode.com From neal at gafter.com Wed Aug 4 08:33:05 2010 From: neal at gafter.com (Neal Gafter) Date: Wed, 4 Aug 2010 08:33:05 -0700 Subject: hg: lambda/lambda/langtools: Handle non-static method references from static context. More specifically, if f is an instance method of Z whose signature is A, B->C, then #obj.f is of type A, B->C and #Z.f is of type Z, A, B->C. In-Reply-To: <4C5985A1.1080806@oracle.com> References: <20100804141331.E804747EDB@hg.openjdk.java.net> <4C597F30.7070200@oracle.com> <4C5984A7.1080401@univ-mlv.fr> <4C5985A1.1080806@oracle.com> Message-ID: On Wed, Aug 4, 2010 at 8:22 AM, Brian Goetz wrote: > Has the 292 EG made any progress in defining the semantics and > nonfunctional > behavior (i.e., performance) of asSam()? I am curious to hear. Will > MethodHandles.asSam(methodHandle, clazz) allocate a fresh MH on each > invocation, or will they be cached somehow so that the above is > allocation-free (and subsequent invocation is indirection-free)? > Brian- Project lambda hasn't specified the behavior of the conversion (i.e., when are exceptions from the SAM constructor thrown), so it's hard to know what to want from jsr292. Perhaps now would be a good time to specify the desired behavior and see if jsr292 can deliver it. Cheers, Neal From maurizio.cimadamore at oracle.com Wed Aug 4 09:47:26 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 04 Aug 2010 17:47:26 +0100 Subject: lambda syntax tutorial Message-ID: <4C59999E.8050609@oracle.com> Hi, since most of the features are available in the compiler, I took the time to write a pretty basic syntax document/tutorial that shows the syntax supported by the current lambda prototype. As usual, the document does *not* imply that the currently implemented syntax is also the final one - the aim of this document is to simply help developers working with the lambda prototype. Thanks Maurizio -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: lambda-syntax.txt Url: http://mail.openjdk.java.net/pipermail/lambda-dev/attachments/20100804/41428f70/attachment.txt From grev at miginfocom.com Wed Aug 4 11:13:15 2010 From: grev at miginfocom.com (Mikael Grev) Date: Wed, 4 Aug 2010 20:13:15 +0200 Subject: lambda syntax tutorial In-Reply-To: <4C59999E.8050609@oracle.com> References: <4C59999E.8050609@oracle.com> Message-ID: <86A30A25-EA9D-4BBC-A1A9-099281C304D9@miginfocom.com> I must say that I really like the direction this is heading. Clearly there's now an emphasis on usability at the user side and this is great. I think the reception will be much better by the community with all the simplicity added. Some of the early syntaxes were really not that good IMO. The power also seems to be in the sweet spot. Keep it up guys! I am very much in favor of adding proper properties to Java as well (not just simple getter/setter generation). In comparison to lambdas it would be a breeze and for my type of coding it would have a much bigger impact actually. I can only hope it's being considered for Java 8. Cheers, Mikael Mikael Grev Systems Architect MiG InfoCom AB S:t Olofsg 28a, 3tr 753 32 Uppsala Sweden Ph +46 76 88 22 427 grev at miginfocom.com www.miginfocom.com www.migcalendar.com This message is intended only for the use of the Addressee and may contain information that is PRIVILEGED and CONFIDENTIAL. If you are not the intended recipient, you are hereby notified that any dissemination of this communication is strictly prohibited. If you have received this communication in error, please erase all copies of the message and its attachments and notify us immediately. Thank you - MiG InfoCom Staff On Aug 4, 2010, at 18:47 PM, Maurizio Cimadamore wrote: > Hi, > since most of the features are available in the compiler, I took the time to write a pretty basic syntax document/tutorial that shows the syntax supported by the current lambda prototype. As usual, the document does *not* imply that the currently implemented syntax is also the final one - the aim of this document is to simply help developers working with the lambda prototype. > > Thanks > Maurizio > From brian.goetz at oracle.com Wed Aug 4 14:33:05 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 04 Aug 2010 17:33:05 -0400 Subject: Fun with method references Message-ID: <4C59DC91.5090300@oracle.com> Check this out -- this works with the latest prototype: interface Extractor { public U get(T t); } class Arrays { public > void sortBy(T[] array, Extractor extractor) { ... } } String[] strings = ... Arrays.sortBy(strings, String#length); // sort strings by length Foo[] foos = ... Arrays.sortBy(foos, Foo#getA); // sort by JavaBean property A From pbenedict at apache.org Wed Aug 4 14:45:02 2010 From: pbenedict at apache.org (Paul Benedict) Date: Wed, 4 Aug 2010 16:45:02 -0500 Subject: Fun with method references In-Reply-To: <4C59DC91.5090300@oracle.com> References: <4C59DC91.5090300@oracle.com> Message-ID: Do you think JDK 7 will come with new utility SAM interfaces? I am sure there are other common patterns throughout Java that could be SAM-ified. On Wed, Aug 4, 2010 at 4:33 PM, Brian Goetz wrote: > Check this out -- this works with the latest prototype: > > interface Extractor { > public U get(T t); > } > > class Arrays { > public > > void sortBy(T[] array, Extractor extractor) { ... } > } > > > String[] strings = ... > Arrays.sortBy(strings, String#length); // sort strings by length > > Foo[] foos = ... > Arrays.sortBy(foos, Foo#getA); // sort by JavaBean property A > > > > From mike.duigou at oracle.com Wed Aug 4 14:49:36 2010 From: mike.duigou at oracle.com (Mike Duigou) Date: Wed, 4 Aug 2010 14:49:36 -0700 Subject: Defender Extension Methods -- Resolution and Invoccation Message-ID: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> From Maurizio's Sytax samples Doc: > 3. Defender Methods > ------------------- > > Defender methods are declared using the 'extension' keyword, as follows: > > extension List map(Mapper r) default Collections.listMapper; > > A defender method declaration is structured in two parts, (i) a method signature, declaring formal arguments, formal type-arguments and return-type and (ii) a default implementation, that is, the implementation the method should default to if none is found in the class implementing the extended interface. Have you considered extensions with no default? I understand that the defender is primarily intended to support interface evolution but providing a default implementation isn't always practical. I'd prefer to see a "missing implementation of xyz" compile error to a usage pattern which involves default methods who's only purpose is to generate a runtime exception for the unsupported operation. Is the resolution of the extension method intended to occur at compile time or at invocation time? ie. will compiled code which refers to the extension method include a call to the named method through the interface or a call to the static default method. For greatest flexibility in interface evolution it would be much more useful if the resolution happens at the time the method is invoked. Mike From brian.goetz at oracle.com Wed Aug 4 14:50:29 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 04 Aug 2010 17:50:29 -0400 Subject: Current status of prototype / call to action Message-ID: <4C59E0A5.4030704@oracle.com> Maurizio has recently put back a number of changes that round out the major features outlined in the SotLv2, and this is a good point for those who have been sitting on the sidelines to try it out. What we need most right now is for people to try it out on real code bases, and share their experience with us. If you are having trouble building it from source, let us know. From brian.goetz at oracle.com Wed Aug 4 14:49:26 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 04 Aug 2010 17:49:26 -0400 Subject: Fun with method references In-Reply-To: References: <4C59DC91.5090300@oracle.com> Message-ID: <4C59E066.6040807@oracle.com> Yes, it is our plan to provide a reasonable "starter kit" of SAM interfaces, which might include Predicate, Block, Mapper, etc. (Such a collection will never be complete) and to use those in standard APIs where practical (such as the suggested Arrays.sortBy example below.) Details to be determined. On 8/4/2010 5:45 PM, Paul Benedict wrote: > Do you think JDK 7 will come with new utility SAM interfaces? I am sure > there are other common patterns throughout Java that could be SAM-ified. > > On Wed, Aug 4, 2010 at 4:33 PM, Brian Goetz > wrote: > > Check this out -- this works with the latest prototype: > > interface Extractor { > public U get(T t); > } > > class Arrays { > public > > void sortBy(T[] array, Extractor extractor) { ... } > } > > > String[] strings = ... > Arrays.sortBy(strings, String#length); // sort strings by length > > Foo[] foos = ... > Arrays.sortBy(foos, Foo#getA); // sort by JavaBean property A > > > > From brian.goetz at oracle.com Wed Aug 4 14:58:43 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 04 Aug 2010 17:58:43 -0400 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> Message-ID: <4C59E293.70701@oracle.com> There's currently no way to specify an extension method with no default. But you could easily simulate that with a default that throws UOE. Resolution is fully dynamic. Let's say you have the following: interface I { public extension void foo() default Moo.foo(); } class C implements I { } class Client { public void yada() { C c = new C(); c.foo(); } } At compile time, no non-default implementation exists. But if C were recompiled to provide an implementation (or I is recompiled to provide a different default), at runtime that would be reflected in the behavior. On 8/4/2010 5:49 PM, Mike Duigou wrote: >> From Maurizio's Sytax samples Doc: > >> 3. Defender Methods >> ------------------- >> >> Defender methods are declared using the 'extension' keyword, as follows: >> >> extension List map(Mapper r) default Collections.listMapper; >> >> A defender method declaration is structured in two parts, (i) a method signature, declaring formal arguments, formal type-arguments and return-type and (ii) a default implementation, that is, the implementation the method should default to if none is found in the class implementing the extended interface. > > Have you considered extensions with no default? I understand that the defender is primarily intended to support interface evolution but providing a default implementation isn't always practical. I'd prefer to see a "missing implementation of xyz" compile error to a usage pattern which involves default methods who's only purpose is to generate a runtime exception for the unsupported operation. > > Is the resolution of the extension method intended to occur at compile time or at invocation time? ie. will compiled code which refers to the extension method include a call to the named method through the interface or a call to the static default method. For greatest flexibility in interface evolution it would be much more useful if the resolution happens at the time the method is invoked. > > Mike > From crazybob at crazybob.org Wed Aug 4 15:05:54 2010 From: crazybob at crazybob.org (Bob Lee) Date: Wed, 4 Aug 2010 15:05:54 -0700 Subject: Fun with method references In-Reply-To: <4C59DC91.5090300@oracle.com> References: <4C59DC91.5090300@oracle.com> Message-ID: Brian, This looks awesome. It's going to be *huge* for UI logic. Please, please support "-target 5" if you don't already. Bob From grev at miginfocom.com Wed Aug 4 15:05:59 2010 From: grev at miginfocom.com (Mikael Grev) Date: Thu, 5 Aug 2010 00:05:59 +0200 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: <4C59E293.70701@oracle.com> References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> <4C59E293.70701@oracle.com> Message-ID: <40509310-4F73-46D4-9F3D-846172A611C8@miginfocom.com> Maybe I have missed the discussion on this and if so I'm sorry. Why can't we define the default method code directly in the extension? To me that would be the natural thing to do. Proxying it to some other method just looks like boiler code to me. I understand the "keep the interface code free" need but is it the only reason? On Aug 4, 2010, at 23:58 PM, Brian Goetz wrote: > There's currently no way to specify an extension method with no default. But > you could easily simulate that with a default that throws UOE. > > Resolution is fully dynamic. Let's say you have the following: > > interface I { > public extension void foo() default Moo.foo(); > } > > class C implements I { } > > class Client { > public void yada() { > C c = new C(); > c.foo(); > } > } > > At compile time, no non-default implementation exists. But if C were > recompiled to provide an implementation (or I is recompiled to provide a > different default), at runtime that would be reflected in the behavior. > > On 8/4/2010 5:49 PM, Mike Duigou wrote: >>> From Maurizio's Sytax samples Doc: >> >>> 3. Defender Methods >>> ------------------- >>> >>> Defender methods are declared using the 'extension' keyword, as follows: >>> >>> extension List map(Mapper r) default Collections.listMapper; >>> >>> A defender method declaration is structured in two parts, (i) a method signature, declaring formal arguments, formal type-arguments and return-type and (ii) a default implementation, that is, the implementation the method should default to if none is found in the class implementing the extended interface. >> >> Have you considered extensions with no default? I understand that the defender is primarily intended to support interface evolution but providing a default implementation isn't always practical. I'd prefer to see a "missing implementation of xyz" compile error to a usage pattern which involves default methods who's only purpose is to generate a runtime exception for the unsupported operation. >> >> Is the resolution of the extension method intended to occur at compile time or at invocation time? ie. will compiled code which refers to the extension method include a call to the named method through the interface or a call to the static default method. For greatest flexibility in interface evolution it would be much more useful if the resolution happens at the time the method is invoked. >> >> Mike >> From forax at univ-mlv.fr Wed Aug 4 15:16:52 2010 From: forax at univ-mlv.fr (=?UTF-8?B?UsOpbWkgRm9yYXg=?=) Date: Thu, 05 Aug 2010 00:16:52 +0200 Subject: Fun with method references In-Reply-To: <4C59E066.6040807@oracle.com> References: <4C59DC91.5090300@oracle.com> <4C59E066.6040807@oracle.com> Message-ID: <4C59E6D4.50104@univ-mlv.fr> Le 04/08/2010 23:49, Brian Goetz a ?crit : > Yes, it is our plan to provide a reasonable "starter kit" of SAM interfaces, > which might include Predicate, Block, Mapper, etc. (Such a collection will > never be complete) and to use those in standard APIs where practical (such as > the suggested Arrays.sortBy example below.) Details to be determined. > If you do that, you will not be able to introduce function type later ! In my opinion, I will be happy if 1) you don't introduce such API now. 2) you introduce them and show how they can be retrofit to use function type. I have another fear. The introduction of lambda in C# has shown that the API to deal with them is really huge. You need more than a year to have a polished version of such API. R?mi > On 8/4/2010 5:45 PM, Paul Benedict wrote: > >> Do you think JDK 7 will come with new utility SAM interfaces? I am sure >> there are other common patterns throughout Java that could be SAM-ified. >> >> On Wed, Aug 4, 2010 at 4:33 PM, Brian Goetz> > wrote: >> >> Check this out -- this works with the latest prototype: >> >> interface Extractor { >> public U get(T t); >> } >> >> class Arrays { >> public> >> void sortBy(T[] array, Extractor extractor) { ... } >> } >> >> >> String[] strings = ... >> Arrays.sortBy(strings, String#length); // sort strings by length >> >> Foo[] foos = ... >> Arrays.sortBy(foos, Foo#getA); // sort by JavaBean property A >> >> >> >> >> > From pbenedict at apache.org Wed Aug 4 15:12:41 2010 From: pbenedict at apache.org (Paul Benedict) Date: Wed, 4 Aug 2010 17:12:41 -0500 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: <4C59E293.70701@oracle.com> References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> <4C59E293.70701@oracle.com> Message-ID: Since interfaces are pure contracts, providing a default *implementation* smells of a philosophical problem to me. It seems hack-ish. I also don't have a better answer, but C# extension methods look more appealing. Paul On Wed, Aug 4, 2010 at 4:58 PM, Brian Goetz wrote: > There's currently no way to specify an extension method with no default. > But > you could easily simulate that with a default that throws UOE. > > Resolution is fully dynamic. Let's say you have the following: > > interface I { > public extension void foo() default Moo.foo(); > } > > class C implements I { } > > class Client { > public void yada() { > C c = new C(); > c.foo(); > } > } > > At compile time, no non-default implementation exists. But if C were > recompiled to provide an implementation (or I is recompiled to provide a > different default), at runtime that would be reflected in the behavior. > > On 8/4/2010 5:49 PM, Mike Duigou wrote: > >> From Maurizio's Sytax samples Doc: > > > >> 3. Defender Methods > >> ------------------- > >> > >> Defender methods are declared using the 'extension' keyword, as follows: > >> > >> extension List map(Mapper r) default Collections.listMapper; > >> > >> A defender method declaration is structured in two parts, (i) a method > signature, declaring formal arguments, formal type-arguments and return-type > and (ii) a default implementation, that is, the implementation the method > should default to if none is found in the class implementing the extended > interface. > > > > Have you considered extensions with no default? I understand that the > defender is primarily intended to support interface evolution but providing > a default implementation isn't always practical. I'd prefer to see a > "missing implementation of xyz" compile error to a usage pattern which > involves default methods who's only purpose is to generate a runtime > exception for the unsupported operation. > > > > Is the resolution of the extension method intended to occur at compile > time or at invocation time? ie. will compiled code which refers to the > extension method include a call to the named method through the interface or > a call to the static default method. For greatest flexibility in interface > evolution it would be much more useful if the resolution happens at the time > the method is invoked. > > > > Mike > > > > From forax at univ-mlv.fr Wed Aug 4 15:17:59 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Thu, 05 Aug 2010 00:17:59 +0200 Subject: Fun with method references In-Reply-To: References: <4C59DC91.5090300@oracle.com> Message-ID: <4C59E717.8050307@univ-mlv.fr> Le 05/08/2010 00:05, Bob Lee a ?crit : > Brian, > > This looks awesome. It's going to be *huge* for UI logic. Please, please > support "-target 5" if you don't already. > > Bob > > with a backport or not ? http://wiki.jvmlangsummit.com/JSR292Backport R?mi From forax at univ-mlv.fr Wed Aug 4 15:21:14 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Thu, 05 Aug 2010 00:21:14 +0200 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> <4C59E293.70701@oracle.com> Message-ID: <4C59E7DA.3020807@univ-mlv.fr> Le 05/08/2010 00:12, Paul Benedict a ?crit : > Since interfaces are pure contracts, providing a default *implementation* > smells of a philosophical problem to me. It seems hack-ish. I also don't > have a better answer, but C# extension methods look more appealing. > > Paul > You can't override a C# extension method. C# extension method is a compiler hack, Java extension method is a VM hack. R?mi > On Wed, Aug 4, 2010 at 4:58 PM, Brian Goetz wrote: > > >> There's currently no way to specify an extension method with no default. >> But >> you could easily simulate that with a default that throws UOE. >> >> Resolution is fully dynamic. Let's say you have the following: >> >> interface I { >> public extension void foo() default Moo.foo(); >> } >> >> class C implements I { } >> >> class Client { >> public void yada() { >> C c = new C(); >> c.foo(); >> } >> } >> >> At compile time, no non-default implementation exists. But if C were >> recompiled to provide an implementation (or I is recompiled to provide a >> different default), at runtime that would be reflected in the behavior. >> >> On 8/4/2010 5:49 PM, Mike Duigou wrote: >> >>>> From Maurizio's Sytax samples Doc: >>>> >>> >>>> 3. Defender Methods >>>> ------------------- >>>> >>>> Defender methods are declared using the 'extension' keyword, as follows: >>>> >>>> extension List map(Mapper r) default Collections.listMapper; >>>> >>>> A defender method declaration is structured in two parts, (i) a method >>>> >> signature, declaring formal arguments, formal type-arguments and return-type >> and (ii) a default implementation, that is, the implementation the method >> should default to if none is found in the class implementing the extended >> interface. >> >>> Have you considered extensions with no default? I understand that the >>> >> defender is primarily intended to support interface evolution but providing >> a default implementation isn't always practical. I'd prefer to see a >> "missing implementation of xyz" compile error to a usage pattern which >> involves default methods who's only purpose is to generate a runtime >> exception for the unsupported operation. >> >>> Is the resolution of the extension method intended to occur at compile >>> >> time or at invocation time? ie. will compiled code which refers to the >> extension method include a call to the named method through the interface or >> a call to the static default method. For greatest flexibility in interface >> evolution it would be much more useful if the resolution happens at the time >> the method is invoked. >> >>> Mike >>> >>> >> >> > From nathan.bryant at linkshare.com Wed Aug 4 15:16:22 2010 From: nathan.bryant at linkshare.com (Nathan Bryant) Date: Thu, 5 Aug 2010 07:16:22 +0900 Subject: Defender Extension Methods -- Resolution and Invoccation References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com><4C59E293.70701@oracle.com> Message-ID: <7FDA6630E1822F448C97A48D5D733094013F61E1@EXVMSTOR302.intra.rakuten.co.jp> C# extension methods are statically dispatched, correct? -----Original Message----- From: lambda-dev-bounces at openjdk.java.net [mailto:lambda-dev-bounces at openjdk.java.net] On Behalf Of Paul Benedict Sent: Wednesday, August 04, 2010 6:13 PM To: Brian Goetz Cc: lambda-dev at openjdk.java.net Subject: Re: Defender Extension Methods -- Resolution and Invoccation Since interfaces are pure contracts, providing a default *implementation* smells of a philosophical problem to me. It seems hack-ish. I also don't have a better answer, but C# extension methods look more appealing. Paul On Wed, Aug 4, 2010 at 4:58 PM, Brian Goetz wrote: > There's currently no way to specify an extension method with no default. > But > you could easily simulate that with a default that throws UOE. > > Resolution is fully dynamic. Let's say you have the following: > > interface I { > public extension void foo() default Moo.foo(); > } > > class C implements I { } > > class Client { > public void yada() { > C c = new C(); > c.foo(); > } > } > > At compile time, no non-default implementation exists. But if C were > recompiled to provide an implementation (or I is recompiled to provide a > different default), at runtime that would be reflected in the behavior. > > On 8/4/2010 5:49 PM, Mike Duigou wrote: > >> From Maurizio's Sytax samples Doc: > > > >> 3. Defender Methods > >> ------------------- > >> > >> Defender methods are declared using the 'extension' keyword, as follows: > >> > >> extension List map(Mapper r) default Collections.listMapper; > >> > >> A defender method declaration is structured in two parts, (i) a method > signature, declaring formal arguments, formal type-arguments and return-type > and (ii) a default implementation, that is, the implementation the method > should default to if none is found in the class implementing the extended > interface. > > > > Have you considered extensions with no default? I understand that the > defender is primarily intended to support interface evolution but providing > a default implementation isn't always practical. I'd prefer to see a > "missing implementation of xyz" compile error to a usage pattern which > involves default methods who's only purpose is to generate a runtime > exception for the unsupported operation. > > > > Is the resolution of the extension method intended to occur at compile > time or at invocation time? ie. will compiled code which refers to the > extension method include a call to the named method through the interface or > a call to the static default method. For greatest flexibility in interface > evolution it would be much more useful if the resolution happens at the time > the method is invoked. > > > > Mike > > > > From crazybob at crazybob.org Wed Aug 4 15:18:18 2010 From: crazybob at crazybob.org (Bob Lee) Date: Wed, 4 Aug 2010 15:18:18 -0700 Subject: Fun with method references In-Reply-To: <4C59E717.8050307@univ-mlv.fr> References: <4C59DC91.5090300@oracle.com> <4C59E717.8050307@univ-mlv.fr> Message-ID: On Wed, Aug 4, 2010 at 3:17 PM, R?mi Forax wrote: > with a backport or not ? > http://wiki.jvmlangsummit.com/JSR292Backport I'm fine with a backport so long as it works well on Android. :-) Bob From brian.goetz at oracle.com Wed Aug 4 15:22:43 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 04 Aug 2010 18:22:43 -0400 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: <40509310-4F73-46D4-9F3D-846172A611C8@miginfocom.com> References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> <4C59E293.70701@oracle.com> <40509310-4F73-46D4-9F3D-846172A611C8@miginfocom.com> Message-ID: <4C59E833.8090704@oracle.com> Your characterization of "keep interfaces code-free" is pretty close. While the introduction of default methods unfortunately dirties the distinction between interfaces and classes, we have taken a much smaller step than we could have (say, to mixins or traits or full multiple inheritance) in order to keep as much as possible to the true spirit of interfaces, which we still believe in. Therefore we believe that choosing a syntactic option that reflects that this philosophical leaning is in the best interest of the community. As designed, this is an interface evolution mechanism, not a primary implementation mechanism. Pushing some minor inconvenience to library maintainers for the sake of less confusion on the part of the broad user base is a tradeoff we're happy to make every day of the week. Of course, some people will notice this mechanism has uses beyond interface evolution, and may even use it for such purposes. They may be disappointed that it is not more powerful (say, not mixins or traits) or that the syntax requires some boilerplate. To them, I say: the glass is half full. > Maybe I have missed the discussion on this and if so I'm sorry. > > Why can't we define the default method code directly in the extension? To me that would be the natural thing to do. Proxying it to some other method just looks like boiler code to me. I understand the "keep the interface code free" need but is it the only reason? > > > On Aug 4, 2010, at 23:58 PM, Brian Goetz wrote: > >> There's currently no way to specify an extension method with no default. But >> you could easily simulate that with a default that throws UOE. >> >> Resolution is fully dynamic. Let's say you have the following: >> >> interface I { >> public extension void foo() default Moo.foo(); >> } >> >> class C implements I { } >> >> class Client { >> public void yada() { >> C c = new C(); >> c.foo(); >> } >> } >> >> At compile time, no non-default implementation exists. But if C were >> recompiled to provide an implementation (or I is recompiled to provide a >> different default), at runtime that would be reflected in the behavior. >> >> On 8/4/2010 5:49 PM, Mike Duigou wrote: >>>> From Maurizio's Sytax samples Doc: >>> >>>> 3. Defender Methods >>>> ------------------- >>>> >>>> Defender methods are declared using the 'extension' keyword, as follows: >>>> >>>> extension List map(Mapper r) default Collections.listMapper; >>>> >>>> A defender method declaration is structured in two parts, (i) a method signature, declaring formal arguments, formal type-arguments and return-type and (ii) a default implementation, that is, the implementation the method should default to if none is found in the class implementing the extended interface. >>> >>> Have you considered extensions with no default? I understand that the defender is primarily intended to support interface evolution but providing a default implementation isn't always practical. I'd prefer to see a "missing implementation of xyz" compile error to a usage pattern which involves default methods who's only purpose is to generate a runtime exception for the unsupported operation. >>> >>> Is the resolution of the extension method intended to occur at compile time or at invocation time? ie. will compiled code which refers to the extension method include a call to the named method through the interface or a call to the static default method. For greatest flexibility in interface evolution it would be much more useful if the resolution happens at the time the method is invoked. >>> >>> Mike >>> > > From brian.goetz at oracle.com Wed Aug 4 15:23:16 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 04 Aug 2010 18:23:16 -0400 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> <4C59E293.70701@oracle.com> Message-ID: <4C59E854.1040406@oracle.com> We considered this. But C# extension methods have a HUGE problem -- they are static compiler tricks, and therefore an implementation cannot provide a better implementation than the one provided. (You are probably reacting more to the fact that that they are use-site instead of declaration-site, and therefore do not "pollute" the interface since extensions are injected under the client's control rather than the library maintainer's.) On 8/4/2010 6:12 PM, Paul Benedict wrote: > Since interfaces are pure contracts, providing a default > *implementation* smells of a philosophical problem to me. It seems > hack-ish. I also don't have a better answer, but C# extension methods > look more appealing. > > Paul > > On Wed, Aug 4, 2010 at 4:58 PM, Brian Goetz > wrote: > > There's currently no way to specify an extension method with no > default. But > you could easily simulate that with a default that throws UOE. > > Resolution is fully dynamic. Let's say you have the following: > > interface I { > public extension void foo() default Moo.foo(); > } > > class C implements I { } > > class Client { > public void yada() { > C c = new C(); > c.foo(); > } > } > > At compile time, no non-default implementation exists. But if C were > recompiled to provide an implementation (or I is recompiled to provide a > different default), at runtime that would be reflected in the behavior. > > On 8/4/2010 5:49 PM, Mike Duigou wrote: > >> From Maurizio's Sytax samples Doc: > > > >> 3. Defender Methods > >> ------------------- > >> > >> Defender methods are declared using the 'extension' keyword, as > follows: > >> > >> extension List map(Mapper r) default > Collections.listMapper; > >> > >> A defender method declaration is structured in two parts, (i) a > method signature, declaring formal arguments, formal type-arguments > and return-type and (ii) a default implementation, that is, the > implementation the method should default to if none is found in the > class implementing the extended interface. > > > > Have you considered extensions with no default? I understand that > the defender is primarily intended to support interface evolution > but providing a default implementation isn't always practical. I'd > prefer to see a "missing implementation of xyz" compile error to a > usage pattern which involves default methods who's only purpose is > to generate a runtime exception for the unsupported operation. > > > > Is the resolution of the extension method intended to occur at > compile time or at invocation time? ie. will compiled code which > refers to the extension method include a call to the named method > through the interface or a call to the static default method. For > greatest flexibility in interface evolution it would be much more > useful if the resolution happens at the time the method is invoked. > > > > Mike > > > > From brian.goetz at oracle.com Wed Aug 4 15:28:41 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 04 Aug 2010 18:28:41 -0400 Subject: Fun with method references In-Reply-To: <4C59E6D4.50104@univ-mlv.fr> References: <4C59DC91.5090300@oracle.com> <4C59E066.6040807@oracle.com> <4C59E6D4.50104@univ-mlv.fr> Message-ID: <4C59E999.7070900@oracle.com> > If you do that, you will not be able to introduce function type later ! But we are already there with Runnable, Callable, Comparator, etc. Any lambda strategy must deal with SAM types in a happy way; the world is full of SAM-ful interfaces. If you are saying that we are likely to make the problem worse before we make it better, that may be so. But there are two possible futures: - SAM types only - SAM types living side-by-side with function types The third possibility, "function types only", expired in 1996. You are absolutely right that the language part of this exercise is small compared to the libraries part. We are anxious to get on to that part of the program. > > In my opinion, I will be happy if > 1) you don't introduce such API now. > 2) you introduce them and show how they can be retrofit to use function > type. > > I have another fear. The introduction of lambda in C# > has shown that the API to deal with them is really huge. > You need more than a year to have a polished version of such API. > > R?mi > >> On 8/4/2010 5:45 PM, Paul Benedict wrote: >> >>> Do you think JDK 7 will come with new utility SAM interfaces? I am sure >>> there are other common patterns throughout Java that could be SAM-ified. >>> >>> On Wed, Aug 4, 2010 at 4:33 PM, Brian Goetz>> > wrote: >>> >>> Check this out -- this works with the latest prototype: >>> >>> interface Extractor { >>> public U get(T t); >>> } >>> >>> class Arrays { >>> public> >>> void sortBy(T[] array, Extractor extractor) { ... } >>> } >>> >>> >>> String[] strings = ... >>> Arrays.sortBy(strings, String#length); // sort strings by length >>> >>> Foo[] foos = ... >>> Arrays.sortBy(foos, Foo#getA); // sort by JavaBean property A >>> >>> >>> >>> >>> >> > > From forax at univ-mlv.fr Wed Aug 4 15:40:09 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Thu, 05 Aug 2010 00:40:09 +0200 Subject: Fun with method references In-Reply-To: References: <4C59DC91.5090300@oracle.com> <4C59E717.8050307@univ-mlv.fr> Message-ID: <4C59EC49.4030205@univ-mlv.fr> Le 05/08/2010 00:18, Bob Lee a ?crit : > On Wed, Aug 4, 2010 at 3:17 PM, R?mi Forax > wrote: > > with a backport or not ? > http://wiki.jvmlangsummit.com/JSR292Backport > > > I'm fine with a backport so long as it works well on Android. :-) > > Bob It works on android but not well. I need bytecode generation to perform well. R?mi From neal at gafter.com Wed Aug 4 15:49:12 2010 From: neal at gafter.com (Neal Gafter) Date: Wed, 4 Aug 2010 15:49:12 -0700 Subject: Fun with method references In-Reply-To: <4C59E999.7070900@oracle.com> References: <4C59DC91.5090300@oracle.com> <4C59E066.6040807@oracle.com> <4C59E6D4.50104@univ-mlv.fr> <4C59E999.7070900@oracle.com> Message-ID: On Wed, Aug 4, 2010 at 3:28 PM, Brian Goetz wrote: > > If you do that, you will not be able to introduce function type later ! > > But we are already there with Runnable, Callable, Comparator, etc. Any > lambda > strategy must deal with SAM types in a happy way; the world is full of > SAM-ful > interfaces. > > If you are saying that we are likely to make the problem worse before we > make > it better, that may be so. But there are two possible futures: > - SAM types only > - SAM types living side-by-side with function types > The more SAMs and SAM APIs you introduce, the worse you will make things for the language with function types later. While it is true that things are already bad, that is no justification for making them worse. From neal at gafter.com Wed Aug 4 15:52:57 2010 From: neal at gafter.com (Neal Gafter) Date: Wed, 4 Aug 2010 15:52:57 -0700 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: <4C59E833.8090704@oracle.com> References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> <4C59E293.70701@oracle.com> <40509310-4F73-46D4-9F3D-846172A611C8@miginfocom.com> <4C59E833.8090704@oracle.com> Message-ID: On Wed, Aug 4, 2010 at 3:22 PM, Brian Goetz wrote: > Your characterization of "keep interfaces code-free" is pretty close. > While > the introduction of default methods unfortunately dirties the distinction > between interfaces and classes, we have taken a much smaller step than we > could have (say, to mixins or traits or full multiple inheritance) in order > to > keep as much as possible to the true spirit of interfaces, which we still > believe in. Therefore we believe that choosing a syntactic option that > reflects that this philosophical leaning is in the best interest of the > community. It seems you've technically observed the word of "keep interfaces code-free" without obeying the spirit of it. There is little point of putting the programmer through the pain of the separation in the current specification if the benefits of the separation don't accrue. From grev at miginfocom.com Wed Aug 4 15:59:55 2010 From: grev at miginfocom.com (Mikael Grev) Date: Thu, 5 Aug 2010 00:59:55 +0200 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> <4C59E293.70701@oracle.com> <40509310-4F73-46D4-9F3D-846172A611C8@miginfocom.com> <4C59E833.8090704@oracle.com> Message-ID: <63C3EBA6-0893-44FA-89F8-4160DF472FBB@miginfocom.com> Thanks Neal, this reflect my stance as well. Making it hard for the end user is never good. If the purpose of the feature is to be able to provide a default implementation for interface evolution (which I believe is about time) I think it is better to stand up for that and make it as easy as possible to do it. On Aug 5, 2010, at 0:52 AM, Neal Gafter wrote: > On Wed, Aug 4, 2010 at 3:22 PM, Brian Goetz wrote: > Your characterization of "keep interfaces code-free" is pretty close. While > the introduction of default methods unfortunately dirties the distinction > between interfaces and classes, we have taken a much smaller step than we > could have (say, to mixins or traits or full multiple inheritance) in order to > keep as much as possible to the true spirit of interfaces, which we still > believe in. Therefore we believe that choosing a syntactic option that > reflects that this philosophical leaning is in the best interest of the > community. > > It seems you've technically observed the word of "keep interfaces code-free" without obeying the spirit of it. There is little point of putting the programmer through the pain of the separation in the current specification if the benefits of the separation don't accrue. From lk at teamten.com Wed Aug 4 16:18:25 2010 From: lk at teamten.com (Lawrence Kesteloot) Date: Wed, 4 Aug 2010 16:18:25 -0700 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> <4C59E293.70701@oracle.com> <40509310-4F73-46D4-9F3D-846172A611C8@miginfocom.com> <4C59E833.8090704@oracle.com> Message-ID: On Wed, Aug 4, 2010 at 3:52 PM, Neal Gafter wrote: > It seems you've technically observed the word of "keep interfaces code-free" > without obeying the spirit of it. ?There is little point of putting the > programmer through the pain of the separation in the current specification > if the benefits of the separation don't accrue. What are you advocating? Putting the code right in the interface? What if the method gets too big, how do you split it up? Do you advocate private methods in interfaces to solve that? Private static fields to store things like Comparators or Collators you might use? Seems like a mess to me. I should be able to read an interface and see a contract, not hundreds of lines of implementation and private garbage. I like the current "punt to another class" approach. Lawrence From forax at univ-mlv.fr Wed Aug 4 16:38:01 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Thu, 05 Aug 2010 01:38:01 +0200 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: <63C3EBA6-0893-44FA-89F8-4160DF472FBB@miginfocom.com> References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> <4C59E293.70701@oracle.com> <40509310-4F73-46D4-9F3D-846172A611C8@miginfocom.com> <4C59E833.8090704@oracle.com> <63C3EBA6-0893-44FA-89F8-4160DF472FBB@miginfocom.com> Message-ID: <4C59F9D9.1020806@univ-mlv.fr> Le 05/08/2010 00:59, Mikael Grev a ?crit : > Thanks Neal, this reflect my stance as well. > > Making it hard for the end user is never good. If the purpose of the feature is to be able to provide a default implementation for interface evolution (which I believe is about time) I think it is better to stand up for that and make it as easy as possible to do it. > Hi Mikael, I think the syntax of defender method has some technical merits: - you can't add code to an interface without breaking all tools that take a look to the bytecode. - solving the problem of a class implementing two interfaces with two extension methods that collide is easier. They should have the same default. - you can easily retrofit existing collection API classes/interfaces to use extension method. - the syntax is close to the VM format. It's not like inner-classes or enums where the compiler generate lot of boilerplate code. A simple benefit is that reflection works like a charm. R?mi > > On Aug 5, 2010, at 0:52 AM, Neal Gafter wrote: > > >> On Wed, Aug 4, 2010 at 3:22 PM, Brian Goetz wrote: >> Your characterization of "keep interfaces code-free" is pretty close. While >> the introduction of default methods unfortunately dirties the distinction >> between interfaces and classes, we have taken a much smaller step than we >> could have (say, to mixins or traits or full multiple inheritance) in order to >> keep as much as possible to the true spirit of interfaces, which we still >> believe in. Therefore we believe that choosing a syntactic option that >> reflects that this philosophical leaning is in the best interest of the >> community. >> >> It seems you've technically observed the word of "keep interfaces code-free" without obeying the spirit of it. There is little point of putting the programmer through the pain of the separation in the current specification if the benefits of the separation don't accrue. >> > > From grev at miginfocom.com Wed Aug 4 16:38:35 2010 From: grev at miginfocom.com (Mikael Grev) Date: Thu, 5 Aug 2010 01:38:35 +0200 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: <4C59F9D9.1020806@univ-mlv.fr> References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> <4C59E293.70701@oracle.com> <40509310-4F73-46D4-9F3D-846172A611C8@miginfocom.com> <4C59E833.8090704@oracle.com> <63C3EBA6-0893-44FA-89F8-4160DF472FBB@miginfocom.com> <4C59F9D9.1020806@univ-mlv.fr> Message-ID: <828A7B18-680E-4D9E-8A04-926C9A39BD05@miginfocom.com> Hello R?mi, Can't this all easily be solved by having the compiler or VM auto generate a class with the implementation? Also note that of course that the current syntax should also be allowed. Best of both worlds? Cheers, Mikael On Aug 5, 2010, at 1:38 AM, R?mi Forax wrote: > Le 05/08/2010 00:59, Mikael Grev a ?crit : >> Thanks Neal, this reflect my stance as well. >> >> Making it hard for the end user is never good. If the purpose of the feature is to be able to provide a default implementation for interface evolution (which I believe is about time) I think it is better to stand up for that and make it as easy as possible to do it. >> > > Hi Mikael, > I think the syntax of defender method has some technical merits: > - you can't add code to an interface without breaking all tools that > take a look > to the bytecode. > - solving the problem of a class implementing two interfaces with two > extension methods > that collide is easier. They should have the same default. > - you can easily retrofit existing collection API classes/interfaces to > use extension method. > - the syntax is close to the VM format. It's not like inner-classes or enums > where the compiler generate lot of boilerplate code. > A simple benefit is that reflection works like a charm. > > R?mi > >> >> On Aug 5, 2010, at 0:52 AM, Neal Gafter wrote: >> >> >>> On Wed, Aug 4, 2010 at 3:22 PM, Brian Goetz wrote: >>> Your characterization of "keep interfaces code-free" is pretty close. While >>> the introduction of default methods unfortunately dirties the distinction >>> between interfaces and classes, we have taken a much smaller step than we >>> could have (say, to mixins or traits or full multiple inheritance) in order to >>> keep as much as possible to the true spirit of interfaces, which we still >>> believe in. Therefore we believe that choosing a syntactic option that >>> reflects that this philosophical leaning is in the best interest of the >>> community. >>> >>> It seems you've technically observed the word of "keep interfaces code-free" without obeying the spirit of it. There is little point of putting the programmer through the pain of the separation in the current specification if the benefits of the separation don't accrue. >>> >> >> From neal at gafter.com Wed Aug 4 17:08:10 2010 From: neal at gafter.com (Neal Gafter) Date: Wed, 4 Aug 2010 17:08:10 -0700 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> <4C59E293.70701@oracle.com> <40509310-4F73-46D4-9F3D-846172A611C8@miginfocom.com> <4C59E833.8090704@oracle.com> Message-ID: On Wed, Aug 4, 2010 at 4:18 PM, Lawrence Kesteloot wrote: > On Wed, Aug 4, 2010 at 3:52 PM, Neal Gafter wrote: > > It seems you've technically observed the word of "keep interfaces > code-free" > > without obeying the spirit of it. There is little point of putting the > > programmer through the pain of the separation in the current > specification > > if the benefits of the separation don't accrue. > > What are you advocating? Putting the code right in the interface? What > if the method gets too big, how do you split it up? Any way you like. You even have the possibility (an option, not a requirement) of a trivial implementation that defers to a static method in some other class. We could allow a private nested class inside the interface (not legal today in the language, but legal in the VM) to assist with the implementation. > Do you advocate > private methods in interfaces to solve that? Private static fields to > store things like Comparators or Collators you might use? Seems like a > mess to me. I should be able to read an interface and see a contract, > not hundreds of lines of implementation and private garbage. > That's true of classes too. If you want to read the contract, you should be looking at the javadoc, not the code. From brian.goetz at oracle.com Wed Aug 4 17:28:26 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 04 Aug 2010 20:28:26 -0400 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: <63C3EBA6-0893-44FA-89F8-4160DF472FBB@miginfocom.com> References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> <4C59E293.70701@oracle.com> <40509310-4F73-46D4-9F3D-846172A611C8@miginfocom.com> <4C59E833.8090704@oracle.com> <63C3EBA6-0893-44FA-89F8-4160DF472FBB@miginfocom.com> Message-ID: <4C5A05AA.8050204@oracle.com> Your are being tripped up by the belief that most Java users are like you! (And we all know there's only one of Neal.) The vast majority of the 12M+ Java developers will probably never use this feature. But doing it this way saves us from imposing what will look like a significant paradigm shift on them, which would certainly rock their world for little benefit. While I will not repeat the mistake of claiming any language feature will be used "exclusively by library writers", I am willing to put library maintainers to some additional small inconvenience (and it is small) if it benefits the community at large (and the benefit is large.) > There is little point of > putting the programmer through the pain of the separation in the > current specification if the benefits of the separation don't accrue. The benefits of the separation do accrue, most definitely, to those users. On 8/4/2010 6:59 PM, Mikael Grev wrote: > Thanks Neal, this reflect my stance as well. > > Making it hard for the end user is never good. If the purpose of the > feature is to be able to provide a default implementation for interface > evolution (which I believe is about time) I think it is better to stand > up for that and make it as easy as possible to do it. > > > On Aug 5, 2010, at 0:52 AM, Neal Gafter wrote: > >> On Wed, Aug 4, 2010 at 3:22 PM, Brian Goetz > > wrote: >> >> Your characterization of "keep interfaces code-free" is pretty >> close. While >> the introduction of default methods unfortunately dirties the >> distinction >> between interfaces and classes, we have taken a much smaller step >> than we >> could have (say, to mixins or traits or full multiple inheritance) >> in order to >> keep as much as possible to the true spirit of interfaces, which >> we still >> believe in. Therefore we believe that choosing a syntactic option that >> reflects that this philosophical leaning is in the best interest >> of the >> community. >> >> >> It seems you've technically observed the word of "keep interfaces >> code-free" without obeying the spirit of it. There is little point of >> putting the programmer through the pain of the separation in the >> current specification if the benefits of the separation don't accrue. > From brian.goetz at oracle.com Wed Aug 4 17:33:29 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 04 Aug 2010 20:33:29 -0400 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: <4C59F9D9.1020806@univ-mlv.fr> References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> <4C59E293.70701@oracle.com> <40509310-4F73-46D4-9F3D-846172A611C8@miginfocom.com> <4C59E833.8090704@oracle.com> <63C3EBA6-0893-44FA-89F8-4160DF472FBB@miginfocom.com> <4C59F9D9.1020806@univ-mlv.fr> Message-ID: <4C5A06D9.6000906@oracle.com> On 8/4/2010 7:38 PM, R?mi Forax wrote: > I think the syntax of defender method has some technical merits: > - solving the problem of a class implementing two interfaces with two > extension methods > that collide is easier. They should have the same default. This one point alone should close down this discussion! From collin.fagan at gmail.com Wed Aug 4 18:16:22 2010 From: collin.fagan at gmail.com (Collin Fagan) Date: Wed, 4 Aug 2010 20:16:22 -0500 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: <4C5A06D9.6000906@oracle.com> References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> <4C59E293.70701@oracle.com> <40509310-4F73-46D4-9F3D-846172A611C8@miginfocom.com> <4C59E833.8090704@oracle.com> <63C3EBA6-0893-44FA-89F8-4160DF472FBB@miginfocom.com> <4C59F9D9.1020806@univ-mlv.fr> <4C5A06D9.6000906@oracle.com> Message-ID: I know I've voiced this before but I'm not a fan of defender methods. I just don't see how this is not already multiple inheritance. Look I'm just your average Joe programmer but I don't understand how the statement "a class implementing two interfaces with two extension methods that collide is easier. They should have the same default." can possibly be true. If each interface provides a default how the heck is the programmer supposed to know which one will eclipse the other? Are you saying the default implementation needs to point to the same class/method? So when I use an interface from common.lang and one from java.util and there just happens to be a collision and they don't share the same default implementation only then am I going to be alerted by the compiler that something is wrong? What happens when the default changes? Does that mean at runtime there will be collsision that was not intended at compile time? Is the default actually part of the method signature? Will I get a method not found exception when there is a change? Will every API developer get 1 and only 1 shot at picking a default implementation? I'm sorry I'm really happy with the hard work people are putting into this. I'm just totally confused by defender methods. Collin On Wed, Aug 4, 2010 at 7:33 PM, Brian Goetz wrote: > On 8/4/2010 7:38 PM, R?mi Forax wrote: > > > I think the syntax of defender method has some technical merits: > > - solving the problem of a class implementing two interfaces with two > > extension methods > > that collide is easier. They should have the same default. > > This one point alone should close down this discussion! > > > > From howard.lovatt at gmail.com Wed Aug 4 18:33:58 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Thu, 5 Aug 2010 11:33:58 +1000 Subject: Defender Extension Methods -- Resolution and Invoccation Message-ID: My view is that people will find: interface List { List sort() { ... } ... } Quite natural and will understand the difference between an interface with a method body and an abstract class. The downside of the present proposal is that we will see a lot of: interface List { extension List sort() default Trait.sort(List); ... static class Trait { public List sort(List l) { ... } ... } } Which everyone is, rightly or wrongly, going to complain is a lot of boiler plate. -- Howard. *Brian Goetz* brian.goetz at oracle.com *Wed Aug 4 17:28:26 PDT 2010 wrote:* ------------------------------ Your are being tripped up by the belief that most Java users are like you! (And we all know there's only one of Neal.) The vast majority of the 12M+ Java developers will probably never use this feature. But doing it this way saves us from imposing what will look like a significant paradigm shift on them, which would certainly rock their world for little benefit. While I will not repeat the mistake of claiming any language feature will be used "exclusively by library writers", I am willing to put library maintainers to some additional small inconvenience (and it is small) if it benefits the community at large (and the benefit is large.) >* There is little point of*>* putting the programmer through the pain of the separation in the*>* current specification if the benefits of the separation don't accrue.* The benefits of the separation do accrue, most definitely, to those users. On 8/4/2010 6:59 PM, Mikael Grev wrote: >* Thanks Neal, this reflect my stance as well.*>**>* Making it hard for the end user is never good. If the purpose of the*>* feature is to be able to provide a default implementation for interface*>* evolution (which I believe is about time) I think it is better to stand*>* up for that and make it as easy as possible to do it.*>**>**>* On Aug 5, 2010, at 0:52 AM, Neal Gafter wrote:*>**>>* On Wed, Aug 4, 2010 at 3:22 PM, Brian Goetz *>>* >> wrote:*>>**>>* Your characterization of "keep interfaces code-free" is pretty*>>* close. While*>>* the introduction of default methods unfortunately dirties the*>>* distinction*>>* between interfaces and classes, we have taken a much smaller step*>>* than we*>>* could have (say, to mixins or traits or full multiple inheritance)*>>* in order to*>>* keep as much as possible to the true spirit of interfaces, which*>>* we still*>>* believe in. Therefore we believe that choosing a syntactic option that*>>* reflects that this philosophical leaning is in the best interest*>>* of the*>>* community.*>>**>>**>>* It seems you've technically observed the word of "keep interfaces*>>* code-free" without obeying the spirit of it. There is little point of*>>* putting the programmer through the pain of the separation in the*>>* current specification if the benefits of the separation don't accrue.* From neal at gafter.com Wed Aug 4 18:35:39 2010 From: neal at gafter.com (Neal Gafter) Date: Wed, 4 Aug 2010 18:35:39 -0700 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> <4C59E293.70701@oracle.com> <40509310-4F73-46D4-9F3D-846172A611C8@miginfocom.com> <4C59E833.8090704@oracle.com> <63C3EBA6-0893-44FA-89F8-4160DF472FBB@miginfocom.com> <4C59F9D9.1020806@univ-mlv.fr> <4C5A06D9.6000906@oracle.com> Message-ID: Colin has a good point. Unless the binary compatibility rules prevent you from ever changing a defender method's implementation (which would be horrible: the whole point of implementations is that they may be changed), the compiler must require the programmer to resolve inheritance of multiple defender methods, even when the implementation happens to be identical in that particular version of the inherited interfaces. I still don't see any compelling reasons for the separation. Brian says that this prevents the feature from forcing a paradigm shift on programmers, but the separation appears to increase (rather than reduce) the conceptual footprint of the feature and therefore the language. On Wed, Aug 4, 2010 at 6:16 PM, Collin Fagan wrote: > I know I've voiced this before but I'm not a fan of defender methods. I > just > don't see how this is not already multiple inheritance. Look I'm just your > average Joe programmer but I don't understand how the statement "a class > implementing two interfaces with two extension methods that collide is > easier. They should have the same default." can possibly be true. If each > interface provides a default how the heck is the programmer supposed to > know > which one will eclipse the other? Are you saying the default implementation > needs to point to the same class/method? So when I use an interface from > common.lang and one from java.util and there just happens to be a collision > and they don't share the same default implementation only then am I going > to > be alerted by the compiler that something is wrong? What happens when the > default changes? Does that mean at runtime there will be collsision that > was > not intended at compile time? Is the default actually part of the method > signature? Will I get a method not found exception when there is a change? > Will every API developer get 1 and only 1 shot at picking a default > implementation? > > I'm sorry I'm really happy with the hard work people are putting into this. > I'm just totally confused by defender methods. > > Collin > > > On Wed, Aug 4, 2010 at 7:33 PM, Brian Goetz > wrote: > > > On 8/4/2010 7:38 PM, R?mi Forax wrote: > > > > > I think the syntax of defender method has some technical merits: > > > - solving the problem of a class implementing two interfaces with two > > > extension methods > > > that collide is easier. They should have the same default. > > > > This one point alone should close down this discussion! > > > > > > > > > > From howard.lovatt at gmail.com Wed Aug 4 18:40:09 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Thu, 5 Aug 2010 11:40:09 +1000 Subject: Defender Extension Methods -- Resolution and Invoccation Message-ID: >>* I think the syntax of defender method has some technical merits:*>>* - solving the problem of a class implementing two interfaces with two*>>* extension methods*>>* that collide is easier. They should have the same default.*> > This one point alone should close down this discussion! Just as easy to throw an error saying it is ambiguous and that the programmer must provide an override to resolve the ambiguity. In fact; I would go as far as to say it is in fact easier, since the runtime will have to check this anyway since a interface might have been recompiled since the class was compiled. -- Howard. From pbenedict at apache.org Wed Aug 4 18:49:56 2010 From: pbenedict at apache.org (Paul Benedict) Date: Wed, 4 Aug 2010 20:49:56 -0500 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> <4C59E293.70701@oracle.com> <40509310-4F73-46D4-9F3D-846172A611C8@miginfocom.com> <4C59E833.8090704@oracle.com> <63C3EBA6-0893-44FA-89F8-4160DF472FBB@miginfocom.com> <4C59F9D9.1020806@univ-mlv.fr> <4C5A06D9.6000906@oracle.com> Message-ID: Correct me if wrong, but did you just point out that default implementations can change from release to release? I never considered that. Even if Oracle would never do that :-), it is likely other developers will be less stringent. Perhaps release X defaults to a quick sort, and release Y replaces it with a better sort. I have strong reservations about making interfaces know anything about implementations. Would anyone here sign a contract where the other party can freely amend at will? No Facebook Privacy Policy jokes please :-) But the point being, if I code to a contract, I don't want someone amending it without me explicitly implementing it on my end. If the new defender methods add things that are just ostensibly against my programming model, and change what I think is a preferred implementation, the idea of a contract is defeated. Paul On Wed, Aug 4, 2010 at 8:35 PM, Neal Gafter wrote: > Colin has a good point. Unless the binary compatibility rules prevent you > from ever changing a defender method's implementation (which would be > horrible: the whole point of implementations is that they may be changed), > the compiler must require the programmer to resolve inheritance of multiple > defender methods, even when the implementation happens to be identical in > that particular version of the inherited interfaces. > > I still don't see any compelling reasons for the separation. Brian says > that this prevents the feature from forcing a paradigm shift on > programmers, > but the separation appears to increase (rather than reduce) the conceptual > footprint of the feature and therefore the language. > > On Wed, Aug 4, 2010 at 6:16 PM, Collin Fagan > wrote: > > > I know I've voiced this before but I'm not a fan of defender methods. I > > just > > don't see how this is not already multiple inheritance. Look I'm just > your > > average Joe programmer but I don't understand how the statement "a class > > implementing two interfaces with two extension methods that collide is > > easier. They should have the same default." can possibly be true. If each > > interface provides a default how the heck is the programmer supposed to > > know > > which one will eclipse the other? Are you saying the default > implementation > > needs to point to the same class/method? So when I use an interface from > > common.lang and one from java.util and there just happens to be a > collision > > and they don't share the same default implementation only then am I going > > to > > be alerted by the compiler that something is wrong? What happens when the > > default changes? Does that mean at runtime there will be collsision that > > was > > not intended at compile time? Is the default actually part of the method > > signature? Will I get a method not found exception when there is a > change? > > Will every API developer get 1 and only 1 shot at picking a default > > implementation? > > > > I'm sorry I'm really happy with the hard work people are putting into > this. > > I'm just totally confused by defender methods. > > > > Collin > > > > > > On Wed, Aug 4, 2010 at 7:33 PM, Brian Goetz > > wrote: > > > > > On 8/4/2010 7:38 PM, R?mi Forax wrote: > > > > > > > I think the syntax of defender method has some technical merits: > > > > - solving the problem of a class implementing two interfaces with two > > > > extension methods > > > > that collide is easier. They should have the same default. > > > > > > This one point alone should close down this discussion! > > > > > > > > > > > > > > > > > > From neal at gafter.com Wed Aug 4 20:12:25 2010 From: neal at gafter.com (Neal Gafter) Date: Wed, 4 Aug 2010 20:12:25 -0700 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> <4C59E293.70701@oracle.com> <40509310-4F73-46D4-9F3D-846172A611C8@miginfocom.com> <4C59E833.8090704@oracle.com> <63C3EBA6-0893-44FA-89F8-4160DF472FBB@miginfocom.com> <4C59F9D9.1020806@univ-mlv.fr> <4C5A06D9.6000906@oracle.com> Message-ID: On Wed, Aug 4, 2010 at 6:49 PM, Paul Benedict wrote: > Correct me if wrong, but did you just point out that default > implementations can change from release to release? I never considered that. > Even if Oracle would never do that :-), it is likely other developers will > be less stringent. Perhaps release X defaults to a quick sort, and release Y > replaces it with a better sort. > > I have strong reservations about making interfaces know anything about > implementations. > > Would anyone here sign a contract where the other party can freely amend at > will? No Facebook Privacy Policy jokes please :-) But the point being, if I > code to a contract, I don't want someone amending it without me explicitly > implementing it on my end. If the new defender methods add things that are > just ostensibly against my programming model, and change what I think is a > preferred implementation, the idea of a contract is defeated. > Implementation details are not part of the contract. If you don't like implementations changing from release to release then I think you have no choice but to stick to one version of the Java platform forever. The addition of defender methods does not change that. From i30817 at gmail.com Wed Aug 4 21:27:35 2010 From: i30817 at gmail.com (Paulo Levi) Date: Thu, 5 Aug 2010 05:27:35 +0100 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> <4C59E293.70701@oracle.com> <40509310-4F73-46D4-9F3D-846172A611C8@miginfocom.com> <4C59E833.8090704@oracle.com> <63C3EBA6-0893-44FA-89F8-4160DF472FBB@miginfocom.com> <4C59F9D9.1020806@univ-mlv.fr> <4C5A06D9.6000906@oracle.com> Message-ID: Finally the old interfaces can be updated without breaking existing code. If you don't mind i'd like to ask about the possible uses of this in the platform today. I have two that have irritated me, should be fairly common. CharSequence missing getChars - supposed readonly interface requires reading one by one when transfering to char[] A classic: List.sort. What are the methods you'd like to add a default implementation of to what interfaces (in the expectation ofourse that implementations would provide better defaults). From i30817 at gmail.com Wed Aug 4 21:30:44 2010 From: i30817 at gmail.com (Paulo Levi) Date: Thu, 5 Aug 2010 05:30:44 +0100 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> <4C59E293.70701@oracle.com> <40509310-4F73-46D4-9F3D-846172A611C8@miginfocom.com> <4C59E833.8090704@oracle.com> <63C3EBA6-0893-44FA-89F8-4160DF472FBB@miginfocom.com> <4C59F9D9.1020806@univ-mlv.fr> <4C5A06D9.6000906@oracle.com> Message-ID: I'd like also to ask what is the policy on defender methods from version to version. Are they forever or can they be deleted from, say, the version after they are introduced? I wouldn't mind to be warning to depend on the default version of the defender method, if that ends up less efficient that normal dispatch (the obsolescence scheme above assumes this) From pbenedict at apache.org Wed Aug 4 22:49:07 2010 From: pbenedict at apache.org (Paul Benedict) Date: Thu, 5 Aug 2010 00:49:07 -0500 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> <4C59E293.70701@oracle.com> <40509310-4F73-46D4-9F3D-846172A611C8@miginfocom.com> <4C59E833.8090704@oracle.com> <63C3EBA6-0893-44FA-89F8-4160DF472FBB@miginfocom.com> <4C59F9D9.1020806@univ-mlv.fr> <4C5A06D9.6000906@oracle.com> Message-ID: Neal, does C# have something similar? I am curious with your background in language design, how useful or common are defender methods. On Wed, Aug 4, 2010 at 11:30 PM, Paulo Levi wrote: > I'd like also to ask what is the policy on defender methods from version to > version. Are they forever or can they be deleted from, say, the version > after they are introduced? I wouldn't mind to be warning to depend on the > default version of the defender method, if that ends up less efficient that > normal dispatch (the obsolescence scheme above assumes this) > From neal at gafter.com Thu Aug 5 00:01:49 2010 From: neal at gafter.com (Neal Gafter) Date: Thu, 5 Aug 2010 00:01:49 -0700 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> <4C59E293.70701@oracle.com> <40509310-4F73-46D4-9F3D-846172A611C8@miginfocom.com> <4C59E833.8090704@oracle.com> <63C3EBA6-0893-44FA-89F8-4160DF472FBB@miginfocom.com> <4C59F9D9.1020806@univ-mlv.fr> <4C5A06D9.6000906@oracle.com> Message-ID: C# has extension methods that serve a similar purpose. C# extension methods are more flexible in some respects - for example, an API can be retrofitted onto a third-party framework, or a third-party API can be retrofitted to the LINQ pattern, using extension methods. Extension methods are used very widely to do the kinds of things Java does with classes such as java.util.Collections. Yesterday I wrote an extension method to "transpose" (the C# equivalent of) an Iterable>, turning it into another Iterable> whose first element gathers up all the first elements of the input lists, and so on. The improvement in readability is significant. These kinds of uses will not be possible with defender methods. Defender methods are more flexible in another respect - they are dynamically dispatched and can be overridden for particular subclasses. On Wed, Aug 4, 2010 at 10:49 PM, Paul Benedict wrote: > Neal, does C# have something similar? I am curious with your background in > language design, how useful or common are defender methods. > > > On Wed, Aug 4, 2010 at 11:30 PM, Paulo Levi wrote: > >> I'd like also to ask what is the policy on defender methods from version >> to version. Are they forever or can they be deleted from, say, the version >> after they are introduced? I wouldn't mind to be warning to depend on the >> default version of the defender method, if that ends up less efficient that >> normal dispatch (the obsolescence scheme above assumes this) >> > > From scolebourne at joda.org Thu Aug 5 01:59:23 2010 From: scolebourne at joda.org (Stephen Colebourne) Date: Thu, 5 Aug 2010 09:59:23 +0100 Subject: Fun with method references In-Reply-To: References: <4C59DC91.5090300@oracle.com> <4C59E066.6040807@oracle.com> <4C59E6D4.50104@univ-mlv.fr> <4C59E999.7070900@oracle.com> Message-ID: On 4 August 2010 23:49, Neal Gafter wrote: > The more SAMs and SAM APIs you introduce, the worse you will make things for > the language with function types later. ?While it is true that things are > already bad, that is no justification for making them worse. Yes there are. About 10 milliion - the number of Java developers out there. They need the best APIs they can get *now* not at some intangible point in the future. Stephen From forax at univ-mlv.fr Thu Aug 5 02:32:13 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Thu, 05 Aug 2010 11:32:13 +0200 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> <4C59E293.70701@oracle.com> <40509310-4F73-46D4-9F3D-846172A611C8@miginfocom.com> <4C59E833.8090704@oracle.com> <63C3EBA6-0893-44FA-89F8-4160DF472FBB@miginfocom.com> <4C59F9D9.1020806@univ-mlv.fr> <4C5A06D9.6000906@oracle.com> Message-ID: <4C5A851D.8050209@univ-mlv.fr> Le 05/08/2010 03:35, Neal Gafter a ?crit : > Colin has a good point. Unless the binary compatibility rules prevent you > from ever changing a defender method's implementation (which would be > horrible: the whole point of implementations is that they may be changed), > the compiler must require the programmer to resolve inheritance of multiple > defender methods, even when the implementation happens to be identical in > that particular version of the inherited interfaces. > Implementations may change but that doesn't mean that defaults may change. The static method implementation can change without any problem. If we use defaults to disambiguate, it will be binary incompatible to change them. > I still don't see any compelling reasons for the separation. Brian says > that this prevents the feature from forcing a paradigm shift on programmers, > but the separation appears to increase (rather than reduce) the conceptual > footprint of the feature and therefore the language. > R?mi From forax at univ-mlv.fr Thu Aug 5 02:38:48 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Thu, 05 Aug 2010 11:38:48 +0200 Subject: lambda syntax tutorial In-Reply-To: <4C59999E.8050609@oracle.com> References: <4C59999E.8050609@oracle.com> Message-ID: <4C5A86A8.1020608@univ-mlv.fr> Le 04/08/2010 18:47, Maurizio Cimadamore a ?crit : > Hi, > since most of the features are available in the compiler, I took the > time to write a pretty basic syntax document/tutorial that shows the > syntax supported by the current lambda prototype. As usual, the > document does *not* imply that the currently implemented syntax is > also the final one - the aim of this document is to simply help > developers working with the lambda prototype. > > Thanks > Maurizio Hi, see my comment at the end of this mail. > > Really Provisional Syntax for Lambda Project: August 2010 > Maurizio Cimadamore > > This document is a rather informal and basic guide on the syntax currently implemented in the lambda prototype. > > 1. Lambda expressions > --------------------- > > Lambda expressions starts with the special '#' character. > > #() { ... } > # { ... } > > Note: a nil-ary argument list can be omitted. > > 1.1 Formal parameters > > The formal parameters accepted by a lambda expression are enclosed in parenthesis (as with method declaration): > > #(int x, int y) { ... } > #(x, y) { ... } > > Note: the type of a lambda parameter can be omitted - in this case the compiler will infer a type from the target type of the lambda conversion. > > 1.2 Body > > The body of a lambda expression can be either (i) an expression or (ii) a statement list (terminated by a ';'). > > # { System.out.println("Hello"); System.out.println("Lambda!"); } > #(int x, int y) { x + y } > > 1.3 Target-type > > A target-type can be explicitly selected using the following syntax: > > Mapper #(x){ x.toString(); } > > Note: the explicit target-type syntax can be handy in case of overload resolution. > > 2. Exception transparency > ------------------------- > > Exception type-parameters are declared using the 'throws' keyword: > > class Foo { ... } > > 2.1 Disjunctive Types > > An exception type-parameter can be instantiated by a disjunctive type, a list of reference types separated by a '|' char: > > Foo > > The nil-ary disjunctive is denoted using the keyword 'void': > > Foo > > Note: 'void' is allowed as an actual type-argument only in correspondence with exception type-parameters. > > > 3. Defender Methods > ------------------- > > Defender methods are declared using the 'extension' keyword, as follows: > > extension List map(Mapper r) default Collections.listMapper; > > A defender method declaration is structured in two parts, (i) a method signature, declaring formal arguments, formal type-arguments and return-type and (ii) a default implementation, that is, the implementation the method should default to if none is found in the class implementing the extended interface. > > > 4. Method References > -------------------- > > The syntax for method references uses the infix '#' operator; the selector of a method reference can be either a valid Java expression or a type: > > Foo#bar() > new Foo()#bar() > > 4.1. Actual Arguments > > The actual argument type list associated with a method reference is optional: > > Foo#baz > I think you can't do that because inserting an overloading method is a source backward compatible change. With this syntax, inserting an overloading method may break method references. > However, if required, actual argument types can be specified after the method references, enclosed in parenthesis, as in: > > Foo#baz(Integer, String). > > Note: the explicit syntax can be handy in case of overload resolution. > In my opinion, explicit syntax should be the only existing one. R?mi From oehrstroem at gmail.com Thu Aug 5 02:57:05 2010 From: oehrstroem at gmail.com (Fredrik Ohrstrom) Date: Thu, 5 Aug 2010 11:57:05 +0200 Subject: lambda syntax tutorial In-Reply-To: <4C5A86A8.1020608@univ-mlv.fr> References: <4C59999E.8050609@oracle.com> <4C5A86A8.1020608@univ-mlv.fr> Message-ID: >> The actual argument type list associated with a method reference is optional: >> >> Foo#baz >> > > I think you can't do that because inserting an overloading method > is a source backward compatible change. That cannot be true. If I insert a more specified overloading method into class Test, clearly you will have to recompile the code that uses Test. For example compile Test and Usage: public class Test { public static void foo(Object a) { System.err.println("Object"); } //public static void foo(String a) { System.err.println("String"); } } public class Usage { public static void main(String... args) { Test.foo(""); } } Then recompile only Test but with foo(String) enabled. Obviously when you run Usage it will still use foo(Object) since that is what is encoded into the bytecode of Usage. The same will be true for the MethodHandle ldc. > With this syntax, inserting an overloading method may break method > references. Any change to the overloading hierarchy will potentially break code that uses the overloaded code. You have to recompile to get the static references right. > In my opinion, explicit syntax should be the only existing one. No. This is a good syntax. //Fredrik From maurizio.cimadamore at oracle.com Thu Aug 5 03:16:04 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 05 Aug 2010 11:16:04 +0100 Subject: lambda syntax tutorial In-Reply-To: <4C5A86A8.1020608@univ-mlv.fr> References: <4C59999E.8050609@oracle.com> <4C5A86A8.1020608@univ-mlv.fr> Message-ID: <4C5A8F64.6010905@oracle.com> >> The actual argument type list associated with a method reference is optional: >> >> Foo#baz >> >> > I think you can't do that because inserting an overloading method > is a source backward compatible change. > > With this syntax, inserting an overloading method may break method > references. > > >> However, if required, actual argument types can be specified after the method references, enclosed in parenthesis, as in: >> >> Foo#baz(Integer, String). >> >> Note: the explicit syntax can be handy in case of overload resolution. >> >> > In my opinion, explicit syntax should be the only existing one. > Uhmm, yes and no. On the one hand, as Friedrik has pointed out, adding overloaded versions of a method to a class can already result in ambiguity errors (best case) or 'stale' resolution (worst case) anywhere else in the codebase. On the other hand, I admit that this syntax is more prone to this kind of problems since the argument list is completely unspecified - but it's just matter of quantity, not quality ;-) Explicit syntax does not entirely solve the problem, as explicit argument types might still undergo an overload resolution process: interface A {} interface B {} class C implements A,B {} class Foo { void m(A a) { } } Foo#m(C) //ok, this resolves to Foo.m(A) now suppose to add a method to Foo: class Foo { void m(A a) { } void m(B a) { } } Foo#m(C) //ambiguity here, both m(A) and m(B) apply!! So, even with explicit syntax you have a breakage... ...unless you are proposing that Foo#m(C) should not compile in the first place (i.e. because there should be an exact match between the explicit types of the method reference and the underlying VM method descriptor). Maurizio > R?mi > > > > From oehrstroem at gmail.com Thu Aug 5 03:47:07 2010 From: oehrstroem at gmail.com (Fredrik Ohrstrom) Date: Thu, 5 Aug 2010 12:47:07 +0200 Subject: lambda syntax tutorial In-Reply-To: <4C5A8F64.6010905@oracle.com> References: <4C59999E.8050609@oracle.com> <4C5A86A8.1020608@univ-mlv.fr> <4C5A8F64.6010905@oracle.com> Message-ID: > Uhmm, yes and no. > On the one hand, as Fredrik has pointed out, adding overloaded versions > of a method to a class can already result in ambiguity errors (best > case) or 'stale' resolution (worst case) anywhere else in the codebase. > > On the other hand, I admit that this syntax is more prone to this kind > of problems since the argument list is completely unspecified - but it's > just matter of quantity, not quality ;-) Well, you could either say that when searching for the most specified method target, you take the one with the fewest arguments and supply null as the arguments for resolution. Or you could simply forbid compiling when several overloaded targets exist. > Explicit syntax does not entirely solve the problem, as explicit > argument types might still undergo an overload resolution process: Exactly, Joe Darcy's blog entry is a good read: http://blogs.sun.com/darcy/entry/kinds_of_compatibility Regarding the question whether adding overloaded methods should be considered as source compatible, I quote: "Adding overloaded methods has the potential to change method resolution and thus change the signatures of the method call sites in the resulting class file. Whether or not such a change is problematic with respect to source compatibility depends on what semantics are required and how the different overloaded methods operate on the same inputs, which interacts with behavioral equivalence notions." //Fredrik From neal at gafter.com Thu Aug 5 04:20:58 2010 From: neal at gafter.com (Neal Gafter) Date: Thu, 5 Aug 2010 04:20:58 -0700 Subject: lambda syntax tutorial In-Reply-To: <4C59999E.8050609@oracle.com> References: <4C59999E.8050609@oracle.com> Message-ID: Mautizio- Careful with the syntax. The source fragment AD could be either an expression or a variable declaration. I imagine that the parser now requires lookahead in code that could previously have been parsed in one pass. This is likely to be inconvenient as the language is further extended. Cheers, Neal On Wed, Aug 4, 2010 at 9:47 AM, Maurizio Cimadamore < maurizio.cimadamore at oracle.com> wrote: > Hi, > since most of the features are available in the compiler, I took the time > to write a pretty basic syntax document/tutorial that shows the syntax > supported by the current lambda prototype. As usual, the document does *not* > imply that the currently implemented syntax is also the final one - the aim > of this document is to simply help developers working with the lambda > prototype. > > Thanks > Maurizio > > > > From neal at gafter.com Thu Aug 5 04:22:47 2010 From: neal at gafter.com (Neal Gafter) Date: Thu, 5 Aug 2010 04:22:47 -0700 Subject: Fun with method references In-Reply-To: References: <4C59DC91.5090300@oracle.com> <4C59E066.6040807@oracle.com> <4C59E6D4.50104@univ-mlv.fr> <4C59E999.7070900@oracle.com> Message-ID: On Thu, Aug 5, 2010 at 1:59 AM, Stephen Colebourne wrote: > On 4 August 2010 23:49, Neal Gafter wrote: > > The more SAMs and SAM APIs you introduce, the worse you will make things > for > > the language with function types later. While it is true that things are > > already bad, that is no justification for making them worse. > > Yes there are. About 10 milliion - the number of Java developers out > there. They need the best APIs they can get *now* not at some > intangible point in the future. > Its true that adding SAMs now would be better, but apparently resource and time constraints prevent Oracle from doing everything at once. From maurizio.cimadamore at oracle.com Thu Aug 5 04:43:52 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 05 Aug 2010 12:43:52 +0100 Subject: lambda syntax tutorial In-Reply-To: References: <4C59999E.8050609@oracle.com> Message-ID: <4C5AA3F8.9050409@oracle.com> On 05/08/10 12:20, Neal Gafter wrote: > Mautizio- > > Careful with the syntax. The source fragment > > AD > > could be either an expression or a variable declaration. I imagine > that the parser now requires lookahead in code that could previously > have been parsed in one pass. This is likely to be inconvenient as > the language is further extended. We are aware of the problem - strange that this observation comes from you - who essentially proposed this syntax [1] :-) I think that the only problem is with cast expressions (where there is an ambiguity between parenthesized expressions and cast to a disjunctive type) - I don't think an expression of that kind can occur in a context where a variable declarator could be expected, am I wrong? [1] - http://mail.openjdk.java.net/pipermail/lambda-dev/2010-June/001485.html > > Cheers, > Neal > > On Wed, Aug 4, 2010 at 9:47 AM, Maurizio Cimadamore > > wrote: > > Hi, > since most of the features are available in the compiler, I took > the time to write a pretty basic syntax document/tutorial that > shows the syntax supported by the current lambda prototype. As > usual, the document does *not* imply that the currently > implemented syntax is also the final one - the aim of this > document is to simply help developers working with the lambda > prototype. > > Thanks > Maurizio > > > > From brian.goetz at oracle.com Thu Aug 5 05:41:37 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 05 Aug 2010 08:41:37 -0400 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> <4C59E293.70701@oracle.com> <40509310-4F73-46D4-9F3D-846172A611C8@miginfocom.com> <4C59E833.8090704@oracle.com> <63C3EBA6-0893-44FA-89F8-4160DF472FBB@miginfocom.com> <4C59F9D9.1020806@univ-mlv.fr> <4C5A06D9.6000906@oracle.com> Message-ID: <4C5AB181.4050101@oracle.com> > Correct me if wrong, but did you just point out that default implementations > can change from release to release? I never considered that. Even if Oracle > would never do that :-), it is likely other developers will be less > stringent. Perhaps release X defaults to a quick sort, and release Y > replaces it with a better sort. Of course. Same thing when you extend AbstractList; the superclass implementation of size() could change. > I have strong reservations about making interfaces know anything about > implementations. They don't. The interface is a place to specify the fallback strategy should the implementation fail to provide one. > Would anyone here sign a contract where the other party can freely amend at > will? You do so every time you extend a class. Really. From brian.goetz at oracle.com Thu Aug 5 05:44:29 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 05 Aug 2010 08:44:29 -0400 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> <4C59E293.70701@oracle.com> <40509310-4F73-46D4-9F3D-846172A611C8@miginfocom.com> <4C59E833.8090704@oracle.com> <63C3EBA6-0893-44FA-89F8-4160DF472FBB@miginfocom.com> <4C59F9D9.1020806@univ-mlv.fr> <4C5A06D9.6000906@oracle.com> Message-ID: <4C5AB22D.9040709@oracle.com> > If you don't mind i'd like to ask about the possible uses of this in the > platform today. Good, because that's the point! > CharSequence missing getChars - supposed readonly interface requires reading > one by one when transfering to char[] > A classic: List.sort. We are definitely looking at List.sort(). Feel free to make suggestions for others. From brian.goetz at oracle.com Thu Aug 5 05:45:21 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 05 Aug 2010 08:45:21 -0400 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> <4C59E293.70701@oracle.com> <40509310-4F73-46D4-9F3D-846172A611C8@miginfocom.com> <4C59E833.8090704@oracle.com> <63C3EBA6-0893-44FA-89F8-4160DF472FBB@miginfocom.com> <4C59F9D9.1020806@univ-mlv.fr> <4C5A06D9.6000906@oracle.com> Message-ID: <4C5AB261.8020609@oracle.com> Removing a method from an interface is binary incompatible, and will remain so. Changing the default will be binary compatible. On 8/5/2010 12:30 AM, Paulo Levi wrote: > I'd like also to ask what is the policy on defender methods from version to > version. Are they forever or can they be deleted from, say, the version > after they are introduced? I wouldn't mind to be warning to depend on the > default version of the defender method, if that ends up less efficient that > normal dispatch (the obsolescence scheme above assumes this) > From scolebourne at joda.org Thu Aug 5 05:57:32 2010 From: scolebourne at joda.org (Stephen Colebourne) Date: Thu, 5 Aug 2010 13:57:32 +0100 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: <4C5A05AA.8050204@oracle.com> References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> <4C59E293.70701@oracle.com> <40509310-4F73-46D4-9F3D-846172A611C8@miginfocom.com> <4C59E833.8090704@oracle.com> <63C3EBA6-0893-44FA-89F8-4160DF472FBB@miginfocom.com> <4C5A05AA.8050204@oracle.com> Message-ID: On 5 August 2010 01:28, Brian Goetz wrote: > Your are being tripped up by the belief that most Java users are like you! > (And we all know there's only one of Neal.) > > The vast majority of the 12M+ Java developers will probably never use this > feature. ?But doing it this way saves us from imposing what will look like a > significant paradigm shift on them, which would certainly rock their world for > little benefit. I think this is not actually going to be so. Adding a defender method will I suspect be a quite common operation for the 12+M devs. Certainly not all, but enough. This statement seems to be at the heart of the tension of not including the implementation in the interface (which is the /natural/ place to expect to find it - static methods and helper classes are essentially just a horid hack). BTW. I think the hangup over the meaning of interface vs class is overblown. Don't get me wrong, this is better than what we have today. And the ability for implementations to supply their own implementation is essential. More broadly, design patterns are one way that languages evolve. Consider the enum pattern to language feature in Java. With this feature, there is an obvious pattern: public interface Foo { getWorld(); extension checkWorld() default Utils.checkWorld(Foo); static class Utils { void checkWorld(Foo foo) { if (foo.getWorld().isValid() == false) { throw new RuntimeException(); } } } } Certainly, if this feature goes in as is I will be writing up and describing this as the default way to write new static helper classes targetted as extension methods. So its a pattern. Just boilerplate. But thats OK, as no-one expects anything but boilerplate from Java Seriously, the benefits of the open process are a greater ability to see into the future. Consider this an indication of what JDK 8/9 might contain... Stephen From brian.goetz at oracle.com Thu Aug 5 06:36:06 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 05 Aug 2010 09:36:06 -0400 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> <4C59E293.70701@oracle.com> <40509310-4F73-46D4-9F3D-846172A611C8@miginfocom.com> <4C59E833.8090704@oracle.com> <63C3EBA6-0893-44FA-89F8-4160DF472FBB@miginfocom.com> <4C59F9D9.1020806@univ-mlv.fr> <4C5A06D9.6000906@oracle.com> Message-ID: <4C5ABE46.4050205@oracle.com> > I know I've voiced this before but I'm not a fan of defender methods. I > just don't see how this is not already multiple inheritance. Java has always had multiple inheritance of types, through interfaces. (And since 1.1 Java has had multiple inheritance of behavior in the context of inner classes; members of both the lexical scope and the inner class hierarchy are in scope inside an inner class.) Multiple inheritance per se is not evil; we've been enjoying it for years. The real pain of multiple inheritance is when it comes to *state* (as with so many things). Defender methods do not introduce state in interfaces. Defender methods are clearly a point on the spectrum somewhere between the current state of Java and C++. Note also that it is not as far along this spectrum as mixins or traits. Some have advocated we should do mixins or traits or... Because defender methods is a more measured solution that meets the current goal (be able to add lambdaphilic methods to interfaces like Collection.filter), this solution is preferred to those other solutions. From john at milsson.nu Thu Aug 5 06:54:10 2010 From: john at milsson.nu (John Nilsson) Date: Thu, 5 Aug 2010 15:54:10 +0200 Subject: Fun with method references In-Reply-To: <4C59DC91.5090300@oracle.com> References: <4C59DC91.5090300@oracle.com> Message-ID: On Wed, Aug 4, 2010 at 11:33 PM, Brian Goetz wrote: > Check this out -- this works with the latest prototype: > Arrays.sortBy(foos, Foo#getA); ? ? ? ? ?// sort by JavaBean property A I'm wondering if this kind of thing will increase the demand for tuples in the language. So far it has been my experience that most uses of classes such as Pair is better served by actually naming the attribute collection to something sensible. But with code like this I can see how a simple tuple would simplify things. So will Arrays.sortBy(foos, tuple(Foo#getA,Foo#getB)) be good enough or would it be better with Arrays.sortBy(foos, (Foo#getA,Foo#getB)) // Standard parenthesis tuple syntax or Arrays.sortBy(foos, Foo#getA x Foo#getB) // Product combinator operator BR, John From forax at univ-mlv.fr Thu Aug 5 07:03:56 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Thu, 05 Aug 2010 16:03:56 +0200 Subject: lambda syntax tutorial In-Reply-To: References: <4C59999E.8050609@oracle.com> <4C5A86A8.1020608@univ-mlv.fr> <4C5A8F64.6010905@oracle.com> Message-ID: <4C5AC4CC.80203@univ-mlv.fr> Le 05/08/2010 12:47, Fredrik Ohrstrom a ?crit : >> Uhmm, yes and no. >> On the one hand, as Fredrik has pointed out, adding overloaded versions >> of a method to a class can already result in ambiguity errors (best >> case) or 'stale' resolution (worst case) anywhere else in the codebase. >> >> On the other hand, I admit that this syntax is more prone to this kind >> of problems since the argument list is completely unspecified - but it's >> just matter of quantity, not quality ;-) >> > Well, you could either say that when searching for the most specified > method target, you take the one with the fewest arguments and supply > null as the arguments for resolution. > > Or you could simply forbid compiling when several overloaded targets exist. > > >> Explicit syntax does not entirely solve the problem, as explicit >> argument types might still undergo an overload resolution process: >> > Exactly, Joe Darcy's blog entry is a good read: > http://blogs.sun.com/darcy/entry/kinds_of_compatibility > > Regarding the question whether adding overloaded methods should be > considered as source compatible, I quote: > > "Adding overloaded methods has the potential to change method > resolution and thus change the signatures of the method call sites in > the resulting class file. Whether or not such a change is problematic > with respect to source compatibility depends on what semantics are > required and how the different overloaded methods operate on the same > inputs, which interacts with behavioral equivalence notions." > > //Fredrik > Ok, I was not crystal clear. Let's take an example, this code compile. Following the criterion of Joe, I can add A.m(B) because its semantics is equivalent to the semantics of A.m(A). However it will not compile anymore ! class A { public static A m(A a) { return null; } //public static A m(B b) { return null; } } class B extends A { } interface Foo { T m(T t); } ... Foo foo = A#m; It will always compile if the last instruction is: Foo foo = A#m(A); R?mi From tronicek at fit.cvut.cz Thu Aug 5 07:14:26 2010 From: tronicek at fit.cvut.cz (=?utf-8?B?IlpkZW7Em2sgVHJvbsOtxI1layI=?=) Date: Thu, 5 Aug 2010 16:14:26 +0200 Subject: lambda syntax tutorial Message-ID: Adding an overloaded method can break source compatibility even now: class A { static void m(int i, double d) { } //static void m(double d, int i) { } } class Main { public static void main(String[] args) { A.m(1, 2); } } Z. -- Zdenek Tronicek FIT CTU in Prague http://www.dzone.com/links/api_evolution_with_refactoringng.html R?mi Forax napsal(a): > Ok, I was not crystal clear. Let's take an example, > this code compile. > Following the criterion of Joe, I can add A.m(B) because > its semantics is equivalent to the semantics of A.m(A). > However it will not compile anymore ! > class A { > public static A m(A a) { return null; } > //public static A m(B b) { return null; } > } > class B extends A { } > interface Foo { > T m(T t); > } > ... > Foo foo = A#m; > It will always compile if the last instruction is: > Foo foo = A#m(A); > R?mi From forax at univ-mlv.fr Thu Aug 5 07:26:19 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Thu, 05 Aug 2010 16:26:19 +0200 Subject: Fun with method references In-Reply-To: References: <4C59DC91.5090300@oracle.com> Message-ID: <4C5ACA0B.80601@univ-mlv.fr> Le 05/08/2010 15:54, John Nilsson a ?crit : > On Wed, Aug 4, 2010 at 11:33 PM, Brian Goetz wrote: > >> Check this out -- this works with the latest prototype: >> Arrays.sortBy(foos, Foo#getA); // sort by JavaBean property A >> > I'm wondering if this kind of thing will increase the demand for > tuples in the language. So far it has been my experience that most > uses of classes such as Pair is better served by actually naming > the attribute collection to something sensible. But with code like > this I can see how a simple tuple would simplify things. > > So will > Arrays.sortBy(foos, tuple(Foo#getA,Foo#getB)) > be good enough or would it be better with > Arrays.sortBy(foos, (Foo#getA,Foo#getB)) // Standard parenthesis tuple syntax > or > Arrays.sortBy(foos, Foo#getA x Foo#getB) // Product combinator operator > > BR, > John > John, my advice here is to use the varargs syntax (with an @SuppressWarnings("varargs")) But it doesn't work with the current prototype. Worst there is not lambda conversion between #int(String) and Extractor. import java.util.List; public class MyTest2 { interface Extractor { public U get(T t); } static class Arrays { public static > void sortBy(List c, Extractor extractor) { } //public static > void sortBy(List c, Extractor extractor) { } //public static > void sortBy(List c, Extractor... extractor) { } } public static void main(String[] args) { List list = java.util.Arrays.asList(args); Arrays.sortBy(list, #(String s){s.length()}); } } R?mi From forax at univ-mlv.fr Thu Aug 5 07:37:05 2010 From: forax at univ-mlv.fr (=?UTF-8?B?UsOpbWkgRm9yYXg=?=) Date: Thu, 05 Aug 2010 16:37:05 +0200 Subject: lambda syntax tutorial In-Reply-To: References: Message-ID: <4C5ACC91.7060208@univ-mlv.fr> Le 05/08/2010 16:14, "Zden?k Tron??ek" a ?crit : > Adding an overloaded method can break source compatibility even now: > > class A { > static void m(int i, double d) { } > //static void m(double d, int i) { } > } > > class Main { > public static void main(String[] args) { > A.m(1, 2); > } > } > > Z. > You are right, but without method reference, my example was legal. This trick was used in 1.4 to introduce StringBuffer.append(StringBuffer) even if a method StringBuffer.append(Object) was already existing. see http://www.itjungle.com/mgo/mgo072303-story01.html R?mi From nathan.bryant at linkshare.com Thu Aug 5 07:32:32 2010 From: nathan.bryant at linkshare.com (Nathan Bryant) Date: Thu, 5 Aug 2010 23:32:32 +0900 Subject: lambda syntax tutorial References: <4C59999E.8050609@oracle.com><4C5A86A8.1020608@univ-mlv.fr> Message-ID: <7FDA6630E1822F448C97A48D5D7330940147335B@EXVMSTOR302.intra.rakuten.co.jp> Remi and Fredrik wrote: ... > In my opinion, explicit syntax should be the only existing one. No. This is a good syntax. ... Explicit syntax in most cases will be more verbose than no syntax at all, and more verbose than simply using a lambda to extract the reference. From kevinb at google.com Thu Aug 5 09:22:01 2010 From: kevinb at google.com (Kevin Bourrillion) Date: Thu, 5 Aug 2010 09:22:01 -0700 Subject: lambda syntax tutorial In-Reply-To: <7FDA6630E1822F448C97A48D5D7330940147335B@EXVMSTOR302.intra.rakuten.co.jp> References: <4C59999E.8050609@oracle.com> <4C5A86A8.1020608@univ-mlv.fr> <7FDA6630E1822F448C97A48D5D7330940147335B@EXVMSTOR302.intra.rakuten.co.jp> Message-ID: Agreed, adding an overload can sometimes be source-incompatible today, even for a final class. But in how many ways can this happen? I'm only thinking of one so far: if there could exist any list of actual parameter types that would become ambiguous. (If one of my signatures is a refinement of the other, I should have no problem, since I should darn well be making sure the two have equivalent behavior for the same inputs anyway). This is pretty simple for me to watch out for in my API changes to my released libraries. And, I sometimes even have recourse to avoid it: for example if I have only String join(Iterable iterable); and I want to add String join(Iterator iterable); I believe I can do this source-compatibly if I also add at the same time @Deprecated & Iterable> String join(T iter) { return join((Iterable) iter); } (I'm planning to try exactly this in Guava. Yes, I think it's as lame as anyone that a class would implement both of those types. Still, I like knowing my changes are completely compatible.) So, my question is: to what degree does the current proposal expand the set of categories of source-incompatible API additions we can make? And how workaround-able are those? For example, if Foo#bar has no contextual smarts at all, then adding overload #2 of any method would *always* be source-incompatible (which would be hideous!). So how much intelligence does it have? P.S. fun trivia if you haven't heard it: my colleague once found a case where adding overload C caused previous source references to overload A to suddenly be compiled as references to overload B! Ahh, fun times. http://twofoos.org/content/java-type-system-holes/ From mcnepp02 at googlemail.com Thu Aug 5 09:33:29 2010 From: mcnepp02 at googlemail.com (Gernot Neppert) Date: Thu, 05 Aug 2010 18:33:29 +0200 Subject: new keyword 'extension' really necessary? In-Reply-To: <4C59999E.8050609@oracle.com> References: <4C59999E.8050609@oracle.com> Message-ID: <4C5AE7D9.7010403@googlemail.com> Hi Maurizio, I do not have compiler writing skils, so I'm curious why the keyword 'extension' should be nessesary to introduce defender methods. A defender method declaration without the prefix 'extension' looks quite distinguishable to me. Example: interface List { void sort(Comparator comp) default Collections.sort(List); } So, why the new keyword? (An answer such as 'This is necessary to disambiguate the grammar' would suffice...) From maurizio.cimadamore at oracle.com Thu Aug 5 09:42:31 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 05 Aug 2010 17:42:31 +0100 Subject: new keyword 'extension' really necessary? In-Reply-To: <4C5AE7D9.7010403@googlemail.com> References: <4C59999E.8050609@oracle.com> <4C5AE7D9.7010403@googlemail.com> Message-ID: <4C5AE9F7.4070600@oracle.com> On 05/08/10 17:33, Gernot Neppert wrote: > Hi Maurizio, > > I do not have compiler writing skils, so I'm curious why the keyword > 'extension' should be nessesary to introduce defender methods. > A defender method declaration without the prefix 'extension' looks > quite distinguishable to me. Example: > > interface List > { > void sort(Comparator comp) default > Collections.sort(List); > } > > So, why the new keyword? > > (An answer such as 'This is necessary to disambiguate the grammar' > would suffice...) > > 'This is necessary to disambiguate the grammar' ;-) Annotations: @interface MyAnnotation { String stringValue() default "defaultString"; } [I guess that with some heavy-lifting and semantic lookahead it would be possible for the compiler to disambiguate the two cases, however we also felt that 'extension' methods were peculiar enough to deserve their own mini-keyword] Note that 'extension' is not a new keyword - it's a context-dependent keyword, which means you will still able to do: class extension { extension extension = extension; } Maurizio From brian.goetz at oracle.com Thu Aug 5 09:46:07 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 05 Aug 2010 12:46:07 -0400 Subject: new keyword 'extension' really necessary? In-Reply-To: <4C5AE7D9.7010403@googlemail.com> References: <4C59999E.8050609@oracle.com> <4C5AE7D9.7010403@googlemail.com> Message-ID: <4C5AEACF.4060803@oracle.com> In addition to Maurizio's syntactic arguments, we believe there is value in identifying extension methods as, well, extension methods. On 8/5/2010 12:33 PM, Gernot Neppert wrote: > Hi Maurizio, > > I do not have compiler writing skils, so I'm curious why the keyword > 'extension' should be nessesary to introduce defender methods. > A defender method declaration without the prefix 'extension' looks quite > distinguishable to me. Example: > > interface List > { > void sort(Comparator comp) default Collections.sort(List); > } > > So, why the new keyword? > > (An answer such as 'This is necessary to disambiguate the grammar' would > suffice...) > > > From forax at univ-mlv.fr Thu Aug 5 10:39:31 2010 From: forax at univ-mlv.fr (=?UTF-8?B?UsOpbWkgRm9yYXg=?=) Date: Thu, 05 Aug 2010 19:39:31 +0200 Subject: lambda syntax tutorial In-Reply-To: References: <4C59999E.8050609@oracle.com> <4C5A86A8.1020608@univ-mlv.fr> <7FDA6630E1822F448C97A48D5D7330940147335B@EXVMSTOR302.intra.rakuten.co.jp> Message-ID: <4C5AF753.70505@univ-mlv.fr> Le 05/08/2010 18:22, Kevin Bourrillion a ?crit : > Agreed, adding an overload can sometimes be source-incompatible today, > even for a final class. But in how many ways can this happen? I'm > only thinking of one so far: if there could exist any list of actual > parameter types that would become ambiguous. (If one of my signatures > is a refinement of the other, I should have no problem, since I should > darn well be making sure the two have equivalent behavior for the same > inputs anyway). > > This is pretty simple for me to watch out for in my API changes to my > released libraries. And, I sometimes even have recourse to avoid it: > for example if I have only > > String join(Iterable iterable); > > and I want to add > > String join(Iterator iterable); > > I believe I can do this source-compatibly if I also add at the same time > > @Deprecated > & Iterable> String join(T iter) { > return join((Iterable) iter); > } > > (I'm planning to try exactly this in Guava. Yes, I think it's as lame > as anyone that a class would implement both of those types. Still, I > like knowing my changes are completely compatible.) In fact, there is a trick, you can just add: > String join(T iterator) { ... } because it's a parametrized method, join(Iterable) will be selected first if a class implements both types. > > So, my question is: to what degree does the current proposal expand > the set of categories of source-incompatible API additions we can > make? And how workaround-able are those? For example, if Foo#bar has > no contextual smarts at all, then adding overload #2 of any method > would /always/ be source-incompatible (which would be hideous!). So > how much intelligence does it have? I think we have no degree of freedom if the syntax doesn't specify the parameter types. > > > P.S. fun trivia if you haven't heard it: my colleague once found a > case where adding overload C caused previous source references to > overload A to suddenly be compiled as references to overload B! Ahh, > fun times. > http://twofoos.org/content/java-type-system-holes/ > R?mi From nathan.bryant at linkshare.com Thu Aug 5 11:08:41 2010 From: nathan.bryant at linkshare.com (Nathan Bryant) Date: Fri, 6 Aug 2010 03:08:41 +0900 Subject: lambda syntax tutorial References: <4C59999E.8050609@oracle.com><4C5A86A8.1020608@univ-mlv.fr><7FDA6630E1822F448C97A48D5D7330940147335B@EXVMSTOR302.intra.rakuten.co.jp> Message-ID: <7FDA6630E1822F448C97A48D5D733094014735FF@EXVMSTOR302.intra.rakuten.co.jp> Kevin Bourrillion wrote: ? For example, if Foo#bar has no contextual smarts at all, then adding overload #2 of any method would always be source-incompatible (which would be hideous!). So how much intelligence does it have? The worst-case of overloading always producing breakage can be ruled out; the set of possible overloads can only include those that have SAM types that are compatible with any of the overloads of Foo#bar . From there, resolution should proceed in the usual way (most specific wins, or else the programmer must disambiguate.) In order for the worst ambiguities to arise, Foo.bar and the target method must both be overloaded. Is this really that common of a case? Any lesser ambiguities are the ones that can also arise with the lambda parameter type inference that is already implemented. From opinali at gmail.com Thu Aug 5 11:25:56 2010 From: opinali at gmail.com (Osvaldo Doederlein) Date: Thu, 5 Aug 2010 15:25:56 -0300 Subject: new keyword 'extension' really necessary? In-Reply-To: <4C5AEACF.4060803@oracle.com> References: <4C59999E.8050609@oracle.com> <4C5AE7D9.7010403@googlemail.com> <4C5AEACF.4060803@oracle.com> Message-ID: Extension methods are not allowed inside annotations, so I guess the implementation and spec issues are at least less severe, as disambiguation is trivial by the outer context being an annotation or not. Maybe it can't be completely handled by (simple) grammar changes, but that would be about it (it seems; correct me if that's wrong). And I think the similar style (same syntax for annotation defaults and for extension methods) is actually good. These are basically the same thing, in a very abstract level: a structure (interface or annotation) that has some feature (annotation field or method) which offers a default "value". 2010/8/5 Brian Goetz : > In addition to Maurizio's syntactic arguments, we believe there is value in > identifying extension methods as, well, extension methods. By the same logic, maybe we need an army of new redundant qualifiers such as "method", "field", etc.? (OTOH, we already have some redundant qualifiers - like 'abstract' for a method signature that's not followed by '{', or allowing 'private final' methods and 'public' interface methods, or 'final' for arguments in abstract method declarations. But I don't want more of the same.) A+ Osvaldo > On 8/5/2010 12:33 PM, Gernot Neppert wrote: >> Hi Maurizio, >> >> I do not have compiler writing skils, so I'm curious why the keyword >> 'extension' should be nessesary to introduce defender methods. >> A defender method declaration without the prefix 'extension' looks quite >> distinguishable to me. Example: >> >> interface List >> { >> ? ? ?void sort(Comparator ?comp) default Collections.sort(List); >> } >> >> So, why the new keyword? >> >> (An answer such as 'This is necessary to disambiguate the grammar' would >> suffice...) >> >> >> > > From forax at univ-mlv.fr Thu Aug 5 12:17:58 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Thu, 05 Aug 2010 21:17:58 +0200 Subject: new keyword 'extension' really necessary? In-Reply-To: References: <4C59999E.8050609@oracle.com> <4C5AE7D9.7010403@googlemail.com> <4C5AEACF.4060803@oracle.com> Message-ID: <4C5B0E66.1020605@univ-mlv.fr> Le 05/08/2010 20:25, Osvaldo Doederlein a ?crit : > Extension methods are not allowed inside annotations, so I guess the > implementation and spec issues are at least less severe, as > disambiguation is trivial by the outer context being an annotation or > not. Maybe it can't be completely handled by (simple) grammar changes, > but that would be about it (it seems; correct me if that's wrong). > In fact, there is no 'grammar' problem. The local keyword 'extension' avoid to change too much the javac parser, a hand written top-down recursive parser. But the real value is, as Brian says, that an extension method is tagged with the local keyword 'extension'. Easy to explain, easy to grasp. > And I think the similar style (same syntax for annotation defaults and > for extension methods) is actually good. These are basically the same > thing, in a very abstract level: a structure (interface or annotation) > that has some feature (annotation field or method) which offers a > default "value". > > R?mi > 2010/8/5 Brian Goetz: > >> In addition to Maurizio's syntactic arguments, we believe there is value in >> identifying extension methods as, well, extension methods. >> > By the same logic, maybe we need an army of new redundant qualifiers > such as "method", "field", etc.? > > (OTOH, we already have some redundant qualifiers - like 'abstract' for > a method signature that's not followed by '{', or allowing 'private > final' methods and 'public' interface methods, or 'final' for > arguments in abstract method declarations. But I don't want more of > the same.) > > A+ > Osvaldo > > >> On 8/5/2010 12:33 PM, Gernot Neppert wrote: >> >>> Hi Maurizio, >>> >>> I do not have compiler writing skils, so I'm curious why the keyword >>> 'extension' should be nessesary to introduce defender methods. >>> A defender method declaration without the prefix 'extension' looks quite >>> distinguishable to me. Example: >>> >>> interface List >>> { >>> void sort(Comparator comp) default Collections.sort(List); >>> } >>> >>> So, why the new keyword? >>> >>> (An answer such as 'This is necessary to disambiguate the grammar' would >>> suffice...) >>> >>> >>> >>> >> >> > From scolebourne at joda.org Thu Aug 5 12:57:46 2010 From: scolebourne at joda.org (Stephen Colebourne) Date: Thu, 5 Aug 2010 20:57:46 +0100 Subject: Method references with types [Re: lambda syntax tutorial] Message-ID: No one has yet mentioned another danger with using Foo#bar instead of Foo#bar(String). The former choice at this point closes off options in the future for Java. Foo#bar is the only sensible syntax for a field literal. Java can have both fields and methods with the same name. This has the potential to be a limitation to future language development. If there is a positive decision here today that field literals will never be added (and that any future property literals will never clash) then fine, but that seems like a strong statement at this point. Stephen On 5 August 2010 19:08, Nathan Bryant wrote: > Kevin Bourrillion wrote: > ? ?For example, if Foo#bar has no contextual smarts at all, then adding overload #2 of any method would always be source-incompatible (which would be hideous!). ?So how much intelligence does it have? > > > > The worst-case of overloading always producing breakage can be ruled out; the set of possible overloads can only include those that have SAM types that are compatible with any of the overloads of Foo#bar . > > > > From there, resolution should proceed in the usual way (most specific wins, or else the programmer must disambiguate.) > > > > In order for the worst ambiguities to arise, Foo.bar and the target method must both be overloaded. Is this really that common of a case? Any lesser ambiguities are the ones that can also arise with the lambda parameter type inference that is already implemented. > > > From pbenedict at apache.org Thu Aug 5 14:03:26 2010 From: pbenedict at apache.org (Paul Benedict) Date: Thu, 5 Aug 2010 16:03:26 -0500 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: References: Message-ID: Good point Stephen. Parentheses should refer to methods, and without them to fields. Your insight will definitely retain the separate namespaces that Java has established. PS: Is Lambda also considering any support to turn method/field references into java.lang.reflect types? On Thu, Aug 5, 2010 at 2:57 PM, Stephen Colebourne wrote: > No one has yet mentioned another danger with using Foo#bar instead of > Foo#bar(String). > > The former choice at this point closes off options in the future for Java. > > Foo#bar is the only sensible syntax for a field literal. Java can have > both fields and methods with the same name. This has the potential to > be a limitation to future language development. > > If there is a positive decision here today that field literals will > never be added (and that any future property literals will never > clash) then fine, but that seems like a strong statement at this > point. > > Stephen > > > On 5 August 2010 19:08, Nathan Bryant wrote: > > Kevin Bourrillion wrote: > > ? For example, if Foo#bar has no contextual smarts at all, then adding > overload #2 of any method would always be source-incompatible (which would > be hideous!). So how much intelligence does it have? > > > > > > > > The worst-case of overloading always producing breakage can be ruled out; > the set of possible overloads can only include those that have SAM types > that are compatible with any of the overloads of Foo#bar . > > > > > > > > From there, resolution should proceed in the usual way (most specific > wins, or else the programmer must disambiguate.) > > > > > > > > In order for the worst ambiguities to arise, Foo.bar and the target > method must both be overloaded. Is this really that common of a case? Any > lesser ambiguities are the ones that can also arise with the lambda > parameter type inference that is already implemented. > > > > > > > > From brian.goetz at oracle.com Thu Aug 5 14:08:46 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 05 Aug 2010 17:08:46 -0400 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: References: Message-ID: <4C5B285E.6040103@oracle.com> It has been mentioned, but only on whiteboards so far :) We are for this reason considering #foo.bar() instead of #foo.bar. We are also considering a greedy prefix syntax instead of infix. On 8/5/2010 3:57 PM, Stephen Colebourne wrote: > No one has yet mentioned another danger with using Foo#bar instead of > Foo#bar(String). > > The former choice at this point closes off options in the future for Java. > > Foo#bar is the only sensible syntax for a field literal. Java can have > both fields and methods with the same name. This has the potential to > be a limitation to future language development. > > If there is a positive decision here today that field literals will > never be added (and that any future property literals will never > clash) then fine, but that seems like a strong statement at this > point. > > Stephen > > > On 5 August 2010 19:08, Nathan Bryant wrote: >> Kevin Bourrillion wrote: >> ? For example, if Foo#bar has no contextual smarts at all, then adding overload #2 of any method would always be source-incompatible (which would be hideous!). So how much intelligence does it have? >> >> >> >> The worst-case of overloading always producing breakage can be ruled out; the set of possible overloads can only include those that have SAM types that are compatible with any of the overloads of Foo#bar . >> >> >> >> From there, resolution should proceed in the usual way (most specific wins, or else the programmer must disambiguate.) >> >> >> >> In order for the worst ambiguities to arise, Foo.bar and the target method must both be overloaded. Is this really that common of a case? Any lesser ambiguities are the ones that can also arise with the lambda parameter type inference that is already implemented. >> >> >> > From forax at univ-mlv.fr Thu Aug 5 14:30:14 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Thu, 05 Aug 2010 23:30:14 +0200 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: References: Message-ID: <4C5B2D66.5090502@univ-mlv.fr> Le 05/08/2010 23:03, Paul Benedict a ?crit : > Good point Stephen. Parentheses should refer to methods, and without them to > fields. Your insight will definitely retain the separate namespaces that > Java has established. > > PS: Is Lambda also considering any support to turn method/field references > into java.lang.reflect types? > JSR 292 already adds support for instance field/static field references in the VM. The question is just, should they have a syntax in Java. R?mi From grev at miginfocom.com Thu Aug 5 14:31:30 2010 From: grev at miginfocom.com (Mikael Grev) Date: Thu, 5 Aug 2010 23:31:30 +0200 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: <4C5B285E.6040103@oracle.com> References: <4C5B285E.6040103@oracle.com> Message-ID: <17EA03CD-45E0-4534-BA72-0886FB5F2846@miginfocom.com> A really clear version would be #Foo.bar(...) Expressing clearly that anything goes as parameter. On Aug 5, 2010, at 23:08 PM, Brian Goetz wrote: > It has been mentioned, but only on whiteboards so far :) > > We are for this reason considering #foo.bar() instead of #foo.bar. We are > also considering a greedy prefix syntax instead of infix. > > On 8/5/2010 3:57 PM, Stephen Colebourne wrote: >> No one has yet mentioned another danger with using Foo#bar instead of >> Foo#bar(String). >> >> The former choice at this point closes off options in the future for Java. >> >> Foo#bar is the only sensible syntax for a field literal. Java can have >> both fields and methods with the same name. This has the potential to >> be a limitation to future language development. >> >> If there is a positive decision here today that field literals will >> never be added (and that any future property literals will never >> clash) then fine, but that seems like a strong statement at this >> point. >> >> Stephen >> >> >> On 5 August 2010 19:08, Nathan Bryant wrote: >>> Kevin Bourrillion wrote: >>> ? For example, if Foo#bar has no contextual smarts at all, then adding overload #2 of any method would always be source-incompatible (which would be hideous!). So how much intelligence does it have? >>> >>> >>> >>> The worst-case of overloading always producing breakage can be ruled out; the set of possible overloads can only include those that have SAM types that are compatible with any of the overloads of Foo#bar . >>> >>> >>> >>> From there, resolution should proceed in the usual way (most specific wins, or else the programmer must disambiguate.) >>> >>> >>> >>> In order for the worst ambiguities to arise, Foo.bar and the target method must both be overloaded. Is this really that common of a case? Any lesser ambiguities are the ones that can also arise with the lambda parameter type inference that is already implemented. >>> >>> >>> >> From pbenedict at apache.org Thu Aug 5 14:32:59 2010 From: pbenedict at apache.org (Paul Benedict) Date: Thu, 5 Aug 2010 16:32:59 -0500 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: <4C5B2D66.5090502@univ-mlv.fr> References: <4C5B2D66.5090502@univ-mlv.fr> Message-ID: My point is these two automatic conversions would be pretty cool. Just to continue Brian's example: interface Extractor { public U get(T t); } class Arrays { public > void sortBy(T[] array, Extractor extractor) { ... } } // automatic SAM conversion Arrays.sortBy(strings, String#length()); // automatic reflected method conversion java.lang.reflect.Method m = String#length(); Paul On Thu, Aug 5, 2010 at 4:30 PM, R?mi Forax wrote: > Le 05/08/2010 23:03, Paul Benedict a ?crit : > > Good point Stephen. Parentheses should refer to methods, and without them > to > > fields. Your insight will definitely retain the separate namespaces that > > Java has established. > > > > PS: Is Lambda also considering any support to turn method/field > references > > into java.lang.reflect types? > > > > JSR 292 already adds support for instance field/static field references > in the VM. > The question is just, should they have a syntax in Java. > > R?mi > > From forax at univ-mlv.fr Thu Aug 5 14:58:18 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Thu, 05 Aug 2010 23:58:18 +0200 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: References: <4C5B2D66.5090502@univ-mlv.fr> Message-ID: <4C5B33FA.9020904@univ-mlv.fr> Le 05/08/2010 23:32, Paul Benedict a ?crit : > My point is these two automatic conversions would be pretty cool. Just > to continue Brian's example: > > interface Extractor { > public U get(T t); > } > > class Arrays { > public > > void sortBy(T[] array, Extractor extractor) { ... } > } > > // automatic SAM conversion > Arrays.sortBy(strings, String#length()); > > // automatic reflected method conversion > java.lang.reflect.Method m = String#length(); > > Paul In fact, it will be something like java.dyn.MethodHandle mh = String#length(); and to invoke it int length; try { length = mh.invokeGeneric("foo"); } catch(WrongTypeException e) { // it's a runtime exception so you can forget it but // it's just to remember that this call is not typesafe ... } catch(Throwable t) { // you have also to deal with any exceptions // as previously said, this call is not typesafe ... } As you see the fact that you have to deal with exceptions like any reflection calls make this syntax not really attractive except if you are a developer of a dynamic language runtime or want to play with invokedynamic. It's better to create an interface like Brian does, in that case you don't loose the type safety: Extractor extractor = String#length(); int length = extractor.get(); Also note that even if you use an Integer in the signature, the VM is already able to not do the corresponding boxing (see one of the last mail of Fredrik on this list). R?mi > > On Thu, Aug 5, 2010 at 4:30 PM, R?mi Forax > wrote: > > Le 05/08/2010 23:03, Paul Benedict a ?crit : > > Good point Stephen. Parentheses should refer to methods, and > without them to > > fields. Your insight will definitely retain the separate > namespaces that > > Java has established. > > > > PS: Is Lambda also considering any support to turn method/field > references > > into java.lang.reflect types? > > > > JSR 292 already adds support for instance field/static field > references > in the VM. > The question is just, should they have a syntax in Java. > > R?mi > > From pbenedict at apache.org Thu Aug 5 14:59:45 2010 From: pbenedict at apache.org (Paul Benedict) Date: Thu, 5 Aug 2010 16:59:45 -0500 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: <4C5B33FA.9020904@univ-mlv.fr> References: <4C5B2D66.5090502@univ-mlv.fr> <4C5B33FA.9020904@univ-mlv.fr> Message-ID: On Thu, Aug 5, 2010 at 4:58 PM, R?mi Forax wrote: > In fact, it will be something like > > java.dyn.MethodHandle mh = String#length(); > > Okay, so I would add that too and allow three conversions. I don't think casting to reflected methods/fields should be forgotten. I understand why JSR-292 wants to MethodHandles -- that makes sense and I support it. But there is so much code today built around reflection, and being able to cast to those classes would be added value. // automatic SAM conversion Arrays.sortBy(strings, String#length()); // automatic reflected method conversion java.lang.reflect.Method m = String#length(); // automatic invokedynamic conversion java.dyn.MethodHandle mh = String#length(); Paul From nathan.bryant at linkshare.com Thu Aug 5 15:09:09 2010 From: nathan.bryant at linkshare.com (Nathan Bryant) Date: Fri, 6 Aug 2010 07:09:09 +0900 Subject: Method references with types [Re: lambda syntax tutorial] References: <4C5B2D66.5090502@univ-mlv.fr> <4C5B33FA.9020904@univ-mlv.fr> Message-ID: <7FDA6630E1822F448C97A48D5D733094014738ED@EXVMSTOR302.intra.rakuten.co.jp> Remi Forax wrote: > Also note that even if you use an Integer in the signature, the VM > is already able to not do the corresponding boxing > (see one of the last mail of Fredrik on this list). The PowerPoint I saw dealt with adding function types to the VM as basically a type annotation on MethodHandle, which would be renamed Function. (A proposal I support, as it makes MethodHandles a first class citizen, not something that is only really useful to compiler backend writers.) In this case, the compiler is able to remove the primitives. However, the more general box/unbox elimination optimization has not been implemented yet either in JDK7 or in any publically released version of JRockit. It also depends on the ability to inline. From maurizio.cimadamore at oracle.com Thu Aug 5 15:22:28 2010 From: maurizio.cimadamore at oracle.com (maurizio cimadamore) Date: Thu, 05 Aug 2010 23:22:28 +0100 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: <17EA03CD-45E0-4534-BA72-0886FB5F2846@miginfocom.com> References: <4C5B285E.6040103@oracle.com> <17EA03CD-45E0-4534-BA72-0886FB5F2846@miginfocom.com> Message-ID: <4C5B39A4.6070504@oracle.com> On 05/08/2010 22:31, Mikael Grev wrote: > A really clear version would be > > #Foo.bar(...) > That variant has also been considered - it has the clear advantage of not being ambiguous w.r.t. no-arg method references. Maurizio > Expressing clearly that anything goes as parameter. > > On Aug 5, 2010, at 23:08 PM, Brian Goetz wrote: > > >> It has been mentioned, but only on whiteboards so far :) >> >> We are for this reason considering #foo.bar() instead of #foo.bar. We are >> also considering a greedy prefix syntax instead of infix. >> >> On 8/5/2010 3:57 PM, Stephen Colebourne wrote: >> >>> No one has yet mentioned another danger with using Foo#bar instead of >>> Foo#bar(String). >>> >>> The former choice at this point closes off options in the future for Java. >>> >>> Foo#bar is the only sensible syntax for a field literal. Java can have >>> both fields and methods with the same name. This has the potential to >>> be a limitation to future language development. >>> >>> If there is a positive decision here today that field literals will >>> never be added (and that any future property literals will never >>> clash) then fine, but that seems like a strong statement at this >>> point. >>> >>> Stephen >>> >>> >>> On 5 August 2010 19:08, Nathan Bryant wrote: >>> >>>> Kevin Bourrillion wrote: >>>> ? For example, if Foo#bar has no contextual smarts at all, then adding overload #2 of any method would always be source-incompatible (which would be hideous!). So how much intelligence does it have? >>>> >>>> >>>> >>>> The worst-case of overloading always producing breakage can be ruled out; the set of possible overloads can only include those that have SAM types that are compatible with any of the overloads of Foo#bar . >>>> >>>> >>>> >>>> From there, resolution should proceed in the usual way (most specific wins, or else the programmer must disambiguate.) >>>> >>>> >>>> >>>> In order for the worst ambiguities to arise, Foo.bar and the target method must both be overloaded. Is this really that common of a case? Any lesser ambiguities are the ones that can also arise with the lambda parameter type inference that is already implemented. >>>> >>>> >>>> >>>> >>> > > From scolebourne at joda.org Thu Aug 5 15:59:40 2010 From: scolebourne at joda.org (Stephen Colebourne) Date: Thu, 5 Aug 2010 23:59:40 +0100 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: References: <4C5B2D66.5090502@univ-mlv.fr> <4C5B33FA.9020904@univ-mlv.fr> Message-ID: The complete set of conversions would be: // automatic SAM conversion to instance method from an expression str#length() assignable to interface IntProducer { int get(); } // automatic SAM conversion to instance method String#length() assignable to interface IntExtractor { int get(String); } // automatic SAM conversion to static method String#valueOf(int) assignable to interface IntFactory { String get(int); } // automatic SAM conversion to constructor Integer#l(String) assignable to interface IntegerFactory { Integer get(String); } // automatic reflected method conversion java.lang.reflect.Method m = String#length(); // automatic reflected constructor conversion java.lang.reflect.Constructor c = Integer#l(String); // automatic reflected field conversion java.lang.reflect.Field f = Person#lsurname; // automatic invokedynamic conversion java.dyn.MethodHandle mh = String#length(); as described in FCM https://docs.google.com/Doc?id=ddhp95vd_6hg3qhc many moons ago. Stephen On 5 August 2010 22:59, Paul Benedict wrote: > // automatic SAM conversion > Arrays.sortBy(strings, String#length()); > > // automatic reflected method conversion > java.lang.reflect.Method m = String#length(); > > // automatic invokedynamic conversion > java.dyn.MethodHandle mh = String#length(); > > Paul > > From scolebourne at joda.org Thu Aug 5 16:09:56 2010 From: scolebourne at joda.org (Stephen Colebourne) Date: Fri, 6 Aug 2010 00:09:56 +0100 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: <4C5B285E.6040103@oracle.com> References: <4C5B285E.6040103@oracle.com> Message-ID: On 5 August 2010 22:08, Brian Goetz wrote: > We are for this reason considering #foo.bar() instead of #foo.bar. ?We are > also considering a greedy prefix syntax instead of infix. I'm assuming these two sentences are independent, as I can't see why changing the syntax solves the problem (well, I can, but only in the sense of having method and field references look very different, which seems daft). As discussed in a previous thread, John, Josh and I will steer you strongly towards infix. The current prototype has got it right. I'd also note that Foo#bar(...) is acceptable to me, although it feels somewhat pointless. Stephen From howard.lovatt at gmail.com Thu Aug 5 17:05:45 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Fri, 6 Aug 2010 10:05:45 +1000 Subject: Method references with types [Re: lambda syntax tutorial] Message-ID: On 5 August 2010 22:08, Brian Goetz > wrote: >* We are for this reason considering #foo.bar() instead of #foo.bar. We are*>* also considering a greedy prefix syntax instead of infix.* I would favour the infix notation with compulsory types, to mimic the Javadoc notation. If the foo#bar(...) notation is added then ideally this notation would be added to Javadoc so that the two remain in sync. -- Howard. From howard.lovatt at gmail.com Thu Aug 5 17:24:01 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Fri, 6 Aug 2010 10:24:01 +1000 Subject: lambda syntax tutorial (3. Defender Methods) Message-ID: > 3. Defender Methods > ------------------- > > Defender methods are declared using the 'extension' keyword, as follows: > > extension List map(Mapper r) default Collections.listMapper; > > A defender method declaration is structured in two parts, (i) a method > signature, declaring formal arguments, formal type-arguments and > return-type and (ii) a default implementation, that is, the implementation > the method should default to if none is found in the class implementing > the extended interface. To be consistent with Javadoc and Method References I would suggest: extension List map(Mapper r) default Collections#listMapper; IE use a # instead of a . so that it is clear that it is a literal reference to a method and not a method call (as well as the consistency reason already mentioned). ? -- Howard. From brian.goetz at oracle.com Thu Aug 5 18:11:47 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 05 Aug 2010 21:11:47 -0400 Subject: lambda syntax tutorial (3. Defender Methods) In-Reply-To: References: Message-ID: <4C5B6153.4080109@oracle.com> > To be consistent with Javadoc and Method References I would suggest: > > extension List map(Mapper r) default Collections#listMapper; Ah, but that would only expose another inconsistency, which would surely result in the following question: "why can I use a method reference but not a lambda expression?" > IE use a # instead of a . so that it is clear that it is a literal > reference to a method and not a method call (as well as the > consistency reason already mentioned). From john at milsson.nu Thu Aug 5 18:54:59 2010 From: john at milsson.nu (John Nilsson) Date: Fri, 6 Aug 2010 03:54:59 +0200 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: References: <4C5B2D66.5090502@univ-mlv.fr> <4C5B33FA.9020904@univ-mlv.fr> Message-ID: On Fri, Aug 6, 2010 at 12:59 AM, Stephen Colebourne wrote: > The complete set of conversions would be: > [...] How about expressions? #String.length() + 2 #A.getB().getC() and even partiall application? #A.getB(2).getC() #A.getB(Integer).getC() BR, John From brian.goetz at oracle.com Thu Aug 5 19:17:47 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 05 Aug 2010 22:17:47 -0400 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: References: <4C5B2D66.5090502@univ-mlv.fr> <4C5B33FA.9020904@univ-mlv.fr> Message-ID: <4C5B70CB.7040703@oracle.com> Why? On 8/5/2010 9:54 PM, John Nilsson wrote: > On Fri, Aug 6, 2010 at 12:59 AM, Stephen Colebourne > wrote: >> The complete set of conversions would be: >> [...] > > How about expressions? > > #String.length() + 2 > > #A.getB().getC() > > and even partiall application? > > #A.getB(2).getC() > > #A.getB(Integer).getC() > > BR, > John > From howard.lovatt at gmail.com Thu Aug 5 19:26:06 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Fri, 6 Aug 2010 12:26:06 +1000 Subject: Method references with types [Re: lambda syntax tutorial] Message-ID: John Nilsson john at milsson.nu Thu Aug 5 18:54:59 PDT 2010 wrote: > On Fri, Aug 6, 2010 at 12:59 AM, Stephen Colebourne wrote: >> The complete set of conversions would be: >> [...] > > How about expressions? > > #String.length() + 2 > > #A.getB().getC() > > and even partiall application? > > #A.getB(2).getC() > > #A.getB(Integer).getC() Good reason to use the infix notation, then it doesn't look like a call and hence people won't expect an expression to be an option. ? -- Howard. From collin.fagan at gmail.com Thu Aug 5 19:28:56 2010 From: collin.fagan at gmail.com (Collin Fagan) Date: Thu, 5 Aug 2010 21:28:56 -0500 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: References: <4C5B285E.6040103@oracle.com> Message-ID: I did some experimenting with the different literals from FCM and I have say it removed unbelievable amounts of boilerplate code. http://java.dzone.com/news/experimenting-fcm Looking back I have to say one thing I didn't emphasize enough was how powerful this is when combined with generics. Basically one you write a ListModel that takes a method reference to you pretty much never have to write another one again. Once you build a TableModel that defines columns via methods refrences you never need to do it again. Here is an example: MethodRefrenceTableModel personModel = new MethodRefrenceTableModel<>(); // haha diamond operator! model.addColumn("First Name", Person#getFirstName()); model.addColumn("Last Name", Person#getLastName()); model.addColumn("Date Of Birth", Person#getDob()); MethodRefrenceTableModel planetModel = new MethodRefrenceTableModel<>(); model.addColumn("Name", Planet#getName()); model.addColumn("Size", Planet#getSize()); Now these are all Swing examples but the same idea applies to Apache Wicket or basically any other view technology. How about a comparator? Comparator firstNameFirst = new Comparator( Person#getFirstName(), Person#getLastName()); Comparator lastNameFirst = new Comparator( Person#getLastName(), Person#getFirstName()); JPA 2.0 generates a Metamodel which is very similar to a method reference. (OK two method references which make it more like a property.) http://docs.jboss.org/hibernate/jpamodelgen/1.0/reference/en-US/html_single/ It might look more like this with method references. CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder(); CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Person.class); Root person = criteriaQuery.from(Person.class); criteriaQuery.select(person).where(criteriaBuilder.equal(Person#getFirstName()), "Bob"); I know these examples are probably a bit blue collar but if it doesn't push too far outside the scope of this project I'd like to see thease type of use cases considered. Thanks, Collin On Thu, Aug 5, 2010 at 6:09 PM, Stephen Colebourne wrote: > On 5 August 2010 22:08, Brian Goetz wrote: > > We are for this reason considering #foo.bar() instead of #foo.bar. We > are > > also considering a greedy prefix syntax instead of infix. > > I'm assuming these two sentences are independent, as I can't see why > changing the syntax solves the problem (well, I can, but only in the > sense of having method and field references look very different, which > seems daft). > > As discussed in a previous thread, John, Josh and I will steer you > strongly towards infix. The current prototype has got it right. > > I'd also note that Foo#bar(...) is acceptable to me, although it feels > somewhat pointless. > > Stephen > > From howard.lovatt at gmail.com Thu Aug 5 19:35:37 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Fri, 6 Aug 2010 12:35:37 +1000 Subject: lambda syntax tutorial (3. Defender Methods) Message-ID: >> To be consistent with Javadoc and Method References I would suggest: >> >> extension List map(Mapper r) default Collections#listMapper; > > Ah, but that would only expose another inconsistency, which would surely > result in the following question: "why can I use a method reference but not a > lambda expression?" To which I would say, why not? extension List map(Mapper r) default #(r) { ... }; Looks good and useful to me. But you have to remember that I favour: List map(Mapper r) { ... } -- Howard :) From brian.goetz at oracle.com Thu Aug 5 19:30:44 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 05 Aug 2010 22:30:44 -0400 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: References: Message-ID: <4C5B73D4.1040908@oracle.com> For completeness: >> How about expressions? >> >> #String.length() + 2 Type error. >> #A.getB().getC() Greedy. Evaluate t=A.getB(), then evaluate to #t.getC(). >> and even partiall application? >> >> #A.getB(2).getC() Nope. >> #A.getB(Integer).getC() Nope. From scolebourne at joda.org Fri Aug 6 02:18:57 2010 From: scolebourne at joda.org (Stephen Colebourne) Date: Fri, 6 Aug 2010 10:18:57 +0100 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: <4C5B73D4.1040908@oracle.com> References: <4C5B73D4.1040908@oracle.com> Message-ID: On 6 August 2010 03:30, Brian Goetz wrote: >>> #A.getB().getC() > > Greedy. ?Evaluate t=A.getB(), then evaluate to #t.getC(). Huh? That is seriously confusing to read. Whereas A.getB()#getC() is a lot clearer in terms of what will be evaluated now and what captured. Stephen From peter.levart at marand.si Fri Aug 6 03:25:29 2010 From: peter.levart at marand.si (Peter Levart) Date: Fri, 6 Aug 2010 12:25:29 +0200 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: References: <4C5B285E.6040103@oracle.com> Message-ID: <201008061225.29510.peter.levart@marand.si> On 08/06/10, Stephen Colebourne wrote: > On 5 August 2010 22:08, Brian Goetz wrote: > > We are for this reason considering #foo.bar() instead of #foo.bar. We are > > also considering a greedy prefix syntax instead of infix. > > I'm assuming these two sentences are independent, as I can't see why > changing the syntax solves the problem (well, I can, but only in the > sense of having method and field references look very different, which > seems daft). > > As discussed in a previous thread, John, Josh and I will steer you > strongly towards infix. The current prototype has got it right. > > I'd also note that Foo#bar(...) is acceptable to me, although it feels > somewhat pointless. It is not. For example: class Foo { int bar() { return 0; } // 1st int bar(String s) { return s.length(); } // 2nd } // how do I select 1st method if Foo#bar() actualy means Foo#bar(...) ? Peter > > Stephen > > From scolebourne at joda.org Fri Aug 6 03:49:07 2010 From: scolebourne at joda.org (Stephen Colebourne) Date: Fri, 6 Aug 2010 11:49:07 +0100 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: <201008061225.29510.peter.levart@marand.si> References: <4C5B285E.6040103@oracle.com> <201008061225.29510.peter.levart@marand.si> Message-ID: On 6 August 2010 11:25, Peter Levart wrote: > On 08/06/10, Stephen Colebourne wrote: >> I'd also note that Foo#bar(...) is acceptable to me, although it feels >> somewhat pointless. > > It is not. For example: > > class Foo { > ?int bar() { return 0; } // 1st > ?int bar(String s) { return s.length(); } // 2nd > } > > // how do I select 1st method if Foo#bar() actualy means Foo#bar(...) ? Agreed. Foo#bar() implying any method named bar is never going to fly. My "pointless" comment was contrasting Foo#bar(...) to Foo#bar(String,Integer). Stephen From forax at univ-mlv.fr Fri Aug 6 08:03:39 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Fri, 06 Aug 2010 17:03:39 +0200 Subject: lambda syntax tutorial (3. Defender Methods) In-Reply-To: <4C5B6153.4080109@oracle.com> References: <4C5B6153.4080109@oracle.com> Message-ID: <4C5C244B.4080009@univ-mlv.fr> Le 06/08/2010 03:11, Brian Goetz a ?crit : >> To be consistent with Javadoc and Method References I would suggest: >> >> extension List map(Mapper r) default Collections#listMapper; >> > Ah, but that would only expose another inconsistency, which would surely > result in the following question: "why can I use a method reference but not a > lambda expression?" > perhaps because method reference is a kind of constant lambda. A constant lambda has the great property to be 'internable' (inserted in the bytecode) by the compiler. > >> IE use a # instead of a . so that it is clear that it is a literal >> reference to a method and not a method call (as well as the >> consistency reason already mentioned). >> R?mi From neal at gafter.com Fri Aug 6 08:15:15 2010 From: neal at gafter.com (Neal Gafter) Date: Fri, 6 Aug 2010 08:15:15 -0700 Subject: Fun with method references In-Reply-To: References: <4C59DC91.5090300@oracle.com> <4C59E066.6040807@oracle.com> <4C59E6D4.50104@univ-mlv.fr> <4C59E999.7070900@oracle.com> Message-ID: I made a typo. ?What I meant to say was "Its true that adding function types now would be better, but apparently resource and?time constraints prevent Oracle from doing everything at once." Adding SAMs now instead makes the transition to function types worse. Cheers, Neal On Thursday, August 5, 2010, Neal Gafter wrote: > On Thu, Aug 5, 2010 at 1:59 AM, Stephen Colebourne wrote: > > On 4 August 2010 23:49, Neal Gafter wrote: >> The more SAMs and SAM APIs you introduce, the worse you will make things for >> the language with function types later. ?While it is true that things are >> already bad, that is no justification for making them worse. > > Yes there are. About 10 milliion - the number of Java developers out > there. They need the best APIs they can get *now* not at some > intangible point in the future. From forax at univ-mlv.fr Fri Aug 6 08:30:36 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Fri, 06 Aug 2010 17:30:36 +0200 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: <7FDA6630E1822F448C97A48D5D733094014738ED@EXVMSTOR302.intra.rakuten.co.jp> References: <4C5B2D66.5090502@univ-mlv.fr> <4C5B33FA.9020904@univ-mlv.fr> <7FDA6630E1822F448C97A48D5D733094014738ED@EXVMSTOR302.intra.rakuten.co.jp> Message-ID: <4C5C2A9C.7040305@univ-mlv.fr> Le 06/08/2010 00:09, Nathan Bryant a ?crit : > > Remi Forax wrote: > > >> Also note that even if you use an Integer in the signature, the VM >> is already able to not do the corresponding boxing >> (see one of the last mail of Fredrik on this list). >> > The PowerPoint I saw dealt with adding function types to the VM as basically a type annotation on MethodHandle, which would be renamed Function. (A proposal I support, as it makes MethodHandles a first class citizen, not something that is only really useful to compiler backend writers.) > I was refering to the demo page 30 of the slides, This example in particular: Integer c = mh.invoke((Integer)3, 3); There is a boxing and this boxing can be removed because the method reference is declared with an int. MethodHandle by itself is not very useful in plain old Java because it's not typesafe. method handle is a kind of how the reflection API should have been done, so it's truly faster than reflection but like reflection it's not typesafe. I see lambda SAM conversion as a thin typesafe wrapper on top of method handle. We get the backward compatibility with most of the legacy code that deal with SAM types in the same move. But we lost function types during the battle :( > In this case, the compiler is able to remove the primitives. However, the more general box/unbox elimination optimization has not been implemented yet either in JDK7 or in any publically released version of JRockit. It also depends on the ability to inline. > jdk7 has escape analysis and you're right it depends if the callsite is monomorphic and inlinable. R?mi From forax at univ-mlv.fr Fri Aug 6 08:38:41 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Fri, 06 Aug 2010 17:38:41 +0200 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: <4C5B6C65.8090402@univ-mlv.fr> References: <4C5B2D66.5090502@univ-mlv.fr> <4C5B33FA.9020904@univ-mlv.fr> <4C5B6C65.8090402@univ-mlv.fr> Message-ID: <4C5C2C81.80101@univ-mlv.fr> Le 05/08/2010 23:59, Paul Benedict a ?crit : > On Thu, Aug 5, 2010 at 4:58 PM, R?mi Forax > wrote: > > In fact, it will be something like > > java.dyn.MethodHandle mh = String#length(); > > > Okay, so I would add that too and allow three conversions. I don't > think casting to reflected methods/fields should be forgotten. I > understand why JSR-292 wants to MethodHandles -- that makes sense and > I support it. But there is so much code today built around reflection, > and being able to cast to those classes would be added value. > > // automatic SAM conversion > Arrays.sortBy(strings, String#length()); > > // automatic reflected method conversion > java.lang.reflect.Method m = String#length(); > > // automatic invokedynamic conversion > java.dyn.MethodHandle mh = String#length(); > > Paul Paul, there is a secret plan to rewrite java.lang.Method and java.lang.Field using MethodHandle to do the plumbing. http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6824466 R?mi From pbenedict at apache.org Fri Aug 6 08:40:54 2010 From: pbenedict at apache.org (Paul Benedict) Date: Fri, 6 Aug 2010 10:40:54 -0500 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: <4C5C2C81.80101@univ-mlv.fr> References: <4C5B2D66.5090502@univ-mlv.fr> <4C5B33FA.9020904@univ-mlv.fr> <4C5B6C65.8090402@univ-mlv.fr> <4C5C2C81.80101@univ-mlv.fr> Message-ID: Remi, That's pretty cool!! Does supporting a conversion to java.lang.reflect types make a difference? I still think so because it's part of the public api, but what are your thoughts on it? Paul On Fri, Aug 6, 2010 at 10:38 AM, R?mi Forax wrote: > Le 05/08/2010 23:59, Paul Benedict a ?crit : > > On Thu, Aug 5, 2010 at 4:58 PM, R?mi Forax wrote: > >> In fact, it will be something like >> >> java.dyn.MethodHandle mh = String#length(); >> >> > Okay, so I would add that too and allow three conversions. I don't think > casting to reflected methods/fields should be forgotten. I understand why > JSR-292 wants to MethodHandles -- that makes sense and I support it. But > there is so much code today built around reflection, and being able to cast > to those classes would be added value. > > // automatic SAM conversion > Arrays.sortBy(strings, String#length()); > > // automatic reflected method conversion > java.lang.reflect.Method m = String#length(); > > // automatic invokedynamic conversion > java.dyn.MethodHandle mh = String#length(); > > Paul > > > Paul, > there is a secret plan to rewrite java.lang.Method and java.lang.Field > using MethodHandle to do the plumbing. > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6824466 > > R?mi > From opinali at gmail.com Fri Aug 6 08:42:18 2010 From: opinali at gmail.com (Osvaldo Doederlein) Date: Fri, 6 Aug 2010 12:42:18 -0300 Subject: new keyword 'extension' really necessary? In-Reply-To: <4C5B0E66.1020605@univ-mlv.fr> References: <4C59999E.8050609@oracle.com> <4C5AE7D9.7010403@googlemail.com> <4C5AEACF.4060803@oracle.com> <4C5B0E66.1020605@univ-mlv.fr> Message-ID: 2010/8/5 R?mi Forax : > Le 05/08/2010 20:25, Osvaldo Doederlein a ?crit : >> Extension methods are not allowed inside annotations, so I guess the >> implementation and spec issues are at least less severe, as >> disambiguation is trivial by the outer context being an annotation or >> not. Maybe it can't be completely handled by (simple) grammar changes, >> but that would be about it (it seems; correct me if that's wrong). > > In fact, there is no 'grammar' problem. > The local keyword 'extension' avoid to change too much the javac parser, > a hand written top-down recursive parser. > > But the real value is, as Brian says, that an extension method > is tagged with the local keyword 'extension'. > Easy to explain, easy to grasp. You imply that without 'extension', the syntax is hard to explain, hard to grasp. This is where I disagree. This verbose, DRY-violation syntax won't buy anything; 'default' is perfectly fine, I don't think programmers will be confused. Notice also that you assume that programmers want to make the association between the syntax and the feature name "extension method", but this name is just a convention and in some degree arbitrary - we could decide to use "defender method", or maybe even "default method" [in that case the 'default' is certainly sufficient ;-) ] Don't underestimate the ability of programmers to coalesce different, but correlated features, into a common abstract model (my comment below) with shared syntax. All programming languages do this all the time, in many different situations. For example, C++ famously uses "= 0" for abstract method declarations; when I was a C coder who started learning C++ I considered this pretty cool and natural, because zero/NULL is a very big concept in C/C++ (much more so than in Java with its well-behaved and restricted pointers, lack of function pointers etc.)... declaring "virtual void f() = 0" is intuitive, it recalls an explicit function pointer table that contains zero or NULL for that function, only concrete subclasses will have a similar table with a non-null pointer in the same slot. The learning C -> C++ convert will understand this even if not familiar with the structure of vtables, which are much more complex than the explicit function pointer tables that C programs would use for similar needs. >> And I think the similar style (same syntax for annotation defaults and >> for extension methods) is actually good. These are basically the same >> thing, in a very abstract level: a structure (interface or annotation) >> that has some feature (annotation field or method) which offers a >> default "value". >> >> > > R?mi > >> 2010/8/5 Brian Goetz: >> >>> In addition to Maurizio's syntactic arguments, we believe there is value in >>> identifying extension methods as, well, extension methods. >>> >> By the same logic, maybe we need an army of new redundant qualifiers >> such as "method", "field", etc.? >> >> (OTOH, we already have some redundant qualifiers - like 'abstract' for >> a method signature that's not followed by '{', or allowing 'private >> final' methods and 'public' interface methods, or 'final' for >> arguments in abstract method declarations. But I don't want more of >> the same.) >> >> A+ >> Osvaldo >> >> >>> On 8/5/2010 12:33 PM, Gernot Neppert wrote: >>> >>>> Hi Maurizio, >>>> >>>> I do not have compiler writing skils, so I'm curious why the keyword >>>> 'extension' should be nessesary to introduce defender methods. >>>> A defender method declaration without the prefix 'extension' looks quite >>>> distinguishable to me. Example: >>>> >>>> interface List >>>> { >>>> ? ? ? void sort(Comparator ? ?comp) default Collections.sort(List); >>>> } >>>> >>>> So, why the new keyword? >>>> >>>> (An answer such as 'This is necessary to disambiguate the grammar' would >>>> suffice...) >>>> >>>> >>>> >>>> >>> >>> >> > > > From mcnepp02 at googlemail.com Fri Aug 6 09:10:47 2010 From: mcnepp02 at googlemail.com (Gernot Neppert) Date: Fri, 06 Aug 2010 18:10:47 +0200 Subject: new keyword 'extension' really necessary? In-Reply-To: References: <4C59999E.8050609@oracle.com> <4C5AE7D9.7010403@googlemail.com> <4C5AEACF.4060803@oracle.com> <4C5B0E66.1020605@univ-mlv.fr> Message-ID: <4C5C3407.6030607@googlemail.com> Osvaldo Doederlein schrieb: > 2010/8/5 R?mi Forax : > >> Le 05/08/2010 20:25, Osvaldo Doederlein a ?crit : >> >>> Extension methods are not allowed inside annotations, so I guess the >>> implementation and spec issues are at least less severe, as >>> disambiguation is trivial by the outer context being an annotation or >>> not. Maybe it can't be completely handled by (simple) grammar changes, >>> but that would be about it (it seems; correct me if that's wrong). >>> >> In fact, there is no 'grammar' problem. >> The local keyword 'extension' avoid to change too much the javac parser, >> a hand written top-down recursive parser. >> >> But the real value is, as Brian says, that an extension method >> is tagged with the local keyword 'extension'. >> Easy to explain, easy to grasp. >> > > You imply that without 'extension', the syntax is hard to explain, > hard to grasp. This is where I disagree. This verbose, DRY-violation > syntax won't buy anything; 'default' is perfectly fine, I don't think > programmers will be confused. Notice also that you assume that > programmers want to make the association between the syntax and the > feature name "extension method", but this name is just a convention > and in some degree arbitrary - we could decide to use "defender > method", or maybe even "default method" [in that case the 'default' is > certainly sufficient ;-) ] > I think you have a good point here: the experts who came up with the idea of 'extension' have a certain perception of this new feature: For them, it shall only ever be used by so-called 'library developers' who will responsibly evolve existing interfaces. It seems they want to make sure that this view of theirs is somehow conveyed by the syntax. IMHO, that is a futile endeavour. People will use the new feature for whatever purpose comes to their minds. There will be no restriction to evolving Standard JDK interfaces. Technically, the new keyword 'extension' does not much sense. You can design an interface from scratch and make all methods 'extension methods' right from the beginning, e.g. for the sake of easier implementation by clients. Then, nothing is being 'extended'... From peter.levart at marand.si Fri Aug 6 09:57:36 2010 From: peter.levart at marand.si (Peter Levart) Date: Fri, 6 Aug 2010 18:57:36 +0200 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: References: Message-ID: <201008061857.36614.peter.levart@marand.si> While it would be nice if method reference expressions and lambda expressions could be directly convertible to "java.dyn.MethodHandle" and/or "java.lang.reflect.Method" objects, these two target types do not provide for static type-safety, parameter type inference and exception transparency from the language perspective. I don't know what the final compilation strategy is going to be for lambdas and method references, but it was suggested that they both would first be materialized as a MethodHandle and then this MH would be converted to target SAM instance using static method: MethodHandles.asSam(MethodHandle, Class) So instead of enabling direct conversion of method reference expressions and lambda expressions to MethodHandles and/or Methods, I propose that the target SAM instance returned from the MethodHandles.asSam method, in addition to implementing/extending the target SAM type, also conditionaly implements the following additional interfaces: // if converted from a lambda expression ... public interface MethodHandleReference { MethodHandle getTargetMethodHandle(); } // if converted from an unbound method reference expression (i.e. Foo#bar()) ... public interface MethodReference extends MethodHandleReference { Method getTargetMethod(); } // if converted from a bound method reference expression (i.e. someFoo#bar()) ... public interface BoundMethodReference extends MethodReference { T getBoundInstance(); MethodHandle getBoundMethodHandle(); } // if converted from a constructor reference expression (i.e. #new Foo()) public interface ConstructorReference extends MethodHandleReference { Constructor getTargetConstructor(); } ... these 4 interfaces could be treated in a special way when converting to SAM types. For example, with the following method definition: public doSomething(T sam) { ... } ... one could force the client of such API to only accept a method reference expression compatible with the particular SAM type. With such scheme you could get both worlds at the same time: static type-safeness and dynamic/reflective access. Regards, Peter On 08/06/10, Stephen Colebourne wrote: > The complete set of conversions would be: > > // automatic SAM conversion to instance method from an expression > str#length() > assignable to > interface IntProducer { int get(); } > > // automatic SAM conversion to instance method > String#length() > assignable to > interface IntExtractor { int get(String); } > > // automatic SAM conversion to static method > String#valueOf(int) > assignable to > interface IntFactory { String get(int); } > > // automatic SAM conversion to constructor > Integer#l(String) > assignable to > interface IntegerFactory { Integer get(String); } > > // automatic reflected method conversion > java.lang.reflect.Method m = String#length(); > > // automatic reflected constructor conversion > java.lang.reflect.Constructor c = Integer#l(String); > > // automatic reflected field conversion > java.lang.reflect.Field f = Person#lsurname; > > // automatic invokedynamic conversion > java.dyn.MethodHandle mh = String#length(); > > > as described in FCM https://docs.google.com/Doc?id=ddhp95vd_6hg3qhc > many moons ago. > > Stephen > > > > On 5 August 2010 22:59, Paul Benedict wrote: > > // automatic SAM conversion > > Arrays.sortBy(strings, String#length()); > > > > // automatic reflected method conversion > > java.lang.reflect.Method m = String#length(); > > > > // automatic invokedynamic conversion > > java.dyn.MethodHandle mh = String#length(); > > > > Paul > > > > > > From kevinb at google.com Fri Aug 6 10:05:56 2010 From: kevinb at google.com (Kevin Bourrillion) Date: Fri, 6 Aug 2010 10:05:56 -0700 Subject: Fun with method references In-Reply-To: References: <4C59DC91.5090300@oracle.com> <4C59E066.6040807@oracle.com> <4C59E6D4.50104@univ-mlv.fr> <4C59E999.7070900@oracle.com> Message-ID: On Fri, Aug 6, 2010 at 8:15 AM, Neal Gafter wrote: I made a typo. What I meant to say was "Its true that adding function > types now would be better, but apparently resource and time > constraints prevent Oracle from doing everything at once." > Of course -- and I'm really trying not to be inflammatory here, just note a fact lest it be forgotten -- some of us are very happy about that fact. -- Kevin Bourrillion @ Google http://guava-libraries.googlecode.com From kevinb at google.com Fri Aug 6 10:12:09 2010 From: kevinb at google.com (Kevin Bourrillion) Date: Fri, 6 Aug 2010 10:12:09 -0700 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: References: <4C5B73D4.1040908@oracle.com> Message-ID: I strongly agree. Having two nearby dots mean two completely different things... it's a trap. On Fri, Aug 6, 2010 at 2:18 AM, Stephen Colebourne wrote: > On 6 August 2010 03:30, Brian Goetz wrote: > >>> #A.getB().getC() > > > > Greedy. Evaluate t=A.getB(), then evaluate to #t.getC(). > > Huh? That is seriously confusing to read. > > Whereas A.getB()#getC() is a lot clearer in terms of what will be > evaluated now and what captured. > > Stephen > > -- Kevin Bourrillion @ Google http://guava-libraries.googlecode.com From forax at univ-mlv.fr Fri Aug 6 11:09:55 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Fri, 06 Aug 2010 20:09:55 +0200 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: References: <4C5B2D66.5090502@univ-mlv.fr> <4C5B33FA.9020904@univ-mlv.fr> <4C5B6C65.8090402@univ-mlv.fr> <4C5C2C81.80101@univ-mlv.fr> Message-ID: <4C5C4FF3.9040604@univ-mlv.fr> Le 06/08/2010 17:40, Paul Benedict a ?crit : > Remi, > > That's pretty cool!! Does supporting a conversion to java.lang.reflect > types make a difference? I still think so because it's part of the > public api, but what are your thoughts on it? There are lot of mismatches between method reference and java.lang.reflect.Method: java.lang.reflect.Method is a method that is not bound to a peculiar receiver, foo#bar() is a method reference which is bound to a receiver (foo). java.lang.reflect.Method represent a callee, a method that can be called, foo#bar() is a method reference, a call partially resolved. (e.g. foo#bar.getAnnotation() has no meaning). java.lang.reflect.Method checks security at each invocation, foo#bar checks security once when created. I let you draw your own conclusion :) > > Paul R?mi > > On Fri, Aug 6, 2010 at 10:38 AM, R?mi Forax > wrote: > > Le 05/08/2010 23:59, Paul Benedict a ?crit : >> On Thu, Aug 5, 2010 at 4:58 PM, R?mi Forax > > wrote: >> >> In fact, it will be something like >> >> java.dyn.MethodHandle mh = String#length(); >> >> >> Okay, so I would add that too and allow three conversions. I >> don't think casting to reflected methods/fields should be >> forgotten. I understand why JSR-292 wants to MethodHandles -- >> that makes sense and I support it. But there is so much code >> today built around reflection, and being able to cast to those >> classes would be added value. >> >> // automatic SAM conversion >> Arrays.sortBy(strings, String#length()); >> >> // automatic reflected method conversion >> java.lang.reflect.Method m = String#length(); >> >> // automatic invokedynamic conversion >> java.dyn.MethodHandle mh = String#length(); >> >> Paul > > Paul, > there is a secret plan to rewrite java.lang.Method and java.lang.Field > using MethodHandle to do the plumbing. > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6824466 > > R?mi > > From forax at univ-mlv.fr Fri Aug 6 11:11:01 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Fri, 06 Aug 2010 20:11:01 +0200 Subject: Fun with method references In-Reply-To: References: <4C59DC91.5090300@oracle.com> <4C59E066.6040807@oracle.com> <4C59E6D4.50104@univ-mlv.fr> <4C59E999.7070900@oracle.com> Message-ID: <4C5C5035.9060308@univ-mlv.fr> Le 06/08/2010 17:15, Neal Gafter a ?crit : > I made a typo. What I meant to say was "Its true that adding function > types now would be better, but apparently resource and time > constraints prevent Oracle from doing everything at once." > > Adding SAMs now instead makes the transition to function types worse. > > Cheers, > Neal > So what do you propose ? R?mi From brian.goetz at oracle.com Fri Aug 6 10:09:28 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Fri, 06 Aug 2010 13:09:28 -0400 Subject: new keyword 'extension' really necessary? In-Reply-To: <4C5C3407.6030607@googlemail.com> References: <4C59999E.8050609@oracle.com> <4C5AE7D9.7010403@googlemail.com> <4C5AEACF.4060803@oracle.com> <4C5B0E66.1020605@univ-mlv.fr> <4C5C3407.6030607@googlemail.com> Message-ID: <4C5C41C8.9010708@oracle.com> Guiding Principle 1 for the Java Language: Reading code is more important that writing code. Occasional DRY violations are perfectly allowed, and even encouraged, if they further this principle. DRY is not an end unto itself. Your opinion is noted, but I don't think there's any value in continuing this thread. We have far more important things to focus on, and "I don't like this syntax" discussions are tremendously distracting from the real goal, however well-intentioned they are. There is, however, tremendous value in you actually *trying* the prototype. Have you done that? I welcome everyone's experience with what has been built so far. On 8/6/2010 12:10 PM, Gernot Neppert wrote: > Osvaldo Doederlein schrieb: >> 2010/8/5 R?mi Forax: >> >>> Le 05/08/2010 20:25, Osvaldo Doederlein a ?crit : >>> >>>> Extension methods are not allowed inside annotations, so I guess the >>>> implementation and spec issues are at least less severe, as >>>> disambiguation is trivial by the outer context being an annotation or >>>> not. Maybe it can't be completely handled by (simple) grammar changes, >>>> but that would be about it (it seems; correct me if that's wrong). >>>> >>> In fact, there is no 'grammar' problem. >>> The local keyword 'extension' avoid to change too much the javac parser, >>> a hand written top-down recursive parser. >>> >>> But the real value is, as Brian says, that an extension method >>> is tagged with the local keyword 'extension'. >>> Easy to explain, easy to grasp. >>> >> >> You imply that without 'extension', the syntax is hard to explain, >> hard to grasp. This is where I disagree. This verbose, DRY-violation >> syntax won't buy anything; 'default' is perfectly fine, I don't think >> programmers will be confused. Notice also that you assume that >> programmers want to make the association between the syntax and the >> feature name "extension method", but this name is just a convention >> and in some degree arbitrary - we could decide to use "defender >> method", or maybe even "default method" [in that case the 'default' is >> certainly sufficient ;-) ] >> > > I think you have a good point here: > the experts who came up with the idea of 'extension' have a certain > perception of this new feature: > For them, it shall only ever be used by so-called 'library developers' > who will responsibly evolve existing interfaces. > It seems they want to make sure that this view of theirs is somehow > conveyed by the syntax. > > IMHO, that is a futile endeavour. People will use the new feature for > whatever purpose comes to their minds. There will be no restriction to > evolving Standard JDK interfaces. > > Technically, the new keyword 'extension' does not much sense. You can > design an interface from scratch and make all methods 'extension > methods' right from the beginning, e.g. for the sake of easier > implementation by clients. Then, nothing is being 'extended'... > > > > From collin.fagan at gmail.com Fri Aug 6 12:36:03 2010 From: collin.fagan at gmail.com (Collin Fagan) Date: Fri, 6 Aug 2010 14:36:03 -0500 Subject: Trying the prototype Message-ID: > Brian Goetz > There is, however, tremendous value in you actually *trying* the prototype. > Have you done that? I sir have not and would very much like to. Should I just get the latest openjdk build (103?) or does Project Lambda have it's own branch? Is there a page that walks me through compiling from source? thanks, Collin From nathan.bryant at linkshare.com Fri Aug 6 12:46:04 2010 From: nathan.bryant at linkshare.com (Nathan Bryant) Date: Sat, 7 Aug 2010 04:46:04 +0900 Subject: Method references with types [Re: lambda syntax tutorial] References: <4C5B2D66.5090502@univ-mlv.fr> <4C5B33FA.9020904@univ-mlv.fr> <7FDA6630E1822F448C97A48D5D733094014738ED@EXVMSTOR302.intra.rakuten.co.jp> <4C5C2A9C.7040305@univ-mlv.fr> Message-ID: <7FDA6630E1822F448C97A48D5D73309401473E4E@EXVMSTOR302.intra.rakuten.co.jp> R?mi, In the Scala microbenchmarks I was playing with most recently, I found some big performance loss in cases where the JVM couldn't remove boxing; this is in trivial, single-thread, monomorphic situations where I would have expected inlining to take place. Google searching has led me to believe the JVM has problems with Integer.valueOf() instead of new Integer(), but that is not enough to explain the results. So if optimizations are part of the argument against function types, I don't think the optimizations are quite there yet. I also found Java's collection traversals to be much faster than Scala's for the cases I tried. -----Original Message----- From: R?mi Forax [mailto:forax at univ-mlv.fr] Sent: Friday, August 06, 2010 11:31 AM To: Nathan Bryant Cc: Paul Benedict; lambda-dev at openjdk.java.net Subject: Re: Method references with types [Re: lambda syntax tutorial] Le 06/08/2010 00:09, Nathan Bryant a ?crit : > > Remi Forax wrote: > > >> Also note that even if you use an Integer in the signature, the VM >> is already able to not do the corresponding boxing >> (see one of the last mail of Fredrik on this list). >> > The PowerPoint I saw dealt with adding function types to the VM as basically a type annotation on MethodHandle, which would be renamed Function. (A proposal I support, as it makes MethodHandles a first class citizen, not something that is only really useful to compiler backend writers.) > I was refering to the demo page 30 of the slides, This example in particular: Integer c = mh.invoke((Integer)3, 3); There is a boxing and this boxing can be removed because the method reference is declared with an int. MethodHandle by itself is not very useful in plain old Java because it's not typesafe. method handle is a kind of how the reflection API should have been done, so it's truly faster than reflection but like reflection it's not typesafe. I see lambda SAM conversion as a thin typesafe wrapper on top of method handle. We get the backward compatibility with most of the legacy code that deal with SAM types in the same move. But we lost function types during the battle :( > In this case, the compiler is able to remove the primitives. However, the more general box/unbox elimination optimization has not been implemented yet either in JDK7 or in any publically released version of JRockit. It also depends on the ability to inline. > jdk7 has escape analysis and you're right it depends if the callsite is monomorphic and inlinable. R?mi From maurizio.cimadamore at oracle.com Fri Aug 6 12:54:29 2010 From: maurizio.cimadamore at oracle.com (maurizio cimadamore) Date: Fri, 06 Aug 2010 20:54:29 +0100 Subject: Trying the prototype In-Reply-To: References: Message-ID: <4C5C6875.3090105@oracle.com> On 06/08/2010 20:36, Collin Fagan wrote: >> Brian Goetz >> There is, however, tremendous value in you actually *trying* the >> > prototype. > >> Have you done that? >> > I sir have not and would very much like to. Should I just get the latest > openjdk build (103?) or does Project Lambda have it's own branch? Is there a > page that walks me through compiling from source? > > thanks, > > Collin > > Hi Collin thanks for your interest in project lambda. The easiest way to try the prototype is to have a JDK binary snapshot available (b103 or greater); you then need to do the following: 1) clone the 'langtools' repository of the lambda branch: hg clone http://hg.openjdk.java.net/lambda/lambda/langtools [this will create a new 'langtools' folder in your current folder] 2) build the compiler cd langtools/make ant -Dboot.java.home= -Dtarget.java.home= build-all-tools This should compile all tools (javac/javap/javah/javadoc/apt) and should result in a new folder called 'dist' under the 'langtools' folder. Inside 'dist' there is a subfolder named 'bin' - inside, you will find the executables for java/javac that should allow you to compile and execute code containing lambda expressions. [If you like NetBeans, there's a NB project under langtools/make - the project name is 'langtools' - once the project has been opened in the IDE, you can simply build everything by pressing F-11, or by selecting 'Build' from the project contexual menu... however ant options (-Dboot.java.home and -Dtarget.java.home) still need to be specified manually --- this can be done by accessing the menu under Tools->Options->Misc->Ant and by inserting the appropriate value in the text field at the bottom of the tab]. Maurizio From neal at gafter.com Fri Aug 6 13:02:46 2010 From: neal at gafter.com (Neal Gafter) Date: Fri, 6 Aug 2010 13:02:46 -0700 Subject: Fun with method references In-Reply-To: <4C5C5035.9060308@univ-mlv.fr> References: <4C59DC91.5090300@oracle.com> <4C59E066.6040807@oracle.com> <4C59E6D4.50104@univ-mlv.fr> <4C59E999.7070900@oracle.com> <4C5C5035.9060308@univ-mlv.fr> Message-ID: I propose that function types are higher priority than extension methods/defender methods. On Friday, August 6, 2010, R?mi Forax wrote: > Le 06/08/2010 17:15, Neal Gafter a ?crit : >> I made a typo. ?What I meant to say was "Its true that adding function >> types now would be better, but apparently resource and time >> constraints prevent Oracle from doing everything at once." >> >> Adding SAMs now instead makes the transition to function types worse. >> >> Cheers, >> Neal >> > > So what do you propose ? > > R?mi > > > From alex.buckley at oracle.com Fri Aug 6 13:06:38 2010 From: alex.buckley at oracle.com (Alex Buckley) Date: Fri, 06 Aug 2010 13:06:38 -0700 Subject: Fun with method references In-Reply-To: References: <4C59DC91.5090300@oracle.com> <4C59E066.6040807@oracle.com> <4C59E6D4.50104@univ-mlv.fr> <4C59E999.7070900@oracle.com> <4C5C5035.9060308@univ-mlv.fr> Message-ID: <4C5C6B4E.2050702@oracle.com> Proposal rejected. Alex On 8/6/2010 1:02 PM, Neal Gafter wrote: > I propose that function types are higher priority than extension > methods/defender methods. > > On Friday, August 6, 2010, R?mi Forax wrote: >> Le 06/08/2010 17:15, Neal Gafter a ?crit : >>> I made a typo. What I meant to say was "Its true that adding function >>> types now would be better, but apparently resource and time >>> constraints prevent Oracle from doing everything at once." >>> >>> Adding SAMs now instead makes the transition to function types worse. >>> >>> Cheers, >>> Neal >>> >> So what do you propose ? >> >> R?mi >> >> >> > From collin.fagan at gmail.com Fri Aug 6 13:08:16 2010 From: collin.fagan at gmail.com (Collin Fagan) Date: Fri, 6 Aug 2010 15:08:16 -0500 Subject: Trying the prototype In-Reply-To: <4C5C6875.3090105@oracle.com> References: <4C5C6875.3090105@oracle.com> Message-ID: Wow quick response. :) Thank you On Fri, Aug 6, 2010 at 2:54 PM, maurizio cimadamore < maurizio.cimadamore at oracle.com> wrote: > On 06/08/2010 20:36, Collin Fagan wrote: > >> Brian Goetz >>> There is, however, tremendous value in you actually *trying* the >>> >>> >> prototype. >> >> >>> Have you done that? >>> >>> >> I sir have not and would very much like to. Should I just get the latest >> openjdk build (103?) or does Project Lambda have it's own branch? Is there >> a >> page that walks me through compiling from source? >> >> thanks, >> >> Collin >> >> >> > Hi Collin > thanks for your interest in project lambda. The easiest way to try the > prototype is to have a JDK binary snapshot available (b103 or greater); you > then need to do the following: > > 1) clone the 'langtools' repository of the lambda branch: > > hg clone http://hg.openjdk.java.net/lambda/lambda/langtools > > [this will create a new 'langtools' folder in your current folder] > > 2) build the compiler > > cd langtools/make > > ant -Dboot.java.home= -Dtarget.java.home= > build-all-tools > > This should compile all tools (javac/javap/javah/javadoc/apt) and should > result in a new folder called 'dist' under the 'langtools' folder. Inside > 'dist' there is a subfolder named 'bin' - inside, you will find the > executables for java/javac that should allow you to compile and execute code > containing lambda expressions. > > [If you like NetBeans, there's a NB project under langtools/make - the > project name is 'langtools' - once the project has been opened in the IDE, > you can simply build everything by pressing F-11, or by selecting 'Build' > from the project contexual menu... however ant options (-Dboot.java.home and > -Dtarget.java.home) still need to be specified manually --- this can be done > by accessing the menu under Tools->Options->Misc->Ant and by inserting the > appropriate value in the text field at the bottom of the tab]. > > Maurizio > > > From pbenedict at apache.org Fri Aug 6 13:16:52 2010 From: pbenedict at apache.org (Paul Benedict) Date: Fri, 6 Aug 2010 15:16:52 -0500 Subject: Fun with method references In-Reply-To: <4C5C6B4E.2050702@oracle.com> References: <4C59DC91.5090300@oracle.com> <4C59E066.6040807@oracle.com> <4C59E6D4.50104@univ-mlv.fr> <4C59E999.7070900@oracle.com> <4C5C5035.9060308@univ-mlv.fr> <4C5C6B4E.2050702@oracle.com> Message-ID: Alex, would you mind elaborating a little on your answer for the benefit of the community? I am at least interested on what your thoughts are. Paul On Fri, Aug 6, 2010 at 3:06 PM, Alex Buckley wrote: > Proposal rejected. > > Alex > > On 8/6/2010 1:02 PM, Neal Gafter wrote: > > I propose that function types are higher priority than extension > > methods/defender methods. > > > > On Friday, August 6, 2010, R?mi Forax wrote: > >> Le 06/08/2010 17:15, Neal Gafter a ?crit : > >>> I made a typo. What I meant to say was "Its true that adding function > >>> types now would be better, but apparently resource and time > >>> constraints prevent Oracle from doing everything at once." > >>> > >>> Adding SAMs now instead makes the transition to function types worse. > >>> > >>> Cheers, > >>> Neal > >>> > >> So what do you propose ? > >> > >> R?mi > >> > >> > >> > > > > From nathan.bryant at linkshare.com Fri Aug 6 13:20:04 2010 From: nathan.bryant at linkshare.com (Nathan Bryant) Date: Sat, 7 Aug 2010 05:20:04 +0900 Subject: Fun with method references References: <4C59DC91.5090300@oracle.com><4C59E066.6040807@oracle.com> <4C59E6D4.50104@univ-mlv.fr><4C59E999.7070900@oracle.com> Message-ID: <7FDA6630E1822F448C97A48D5D73309401473E9C@EXVMSTOR302.intra.rakuten.co.jp> It also makes the transition to reified generics worse, by adding new non-reified types to the standard library. Neal Gafter wrote: > Adding SAMs now instead makes the transition to function types worse. From brian.goetz at oracle.com Fri Aug 6 13:22:06 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Fri, 06 Aug 2010 16:22:06 -0400 Subject: Fun with method references In-Reply-To: <7FDA6630E1822F448C97A48D5D73309401473E9C@EXVMSTOR302.intra.rakuten.co.jp> References: <4C59DC91.5090300@oracle.com><4C59E066.6040807@oracle.com> <4C59E6D4.50104@univ-mlv.fr><4C59E999.7070900@oracle.com> <7FDA6630E1822F448C97A48D5D73309401473E9C@EXVMSTOR302.intra.rakuten.co.jp> Message-ID: <4C5C6EEE.5010803@oracle.com> Adding non-reified function types would be even worse in that regard. On 8/6/2010 4:20 PM, Nathan Bryant wrote: > It also makes the transition to reified generics worse, by adding new > non-reified types to the standard library. > > Neal Gafter wrote: >> Adding SAMs now instead makes the transition to function types worse. > > From nathan.bryant at linkshare.com Fri Aug 6 13:26:36 2010 From: nathan.bryant at linkshare.com (Nathan Bryant) Date: Sat, 7 Aug 2010 05:26:36 +0900 Subject: Fun with method references References: <4C59DC91.5090300@oracle.com><4C59E066.6040807@oracle.com> <4C59E6D4.50104@univ-mlv.fr><4C59E999.7070900@oracle.com> <7FDA6630E1822F448C97A48D5D73309401473E9C@EXVMSTOR302.intra.rakuten.co.jp> <4C5C6EEE.5010803@oracle.com> Message-ID: <7FDA6630E1822F448C97A48D5D73309401473EAC@EXVMSTOR302.intra.rakuten.co.jp> I'd thought that MethodHandles were type checked at runtime, and that function types built on top of them could also express primitives. Perhaps you are reacting to the "round trip through generics" aspect of the presentation that's recently been referred to, or that some of the proposals to date have implemented function types as translation to generic SAMs named Function0, Function1, etc. But surely this is not the only possible implementation choice. -----Original Message----- From: Brian Goetz [mailto:brian.goetz at oracle.com] Sent: Friday, August 06, 2010 4:22 PM To: Nathan Bryant Cc: Neal Gafter; lambda-dev at openjdk.java.net Subject: Re: Fun with method references Adding non-reified function types would be even worse in that regard. On 8/6/2010 4:20 PM, Nathan Bryant wrote: > It also makes the transition to reified generics worse, by adding new > non-reified types to the standard library. > > Neal Gafter wrote: >> Adding SAMs now instead makes the transition to function types worse. > > From brian.goetz at oracle.com Fri Aug 6 13:44:50 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Fri, 06 Aug 2010 16:44:50 -0400 Subject: Fun with method references In-Reply-To: <7FDA6630E1822F448C97A48D5D73309401473EAC@EXVMSTOR302.intra.rakuten.co.jp> References: <4C59DC91.5090300@oracle.com><4C59E066.6040807@oracle.com> <4C59E6D4.50104@univ-mlv.fr><4C59E999.7070900@oracle.com> <7FDA6630E1822F448C97A48D5D73309401473E9C@EXVMSTOR302.intra.rakuten.co.jp> <4C5C6EEE.5010803@oracle.com> <7FDA6630E1822F448C97A48D5D73309401473EAC@EXVMSTOR302.intra.rakuten.co.jp> Message-ID: <4C5C7442.80406@oracle.com> They are type checked at runtime, making them dynamically type-safe. However, both generics and MHs have the problem that you could not overload methods whose arguments are function types; since under either scheme foo({ String => int } stringHandler) { ... } foo({ Bar => int } barHandler { ... } could not be overloaded since they would have the same erasure. But users would find it a very confusing restriction (especially if the scheme did permit overloading on arity, as some function-to-generics mappings permit.) This restriction really makes surfacing function types a non-starter at this point. On 8/6/2010 4:26 PM, Nathan Bryant wrote: > I'd thought that MethodHandles were type checked at runtime, and that > function types built on top of them could also express primitives. > > Perhaps you are reacting to the "round trip through generics" aspect of > the presentation that's recently been referred to, or that some of the > proposals to date have implemented function types as translation to > generic SAMs named Function0, Function1, etc. But surely this is not the > only possible implementation choice. > > -----Original Message----- > From: Brian Goetz [mailto:brian.goetz at oracle.com] > Sent: Friday, August 06, 2010 4:22 PM > To: Nathan Bryant > Cc: Neal Gafter; lambda-dev at openjdk.java.net > Subject: Re: Fun with method references > > Adding non-reified function types would be even worse in that regard. > > On 8/6/2010 4:20 PM, Nathan Bryant wrote: >> It also makes the transition to reified generics worse, by adding new >> non-reified types to the standard library. >> >> Neal Gafter wrote: >>> Adding SAMs now instead makes the transition to function types worse. >> >> From forax at univ-mlv.fr Fri Aug 6 14:19:46 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Fri, 06 Aug 2010 23:19:46 +0200 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: <7FDA6630E1822F448C97A48D5D73309401473E4E@EXVMSTOR302.intra.rakuten.co.jp> References: <4C5B2D66.5090502@univ-mlv.fr> <4C5B33FA.9020904@univ-mlv.fr> <7FDA6630E1822F448C97A48D5D733094014738ED@EXVMSTOR302.intra.rakuten.co.jp> <4C5C2A9C.7040305@univ-mlv.fr> <7FDA6630E1822F448C97A48D5D73309401473E4E@EXVMSTOR302.intra.rakuten.co.jp> Message-ID: <4C5C7C72.5040504@univ-mlv.fr> Le 06/08/2010 21:46, Nathan Bryant a ?crit : > R?mi, > > In the Scala microbenchmarks I was playing with most recently, I found some big performance loss in cases where the JVM couldn't remove boxing; this is in trivial, single-thread, monomorphic situations where I would have expected inlining to take place. I'm not a scala god but it seems that most of the scala loops are megamorphic. > Google searching has led me to believe the JVM has problems with Integer.valueOf() instead of new Integer(), but that is not enough to explain the results. So if optimizations are part of the argument against function types, I don't think the optimizations are quite there yet. > That's weird, there is a special trick in the VM to handle Integer.valueOf() see in opto/memnode.cpp, the function named eliminate_autobox. > I also found Java's collection traversals to be much faster than Scala's for the cases I tried. > R?mi > -----Original Message----- > From: R?mi Forax [mailto:forax at univ-mlv.fr] > Sent: Friday, August 06, 2010 11:31 AM > To: Nathan Bryant > Cc: Paul Benedict; lambda-dev at openjdk.java.net > Subject: Re: Method references with types [Re: lambda syntax tutorial] > > Le 06/08/2010 00:09, Nathan Bryant a ?crit : > >> Remi Forax wrote: >> >> >> >>> Also note that even if you use an Integer in the signature, the VM >>> is already able to not do the corresponding boxing >>> (see one of the last mail of Fredrik on this list). >>> >>> >> The PowerPoint I saw dealt with adding function types to the VM as basically a type annotation on MethodHandle, which would be renamed Function. (A proposal I support, as it makes MethodHandles a first class citizen, not something that is only really useful to compiler backend writers.) >> >> > I was refering to the demo page 30 of the slides, > This example in particular: > Integer c = mh.invoke((Integer)3, 3); > There is a boxing and this boxing can be removed because > the method reference is declared with an int. > > MethodHandle by itself is not very useful in plain old Java because it's > not typesafe. > method handle is a kind of how the reflection API should have been done, > so it's truly faster than reflection but like reflection it's not typesafe. > > I see lambda SAM conversion as a thin typesafe wrapper on top of method > handle. > We get the backward compatibility with most of the legacy code > that deal with SAM types in the same move. > But we lost function types during the battle :( > > >> In this case, the compiler is able to remove the primitives. However, the more general box/unbox elimination optimization has not been implemented yet either in JDK7 or in any publically released version of JRockit. It also depends on the ability to inline. >> >> > jdk7 has escape analysis and you're right it depends if the callsite is > monomorphic and inlinable. > > R?mi > From forax at univ-mlv.fr Fri Aug 6 14:48:32 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Fri, 06 Aug 2010 23:48:32 +0200 Subject: Fun with method references In-Reply-To: <4C5C7442.80406@oracle.com> References: <4C59DC91.5090300@oracle.com><4C59E066.6040807@oracle.com> <4C59E6D4.50104@univ-mlv.fr><4C59E999.7070900@oracle.com> <7FDA6630E1822F448C97A48D5D73309401473E9C@EXVMSTOR302.intra.rakuten.co.jp> <4C5C6EEE.5010803@oracle.com> <7FDA6630E1822F448C97A48D5D73309401473EAC@EXVMSTOR302.intra.rakuten.co.jp> <4C5C7442.80406@oracle.com> Message-ID: <4C5C8330.3010608@univ-mlv.fr> Le 06/08/2010 22:44, Brian Goetz a ?crit : > They are type checked at runtime, making them dynamically type-safe. However, > both generics and MHs have the problem that you could not overload methods > whose arguments are function types; since under either scheme > > foo({ String => int } stringHandler) { ... } > foo({ Bar => int } barHandler { ... } > > could not be overloaded since they would have the same erasure. But users > would find it a very confusing restriction (especially if the scheme did > permit overloading on arity, as some function-to-generics mappings permit.) > > This restriction really makes surfacing function types a non-starter at this > point. > Not a good example, in my opinion. using SAM interfaces instead: interface Foo1 {...} interface Foo2 {...} void foo(Foo1 foo) { ... } void foo(Foo2 foo) { ... } Having two overload methods with interfaces is a notorious poor design. You will always find someone that create a class that implement both interfaces. I have seen more than once a code containing a class implementing Callable *and* Runnable and trying to submit an object implementing that class to an executor service. The funny thing with this example is that the developer have to choose if he want to receive a Future or a Future. R?mi From forax at univ-mlv.fr Fri Aug 6 15:01:30 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Sat, 07 Aug 2010 00:01:30 +0200 Subject: Fun with method references In-Reply-To: <4C5C8330.3010608@univ-mlv.fr> References: <4C59DC91.5090300@oracle.com><4C59E066.6040807@oracle.com> <4C59E6D4.50104@univ-mlv.fr><4C59E999.7070900@oracle.com> <7FDA6630E1822F448C97A48D5D73309401473E9C@EXVMSTOR302.intra.rakuten.co.jp> <4C5C6EEE.5010803@oracle.com> <7FDA6630E1822F448C97A48D5D73309401473EAC@EXVMSTOR302.intra.rakuten.co.jp> <4C5C7442.80406@oracle.com> <4C5C8330.3010608@univ-mlv.fr> Message-ID: <4C5C863A.7040505@univ-mlv.fr> Le 06/08/2010 23:48, R?mi Forax a ?crit : > Le 06/08/2010 22:44, Brian Goetz a ?crit : > >> They are type checked at runtime, making them dynamically type-safe. However, >> both generics and MHs have the problem that you could not overload methods >> whose arguments are function types; since under either scheme >> >> foo({ String => int } stringHandler) { ... } >> foo({ Bar => int } barHandler { ... } >> >> could not be overloaded since they would have the same erasure. But users >> would find it a very confusing restriction (especially if the scheme did >> permit overloading on arity, as some function-to-generics mappings permit.) >> >> This restriction really makes surfacing function types a non-starter at this >> point. >> >> > or worst interface Handler { public int handle(A a); } void foo(Handler stringHandler) { ... } void foo(Handler barHandler) { ... } which exhibits exactly the same erasure problem. R?mi > Not a good example, in my opinion. > using SAM interfaces instead: > > interface Foo1 {...} > interface Foo2 {...} > > void foo(Foo1 foo) { ... } > void foo(Foo2 foo) { ... } > > Having two overload methods with interfaces is a notorious poor design. > You will always find someone that create a class that implement both > interfaces. > > I have seen more than once a code containing a class implementing > Callable *and* Runnable > and trying to submit an object implementing that class to an executor > service. > The funny thing with this example is that the developer have to choose > if he want to receive > a Future or a Future. > > R?mi > > From nathan.bryant at linkshare.com Fri Aug 6 15:55:40 2010 From: nathan.bryant at linkshare.com (Nathan Bryant) Date: Sat, 7 Aug 2010 07:55:40 +0900 Subject: Method references with types [Re: lambda syntax tutorial] References: <4C5B2D66.5090502@univ-mlv.fr> <4C5B33FA.9020904@univ-mlv.fr> <7FDA6630E1822F448C97A48D5D733094014738ED@EXVMSTOR302.intra.rakuten.co.jp> <4C5C2A9C.7040305@univ-mlv.fr> <7FDA6630E1822F448C97A48D5D73309401473E4E@EXVMSTOR302.intra.rakuten.co.jp> <4C5C7C72.5040504@univ-mlv.fr> Message-ID: <7FDA6630E1822F448C97A48D5D73309401473F9E@EXVMSTOR302.intra.rakuten.co.jp> -----Original Message----- From: R?mi Forax [mailto:forax at univ-mlv.fr] > I'm not a scala god but it seems that most of the scala loops are > megamorphic. Not if I explicitly write my own dirty combinators to exclude that problem, or only call each one once in a specific benchmark. Well this discussion is rapidly becoming academic; there will be no function types. From howard.lovatt at gmail.com Fri Aug 6 19:13:46 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Sat, 7 Aug 2010 12:13:46 +1000 Subject: Fun with method references Message-ID: @R?mi, > Not a good example, in my opinion. > using SAM interfaces instead: > > interface Foo1 {...} > interface Foo2 {...} > > void foo(Foo1 foo) { ... } > void foo(Foo2 foo) { ... } But this is easily resolved with a cast > interface Handler { > public int handle(A a); > } > > void foo(Handler stringHandler) { ... } > void foo(Handler barHandler) { ... } This is the exactly the same problem that happens with erased function types and I assume that we don't want is more of these problems. The only way out of this problem for function types (and generics) is to reify them: http://www.artima.com/weblogs/viewpost.jsp?thread=278567 -- Howard. From john at milsson.nu Fri Aug 6 19:36:09 2010 From: john at milsson.nu (John Nilsson) Date: Sat, 7 Aug 2010 04:36:09 +0200 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: <4C5B73D4.1040908@oracle.com> References: <4C5B73D4.1040908@oracle.com> Message-ID: On Fri, Aug 6, 2010 at 4:30 AM, Brian Goetz wrote: > For completeness: > >>> How about expressions? >>> >>> #String.length() + 2 > > Type error. > >>> #A.getB().getC() > > Greedy. ?Evaluate t=A.getB(), then evaluate to #t.getC(). If this is greedy, shouldn't the above example also be greedy? I.e. t=String.length(), then t+2 I was kind of hoping for arbitrary expressions. So that it would rather be intepreted as #(String s){s.length()+2} BR, John From john at milsson.nu Fri Aug 6 19:52:10 2010 From: john at milsson.nu (John Nilsson) Date: Sat, 7 Aug 2010 04:52:10 +0200 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: <4C5B70CB.7040703@oracle.com> References: <4C5B2D66.5090502@univ-mlv.fr> <4C5B33FA.9020904@univ-mlv.fr> <4C5B70CB.7040703@oracle.com> Message-ID: Completness I guess. If a short hand for method calling wrappers is provided. The shorthand should also allow method chaining and if method chaining is support, why not arbitrary expressions? Again, I'm thinking about the use case of declaring property lists to extract from a collection. I want to replace this printAsCsv(customerList,"customerNo","name.first","name.last", "age"); with something type-safe, still easy to to read and hopefully not add any boilerplate. BR, John On Fri, Aug 6, 2010 at 4:17 AM, Brian Goetz wrote: > Why? > > On 8/5/2010 9:54 PM, John Nilsson wrote: >> >> On Fri, Aug 6, 2010 at 12:59 AM, Stephen Colebourne >> ?wrote: >>> >>> The complete set of conversions would be: >>> [...] >> >> How about expressions? >> >> #String.length() + 2 >> >> #A.getB().getC() >> >> and even partiall application? >> >> #A.getB(2).getC() >> >> #A.getB(Integer).getC() >> >> BR, >> John >> > From neal at gafter.com Fri Aug 6 20:11:04 2010 From: neal at gafter.com (Neal Gafter) Date: Fri, 6 Aug 2010 22:11:04 -0500 Subject: Fun with method references In-Reply-To: References: Message-ID: <54E6FF76-C49B-4976-ACA8-905DFAF0DF70@gafter.com> Why are you sending pointers to a proposal that has been shown to be unsound? -Neal On Aug 6, 2010, at 9:13 PM, Howard Lovatt wrote: > @R?mi, > >> Not a good example, in my opinion. >> using SAM interfaces instead: >> >> interface Foo1 {...} >> interface Foo2 {...} >> >> void foo(Foo1 foo) { ... } >> void foo(Foo2 foo) { ... } > > But this is easily resolved with a cast > >> interface Handler { >> public int handle(A a); >> } >> >> void foo(Handler stringHandler) { ... } >> void foo(Handler barHandler) { ... } > > This is the exactly the same problem that happens with erased function types > and I assume that we don't want is more of these problems. The only way out > of this problem for function types (and generics) is to reify them: > > http://www.artima.com/weblogs/viewpost.jsp?thread=278567 > > -- Howard. > From brian.goetz at oracle.com Fri Aug 6 20:16:40 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Fri, 6 Aug 2010 23:16:40 -0400 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: References: <4C5B73D4.1040908@oracle.com> Message-ID: <1DAADB37-C99B-48CA-B823-FF60AC8B7A88@oracle.com> You can have arbitrary expressions: to get what you want, just insert some braces: #{ s -> s.length() + 2 } On Aug 6, 2010, at 10:36 PM, John Nilsson wrote: > On Fri, Aug 6, 2010 at 4:30 AM, Brian Goetz wrote: >> For completeness: >> >>>> How about expressions? >>>> >>>> #String.length() + 2 >> >> Type error. >> >>>> #A.getB().getC() >> >> Greedy. Evaluate t=A.getB(), then evaluate to #t.getC(). > > If this is greedy, shouldn't the above example also be greedy? I.e. > t=String.length(), then t+2 > > I was kind of hoping for arbitrary expressions. So that it would > rather be intepreted as #(String s){s.length()+2} > > BR, > John From brian.goetz at oracle.com Fri Aug 6 20:13:55 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Fri, 6 Aug 2010 23:13:55 -0400 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: References: <4C5B73D4.1040908@oracle.com> Message-ID: <04A6DD74-E36E-4FAA-8346-73B9DE8C4F44@oracle.com> You can have arbitrary expressions: to get what you want, just insert some braces: #{ s -> s.length() + 2 } On Aug 6, 2010, at 10:36 PM, John Nilsson wrote: > On Fri, Aug 6, 2010 at 4:30 AM, Brian Goetz wrote: >> For completeness: >> >>>> How about expressions? >>>> >>>> #String.length() + 2 >> >> Type error. >> >>>> #A.getB().getC() >> >> Greedy. Evaluate t=A.getB(), then evaluate to #t.getC(). > > If this is greedy, shouldn't the above example also be greedy? I.e. > t=String.length(), then t+2 > > I was kind of hoping for arbitrary expressions. So that it would > rather be intepreted as #(String s){s.length()+2} > > BR, > John From howard.lovatt at gmail.com Fri Aug 6 20:50:34 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Sat, 7 Aug 2010 13:50:34 +1000 Subject: Fun with method references In-Reply-To: <54E6FF76-C49B-4976-ACA8-905DFAF0DF70@gafter.com> References: <54E6FF76-C49B-4976-ACA8-905DFAF0DF70@gafter.com> Message-ID: The area that I didn't solve was arrays of function types, I could only do these by erasing the type (i.e. non-reified). Since all the proposals have this problem of erased function types in arrays, including BGGA, I think the characterisation 'unsound' is a tad strong. Or are you saying that all function type proposals, including BGGA, are unsound? On 7 August 2010 13:11, Neal Gafter wrote: > Why are you sending pointers to a proposal that has been shown to be > unsound? > > -Neal > > On Aug 6, 2010, at 9:13 PM, Howard Lovatt wrote: > > > @R?mi, > > > >> Not a good example, in my opinion. > >> using SAM interfaces instead: > >> > >> interface Foo1 {...} > >> interface Foo2 {...} > >> > >> void foo(Foo1 foo) { ... } > >> void foo(Foo2 foo) { ... } > > > > But this is easily resolved with a cast > > > >> interface Handler { > >> public int handle(A a); > >> } > >> > >> void foo(Handler stringHandler) { ... } > >> void foo(Handler barHandler) { ... } > > > > This is the exactly the same problem that happens with erased function > types > > and I assume that we don't want is more of these problems. The only way > out > > of this problem for function types (and generics) is to reify them: > > > > http://www.artima.com/weblogs/viewpost.jsp?thread=278567 > > > > -- Howard. > > > -- -- Howard. From thomas.andreas.jung at googlemail.com Sat Aug 7 00:58:52 2010 From: thomas.andreas.jung at googlemail.com (Thomas Jung) Date: Sat, 7 Aug 2010 09:58:52 +0200 Subject: SAM conversion of inlined lambda expression Message-ID: Hi, I'm playing a bit with the prototype (i.e. I've not read the specs in full) and I'm puzzled after my second step. The initial code that uses Function (http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/base/Function.html) is: Function a = #(x){ "a" + x }; Function b = #(x){ x + "b" }; assertEquals("axb", Functions.compose(a, b).apply("x")); This works with type inference and does the conversion to the type Function. But if I inline the lambda expression it won't convert them. Function c = Functions. compose(#(String x){ "a" + x }, #(String x){ x + "b" }); I've added all type annotations to rule out that this is the problem. The error message is: "method compose in class Functions cannot be applied to given types". (Can I get more information here about the types/problem?) Is this not supported? Thomas From forax at univ-mlv.fr Sat Aug 7 06:16:58 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Sat, 07 Aug 2010 15:16:58 +0200 Subject: SAM conversion of inlined lambda expression In-Reply-To: References: Message-ID: <4C5D5CCA.5090506@univ-mlv.fr> Le 07/08/2010 09:58, Thomas Jung a ?crit : > Hi, > > I'm playing a bit with the prototype (i.e. I've not read the specs in > full) and I'm puzzled after my second step. > > The initial code that uses Function > (http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/base/Function.html) > is: > > Function a = #(x){ "a" + x }; > Function b = #(x){ x + "b" }; > assertEquals("axb", Functions.compose(a, b).apply("x")); > > This works with type inference and does the conversion to the type > Function. But if I inline the lambda expression it won't convert > them. > > Function c = Functions. > compose(#(String x){ "a" + x }, #(String x){ x + "b" }); > > I've added all type annotations to rule out that this is the problem. > The error message is: > "method compose in class Functions cannot be applied to given types". > (Can I get more information here about the types/problem?) > > Is this not supported? > > Thomas > This is a bug, the prototype have a problem to infer types if there is a wilcard in the middle. by example, this doesn't compile: Function b = #(x){ x + "b" }; So you can't use compose which is declared:|* *| <../../../../com/google/common/base/Functions.html#compose%28com.google.common.base.Function,%20com.google.common.base.Function%29>Function <../../../../com/google/common/base/Function.html> |compose <../../../../com/google/common/base/Functions.html#compose%28com.google.common.base.Function,%20com.google.common.base.Function%29>(Function <../../../../com/google/common/base/Function.html> g, Function <../../../../com/google/common/base/Function.html> f)| R?mi From collin.fagan at gmail.com Sat Aug 7 06:50:17 2010 From: collin.fagan at gmail.com (Collin Fagan) Date: Sat, 7 Aug 2010 08:50:17 -0500 Subject: Trying the prototype In-Reply-To: <4C5C6875.3090105@oracle.com> References: <4C5C6875.3090105@oracle.com> Message-ID: Hi Maurizio, I'm think I'm very close to being able to try this out. The compiling (via Netbeans) worked very well and now I have a bin folder with java/javac. My first instinct was to copy these files into the jdk1.7.0\bin folder of the latest snapshot but the file names don't line up, java vs java.exe etc. Am I missing some target platform setting? I'm on Windows 7 64 bit. Then again I could be totally wrong on how I should use these files. Any help would be appreciated. Thanks Collin On Fri, Aug 6, 2010 at 2:54 PM, maurizio cimadamore < maurizio.cimadamore at oracle.com> wrote: > On 06/08/2010 20:36, Collin Fagan wrote: > >> Brian Goetz >>> There is, however, tremendous value in you actually *trying* the >>> >>> >> prototype. >> >> >>> Have you done that? >>> >>> >> I sir have not and would very much like to. Should I just get the latest >> openjdk build (103?) or does Project Lambda have it's own branch? Is there >> a >> page that walks me through compiling from source? >> >> thanks, >> >> Collin >> >> >> > Hi Collin > thanks for your interest in project lambda. The easiest way to try the > prototype is to have a JDK binary snapshot available (b103 or greater); you > then need to do the following: > > 1) clone the 'langtools' repository of the lambda branch: > > hg clone http://hg.openjdk.java.net/lambda/lambda/langtools > > [this will create a new 'langtools' folder in your current folder] > > 2) build the compiler > > cd langtools/make > > ant -Dboot.java.home= -Dtarget.java.home= > build-all-tools > > This should compile all tools (javac/javap/javah/javadoc/apt) and should > result in a new folder called 'dist' under the 'langtools' folder. Inside > 'dist' there is a subfolder named 'bin' - inside, you will find the > executables for java/javac that should allow you to compile and execute code > containing lambda expressions. > > [If you like NetBeans, there's a NB project under langtools/make - the > project name is 'langtools' - once the project has been opened in the IDE, > you can simply build everything by pressing F-11, or by selecting 'Build' > from the project contexual menu... however ant options (-Dboot.java.home and > -Dtarget.java.home) still need to be specified manually --- this can be done > by accessing the menu under Tools->Options->Misc->Ant and by inserting the > appropriate value in the text field at the bottom of the tab]. > > Maurizio > > > From thomas.andreas.jung at googlemail.com Sat Aug 7 07:57:13 2010 From: thomas.andreas.jung at googlemail.com (Thomas Jung) Date: Sat, 7 Aug 2010 16:57:13 +0200 Subject: SAM conversion of inlined lambda expression In-Reply-To: <4C5D5CCA.5090506@univ-mlv.fr> References: <4C5D5CCA.5090506@univ-mlv.fr> Message-ID: Hi R?mi, you're right. Defining public static Function simpleCompose(Function g, Function f){ return Functions.compose(g,f); } Function c = simpleCompose(#(x){ "a" + x }, #(x){ x + "b" }); works. Is there is way to get some debugging information of the type inferencer? Thomas On 7 August 2010 15:16, R?mi Forax wrote: > ?Le 07/08/2010 09:58, Thomas Jung a ?crit : >> Hi, >> >> I'm playing a bit with the prototype (i.e. I've not read the specs in >> full) and I'm puzzled after my second step. >> >> The initial code that uses Function >> (http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/base/Function.html) >> is: >> >> Function ?a = #(x){ "a" + x }; >> Function ?b = #(x){ x + "b" }; >> assertEquals("axb", Functions.compose(a, b).apply("x")); >> >> This works with type inference and does the conversion to the type >> Function. But if I inline the lambda expression it won't convert >> them. >> >> Function ?c = Functions. >> compose(#(String x){ "a" + x }, #(String x){ x + "b" }); >> >> I've added all type annotations to rule out that this is the problem. >> The error message is: >> "method compose in class Functions cannot be applied to given types". >> (Can I get more information here about the types/problem?) >> >> Is this not supported? >> >> Thomas >> > > This is a bug, the prototype have a problem to infer types > if there is a wilcard in the middle. > > by example, this doesn't compile: > Function b = #(x){ x + "b" }; > > So you can't use compose which is declared:|* > *| > <../../../../com/google/common/base/Functions.html#compose%28com.google.common.base.Function,%20com.google.common.base.Function%29>Function > <../../../../com/google/common/base/Function.html> |compose > <../../../../com/google/common/base/Functions.html#compose%28com.google.common.base.Function,%20com.google.common.base.Function%29>(Function > <../../../../com/google/common/base/Function.html> g, Function > <../../../../com/google/common/base/Function.html> f)| > > R?mi > > > > From jonathan.gibbons at oracle.com Sat Aug 7 08:04:59 2010 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Sat, 07 Aug 2010 08:04:59 -0700 Subject: Trying the prototype In-Reply-To: References: <4C5C6875.3090105@oracle.com> Message-ID: <4C5D761B.4050707@oracle.com> Collin, If you have built langtools by itself, the files in langtools/dist/bin/* are scripts to be executed with a system like Cygwin. They are not drop in replacements for the binaries in your Java installation on Windows. On Windows, you have 3 options. 1. Use Cygwin to run the scripts in dist/bin/javac etc. 2. There is no magic in those scripts -- they simply run your standard JDK 7 installation, putting the jar files in langtools/lib/*.jar on the bootclasspath using the java -Xbootclasspath/p: option. This variant of the option prepends the jar files to the normal boot classpath. If you can figure out how to do that for your preferred execution environment, you can do that. 3. Do a full JDK build. On Windows, this can be done, but is not for the faint of heart. -- Jon On 08/07/2010 06:50 AM, Collin Fagan wrote: > Hi Maurizio, > > I'm think I'm very close to being able to try this out. The compiling (via > Netbeans) worked very well and now I have a bin folder with java/javac. My > first instinct was to copy these files into the jdk1.7.0\bin folder of the > latest snapshot but the file names don't line up, java vs java.exe etc. Am I > missing some target platform setting? I'm on Windows 7 64 bit. Then again I > could be totally wrong on how I should use these files. Any help would be > appreciated. > > Thanks > Collin > > On Fri, Aug 6, 2010 at 2:54 PM, maurizio cimadamore< > maurizio.cimadamore at oracle.com> wrote: > > >> On 06/08/2010 20:36, Collin Fagan wrote: >> >> >>> Brian Goetz >>> >>>> There is, however, tremendous value in you actually *trying* the >>>> >>>> >>>> >>> prototype. >>> >>> >>> >>>> Have you done that? >>>> >>>> >>>> >>> I sir have not and would very much like to. Should I just get the latest >>> openjdk build (103?) or does Project Lambda have it's own branch? Is there >>> a >>> page that walks me through compiling from source? >>> >>> thanks, >>> >>> Collin >>> >>> >>> >>> >> Hi Collin >> thanks for your interest in project lambda. The easiest way to try the >> prototype is to have a JDK binary snapshot available (b103 or greater); you >> then need to do the following: >> >> 1) clone the 'langtools' repository of the lambda branch: >> >> hg clone http://hg.openjdk.java.net/lambda/lambda/langtools >> >> [this will create a new 'langtools' folder in your current folder] >> >> 2) build the compiler >> >> cd langtools/make >> >> ant -Dboot.java.home= -Dtarget.java.home= >> build-all-tools >> >> This should compile all tools (javac/javap/javah/javadoc/apt) and should >> result in a new folder called 'dist' under the 'langtools' folder. Inside >> 'dist' there is a subfolder named 'bin' - inside, you will find the >> executables for java/javac that should allow you to compile and execute code >> containing lambda expressions. >> >> [If you like NetBeans, there's a NB project under langtools/make - the >> project name is 'langtools' - once the project has been opened in the IDE, >> you can simply build everything by pressing F-11, or by selecting 'Build' >> from the project contexual menu... however ant options (-Dboot.java.home and >> -Dtarget.java.home) still need to be specified manually --- this can be done >> by accessing the menu under Tools->Options->Misc->Ant and by inserting the >> appropriate value in the text field at the bottom of the tab]. >> >> Maurizio >> >> >> >> > From thomas.andreas.jung at googlemail.com Sat Aug 7 08:26:32 2010 From: thomas.andreas.jung at googlemail.com (Thomas Jung) Date: Sat, 7 Aug 2010 17:26:32 +0200 Subject: Trying the prototype In-Reply-To: <4C5D761B.4050707@oracle.com> References: <4C5C6875.3090105@oracle.com> <4C5D761B.4050707@oracle.com> Message-ID: Hi Collin, > 3. Do a full JDK build. On Windows, this can be done, but is not for the > faint of heart. One possibility to build the JDK for testing is to setup Linux in VirtualBox. Building the JDK with Ubuntu in VirtualBox is straightforward and works as described (http://hg.openjdk.java.net/lambda/lambda/raw-file/39d81b90b100/README-builds.html. Only one environment variable is missing to allow source code download). I suppose this much easier than the whole setup of the environment for Windows. Thomas On 7 August 2010 17:04, Jonathan Gibbons wrote: > Collin, > > If you have built langtools by itself, the files in langtools/dist/bin/* > are scripts to be executed with a system like Cygwin. They are not drop > in replacements for the binaries in your Java installation on Windows. > > On Windows, you have 3 options. > > 1. Use Cygwin to run the scripts in dist/bin/javac etc. > > 2. There is no magic in those scripts -- they simply run your standard > JDK 7 installation, putting the jar files in langtools/lib/*.jar on the > bootclasspath using the java -Xbootclasspath/p: option. This variant of > the option prepends the jar files to the normal boot classpath. If you > can figure out how to do that for your preferred execution environment, > you can do that. > > 3. Do a full JDK build. On Windows, this can be done, but is not for the > faint of heart. > > -- Jon > > > On 08/07/2010 06:50 AM, Collin Fagan wrote: >> Hi Maurizio, >> >> I'm think I'm very close to being able to try this out. The compiling (via >> Netbeans) worked very well and now I have a bin folder with java/javac. My >> first instinct was to copy these files into the jdk1.7.0\bin folder of the >> latest snapshot but the file names don't line up, java vs java.exe etc. Am I >> missing some target platform setting? I'm on Windows 7 64 bit. Then again I >> could be totally wrong on how I should use these files. Any help would be >> appreciated. >> >> Thanks >> Collin >> >> On Fri, Aug 6, 2010 at 2:54 PM, maurizio cimadamore< >> maurizio.cimadamore at oracle.com> ?wrote: >> >> >>> On 06/08/2010 20:36, Collin Fagan wrote: >>> >>> >>>> Brian Goetz >>>> >>>>> There is, however, tremendous value in you actually *trying* the >>>>> >>>>> >>>>> >>>> prototype. >>>> >>>> >>>> >>>>> Have you done that? >>>>> >>>>> >>>>> >>>> I sir have not and would very much like to. Should I just get the latest >>>> openjdk build (103?) or does Project Lambda have it's own branch? Is there >>>> a >>>> page that walks me through compiling from source? >>>> >>>> thanks, >>>> >>>> Collin >>>> >>>> >>>> >>>> >>> Hi Collin >>> thanks for your interest in project lambda. The easiest way to try the >>> prototype is to have a JDK binary snapshot available (b103 or greater); you >>> then need to do the following: >>> >>> 1) clone the 'langtools' repository of the lambda branch: >>> >>> hg clone http://hg.openjdk.java.net/lambda/lambda/langtools >>> >>> [this will create a new 'langtools' folder in your current folder] >>> >>> 2) build the compiler >>> >>> cd langtools/make >>> >>> ant -Dboot.java.home= ?-Dtarget.java.home= >>> build-all-tools >>> >>> This should compile all tools (javac/javap/javah/javadoc/apt) and should >>> result in a new folder called 'dist' under the 'langtools' folder. Inside >>> 'dist' there is a subfolder named 'bin' - inside, you will find the >>> executables for java/javac that should allow you to compile and execute code >>> containing lambda expressions. >>> >>> [If you like NetBeans, there's a NB project under langtools/make - the >>> project name is 'langtools' - once the project has been opened in the IDE, >>> you can simply build everything by pressing F-11, or by selecting 'Build' >>> from the project contexual menu... however ant options (-Dboot.java.home and >>> -Dtarget.java.home) still need to be specified manually --- this can be done >>> by accessing the menu under Tools->Options->Misc->Ant and by inserting the >>> appropriate value in the text field at the bottom of the tab]. >>> >>> Maurizio >>> >>> >>> >>> >> > > > From neal at gafter.com Sat Aug 7 09:32:04 2010 From: neal at gafter.com (Neal Gafter) Date: Sat, 7 Aug 2010 11:32:04 -0500 Subject: Fun with method references In-Reply-To: References: <54E6FF76-C49B-4976-ACA8-905DFAF0DF70@gafter.com> Message-ID: <82F6ACAC-4044-432B-9FD2-DCE2015EF038@gafter.com> I'm saying that your proposal is unsound in the sense that a program in your extension that compiles with no diagnostics can result in heap pollution (variables whose dynamic and static types do not agree). BGGA does not have that problem. You can't "solve" the problem of reification using erasure. -Neal On Aug 6, 2010, at 10:50 PM, Howard Lovatt wrote: > The area that I didn't solve was arrays of function types, I could only do these by erasing the type (i.e. non-reified). Since all the proposals have this problem of erased function types in arrays, including BGGA, I think the characterisation 'unsound' is a tad strong. Or are you saying that all function type proposals, including BGGA, are unsound? > > On 7 August 2010 13:11, Neal Gafter wrote: > Why are you sending pointers to a proposal that has been shown to be unsound? > > -Neal > > On Aug 6, 2010, at 9:13 PM, Howard Lovatt wrote: > > > @R?mi, > > > >> Not a good example, in my opinion. > >> using SAM interfaces instead: > >> > >> interface Foo1 {...} > >> interface Foo2 {...} > >> > >> void foo(Foo1 foo) { ... } > >> void foo(Foo2 foo) { ... } > > > > But this is easily resolved with a cast > > > >> interface Handler { > >> public int handle(A a); > >> } > >> > >> void foo(Handler stringHandler) { ... } > >> void foo(Handler barHandler) { ... } > > > > This is the exactly the same problem that happens with erased function types > > and I assume that we don't want is more of these problems. The only way out > > of this problem for function types (and generics) is to reify them: > > > > http://www.artima.com/weblogs/viewpost.jsp?thread=278567 > > > > -- Howard. > > > > > > -- > -- Howard. > From collin.fagan at gmail.com Sat Aug 7 09:32:02 2010 From: collin.fagan at gmail.com (Collin Fagan) Date: Sat, 7 Aug 2010 11:32:02 -0500 Subject: Trying the prototype In-Reply-To: References: <4C5C6875.3090105@oracle.com> <4C5D761B.4050707@oracle.com> Message-ID: @Jon Well that makes much more sense, thank you. The irony is that I use cygwin all the time but thought I'd better try it without cygwin first 'just to get it to work' LOL. @Thomas Thanks for the info. I'll keep that in mind if I decide I to use maven or something else to manage my classpath. Collin On Sat, Aug 7, 2010 at 10:26 AM, Thomas Jung < thomas.andreas.jung at googlemail.com> wrote: > Hi Collin, > > > 3. Do a full JDK build. On Windows, this can be done, but is not for the > > faint of heart. > > One possibility to build the JDK for testing is to setup Linux in > VirtualBox. Building the JDK with Ubuntu in VirtualBox is > straightforward and works as described > ( > http://hg.openjdk.java.net/lambda/lambda/raw-file/39d81b90b100/README-builds.html > . > Only one environment variable is missing to allow source code > download). I suppose this much easier than the whole setup of the > environment for Windows. > > Thomas > > On 7 August 2010 17:04, Jonathan Gibbons > wrote: > > Collin, > > > > If you have built langtools by itself, the files in langtools/dist/bin/* > > are scripts to be executed with a system like Cygwin. They are not drop > > in replacements for the binaries in your Java installation on Windows. > > > > On Windows, you have 3 options. > > > > 1. Use Cygwin to run the scripts in dist/bin/javac etc. > > > > 2. There is no magic in those scripts -- they simply run your standard > > JDK 7 installation, putting the jar files in langtools/lib/*.jar on the > > bootclasspath using the java -Xbootclasspath/p: option. This variant of > > the option prepends the jar files to the normal boot classpath. If you > > can figure out how to do that for your preferred execution environment, > > you can do that. > > > > 3. Do a full JDK build. On Windows, this can be done, but is not for the > > faint of heart. > > > > -- Jon > > > > > > On 08/07/2010 06:50 AM, Collin Fagan wrote: > >> Hi Maurizio, > >> > >> I'm think I'm very close to being able to try this out. The compiling > (via > >> Netbeans) worked very well and now I have a bin folder with java/javac. > My > >> first instinct was to copy these files into the jdk1.7.0\bin folder of > the > >> latest snapshot but the file names don't line up, java vs java.exe etc. > Am I > >> missing some target platform setting? I'm on Windows 7 64 bit. Then > again I > >> could be totally wrong on how I should use these files. Any help would > be > >> appreciated. > >> > >> Thanks > >> Collin > >> > >> On Fri, Aug 6, 2010 at 2:54 PM, maurizio cimadamore< > >> maurizio.cimadamore at oracle.com> wrote: > >> > >> > >>> On 06/08/2010 20:36, Collin Fagan wrote: > >>> > >>> > >>>> Brian Goetz > >>>> > >>>>> There is, however, tremendous value in you actually *trying* the > >>>>> > >>>>> > >>>>> > >>>> prototype. > >>>> > >>>> > >>>> > >>>>> Have you done that? > >>>>> > >>>>> > >>>>> > >>>> I sir have not and would very much like to. Should I just get the > latest > >>>> openjdk build (103?) or does Project Lambda have it's own branch? Is > there > >>>> a > >>>> page that walks me through compiling from source? > >>>> > >>>> thanks, > >>>> > >>>> Collin > >>>> > >>>> > >>>> > >>>> > >>> Hi Collin > >>> thanks for your interest in project lambda. The easiest way to try the > >>> prototype is to have a JDK binary snapshot available (b103 or greater); > you > >>> then need to do the following: > >>> > >>> 1) clone the 'langtools' repository of the lambda branch: > >>> > >>> hg clone http://hg.openjdk.java.net/lambda/lambda/langtools > >>> > >>> [this will create a new 'langtools' folder in your current folder] > >>> > >>> 2) build the compiler > >>> > >>> cd langtools/make > >>> > >>> ant -Dboot.java.home= -Dtarget.java.home= > >>> build-all-tools > >>> > >>> This should compile all tools (javac/javap/javah/javadoc/apt) and > should > >>> result in a new folder called 'dist' under the 'langtools' folder. > Inside > >>> 'dist' there is a subfolder named 'bin' - inside, you will find the > >>> executables for java/javac that should allow you to compile and execute > code > >>> containing lambda expressions. > >>> > >>> [If you like NetBeans, there's a NB project under langtools/make - the > >>> project name is 'langtools' - once the project has been opened in the > IDE, > >>> you can simply build everything by pressing F-11, or by selecting > 'Build' > >>> from the project contexual menu... however ant options > (-Dboot.java.home and > >>> -Dtarget.java.home) still need to be specified manually --- this can be > done > >>> by accessing the menu under Tools->Options->Misc->Ant and by inserting > the > >>> appropriate value in the text field at the bottom of the tab]. > >>> > >>> Maurizio > >>> > >>> > >>> > >>> > >> > > > > > > > From neal at gafter.com Sat Aug 7 09:39:16 2010 From: neal at gafter.com (Neal Gafter) Date: Sat, 7 Aug 2010 11:39:16 -0500 Subject: SAM conversion of inlined lambda expression In-Reply-To: <4C5D5CCA.5090506@univ-mlv.fr> References: <4C5D5CCA.5090506@univ-mlv.fr> Message-ID: <9008BD72-2321-4280-8E83-BBF3F4E4D817@gafter.com> On Aug 7, 2010, at 8:16 AM, R?mi Forax wrote: > This is a bug, the prototype have a problem to infer types > if there is a wilcard in the middle. > > by example, this doesn't compile: > Function b = #(x){ x + "b" }; Let's hope that this is just a bug, because wildcards must be used widely in higher-order APIs to get proper subtyping, even though the examples we've been discussing so far have simplified away this aspect. As long as APIs are expressed using SAMs and not function types, this is a level of complexity that programmers will simply have to learn when reading these APIs. From jonathan.gibbons at oracle.com Sat Aug 7 10:17:21 2010 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Sat, 07 Aug 2010 10:17:21 -0700 Subject: Trying the prototype In-Reply-To: References: <4C5C6875.3090105@oracle.com> <4C5D761B.4050707@oracle.com> Message-ID: <4C5D9521.7030104@oracle.com> If you're comfortable using Cygwin and have it available, that is definitely your simplest option. :-) -- Jon On 08/07/2010 09:32 AM, Collin Fagan wrote: > @Jon > Well that makes much more sense, thank you. The irony is that I use > cygwin all the time but thought I'd better try it without cygwin first > 'just to get it to work' LOL. > > @Thomas > Thanks for the info. I'll keep that in mind if I decide I to use maven > or something else to manage my classpath. > > Collin > > On Sat, Aug 7, 2010 at 10:26 AM, Thomas Jung > > wrote: > > Hi Collin, > > > 3. Do a full JDK build. On Windows, this can be done, but is not > for the > > faint of heart. > > One possibility to build the JDK for testing is to setup Linux in > VirtualBox. Building the JDK with Ubuntu in VirtualBox is > straightforward and works as described > (http://hg.openjdk.java.net/lambda/lambda/raw-file/39d81b90b100/README-builds.html. > Only one environment variable is missing to allow source code > download). I suppose this much easier than the whole setup of the > environment for Windows. > > Thomas > > On 7 August 2010 17:04, Jonathan Gibbons > > > wrote: > > Collin, > > > > If you have built langtools by itself, the files in > langtools/dist/bin/* > > are scripts to be executed with a system like Cygwin. They are > not drop > > in replacements for the binaries in your Java installation on > Windows. > > > > On Windows, you have 3 options. > > > > 1. Use Cygwin to run the scripts in dist/bin/javac etc. > > > > 2. There is no magic in those scripts -- they simply run your > standard > > JDK 7 installation, putting the jar files in langtools/lib/*.jar > on the > > bootclasspath using the java -Xbootclasspath/p: option. This > variant of > > the option prepends the jar files to the normal boot classpath. > If you > > can figure out how to do that for your preferred execution > environment, > > you can do that. > > > > 3. Do a full JDK build. On Windows, this can be done, but is not > for the > > faint of heart. > > > > -- Jon > > > > > > On 08/07/2010 06:50 AM, Collin Fagan wrote: > >> Hi Maurizio, > >> > >> I'm think I'm very close to being able to try this out. The > compiling (via > >> Netbeans) worked very well and now I have a bin folder with > java/javac. My > >> first instinct was to copy these files into the jdk1.7.0\bin > folder of the > >> latest snapshot but the file names don't line up, java vs > java.exe etc. Am I > >> missing some target platform setting? I'm on Windows 7 64 bit. > Then again I > >> could be totally wrong on how I should use these files. Any > help would be > >> appreciated. > >> > >> Thanks > >> Collin > >> > >> On Fri, Aug 6, 2010 at 2:54 PM, maurizio cimadamore< > >> maurizio.cimadamore at oracle.com > > wrote: > >> > >> > >>> On 06/08/2010 20:36, Collin Fagan wrote: > >>> > >>> > >>>> Brian Goetz > >>>> > >>>>> There is, however, tremendous value in you actually *trying* the > >>>>> > >>>>> > >>>>> > >>>> prototype. > >>>> > >>>> > >>>> > >>>>> Have you done that? > >>>>> > >>>>> > >>>>> > >>>> I sir have not and would very much like to. Should I just get > the latest > >>>> openjdk build (103?) or does Project Lambda have it's own > branch? Is there > >>>> a > >>>> page that walks me through compiling from source? > >>>> > >>>> thanks, > >>>> > >>>> Collin > >>>> > >>>> > >>>> > >>>> > >>> Hi Collin > >>> thanks for your interest in project lambda. The easiest way to > try the > >>> prototype is to have a JDK binary snapshot available (b103 or > greater); you > >>> then need to do the following: > >>> > >>> 1) clone the 'langtools' repository of the lambda branch: > >>> > >>> hg clone http://hg.openjdk.java.net/lambda/lambda/langtools > >>> > >>> [this will create a new 'langtools' folder in your current folder] > >>> > >>> 2) build the compiler > >>> > >>> cd langtools/make > >>> > >>> ant -Dboot.java.home= > -Dtarget.java.home= > >>> build-all-tools > >>> > >>> This should compile all tools (javac/javap/javah/javadoc/apt) > and should > >>> result in a new folder called 'dist' under the 'langtools' > folder. Inside > >>> 'dist' there is a subfolder named 'bin' - inside, you will > find the > >>> executables for java/javac that should allow you to compile > and execute code > >>> containing lambda expressions. > >>> > >>> [If you like NetBeans, there's a NB project under > langtools/make - the > >>> project name is 'langtools' - once the project has been opened > in the IDE, > >>> you can simply build everything by pressing F-11, or by > selecting 'Build' > >>> from the project contexual menu... however ant options > (-Dboot.java.home and > >>> -Dtarget.java.home) still need to be specified manually --- > this can be done > >>> by accessing the menu under Tools->Options->Misc->Ant and by > inserting the > >>> appropriate value in the text field at the bottom of the tab]. > >>> > >>> Maurizio > >>> > >>> > >>> > >>> > >> > > > > > > > > From maurizio.cimadamore at oracle.com Sat Aug 7 10:24:33 2010 From: maurizio.cimadamore at oracle.com (maurizio cimadamore) Date: Sat, 07 Aug 2010 18:24:33 +0100 Subject: SAM conversion of inlined lambda expression In-Reply-To: References: <4C5D5CCA.5090506@univ-mlv.fr> Message-ID: <4C5D96D1.7070409@oracle.com> On 07/08/2010 15:57, Thomas Jung wrote: > Hi R?mi, > > you're right. Defining > > public static Function simpleCompose(Function g, > Function f){ > return Functions.compose(g,f); > } > Function c = simpleCompose(#(x){ "a" + x }, #(x){ x + "b" }); > > works. Is there is way to get some debugging information of the type inferencer? > > Thomas > Hi as Remi pointed out in an earlier email, there's a bug when the target method of a SAM conversion has a wildcard in return type position. Wildcards in argument types work w/o problems - a fix for this problem will be available soon. Thanks Maurizio > On 7 August 2010 15:16, R?mi Forax wrote: > >> Le 07/08/2010 09:58, Thomas Jung a ?crit : >> >>> Hi, >>> >>> I'm playing a bit with the prototype (i.e. I've not read the specs in >>> full) and I'm puzzled after my second step. >>> >>> The initial code that uses Function >>> (http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/base/Function.html) >>> is: >>> >>> Function a = #(x){ "a" + x }; >>> Function b = #(x){ x + "b" }; >>> assertEquals("axb", Functions.compose(a, b).apply("x")); >>> >>> This works with type inference and does the conversion to the type >>> Function. But if I inline the lambda expression it won't convert >>> them. >>> >>> Function c = Functions. >>> compose(#(String x){ "a" + x }, #(String x){ x + "b" }); >>> >>> I've added all type annotations to rule out that this is the problem. >>> The error message is: >>> "method compose in class Functions cannot be applied to given types". >>> (Can I get more information here about the types/problem?) >>> >>> Is this not supported? >>> >>> Thomas >>> >>> >> This is a bug, the prototype have a problem to infer types >> if there is a wilcard in the middle. >> >> by example, this doesn't compile: >> Function b = #(x){ x + "b" }; >> >> So you can't use compose which is declared:|* >> *| >> <../../../../com/google/common/base/Functions.html#compose%28com.google.common.base.Function,%20com.google.common.base.Function%29>Function >> <../../../../com/google/common/base/Function.html> |compose >> <../../../../com/google/common/base/Functions.html#compose%28com.google.common.base.Function,%20com.google.common.base.Function%29>(Function >> <../../../../com/google/common/base/Function.html> g, Function >> <../../../../com/google/common/base/Function.html> f)| >> >> R?mi >> >> >> >> >> > From thomas.andreas.jung at googlemail.com Sat Aug 7 10:55:34 2010 From: thomas.andreas.jung at googlemail.com (Thomas Jung) Date: Sat, 7 Aug 2010 19:55:34 +0200 Subject: type inference problem lead to cannot find symbol error message Message-ID: Hi, I'm still trying out functionality of the Guava library with the lambda prototype. This time I've a strange behavior with the CharMatcher.forPredicate(Predicate predicate) method (http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/base/CharMatcher.html#forPredicate%28com.google.common.base.Predicate%29). If I remove the type of the predicate CharMatcher c = CharMatcher.forPredicate(#(Character c){c.compareTo('e') < 0}); CharMatcher c2 = CharMatcher.forPredicate(#(c){c.compareTo('e') < 0}); it results in the error message: CTest.java:[47,50] cannot find symbol [47,50] is the first opening brace "CharMatcher c2 = CharMatcher.forPredicate(" Any ideas? Thomas From forax at univ-mlv.fr Sat Aug 7 11:33:32 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Sat, 07 Aug 2010 20:33:32 +0200 Subject: type inference problem lead to cannot find symbol error message In-Reply-To: References: Message-ID: <4C5DA6FC.1030809@univ-mlv.fr> Le 07/08/2010 19:55, Thomas Jung a ?crit : > Hi, > > I'm still trying out functionality of the Guava library with the > lambda prototype. > > This time I've a strange behavior with the > CharMatcher.forPredicate(Predicate predicate) > method (http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/base/CharMatcher.html#forPredicate%28com.google.common.base.Predicate%29). > > If I remove the type of the predicate > > CharMatcher c = CharMatcher.forPredicate(#(Character c){c.compareTo('e')< 0}); > CharMatcher c2 = CharMatcher.forPredicate(#(c){c.compareTo('e')< 0}); > > it results in the error message: > > CTest.java:[47,50] cannot find symbol > > [47,50] is the first opening brace "CharMatcher c2 = CharMatcher.forPredicate(" > > Any ideas? > > Thomas > For CharMatcher.forPredicate(#(c){c.compareTo('e') < 0}); c is infered as Object and so the compiler can not find Object.compareTo(...). ? super Foo as parameter should be the infered as Foo and not as Object. R?mi From thomas.andreas.jung at googlemail.com Sat Aug 7 12:12:55 2010 From: thomas.andreas.jung at googlemail.com (Thomas Jung) Date: Sat, 7 Aug 2010 21:12:55 +0200 Subject: Bug: NullPointerException in type inferencer Message-ID: Hi, converting : Predicate i = #(i){i > 0}; Predicate j = #(i){i % 2 == 0}; Predicate k = Predicates.and(i,j); with http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/base/Predicate.html to: Predicate k = Predicates.and(#(i){i > 0},#(i){i % 2 == 0}); results in an NullPointerException: java.lang.NullPointerException at com.sun.tools.javac.comp.Infer.instantiateMethod(Infer.java:417) at com.sun.tools.javac.comp.Resolve.rawInstantiate(Resolve.java:348) at com.sun.tools.javac.comp.Resolve.selectBest(Resolve.java:597) at com.sun.tools.javac.comp.Resolve.findMethod(Resolve.java:809) at com.sun.tools.javac.comp.Resolve.findMethod(Resolve.java:773) at com.sun.tools.javac.comp.Resolve.resolveQualifiedMethod(Resolve.java:1392) Actually, I wanted to see if type inference works from one parameter to another: Collections2.filter( Arrays.asList(-2,-1,0,1,2,3,4), Predicates.and(#(i){i > 0},#(i){i % 2 == 0}); Thomas From thomas.andreas.jung at googlemail.com Sat Aug 7 12:16:04 2010 From: thomas.andreas.jung at googlemail.com (Thomas Jung) Date: Sat, 7 Aug 2010 21:16:04 +0200 Subject: SAM conversion in for expressions Message-ID: Hi, according to the language specification only iterables and arrays are allowed in a for expression: >The enhanced for statement has the form: > >EnhancedForStatement: > for ( VariableModifiersopt Type Identifier: Expression) Statement >The Expression must either have type Iterable or else it must be of an array type (?10.1), or a compile-time error occurs. Iterator iterator = Collections.singleton("a iter").iterator(); Iterable i = #(){ iterator }; for(String s : i) System.out.println(s); for(String s : #(){ iterator }) System.out.println(s); So for the given example only the first expression compiles although the information needed to infer the type is present. I think this is more a matter of consistency than an useful construct. Thomas From neal at gafter.com Sat Aug 7 12:33:57 2010 From: neal at gafter.com (Neal Gafter) Date: Sat, 7 Aug 2010 15:33:57 -0400 Subject: Bug: NullPointerException in type inferencer In-Reply-To: References: Message-ID: Try using Predicate as the target type. On Saturday, August 7, 2010, Thomas Jung wrote: > Hi, > > converting : > > Predicate i = #(i){i > 0}; > Predicate j = #(i){i % 2 == 0}; > Predicate k = Predicates.and(i,j); > > with http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/base/Predicate.html > > to: > > Predicate k = Predicates.and(#(i){i > 0},#(i){i % 2 == 0}); > > results in an NullPointerException: > > java.lang.NullPointerException > ? ? ? ?at com.sun.tools.javac.comp.Infer.instantiateMethod(Infer.java:417) > ? ? ? ?at com.sun.tools.javac.comp.Resolve.rawInstantiate(Resolve.java:348) > ? ? ? ?at com.sun.tools.javac.comp.Resolve.selectBest(Resolve.java:597) > ? ? ? ?at com.sun.tools.javac.comp.Resolve.findMethod(Resolve.java:809) > ? ? ? ?at com.sun.tools.javac.comp.Resolve.findMethod(Resolve.java:773) > ? ? ? ?at com.sun.tools.javac.comp.Resolve.resolveQualifiedMethod(Resolve.java:1392) > > Actually, I wanted to see if type inference works from one parameter to another: > > Collections2.filter( > ? ? ? ?Arrays.asList(-2,-1,0,1,2,3,4), > ? ? ? ?Predicates.and(#(i){i > 0},#(i){i % 2 == 0}); > > Thomas > > From thomas.andreas.jung at googlemail.com Sat Aug 7 12:50:23 2010 From: thomas.andreas.jung at googlemail.com (Thomas Jung) Date: Sat, 7 Aug 2010 21:50:23 +0200 Subject: Bug: NullPointerException in type inferencer In-Reply-To: References: Message-ID: Predicate k = Predicates.and(#(i){i > 0},#(i){i % 2 == 0}) has the same result. And it's not terrible useful. Maybe I've misunderstood you. Thomas On 7 August 2010 21:33, Neal Gafter wrote: > Try using Predicate as the target type. > > On Saturday, August 7, 2010, Thomas Jung > wrote: >> Hi, >> >> converting : >> >> Predicate i = #(i){i > 0}; >> Predicate j = #(i){i % 2 == 0}; >> Predicate k = Predicates.and(i,j); >> >> with http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/base/Predicate.html >> >> to: >> >> Predicate k = Predicates.and(#(i){i > 0},#(i){i % 2 == 0}); >> >> results in an NullPointerException: >> >> java.lang.NullPointerException >> ?? ? ? ?at com.sun.tools.javac.comp.Infer.instantiateMethod(Infer.java:417) >> ?? ? ? ?at com.sun.tools.javac.comp.Resolve.rawInstantiate(Resolve.java:348) >> ?? ? ? ?at com.sun.tools.javac.comp.Resolve.selectBest(Resolve.java:597) >> ?? ? ? ?at com.sun.tools.javac.comp.Resolve.findMethod(Resolve.java:809) >> ?? ? ? ?at com.sun.tools.javac.comp.Resolve.findMethod(Resolve.java:773) >> ?? ? ? ?at com.sun.tools.javac.comp.Resolve.resolveQualifiedMethod(Resolve.java:1392) >> >> Actually, I wanted to see if type inference works from one parameter to another: >> >> Collections2.filter( >> ?? ? ? ?Arrays.asList(-2,-1,0,1,2,3,4), >> ?? ? ? ?Predicates.and(#(i){i > 0},#(i){i % 2 == 0}); >> >> Thomas >> >> > From howard.lovatt at gmail.com Sat Aug 7 17:01:35 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Sun, 8 Aug 2010 10:01:35 +1000 Subject: Fun with method references Message-ID: > I'm saying that your proposal is unsound in the sense that a program in your extension > that compiles with no diagnostics can result in heap pollution (variables whose dynamic > and static types do not agree). BGGA does not have that problem. You can't "solve" > the problem of reification using erasure. Other than arrays of function types I am not aware of any problem areas. Can you elaborate please. ? -- Howard. PS Clearly this exercise is now academic since there won't be function types in 7. Hence I haven't put further work in. From neal at gafter.com Sat Aug 7 19:01:02 2010 From: neal at gafter.com (Neal Gafter) Date: Sat, 7 Aug 2010 22:01:02 -0400 Subject: Fun with method references In-Reply-To: References: Message-ID: Re: "other than..." A type system with even one hole in it is unsound. -Neal On Aug 7, 2010, at 8:01 PM, Howard Lovatt wrote: >> I'm saying that your proposal is unsound in the sense that a program in your extension >> that compiles with no diagnostics can result in heap pollution (variables whose dynamic >> and static types do not agree). BGGA does not have that problem. You can't "solve" >> the problem of reification using erasure. > > Other than arrays of function types I am not aware of any problem > areas. Can you elaborate please. > > -- Howard. > > PS Clearly this exercise is now academic since there won't be function > types in 7. Hence I haven't put further work in. > From oehrstroem at gmail.com Sun Aug 8 02:13:13 2010 From: oehrstroem at gmail.com (Fredrik Ohrstrom) Date: Sun, 8 Aug 2010 11:13:13 +0200 Subject: Fun with method references In-Reply-To: <4C5C863A.7040505@univ-mlv.fr> References: <4C59DC91.5090300@oracle.com> <4C59E066.6040807@oracle.com> <4C59E6D4.50104@univ-mlv.fr> <4C59E999.7070900@oracle.com> <7FDA6630E1822F448C97A48D5D73309401473E9C@EXVMSTOR302.intra.rakuten.co.jp> <4C5C6EEE.5010803@oracle.com> <7FDA6630E1822F448C97A48D5D73309401473EAC@EXVMSTOR302.intra.rakuten.co.jp> <4C5C7442.80406@oracle.com> <4C5C8330.3010608@univ-mlv.fr> <4C5C863A.7040505@univ-mlv.fr> Message-ID: 2010/8/7 R?mi Forax : > > interface Handler { > ? public int handle(A a); > } > > void foo(Handler stringHandler) { ... } > void foo(Handler barHandler) { ... } > > which exhibits exactly the same erasure problem. > Exactly. I strongly believe that we need function types. Whatever restrictions that are put upon them due to erasure, will be lifted whenever we get erasure. It will still be better than forcing a whole new set of SAM-interfaces onto the Java world. Also, for those who really want to have a sort of overloaded functionality depending on the exact type of the function type can do this: void foo(Function f) { if (f invokeableby (String)->int) { fooString(f); } else { if (f invokeableby (Bar)->int) { fooBar(f); } } If you do foo( (String s) -> s.length() ) the foo invokeableby checks will be inlined and the if-statements dead-branch removed and you get a direct call to fooString (which of course might be inlined as well.) //Fredrik From oehrstroem at gmail.com Sun Aug 8 02:27:58 2010 From: oehrstroem at gmail.com (Fredrik Ohrstrom) Date: Sun, 8 Aug 2010 11:27:58 +0200 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: References: Message-ID: 2010/8/5 Stephen Colebourne : > No one has yet mentioned another danger with using Foo#bar instead of > Foo#bar(String). > > The former choice at this point closes off options in the future for Java. > > Foo#bar is the only sensible syntax for a field literal. Java can have > both fields and methods with the same name. This has the potential to > be a limitation to future language development. JSR292 will never offer field literals. However JSR292 offers a quick creation of getters and setter methods. These are pure methodhandles, ie. code. The use cases for pure field literals are a magnitude fewer than for method references literals. If you want field setters and getters it is trivial to write: Function(Person)->int getage = { p -> p.age }; Then Javac can detect that this is an "age getter" and use MethodHandles.lookup to acquire a field getter. When method reference literals are supported, 9999 programmers will write save_button.onClick(this#save); every day, and one programmer will write code for a field literal. //Fredrik From david.goodenough at linkchoose.co.uk Sun Aug 8 02:42:15 2010 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Sun, 8 Aug 2010 10:42:15 +0100 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: References: Message-ID: <201008081042.15464.david.goodenough@linkchoose.co.uk> On Sunday 08 August 2010, Fredrik Ohrstrom wrote: > 2010/8/5 Stephen Colebourne : > > No one has yet mentioned another danger with using Foo#bar instead of > > Foo#bar(String). > > > > The former choice at this point closes off options in the future for > > Java. > > > > Foo#bar is the only sensible syntax for a field literal. Java can have > > both fields and methods with the same name. This has the potential to > > be a limitation to future language development. > > JSR292 will never offer field literals. However JSR292 offers a quick > creation of getters and setter methods. These are pure methodhandles, ie. > code. > > The use cases for pure field literals are a magnitude fewer than for > method references literals. I suspect that this is because most of them are hidden. Look at all the places where the name of a field is passed as a String and all of these are places where field literals would be applicable. I am here thinking of Bean Properties, JDBC and all the JPAs, Swing and the many binding frameworks. Whether these qualify as "pure field literals" I leave for others to judge, but the need for field litereals is real and pressing. Mostly Java is a language that the compiler and IDEs can check, but as soon as field names have to be passed around as names neither the compiler nor IDEs can help. Now I suspect that the fact the compiler and JVM use names all over the place obscures the problem, but the difference here is that the names are only used after they have been regiourously checked. David > > If you want field setters and getters it is trivial to write: > Function(Person)->int getage = { p -> p.age }; > > Then Javac can detect that this is an "age getter" and use > MethodHandles.lookup to acquire a field getter. > > When method reference literals are supported, 9999 programmers will write > save_button.onClick(this#save); > every day, and one programmer will write code for a field literal. > > //Fredrik From scolebourne at joda.org Sun Aug 8 02:46:28 2010 From: scolebourne at joda.org (Stephen Colebourne) Date: Sun, 8 Aug 2010 10:46:28 +0100 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: References: Message-ID: On 8 August 2010 10:27, Fredrik Ohrstrom wrote: > JSR292 will never offer field literals. Technical or philosophical restriction? > If you want field setters and getters it is trivial to write: > Function(Person)->int getage = { p -> p.age }; ie. developers should write boilerplate code... There are two arguments here 1) Consistency. Java has fields and methods. Why are methods getting preference? If I know nothing about the language, then its an additional rule to learn. 2) Properties. I still hope that at some point real properties will be added to Java. I've stated before my view that properties should have been added before generics and closures - they are that critical, and that wasteful. Using up the syntax here may well make property references nigh on impossible. (3) see Davis' mail! Stephen From thomas.andreas.jung at googlemail.com Sun Aug 8 02:53:44 2010 From: thomas.andreas.jung at googlemail.com (Thomas Jung) Date: Sun, 8 Aug 2010 11:53:44 +0200 Subject: Method references with types [Re: lambda syntax tutorial] In-Reply-To: References: Message-ID: Hi Fredrik, > When method reference literals are supported, 9999 programmers will write > save_button.onClick(this#save); > every day, and one programmer will write code for a field literal. I think you underestimate the usefulness of field literals. This "one programmer" is the one using JPA2. If there were field literals the APT metamodel class workaround would probably not be in JPA2. CriteriaQuery q = cb.createQuery(Order.class); Root order = q.from(Order.class); Join item = order.join(Order#lineItems); q.select(order); is much nicer than CriteriaQuery q = cb.createQuery(Order.class); Root order = q.from(Order.class); Join item = order.join(Order_.lineItems); q.select(order); which is a lot of work to implement, to get running and document (field literal vs. there is this strange A_ class generated if you have a working APT setup...). Thomas On 8 August 2010 11:27, Fredrik Ohrstrom wrote: > 2010/8/5 Stephen Colebourne : >> No one has yet mentioned another danger with using Foo#bar instead of >> Foo#bar(String). >> >> The former choice at this point closes off options in the future for Java. >> >> Foo#bar is the only sensible syntax for a field literal. Java can have >> both fields and methods with the same name. This has the potential to >> be a limitation to future language development. > > JSR292 will never offer field literals. However JSR292 offers a quick creation > of getters and setter methods. These are pure methodhandles, ie. code. > > The use cases for pure field literals are a magnitude fewer than for > method references literals. > > If you want field setters and getters it is trivial to write: > Function(Person)->int getage = { p -> p.age }; > > Then Javac can detect that this is an "age getter" and use > MethodHandles.lookup to acquire a field getter. > > When method reference literals are supported, 9999 programmers will write > save_button.onClick(this#save); > every day, and one programmer will write code for a field literal. > > //Fredrik > > From john at milsson.nu Sun Aug 8 11:09:56 2010 From: john at milsson.nu (John Nilsson) Date: Sun, 8 Aug 2010 20:09:56 +0200 Subject: Fun with method references In-Reply-To: References: <4C59DC91.5090300@oracle.com> <4C59E066.6040807@oracle.com> <4C59E6D4.50104@univ-mlv.fr> <4C59E999.7070900@oracle.com> <7FDA6630E1822F448C97A48D5D73309401473E9C@EXVMSTOR302.intra.rakuten.co.jp> <4C5C6EEE.5010803@oracle.com> <7FDA6630E1822F448C97A48D5D73309401473EAC@EXVMSTOR302.intra.rakuten.co.jp> <4C5C7442.80406@oracle.com> <4C5C8330.3010608@univ-mlv.fr> <4C5C863A.7040505@univ-mlv.fr> Message-ID: On Sun, Aug 8, 2010 at 11:13 AM, Fredrik Ohrstrom wrote: > 2010/8/7 R?mi Forax : >> void foo(Handler stringHandler) { ... } >> void foo(Handler barHandler) { ... } >> >> which exhibits exactly the same erasure problem. >> > > Exactly. I strongly believe that we need function types. > Whatever restrictions that are put upon them due to > erasure, will be lifted whenever we get erasure. I don't understand how reification would help here. Isn't overloaded method resolution resolved at compile time? So if there is a problem with overloading, shouldn't this problem be solved at compile time? Mvh, John From howard.lovatt at gmail.com Sun Aug 8 17:37:57 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Mon, 9 Aug 2010 10:37:57 +1000 Subject: Fun with method references Message-ID: >>> void foo(Handler stringHandler) { ... } >>> void foo(Handler barHandler) { ... } >>> >>> which exhibits exactly the same erasure problem. >>> >> >> Exactly. I strongly believe that we need function types. >> Whatever restrictions that are put upon them due to >> erasure, will be lifted whenever we get erasure. > > I don't understand how reification would help here. Isn't overloaded > method resolution resolved at compile time? So if there is a problem > with overloading, shouldn't this problem be solved at compile time? The problem is that both foo(Handler) and foo(Handler) get erased to foo(Handler) and therefore they both can't exist in the same class (they have the same signature in the class file). If generics ere reified then you could have both methods in the same class since they would have different signatures. The same goes for any other feature, including function types, that is implemented via erasure. ? -- Howard. From reinier at zwitserloot.com Mon Aug 9 04:08:53 2010 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Mon, 9 Aug 2010 13:08:53 +0200 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: <4C59F9D9.1020806@univ-mlv.fr> References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> <4C59E293.70701@oracle.com> <40509310-4F73-46D4-9F3D-846172A611C8@miginfocom.com> <4C59E833.8090704@oracle.com> <63C3EBA6-0893-44FA-89F8-4160DF472FBB@miginfocom.com> <4C59F9D9.1020806@univ-mlv.fr> Message-ID: No need to go that far. An implementation provided 'inline' is simply desugared to a 'default' that points to a nested class, just like the boilerplate that has been shown in this thread plenty of times already. What happens if the default method is not accessible/visible from the caller? i.e. why if the $ExtensionImpls class was private? Can the VM deal with this as the Defender Extensions spec is currently defined? It's not currently possible to define anything private in an interface right now, but allowing "private" on inner classes is a simple change. Separate from the idea of allowing inline implementations in addition to pointing at a static method via 'default', how about allowing private inner types in interfaces _regardless_? Even if inline implementations aren't allowed, the boilerplate pattern of storing the default implementations in an inner class is likely to be extremely common, but it REQUIRES that inner class to be public, and thus visible API. There's absolutely no reason for an API user to see that thing. It would have to have the following javadoc: /** Don't look at me. I don't exist. Really. Go away. */ which sounds like something we ought to fix. This fix becomes a lot more difficult if the 'default' method has to be visible/accessible from callers. --Reinier Zwitserloot On Thu, Aug 5, 2010 at 1:38 AM, R?mi Forax wrote: > Le 05/08/2010 00:59, Mikael Grev a ?crit : > > Thanks Neal, this reflect my stance as well. > > > > Making it hard for the end user is never good. If the purpose of the > feature is to be able to provide a default implementation for interface > evolution (which I believe is about time) I think it is better to stand up > for that and make it as easy as possible to do it. > > > > Hi Mikael, > I think the syntax of defender method has some technical merits: > - you can't add code to an interface without breaking all tools that > take a look > to the bytecode. > - solving the problem of a class implementing two interfaces with two > extension methods > that collide is easier. They should have the same default. > - you can easily retrofit existing collection API classes/interfaces to > use extension method. > - the syntax is close to the VM format. It's not like inner-classes or > enums > where the compiler generate lot of boilerplate code. > A simple benefit is that reflection works like a charm. > > R?mi > > > > > On Aug 5, 2010, at 0:52 AM, Neal Gafter wrote: > > > > > >> On Wed, Aug 4, 2010 at 3:22 PM, Brian Goetz > wrote: > >> Your characterization of "keep interfaces code-free" is pretty close. > While > >> the introduction of default methods unfortunately dirties the > distinction > >> between interfaces and classes, we have taken a much smaller step than > we > >> could have (say, to mixins or traits or full multiple inheritance) in > order to > >> keep as much as possible to the true spirit of interfaces, which we > still > >> believe in. Therefore we believe that choosing a syntactic option that > >> reflects that this philosophical leaning is in the best interest of the > >> community. > >> > >> It seems you've technically observed the word of "keep interfaces > code-free" without obeying the spirit of it. There is little point of > putting the programmer through the pain of the separation in the current > specification if the benefits of the separation don't accrue. > >> > > > > > > > From thomas.andreas.jung at googlemail.com Mon Aug 9 04:24:16 2010 From: thomas.andreas.jung at googlemail.com (Thomas Jung) Date: Mon, 9 Aug 2010 13:24:16 +0200 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: References: <4C5A2546-4810-4472-9EA2-10B50F16D2EF@oracle.com> <4C59E293.70701@oracle.com> <40509310-4F73-46D4-9F3D-846172A611C8@miginfocom.com> <4C59E833.8090704@oracle.com> <63C3EBA6-0893-44FA-89F8-4160DF472FBB@miginfocom.com> <4C59F9D9.1020806@univ-mlv.fr> Message-ID: >but it REQUIRES that inner class to be public, and thus visible API. package x; public class X { class A{}; } That's not true. X.A can only be accessed from the package x. (So you have to generate javadoc with -package to expose the class A.) Although a private class would be nicer and inlined methods even nicer. Thomas On 9 August 2010 13:08, Reinier Zwitserloot wrote: > No need to go that far. An implementation provided 'inline' is simply > desugared to a 'default' that points to a nested class, just like the > boilerplate that has been shown in this thread plenty of times already. > > What happens if the default method is not accessible/visible from the > caller? i.e. why if the $ExtensionImpls class was private? Can the VM deal > with this as the Defender Extensions spec is currently defined? It's not > currently possible to define anything private in an interface right now, but > allowing "private" on inner classes is a simple change. > > > Separate from the idea of allowing inline implementations in addition to > pointing at a static method via 'default', how about allowing private inner > types in interfaces _regardless_? Even if inline implementations aren't > allowed, the boilerplate pattern of storing the default implementations in > an inner class is likely to be extremely common, but it REQUIRES that inner > class to be public, and thus visible API. There's absolutely no reason for > an API user to see that thing. It would have to have the following javadoc: > > /** Don't look at me. I don't exist. Really. Go away. */ > > which sounds like something we ought to fix. > > This fix becomes a lot more difficult if the 'default' method has to be > visible/accessible from callers. > > ?--Reinier Zwitserloot > > > > On Thu, Aug 5, 2010 at 1:38 AM, R?mi Forax wrote: > >> Le 05/08/2010 00:59, Mikael Grev a ?crit : >> > Thanks Neal, this reflect my stance as well. >> > >> > Making it hard for the end user is never good. If the purpose of the >> feature is to be able to provide a default implementation for interface >> evolution (which I believe is about time) I think it is better to stand up >> for that and make it as easy as possible to do it. >> > >> >> Hi Mikael, >> I think the syntax of defender method has some technical merits: >> - you can't add code to an interface without breaking all tools that >> take a look >> ? to the bytecode. >> - solving the problem of a class implementing two interfaces with two >> extension methods >> ? that collide is easier. They should have the same default. >> - you can easily retrofit existing collection API classes/interfaces to >> use extension method. >> - the syntax is close to the VM format. It's not like inner-classes or >> enums >> ? where the compiler generate lot of boilerplate code. >> ? A simple benefit is that reflection works like a charm. >> >> R?mi >> >> > >> > On Aug 5, 2010, at 0:52 AM, Neal Gafter wrote: >> > >> > >> >> On Wed, Aug 4, 2010 at 3:22 PM, Brian Goetz >> ?wrote: >> >> Your characterization of "keep interfaces code-free" is pretty close. >> ?While >> >> the introduction of default methods unfortunately dirties the >> distinction >> >> between interfaces and classes, we have taken a much smaller step than >> we >> >> could have (say, to mixins or traits or full multiple inheritance) in >> order to >> >> keep as much as possible to the true spirit of interfaces, which we >> still >> >> believe in. ?Therefore we believe that choosing a syntactic option that >> >> reflects that this philosophical leaning is in the best interest of the >> >> community. >> >> >> >> It seems you've technically observed the word of "keep interfaces >> code-free" without obeying the spirit of it. ?There is little point of >> putting the programmer through the pain of the separation in the current >> specification if the benefits of the separation don't accrue. >> >> >> > >> > >> >> >> > > From thomas.andreas.jung at googlemail.com Mon Aug 9 04:41:38 2010 From: thomas.andreas.jung at googlemail.com (Thomas Jung) Date: Mon, 9 Aug 2010 13:41:38 +0200 Subject: Defender Extension Methods -- Resolution and Invoccation In-Reply-To: References: Message-ID: Oh, I've ignored the fact that classes and interfaces are not the same in this respect as the inner class of an interface is public by default (i.e. can't be package private). My fault. Thomas On 9 August 2010 13:35, Roel Spilker wrote: > Reinier was refering to inner classes in interfaces. > >> -----Oorspronkelijk bericht----- >> Van: thomas.andreas.jung at googlemail.com >> [mailto:lambda-dev-bounces at openjdk.java.net] Namens Thomas Jung >> Verzonden: 09 August 2010 13:24 >> Aan: Reinier Zwitserloot >> CC: lambda-dev at openjdk.java.net >> Onderwerp: Re: Defender Extension Methods -- Resolution and >> Invoccation >> >> >but it REQUIRES that inner ?class to be public, and thus visible API. >> >> package x; >> public class X { >> ? ? class A{}; >> } >> >> That's not true. X.A can only be accessed from the package x. >> (So you have to generate javadoc with -package to expose the class A.) >> >> Although a private class would be nicer and inlined methods >> even nicer. >> >> Thomas >> >> On 9 August 2010 13:08, Reinier Zwitserloot >> wrote: >> > No need to go that far. An implementation provided 'inline' >> is simply >> > desugared to a 'default' that points to a nested class, >> just like the >> > boilerplate that has been shown in this thread plenty of >> times already. >> > >> > What happens if the default method is not >> accessible/visible from the >> > caller? i.e. why if the $ExtensionImpls class was private? >> Can the VM >> > deal with this as the Defender Extensions spec is currently >> defined? >> > It's not currently possible to define anything private in >> an interface >> > right now, but allowing "private" on inner classes is a >> simple change. >> > >> > >> > Separate from the idea of allowing inline implementations >> in addition >> > to pointing at a static method via 'default', how about allowing >> > private inner types in interfaces _regardless_? Even if inline >> > implementations aren't allowed, the boilerplate pattern of >> storing the >> > default implementations in an inner class is likely to be extremely >> > common, but it REQUIRES that inner class to be public, and thus >> > visible API. There's absolutely no reason for an API user >> to see that thing. It would have to have the following javadoc: >> > >> > /** Don't look at me. I don't exist. Really. Go away. */ >> > >> > which sounds like something we ought to fix. >> > >> > This fix becomes a lot more difficult if the 'default' >> method has to >> > be visible/accessible from callers. >> > >> > ?--Reinier Zwitserloot >> > >> > >> > >> > On Thu, Aug 5, 2010 at 1:38 AM, R?mi Forax >> wrote: >> > >> >> Le 05/08/2010 00:59, Mikael Grev a ?crit : >> >> > Thanks Neal, this reflect my stance as well. >> >> > >> >> > Making it hard for the end user is never good. If the purpose of >> >> > the >> >> feature is to be able to provide a default implementation for >> >> interface evolution (which I believe is about time) I think it is >> >> better to stand up for that and make it as easy as >> possible to do it. >> >> > >> >> >> >> Hi Mikael, >> >> I think the syntax of defender method has some technical merits: >> >> - you can't add code to an interface without breaking all >> tools that >> >> take a look >> >> ? to the bytecode. >> >> - solving the problem of a class implementing two >> interfaces with two >> >> extension methods >> >> ? that collide is easier. They should have the same default. >> >> - you can easily retrofit existing collection API >> classes/interfaces >> >> to use extension method. >> >> - the syntax is close to the VM format. It's not like >> inner-classes >> >> or enums >> >> ? where the compiler generate lot of boilerplate code. >> >> ? A simple benefit is that reflection works like a charm. >> >> >> >> R?mi >> >> >> >> > >> >> > On Aug 5, 2010, at 0:52 AM, Neal Gafter wrote: >> >> > >> >> > >> >> >> On Wed, Aug 4, 2010 at 3:22 PM, Brian >> >> >> Goetz >> >> ?wrote: >> >> >> Your characterization of "keep interfaces code-free" is >> pretty close. >> >> ?While >> >> >> the introduction of default methods unfortunately dirties the >> >> distinction >> >> >> between interfaces and classes, we have taken a much >> smaller step >> >> >> than >> >> we >> >> >> could have (say, to mixins or traits or full multiple >> inheritance) >> >> >> in >> >> order to >> >> >> keep as much as possible to the true spirit of >> interfaces, which >> >> >> we >> >> still >> >> >> believe in. ?Therefore we believe that choosing a >> syntactic option >> >> >> that reflects that this philosophical leaning is in the best >> >> >> interest of the community. >> >> >> >> >> >> It seems you've technically observed the word of "keep >> interfaces >> >> code-free" without obeying the spirit of it. ?There is >> little point >> >> of putting the programmer through the pain of the >> separation in the >> >> current specification if the benefits of the separation >> don't accrue. >> >> >> >> >> > >> >> > >> >> >> >> >> >> >> > >> > >> >> > > From nathan.bryant at linkshare.com Mon Aug 9 08:01:33 2010 From: nathan.bryant at linkshare.com (Nathan Bryant) Date: Tue, 10 Aug 2010 00:01:33 +0900 Subject: Fun with method references References: <4C59DC91.5090300@oracle.com><4C59E066.6040807@oracle.com> <4C59E6D4.50104@univ-mlv.fr><4C59E999.7070900@oracle.com><7FDA6630E1822F448C97A48D5D73309401473E9C@EXVMSTOR302.intra.rakuten.co.jp><4C5C6EEE.5010803@oracle.com><7FDA6630E1822F448C97A48D5D73309401473EAC@EXVMSTOR302.intra.rakuten.co.jp><4C5C7442.80406@oracle.com> <4C5C8330.3010608@univ-mlv.fr><4C5C863A.7040505@univ-mlv.fr> Message-ID: <7FDA6630E1822F448C97A48D5D7330940147420B@EXVMSTOR302.intra.rakuten.co.jp> Fredrik Ohrstrom wrote: > Exactly. I strongly believe that we need function types. > Whatever restrictions that are put upon them due to > erasure, will be lifted whenever we get erasure. How, exactly? Introducing reification is an incompatible change. From tom.hawtin at oracle.com Mon Aug 9 08:26:02 2010 From: tom.hawtin at oracle.com (tom.hawtin at oracle.com) Date: Mon, 09 Aug 2010 16:26:02 +0100 Subject: Fun with method references In-Reply-To: References: Message-ID: <4C601E0A.5050609@oracle.com> On 09/08/2010 01:37, Howard Lovatt wrote: > The problem is that both foo(Handler) and foo(Handler) > get erased to foo(Handler) and therefore they both can't exist in the > same class (they have the same signature in the class file). If > generics ere reified then you could have both methods in the same > class since they would have different signatures. The same goes for > any other feature, including function types, that is implemented via > erasure. The generics information is still in the class file format and is available at link-time (and also through the reflection APIs). A necessary change would be for Java SE 7 to allow class files with methods that vary only in generics. As the method resolution magic happens at link-time, there is no need for objects to contain generic information at run-time. OTOH, I'm not a big fan of overloading. Keep it explicit. Tom From maurizio.cimadamore at oracle.com Mon Aug 9 08:28:49 2010 From: maurizio.cimadamore at oracle.com (maurizio.cimadamore at oracle.com) Date: Mon, 09 Aug 2010 15:28:49 +0000 Subject: hg: lambda/lambda/langtools: Fixed some bugs: Message-ID: <20100809152855.032B347001@hg.openjdk.java.net> Changeset: aa43887d183f Author: mcimadamore Date: 2010-08-09 16:27 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/aa43887d183f Fixed some bugs: *) target-type inference failure when target method in a lambda conversion contains wildcards in return-type position *) NPE in Infer.java *) target-type inference failure when target method in lambda conversion is vararg method *) Problems when reading a classfile that has MethodHandle CP entries ! src/share/classes/com/sun/tools/javac/code/Types.java ! src/share/classes/com/sun/tools/javac/comp/Attr.java ! src/share/classes/com/sun/tools/javac/comp/Infer.java ! src/share/classes/com/sun/tools/javac/comp/Resolve.java ! src/share/classes/com/sun/tools/javac/jvm/ClassReader.java ! src/share/classes/com/sun/tools/javac/parser/JavacParser.java ! test/tools/javac/lambda/TargetType04.out + test/tools/javac/lambda/TargetType10.java + test/tools/javac/lambda/TargetType11.java + test/tools/javac/lambda/badMemberRefBytecode/Main.java + test/tools/javac/lambda/badMemberRefBytecode/TestBadMemberRefBytecode.java + test/tools/javac/lambda/badMemberRefBytecode/Use.java From pbenedict at apache.org Mon Aug 9 08:37:41 2010 From: pbenedict at apache.org (Paul Benedict) Date: Mon, 9 Aug 2010 10:37:41 -0500 Subject: JDK 7 Schedule and Lambdas Message-ID: To everyone, Here's the posted JDK 7 milestone schedule: http://openjdk.java.net/projects/jdk7/milestones/ Build 104 was pushed on Friday and there is exactly one month left til 9/9, when is the last build scheduled. I understand there is no obligation for Oracle to discuss internal resource planning, but can anything be said about the remaining 30 days? Or is such an announcement reserved for JavaOne? The ideas and implementation on this list are brewing nicely. I am concerned, however, it will be impossible to be complete with these discussions in the next month. I imagine there are still months to go before settling on what should be the "correct" proposal. Paul From maurizio.cimadamore at oracle.com Mon Aug 9 08:40:25 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Mon, 09 Aug 2010 16:40:25 +0100 Subject: Fun with method references In-Reply-To: <4C601E0A.5050609@oracle.com> References: <4C601E0A.5050609@oracle.com> Message-ID: <4C602169.4010401@oracle.com> On 09/08/10 16:26, tom.hawtin at oracle.com wrote: > On 09/08/2010 01:37, Howard Lovatt wrote: > > >> The problem is that both foo(Handler) and foo(Handler) >> get erased to foo(Handler) and therefore they both can't exist in the >> same class (they have the same signature in the class file). If >> generics ere reified then you could have both methods in the same >> class since they would have different signatures. The same goes for >> any other feature, including function types, that is implemented via >> erasure. >> > The generics information is still in the class file format and is > available at link-time (and also through the reflection APIs). A > necessary change would be for Java SE 7 to allow class files with > methods that vary only in generics. As the method resolution magic > happens at link-time, there is no need for objects to contain generic > information at run-time. > True - however we ought not to forget about 1.4 clients who see no generics at all and, as a result, will not be able to choose between two methods with the same erased signature. Maurizio > OTOH, I'm not a big fan of overloading. Keep it explicit. > > Tom > > From fweimer at bfk.de Mon Aug 9 10:22:32 2010 From: fweimer at bfk.de (Florian Weimer) Date: Mon, 09 Aug 2010 17:22:32 +0000 Subject: Trying the prototype In-Reply-To: <4C5C6875.3090105@oracle.com> (maurizio cimadamore's message of "Fri\, 06 Aug 2010 20\:54\:29 +0100") References: <4C5C6875.3090105@oracle.com> Message-ID: <82bp9blmzr.fsf@mid.bfk.de> * maurizio cimadamore: > 2) build the compiler > > cd langtools/make > > ant -Dboot.java.home= -Dtarget.java.home= > build-all-tools Does this mean that the Project Lambda javac works with an otherwise unmodified JDK 7? Would it be very difficult to get it to work under JDK 6, too? Presumably, that would make experimentation much, much easier. -- Florian Weimer BFK edv-consulting GmbH http://www.bfk.de/ Kriegsstra?e 100 tel: +49-721-96201-1 D-76133 Karlsruhe fax: +49-721-96201-99 From maurizio.cimadamore at oracle.com Mon Aug 9 10:30:18 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Mon, 09 Aug 2010 18:30:18 +0100 Subject: Trying the prototype In-Reply-To: <82bp9blmzr.fsf@mid.bfk.de> References: <4C5C6875.3090105@oracle.com> <82bp9blmzr.fsf@mid.bfk.de> Message-ID: <4C603B2A.8080708@oracle.com> On 09/08/10 18:22, Florian Weimer wrote: > * maurizio cimadamore: > > >> 2) build the compiler >> >> cd langtools/make >> >> ant -Dboot.java.home= -Dtarget.java.home= >> build-all-tools >> > Does this mean that the Project Lambda javac works with an otherwise > unmodified JDK 7? > Yes, because changes are now localized in the compiler area. > Would it be very difficult to get it to work under JDK 6, too? > Presumably, that would make experimentation much, much easier. > > I guess it would be harder - some of the features provided by the lambda compiler sit on top of the VM support for method handles which is a recent addition to JDK 7. Maurizio From forax at univ-mlv.fr Mon Aug 9 13:19:08 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Mon, 09 Aug 2010 22:19:08 +0200 Subject: Trying the prototype In-Reply-To: <4C603B2A.8080708@oracle.com> References: <4C5C6875.3090105@oracle.com> <82bp9blmzr.fsf@mid.bfk.de> <4C603B2A.8080708@oracle.com> Message-ID: <4C6062BC.7020701@univ-mlv.fr> Le 09/08/2010 19:30, Maurizio Cimadamore a ?crit : > On 09/08/10 18:22, Florian Weimer wrote: > >> * maurizio cimadamore: >> >> >> >>> 2) build the compiler >>> >>> cd langtools/make >>> >>> ant -Dboot.java.home= -Dtarget.java.home= >>> build-all-tools >>> >>> >> Does this mean that the Project Lambda javac works with an otherwise >> unmodified JDK 7? >> >> > Yes, because changes are now localized in the compiler area. > >> Would it be very difficult to get it to work under JDK 6, too? >> Presumably, that would make experimentation much, much easier. >> >> >> > I guess it would be harder - some of the features provided by the lambda > compiler sit on top of the VM support for method handles which is a > recent addition to JDK 7. > I've written a backport of JSR 292 API compatible with 1.5, 1.6 VM. see http://code.google.com/p/jvm-language-runtime/downloads/list > Maurizio > R?mi From hlklaperman at gmail.com Mon Aug 9 15:27:07 2010 From: hlklaperman at gmail.com (Harrison Klaperman) Date: Mon, 9 Aug 2010 18:27:07 -0400 Subject: Trying the prototype on Mac OS X (possible?) Message-ID: I've been lurking on this mailing list for several months now and would like to experiment with the prototype. ?Unfortunately, there doesn't seem to be a binary snapshot of JDK7 available for my operating system, Mac OS 10.6. ?I know that Apple insists on providing its own version of a "recent" JDK with its OS. ?Does that mean there's no way of trying a different implementation/version? ?Would I have to build from source? ?Thank you very much for your help! Best, Harrison From reinier at zwitserloot.com Mon Aug 9 16:28:04 2010 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 10 Aug 2010 01:28:04 +0200 Subject: Trying the prototype on Mac OS X (possible?) In-Reply-To: References: Message-ID: Just grab soylatte, then hg the OpenJDK, compile it using soylatte, and use that for the rest. I doubt it'll run swing, but I doubt you need it. NB: Soylatte's homepage insinuates it won't work in snow leopard, but it works just fine. Grab the 64-bit 10.5 build. http://landonf.bikemonkey.org/static/soylatte/ --Reinier Zwitserloot On Tue, Aug 10, 2010 at 12:27 AM, Harrison Klaperman wrote: > I've been lurking on this mailing list for several months now and > would like to experiment with the prototype. Unfortunately, there > doesn't seem to be a binary snapshot of JDK7 available for my > operating system, Mac OS 10.6. I know that Apple insists on providing > its own version of a "recent" JDK with its OS. Does that mean there's > no way of trying a different implementation/version? Would I have to > build from source? Thank you very much for your help! > > Best, > Harrison > > From anrizal05 at yahoo.fr Mon Aug 9 23:16:28 2010 From: anrizal05 at yahoo.fr (Rizal Anwar) Date: Tue, 10 Aug 2010 06:16:28 +0000 (GMT) Subject: Question on exception transparency Message-ID: <705619.2671.qm@web24208.mail.ird.yahoo.com> Hi, I played around with the prototype, and I have a question on exception transparency, especially in type inference. I have the following interface: public interface Block { void run(T param) throws E; } and the following code (assuming ListUtil.foreach is a method accepting a list and a Block). public static void main(String args[]) { List myList = Arrays.asList("A", "B", "K"); try { ListUtil.foreach( myList, Block #(x) {execute(x)}); //////////////////////////////////////////////////////////// } catch (BlockExecutionException e) { e.printStackTrace(); } } private static void execute(String x) throws BlockExecutionException { System.out.println("Execute" + x); } } I wonder whether there is a way not to specify the target Block in the closure I use in the above code ? Isn't is possible to infer the type ? Best regards, Anwar Rizal. From neal at gafter.com Mon Aug 9 23:45:38 2010 From: neal at gafter.com (Neal Gafter) Date: Mon, 9 Aug 2010 23:45:38 -0700 Subject: Question on exception transparency In-Reply-To: <705619.2671.qm@web24208.mail.ird.yahoo.com> References: <705619.2671.qm@web24208.mail.ird.yahoo.com> Message-ID: On Mon, Aug 9, 2010 at 11:16 PM, Rizal Anwar wrote: > Hi, > > I played around with the prototype, and I have a question on exception > transparency, especially in type inference. > > I have the following interface: > > > public interface Block { > void run(T param) throws E; > } > > and the following code (assuming ListUtil.foreach is a method accepting a > list > and a Block). > > public static void main(String args[]) { > List myList = Arrays.asList("A", "B", "K"); > try { > ListUtil.foreach( > myList, > Block #(x) {execute(x)}); > //////////////////////////////////////////////////////////// > > } > catch (BlockExecutionException e) { > e.printStackTrace(); > } > } > > private static void execute(String x) throws BlockExecutionException { > System.out.println("Execute" + x); > } > } > > I wonder whether there is a way not to specify the target Block BlockExecutionException> in the closure I use in the above code ? > Isn't is possible to infer the type ? > We know it is possible, as BGGA does just that. However, project lambda cannot use the BGGA approach, as it does not resolve names in the enclosing scope, but instead resolves names in the scope of the SAM being constructed. In your example, project lambda requires the target SAM type in order to determine which method "execute" is being invoked (it might be a method inherited from the SAM). It needs to know what method that is to know what exceptions it throws. It needs to know the thrown exception types to determine the target SAM. This catch-22 is broken in project lambda by requiring the SAM type be made explicit when the lambda is a parameter to a method invocation. There are two simple ways to address this: (1) Leave things as they are, requiring an explicit target type when lambdas are passed as parameters. In that case lambda expressions can best be though of as a slightly shorter syntax for anonymous inner classes that otherwise suffer all the same problems. (2) Simplify lambda scoping to be lexical, enabling the target type to be inferred as in BGGA It is imaginable that some not-yet-discovered and probably complex, subtle, and clever technique would enable both type inference and project lambda's problematic scoping. No such scheme has yet been proposed. From fweimer at bfk.de Tue Aug 10 01:26:55 2010 From: fweimer at bfk.de (Florian Weimer) Date: Tue, 10 Aug 2010 08:26:55 +0000 Subject: lambda syntax tutorial In-Reply-To: <4C59999E.8050609@oracle.com> (Maurizio Cimadamore's message of "Wed\, 04 Aug 2010 17\:47\:26 +0100") References: <4C59999E.8050609@oracle.com> Message-ID: <82fwymj2k0.fsf@mid.bfk.de> * Maurizio Cimadamore: > Defender methods are declared using the 'extension' keyword, as follows: > > extension List map(Mapper r) default Collections.listMapper; So it seems that "extension" comes after the type parameters, as in: extension T runL(Txn txn) throws SQLException, E default ConnectionPools.runL; I think that's a bit surprising. -- Florian Weimer BFK edv-consulting GmbH http://www.bfk.de/ Kriegsstra?e 100 tel: +49-721-96201-1 D-76133 Karlsruhe fax: +49-721-96201-99 From scolebourne at joda.org Tue Aug 10 01:59:25 2010 From: scolebourne at joda.org (Stephen Colebourne) Date: Tue, 10 Aug 2010 09:59:25 +0100 Subject: lambda syntax tutorial In-Reply-To: <82fwymj2k0.fsf@mid.bfk.de> References: <4C59999E.8050609@oracle.com> <82fwymj2k0.fsf@mid.bfk.de> Message-ID: On 10 August 2010 09:26, Florian Weimer wrote: > So it seems that "extension" comes after the type parameters, as in: > > ? ? extension T runL(Txn txn) throws SQLException, E > ? ? ? ? ? default ConnectionPools.runL; > > I think that's a bit surprising. Yep. If we are forced to have "extension" (why not "default"?) then it should be positioned as it would be for public/private/static/final etc. Stephen From maurizio.cimadamore at oracle.com Tue Aug 10 02:56:28 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Tue, 10 Aug 2010 10:56:28 +0100 Subject: Question on exception transparency In-Reply-To: <705619.2671.qm@web24208.mail.ird.yahoo.com> References: <705619.2671.qm@web24208.mail.ird.yahoo.com> Message-ID: <4C61224C.2000303@oracle.com> Hi your code contains an example of circular inference (as the unknown type of a lambda parameter is used in order to perform method resolution inside the lambda body); there are three ways to solve this: 1) You can type in the target type explicitly (as you've done); this lead to the rather verbose: foreach(..., Block #(x) {execute(x)}); 2) You can secify explicit type-parameters for the 'foreach' method: foreach(..., #(x) {execute(x)}); 3) You can specify the type of the lambda parameter: foreach(..., #(String x) {execute(x)}); The alternative (3) looks the less verbose. [Note: in this particular case I think there's room for type-inference to swallow the circularity, as there's just one 'execute()' method - however, in the general case, it is not safe to do so, as there could be multiple overloaded version of the called method, or, the thrown types of the called method could be generic in a 'throws' type-variable - in such cases the 'real' type of the lambda parameter can significantly alter the way in which lambda thrown types are inferred - as such, the compiler must play the conservative card and infer Exception]. Maurizio On 10/08/10 07:16, Rizal Anwar wrote: > Hi, > > I played around with the prototype, and I have a question on exception > transparency, especially in type inference. > > I have the following interface: > > > public interface Block { > void run(T param) throws E; > } > > and the following code (assuming ListUtil.foreach is a method accepting a list > and a Block). > > public static void main(String args[]) { > List myList = Arrays.asList("A", "B", "K"); > try { > ListUtil.foreach( > myList, > Block #(x) {execute(x)}); > //////////////////////////////////////////////////////////// > > } > catch (BlockExecutionException e) { > e.printStackTrace(); > } > } > > private static void execute(String x) throws BlockExecutionException { > System.out.println("Execute" + x); > } > } > > I wonder whether there is a way not to specify the target Block BlockExecutionException> in the closure I use in the above code ? > Isn't is possible to infer the type ? > > Best regards, > Anwar Rizal. > > > > > From fweimer at bfk.de Tue Aug 10 03:09:09 2010 From: fweimer at bfk.de (Florian Weimer) Date: Tue, 10 Aug 2010 10:09:09 +0000 Subject: Trying to benefit from exception transparency Message-ID: <82fwymhj96.fsf@mid.bfk.de> I'm trying to replace some exsting APIs with something that provides exception transparency. I expected the example below to compile: import java.sql.SQLException; class Main { public static void main(ConnectionPool pool) throws SQLException { pool.run(Txn #{ // *** query("SELECT 1"); }); } } interface ConnectionPool { T run(Txn txn) throws SQLException, E; } abstract class Txn { protected final void query(String statement) throws SQLException { } protected abstract T run() throws E; } But I get an NPE, related to the line marked ***: java.lang.NullPointerException at com.sun.tools.javac.comp.TransTypes.visitIdent(TransTypes.java:702) at com.sun.tools.javac.tree.JCTree$JCIdent.accept(JCTree.java:1817) at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:58) at com.sun.tools.javac.comp.TransTypes.translate(TransTypes.java:425) at com.sun.tools.javac.comp.TransTypes.visitApply(TransTypes.java:594) at com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1323) at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:58) at com.sun.tools.javac.comp.TransTypes.translate(TransTypes.java:425) at com.sun.tools.javac.comp.TransTypes.visitExec(TransTypes.java:572) at com.sun.tools.javac.tree.JCTree$JCExpressionStatement.accept(JCTree.java:1166) at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:58) at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:70) at com.sun.tools.javac.tree.TreeTranslator.visitBlock(TreeTranslator.java:160) at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:789) at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:58) at com.sun.tools.javac.comp.TransTypes.translate(TransTypes.java:425) at com.sun.tools.javac.comp.TransTypes.visitMethodDef(TransTypes.java:461) at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:672) at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:58) at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:70) at com.sun.tools.javac.tree.TreeTranslator.visitClassDef(TreeTranslator.java:134) at com.sun.tools.javac.comp.TransTypes.translateClass(TransTypes.java:811) at com.sun.tools.javac.comp.TransTypes.translateClass(TransTypes.java:794) at com.sun.tools.javac.comp.TransTypes.visitClassDef(TransTypes.java:447) at com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:601) at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:58) at com.sun.tools.javac.comp.TransTypes.translate(TransTypes.java:425) at com.sun.tools.javac.comp.TransTypes.visitNewClass(TransTypes.java:625) at com.sun.tools.javac.tree.JCTree$JCNewClass.accept(JCTree.java:1377) at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:58) at com.sun.tools.javac.comp.TransTypes.translate(TransTypes.java:425) at com.sun.tools.javac.comp.TransTypes.translateArgs(TransTypes.java:196) at com.sun.tools.javac.comp.TransTypes.visitApply(TransTypes.java:610) at com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1323) at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:58) at com.sun.tools.javac.comp.TransTypes.translate(TransTypes.java:425) at com.sun.tools.javac.comp.TransTypes.visitExec(TransTypes.java:572) at com.sun.tools.javac.tree.JCTree$JCExpressionStatement.accept(JCTree.java:1166) at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:58) at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:70) at com.sun.tools.javac.tree.TreeTranslator.visitBlock(TreeTranslator.java:160) at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:789) at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:58) at com.sun.tools.javac.comp.TransTypes.translate(TransTypes.java:425) at com.sun.tools.javac.comp.TransTypes.visitMethodDef(TransTypes.java:461) at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:672) at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:58) at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:70) at com.sun.tools.javac.tree.TreeTranslator.visitClassDef(TreeTranslator.java:134) at com.sun.tools.javac.comp.TransTypes.translateClass(TransTypes.java:811) at com.sun.tools.javac.comp.TransTypes.visitClassDef(TransTypes.java:447) at com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:601) at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:58) at com.sun.tools.javac.comp.TransTypes.translate(TransTypes.java:425) at com.sun.tools.javac.comp.TransTypes.translateTopLevelClass(TransTypes.java:836) at com.sun.tools.javac.main.JavaCompiler.desugar(JavaCompiler.java:1323) at com.sun.tools.javac.main.JavaCompiler.desugar(JavaCompiler.java:1213) at com.sun.tools.javac.main.JavaCompiler.compile2(JavaCompiler.java:849) at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:808) at com.sun.tools.javac.main.Main.compile(Main.java:409) at com.sun.tools.javac.main.Main.compile(Main.java:327) at com.sun.tools.javac.main.Main.compile(Main.java:318) at com.sun.tools.javac.Main.compile(Main.java:82) at com.sun.tools.javac.Main.main(Main.java:67) When I replace the *** line with pool.run(#{ I get an error from the compiler: Main.java:5: unreported exception Exception; must be caught or declared to be thrown pool.run(#{ ^ It is not clear to me why the compiler would infer that Exception is thrown by this piece of code. I'm at this compiler version: changeset: 622:aa43887d183f tag: tip user: mcimadamore date: Mon Aug 09 16:27:25 2010 +0100 summary: Fixed some bugs: -- Florian Weimer BFK edv-consulting GmbH http://www.bfk.de/ Kriegsstra?e 100 tel: +49-721-96201-1 D-76133 Karlsruhe fax: +49-721-96201-99 From maurizio.cimadamore at oracle.com Tue Aug 10 03:38:02 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Tue, 10 Aug 2010 11:38:02 +0100 Subject: Trying to benefit from exception transparency In-Reply-To: <82fwymhj96.fsf@mid.bfk.de> References: <82fwymhj96.fsf@mid.bfk.de> Message-ID: <4C612C0A.7040305@oracle.com> The NPE is obviously a bug; the target type is required in this case as you are accessing a member of 'this' (whose type is the very type that needs to be inferred). Maurizio On 10/08/10 11:09, Florian Weimer wrote: > import java.sql.SQLException; > > class Main { > public static void main(ConnectionPool pool) throws SQLException { > pool.run(Txn #{ // *** > query("SELECT 1"); > }); > } > } > > interface ConnectionPool { > T run(Txn txn) throws SQLException, E; > } > > abstract class Txn { > protected final void query(String statement) throws SQLException { > } > > protected abstract T run() throws E; > } > > From fweimer at bfk.de Tue Aug 10 03:51:29 2010 From: fweimer at bfk.de (Florian Weimer) Date: Tue, 10 Aug 2010 10:51:29 +0000 Subject: Trying to benefit from exception transparency In-Reply-To: <4C612C0A.7040305@oracle.com> (Maurizio Cimadamore's message of "Tue\, 10 Aug 2010 11\:38\:02 +0100") References: <82fwymhj96.fsf@mid.bfk.de> <4C612C0A.7040305@oracle.com> Message-ID: <8262zihham.fsf@mid.bfk.de> * Maurizio Cimadamore: > The NPE is obviously a bug; the target type is required in this case > as you are accessing a member of 'this' (whose type is the very type > that needs to be inferred). Then there's another bug. I've got code which accesses a member of "this" without specifying the target type (but with Exception inferred as the exception). I also don't see why specifying the target type should be necessary in this case. -- Florian Weimer BFK edv-consulting GmbH http://www.bfk.de/ Kriegsstra?e 100 tel: +49-721-96201-1 D-76133 Karlsruhe fax: +49-721-96201-99 From maurizio.cimadamore at oracle.com Tue Aug 10 03:56:41 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Tue, 10 Aug 2010 11:56:41 +0100 Subject: Trying to benefit from exception transparency In-Reply-To: <8262zihham.fsf@mid.bfk.de> References: <82fwymhj96.fsf@mid.bfk.de> <4C612C0A.7040305@oracle.com> <8262zihham.fsf@mid.bfk.de> Message-ID: <4C613069.40808@oracle.com> On 10/08/10 11:51, Florian Weimer wrote: > * Maurizio Cimadamore: > > >> The NPE is obviously a bug; the target type is required in this case >> as you are accessing a member of 'this' (whose type is the very type >> that needs to be inferred). >> > Then there's another bug. I've got code which accesses a member of > "this" without specifying the target type (but with Exception inferred > as the exception). > My answer covered both issues ;-) Maurizio > I also don't see why specifying the target type should be necessary in > this case. > > From maurizio.cimadamore at oracle.com Tue Aug 10 04:29:47 2010 From: maurizio.cimadamore at oracle.com (maurizio.cimadamore at oracle.com) Date: Tue, 10 Aug 2010 11:29:47 +0000 Subject: hg: lambda/lambda/langtools: Superclasses of synthetic classes generated by Unlambda.java should be desugared first. Message-ID: <20100810112949.3DF9A47048@hg.openjdk.java.net> Changeset: 3612c14649dc Author: mcimadamore Date: 2010-08-10 12:28 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/3612c14649dc Superclasses of synthetic classes generated by Unlambda.java should be desugared first. ! src/share/classes/com/sun/tools/javac/main/JavaCompiler.java + test/tools/javac/lambda/BadOrder.java From fweimer at bfk.de Wed Aug 11 08:55:33 2010 From: fweimer at bfk.de (Florian Weimer) Date: Wed, 11 Aug 2010 15:55:33 +0000 Subject: Trying to benefit from exception transparency In-Reply-To: <4C613069.40808@oracle.com> (Maurizio Cimadamore's message of "Tue\, 10 Aug 2010 11\:56\:41 +0100") References: <82fwymhj96.fsf@mid.bfk.de> <4C612C0A.7040305@oracle.com> <8262zihham.fsf@mid.bfk.de> <4C613069.40808@oracle.com> Message-ID: <82aaot9ma2.fsf@mid.bfk.de> * Maurizio Cimadamore: > On 10/08/10 11:51, Florian Weimer wrote: >> * Maurizio Cimadamore: >> >> >>> The NPE is obviously a bug; the target type is required in this case >>> as you are accessing a member of 'this' (whose type is the very type >>> that needs to be inferred). >>> >> Then there's another bug. I've got code which accesses a member of >> "this" without specifying the target type (but with Exception inferred >> as the exception). >> > My answer covered both issues ;-) Ah, okay. Is it true that tag: tip user: mcimadamore date: Tue Aug 10 12:28:18 2010 +0100 summary: Superclasses of synthetic classes generated by Unlambda.java should be desugared first. only fixed one of them? (Otherwise I'm even more confused.) -- Florian Weimer BFK edv-consulting GmbH http://www.bfk.de/ Kriegsstra?e 100 tel: +49-721-96201-1 D-76133 Karlsruhe fax: +49-721-96201-99 From maurizio.cimadamore at oracle.com Wed Aug 11 09:18:49 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 11 Aug 2010 17:18:49 +0100 Subject: Trying to benefit from exception transparency In-Reply-To: <82aaot9ma2.fsf@mid.bfk.de> References: <82fwymhj96.fsf@mid.bfk.de> <4C612C0A.7040305@oracle.com> <8262zihham.fsf@mid.bfk.de> <4C613069.40808@oracle.com> <82aaot9ma2.fsf@mid.bfk.de> Message-ID: <4C62CD69.9030703@oracle.com> On 11/08/10 16:55, Florian Weimer wrote: > * Maurizio Cimadamore: > > >> On 10/08/10 11:51, Florian Weimer wrote: >> >>> * Maurizio Cimadamore: >>> >>> >>> >>>> The NPE is obviously a bug; the target type is required in this case >>>> as you are accessing a member of 'this' (whose type is the very type >>>> that needs to be inferred). >>>> >>>> >>> Then there's another bug. I've got code which accesses a member of >>> "this" without specifying the target type (but with Exception inferred >>> as the exception). >>> >>> >> My answer covered both issues ;-) >> > Ah, okay. Is it true that > > tag: tip > user: mcimadamore > date: Tue Aug 10 12:28:18 2010 +0100 > summary: Superclasses of synthetic classes generated by Unlambda.java should be desugared first. > > only fixed one of them? (Otherwise I'm even more confused.) > > That's true. I fixed the NPE as that was clearly a bug. The other issue (compiler inferring Exception) is not a bug, but a limitation of the inference scheme when the compiler detects a loop when performing type-inference. We could issue a warning for that. Maurizio From thomas.andreas.jung at googlemail.com Thu Aug 12 00:13:49 2010 From: thomas.andreas.jung at googlemail.com (Thomas Jung) Date: Thu, 12 Aug 2010 09:13:49 +0200 Subject: NullPointerException when type parameters are infered from method parameters Message-ID: Hi, I tried to implement the method reference example given on the mailing list and got a NullPointerException in the compiler. The first version sortBy works. The second version throws the exception. public static > void sortBy(T[] array, final Extractor extractor) { Comparator comparator = #(T left, T right){extractor.get(left).compareTo(extractor.get(right)) }; Arrays.sort(array, comparator); } public static > void sortBy2(T[] array, Extractor extractor) { Comparator comparator = #(left, right){extractor.get(left).compareTo(extractor.get(right)) }; Arrays.sort(array, comparator); } String[] input = {"ab", "a", "c", "ba", "afd", "b"}; Arrays2.sortBy(input, String#length); //unstable sort by length String[] expected = {"a", "c", "b", "ab", "ba", "afd"}; assertArrayEquals(input, expected); java.lang.NullPointerException at com.sun.tools.javac.comp.Flow.visitApply(Flow.java:1194) at com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1323) at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49) at com.sun.tools.javac.comp.Flow.scanStat(Flow.java:527) at com.sun.tools.javac.comp.Flow.visitLambda(Flow.java:1269) at com.sun.tools.javac.tree.JCTree$JCLambda.accept(JCTree.java:1479) at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49) at com.sun.tools.javac.comp.Flow.analyzeTree(Flow.java:1442) at com.sun.tools.javac.comp.Flow.analyzeLambda(Flow.java:1239) at com.sun.tools.javac.comp.Attr.attribLambda(Attr.java:2228) at com.sun.tools.javac.comp.Attr.inferLambda(Attr.java:2132) at com.sun.tools.javac.comp.Attr.visitLambda(Attr.java:2081) at com.sun.tools.javac.tree.JCTree$JCLambda.accept(JCTree.java:1479) at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:434) at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:452) at com.sun.tools.javac.comp.Attr.attribExpr(Attr.java:456) at com.sun.tools.javac.comp.Attr.visitVarDef(Attr.java:846) at com.sun.tools.javac.tree.JCTree$JCVariableDecl.accept(JCTree.java:733) at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:434) at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:452) at com.sun.tools.javac.comp.Attr.attribStat(Attr.java:483) at com.sun.tools.javac.comp.Attr.attribStats(Attr.java:499) at com.sun.tools.javac.comp.Attr.visitBlock(Attr.java:877) at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:789) at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:434) at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:452) at com.sun.tools.javac.comp.Attr.attribStat(Attr.java:483) at com.sun.tools.javac.comp.Attr.visitMethodDef(Attr.java:783) at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:672) at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:434) at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:452) at com.sun.tools.javac.comp.Attr.attribStat(Attr.java:483) at com.sun.tools.javac.comp.Attr.attribClassBody(Attr.java:3608) at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:3531) at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:3467) at com.sun.tools.javac.comp.Attr.visitClassDef(Attr.java:664) at com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:601) at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:434) at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:452) at com.sun.tools.javac.comp.Attr.attribStat(Attr.java:483) at com.sun.tools.javac.comp.Attr.attribClassBody(Attr.java:3608) at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:3531) at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:3467) at com.sun.tools.javac.main.JavaCompiler.attribute(JavaCompiler.java:1129) at com.sun.tools.javac.main.JavaCompiler.compile2(JavaCompiler.java:849) at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:808) at com.sun.tools.javac.main.Main.compile(Main.java:409) at com.sun.tools.javac.main.Main.compile(Main.java:327) at com.sun.tools.javac.main.Main.compile(Main.java:318) at com.sun.tools.javac.Main.compile(Main.java:100) Thomas From maurizio.cimadamore at oracle.com Thu Aug 12 04:11:34 2010 From: maurizio.cimadamore at oracle.com (maurizio.cimadamore at oracle.com) Date: Thu, 12 Aug 2010 11:11:34 +0000 Subject: hg: lambda/lambda/langtools: Flow should not analyze lambda body that contains errors due to partially specified parameter types Message-ID: <20100812111140.346E1470DB@hg.openjdk.java.net> Changeset: f8912a5acc0a Author: mcimadamore Date: 2010-08-12 12:04 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/f8912a5acc0a Flow should not analyze lambda body that contains errors due to partially specified parameter types ! src/share/classes/com/sun/tools/javac/code/Flags.java ! src/share/classes/com/sun/tools/javac/comp/Attr.java ! src/share/classes/com/sun/tools/javac/comp/AttrContext.java ! src/share/classes/com/sun/tools/javac/util/Log.java ! src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java + test/tools/javac/lambda/TargetType12.java From peter.levart at marand.si Thu Aug 12 05:40:05 2010 From: peter.levart at marand.si (Peter Levart) Date: Thu, 12 Aug 2010 14:40:05 +0200 Subject: Question on exception transparency In-Reply-To: <4C61224C.2000303@oracle.com> References: <705619.2671.qm@web24208.mail.ird.yahoo.com> <4C61224C.2000303@oracle.com> Message-ID: <201008121440.06446.peter.levart@marand.si> Hello Maurizio (and Brian), On 08/10/10, Maurizio Cimadamore wrote: > Hi > your code contains an example of circular inference (as the unknown type > of a lambda parameter is used in order to perform method resolution > inside the lambda body); there are three ways to solve this: > > 1) You can type in the target type explicitly (as you've done); this > lead to the rather verbose: > > foreach(..., Block #(x) {execute(x)}); > > > 2) You can secify explicit type-parameters for the 'foreach' method: > > foreach(..., #(x) {execute(x)}); > > > 3) You can specify the type of the lambda parameter: > > foreach(..., #(String x) {execute(x)}); Well, neither of your workarounds (even if applied together - example 2 below) currently works, I believe, because of bugs in the prototype. But I think it is vital to make the following code (example 1) work: import java.util.*; public class Closures { public interface Block { void run(T param) throws E; } public static void forEach(Iterable iterable, Block block) throws E { for (T obj : iterable) block.run(obj); } public static void main(String[] args) { // example 1: forEach( Arrays.asList("a", "b", "c"), #(String s){ System.out.println("element: " + s); } ); // example 2 - javac throws NPE: // Closures.forEach( // Arrays.asList("a", "b", "c"), // Block #(String s){ System.out.println("element: " + s); } // ); } } Example 1 represents the majority of use cases when consuming a generic and exception-transparent API... If making that code work means changing "a lot of things" including the meaning of "this" and "resolution of members" within lambda body, then I think it is worth it. On the other hand, if the "feature" of making "this" within lambda body refer to target SAM instance and "resolution of members" within lambda body take SAM instance into consideration first would mean that you always had to specify full SAM type before lambda expression when invoking a generic exception-transparent non-overloaded method, then this "feature" does not in fact help us, since there are workarounds for such situations expressible solely with APIs that demand approximately the same amount of boilerplate and don't require lambdas to support this "feature"... The following example works with current prototype: // example 3: forEach( Arrays.asList("abc", "def"), new BlockImpl(#(self, s) { if (!s.isEmpty()) { System.out.println("element: " + s); self.run(s.substring(1)); } }) ); // supporting API... public interface Block2 { void run(T1 param1, T2 param2) throws E; } public static class BlockImpl implements Block { private final Block2, T, E> block; public BlockImpl(Block2, T, E> block) { this.block = block; } public void run(T param) throws E { block.run(this, param); } } // example to compare amount of boilerplate when prefixing with SAM type (but unfortunately does not yet compile): forEach( Arrays.asList("abc", "def"), Block #(s) { if (!s.isEmpty()) { System.out.println("element: " + s); this.run(s.substring(1)); } } ); You may argue that no such boilerplate would be necessary when invoking a non-generic and/or non-exception-transparent method using non-generic SAM parameter types, but then this project is not playing well with generics. Generics are not deprecated yet, are they? Regards, Peter On 08/10/10, Maurizio Cimadamore wrote: > Hi > your code contains an example of circular inference (as the unknown type > of a lambda parameter is used in order to perform method resolution > inside the lambda body); there are three ways to solve this: > > 1) You can type in the target type explicitly (as you've done); this > lead to the rather verbose: > > foreach(..., Block #(x) {execute(x)}); > > > 2) You can secify explicit type-parameters for the 'foreach' method: > > foreach(..., #(x) {execute(x)}); > > > 3) You can specify the type of the lambda parameter: > > foreach(..., #(String x) {execute(x)}); > > > The alternative (3) looks the less verbose. > > [Note: in this particular case I think there's room for type-inference > to swallow the circularity, as there's just one 'execute()' method - > however, in the general case, it is not safe to do so, as there could be > multiple overloaded version of the called method, or, the thrown types > of the called method could be generic in a 'throws' type-variable - in > such cases the 'real' type of the lambda parameter can significantly > alter the way in which lambda thrown types are inferred - as such, the > compiler must play the conservative card and infer Exception]. > > Maurizio > > On 10/08/10 07:16, Rizal Anwar wrote: > > Hi, > > > > I played around with the prototype, and I have a question on exception > > transparency, especially in type inference. > > > > I have the following interface: > > > > > > public interface Block { > > void run(T param) throws E; > > } > > > > and the following code (assuming ListUtil.foreach is a method accepting a list > > and a Block). > > > > public static void main(String args[]) { > > List myList = Arrays.asList("A", "B", "K"); > > try { > > ListUtil.foreach( > > myList, > > Block #(x) {execute(x)}); > > //////////////////////////////////////////////////////////// > > > > } > > catch (BlockExecutionException e) { > > e.printStackTrace(); > > } > > } > > > > private static void execute(String x) throws BlockExecutionException { > > System.out.println("Execute" + x); > > } > > } > > > > I wonder whether there is a way not to specify the target Block > BlockExecutionException> in the closure I use in the above code ? > > Isn't is possible to infer the type ? > > > > Best regards, > > Anwar Rizal. > > > > > > > > > > > > > From peter.levart at marand.si Thu Aug 12 05:50:15 2010 From: peter.levart at marand.si (Peter Levart) Date: Thu, 12 Aug 2010 14:50:15 +0200 Subject: Question on exception transparency In-Reply-To: <201008121440.06446.peter.levart@marand.si> References: <705619.2671.qm@web24208.mail.ird.yahoo.com> <4C61224C.2000303@oracle.com> <201008121440.06446.peter.levart@marand.si> Message-ID: <201008121450.15414.peter.levart@marand.si> I just noticed new commit. Will try with that revision. Peter On 08/12/10, Peter Levart wrote: > Hello Maurizio (and Brian), > > On 08/10/10, Maurizio Cimadamore wrote: > > Hi > > your code contains an example of circular inference (as the unknown type > > of a lambda parameter is used in order to perform method resolution > > inside the lambda body); there are three ways to solve this: > > > > 1) You can type in the target type explicitly (as you've done); this > > lead to the rather verbose: > > > > foreach(..., Block #(x) {execute(x)}); > > > > > > 2) You can secify explicit type-parameters for the 'foreach' method: > > > > foreach(..., #(x) {execute(x)}); > > > > > > 3) You can specify the type of the lambda parameter: > > > > foreach(..., #(String x) {execute(x)}); > > Well, neither of your workarounds (even if applied together - example 2 below) currently works, I believe, because of bugs in the prototype. > > But I think it is vital to make the following code (example 1) work: > > > import java.util.*; > > public class Closures > { > public interface Block { void run(T param) throws E; } > > public static > void forEach(Iterable iterable, Block block) throws E > { > for (T obj : iterable) block.run(obj); > } > > public static void main(String[] args) > { > // example 1: > forEach( > Arrays.asList("a", "b", "c"), > #(String s){ System.out.println("element: " + s); } > ); > > // example 2 - javac throws NPE: > // Closures.forEach( > // Arrays.asList("a", "b", "c"), > // Block #(String s){ System.out.println("element: " + s); } > // ); > } > } > > > Example 1 represents the majority of use cases when consuming a generic and exception-transparent API... > > If making that code work means changing "a lot of things" including the meaning of "this" and "resolution of members" within lambda body, then I think it is worth it. > > On the other hand, if the "feature" of making "this" within lambda body refer to target SAM instance and "resolution of members" within lambda body take SAM instance into consideration first would mean that you always had to specify full SAM type before lambda expression when invoking a generic exception-transparent non-overloaded method, then this "feature" does not in fact help us, since there are workarounds for such situations expressible solely with APIs that demand approximately the same amount of boilerplate and don't require lambdas to support this "feature"... > > The following example works with current prototype: > > // example 3: > > forEach( > Arrays.asList("abc", "def"), > new BlockImpl(#(self, s) { > if (!s.isEmpty()) { > System.out.println("element: " + s); > self.run(s.substring(1)); > } > }) > ); > > // supporting API... > > public interface Block2 { void run(T1 param1, T2 param2) throws E; } > > public static class BlockImpl implements Block > { > private final Block2, T, E> block; > public BlockImpl(Block2, T, E> block) { this.block = block; } > public void run(T param) throws E { block.run(this, param); } > } > > // example to compare amount of boilerplate when prefixing with SAM type (but unfortunately does not yet compile): > > forEach( > Arrays.asList("abc", "def"), > Block #(s) { > if (!s.isEmpty()) { > System.out.println("element: " + s); > this.run(s.substring(1)); > } > } > ); > > > You may argue that no such boilerplate would be necessary when invoking a non-generic and/or non-exception-transparent method using non-generic SAM parameter types, but then this project is not playing well with generics. Generics are not deprecated yet, are they? > > Regards, Peter > > > On 08/10/10, Maurizio Cimadamore wrote: > > Hi > > your code contains an example of circular inference (as the unknown type > > of a lambda parameter is used in order to perform method resolution > > inside the lambda body); there are three ways to solve this: > > > > 1) You can type in the target type explicitly (as you've done); this > > lead to the rather verbose: > > > > foreach(..., Block #(x) {execute(x)}); > > > > > > 2) You can secify explicit type-parameters for the 'foreach' method: > > > > foreach(..., #(x) {execute(x)}); > > > > > > 3) You can specify the type of the lambda parameter: > > > > foreach(..., #(String x) {execute(x)}); > > > > > > The alternative (3) looks the less verbose. > > > > [Note: in this particular case I think there's room for type-inference > > to swallow the circularity, as there's just one 'execute()' method - > > however, in the general case, it is not safe to do so, as there could be > > multiple overloaded version of the called method, or, the thrown types > > of the called method could be generic in a 'throws' type-variable - in > > such cases the 'real' type of the lambda parameter can significantly > > alter the way in which lambda thrown types are inferred - as such, the > > compiler must play the conservative card and infer Exception]. > > > > Maurizio > > > > On 10/08/10 07:16, Rizal Anwar wrote: > > > Hi, > > > > > > I played around with the prototype, and I have a question on exception > > > transparency, especially in type inference. > > > > > > I have the following interface: > > > > > > > > > public interface Block { > > > void run(T param) throws E; > > > } > > > > > > and the following code (assuming ListUtil.foreach is a method accepting a list > > > and a Block). > > > > > > public static void main(String args[]) { > > > List myList = Arrays.asList("A", "B", "K"); > > > try { > > > ListUtil.foreach( > > > myList, > > > Block #(x) {execute(x)}); > > > //////////////////////////////////////////////////////////// > > > > > > } > > > catch (BlockExecutionException e) { > > > e.printStackTrace(); > > > } > > > } > > > > > > private static void execute(String x) throws BlockExecutionException { > > > System.out.println("Execute" + x); > > > } > > > } > > > > > > I wonder whether there is a way not to specify the target Block > > BlockExecutionException> in the closure I use in the above code ? > > > Isn't is possible to infer the type ? > > > > > > Best regards, > > > Anwar Rizal. > > > > > > > > > > > > > > > > > > > > > > > From maurizio.cimadamore at oracle.com Thu Aug 12 05:52:09 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 12 Aug 2010 13:52:09 +0100 Subject: Question on exception transparency In-Reply-To: <201008121440.06446.peter.levart@marand.si> References: <705619.2671.qm@web24208.mail.ird.yahoo.com> <4C61224C.2000303@oracle.com> <201008121440.06446.peter.levart@marand.si> Message-ID: <4C63EE79.4050200@oracle.com> On 12/08/10 13:40, Peter Levart wrote: > import java.util.*; > > public class Closures > { > public interface Block { void run(T param) throws E; } > > public static > void forEach(Iterable iterable, Block block) throws E > { > for (T obj : iterable) block.run(obj); > } > > public static void main(String[] args) > { > // example 1: > forEach( > Arrays.asList("a", "b", "c"), > #(String s){ System.out.println("element: " + s); } > ); > > // example 2 - javac throws NPE: > // Closures.forEach( > // Arrays.asList("a", "b", "c"), > // Block #(String s){ System.out.println("element: " + s); } > // ); > } > } > The following works for me: Closures.forEach( Arrays.asList("a", "b", "c"), Block #(s){ System.out.println("element: " + s); } ); I guess the NPE has been fixed in the last push. However I noticed a problem when 'void' is specified as explicit type-parameter for a generic method - for example, the following doesn't work: Closures.forEach( Arrays.asList("a", "b", "c"), null); I will investigate on this... Maurizio From thomas.andreas.jung at googlemail.com Thu Aug 12 07:49:07 2010 From: thomas.andreas.jung at googlemail.com (Thomas Jung) Date: Thu, 12 Aug 2010 16:49:07 +0200 Subject: hg: lambda/lambda/langtools: Flow should not analyze lambda body that contains errors due to partially specified parameter types In-Reply-To: <20100812111140.346E1470DB@hg.openjdk.java.net> References: <20100812111140.346E1470DB@hg.openjdk.java.net> Message-ID: Thanks. This seems to fix my problem. Thomas On 12 August 2010 13:11, wrote: > Changeset: f8912a5acc0a > Author: ? ?mcimadamore > Date: ? ? ?2010-08-12 12:04 +0100 > URL: ? ? ? http://hg.openjdk.java.net/lambda/lambda/langtools/rev/f8912a5acc0a > > Flow should not analyze lambda body that contains errors due to partially specified parameter types > > ! src/share/classes/com/sun/tools/javac/code/Flags.java > ! src/share/classes/com/sun/tools/javac/comp/Attr.java > ! src/share/classes/com/sun/tools/javac/comp/AttrContext.java > ! src/share/classes/com/sun/tools/javac/util/Log.java > ! src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java > + test/tools/javac/lambda/TargetType12.java > > > From maurizio.cimadamore at oracle.com Thu Aug 12 08:18:17 2010 From: maurizio.cimadamore at oracle.com (maurizio.cimadamore at oracle.com) Date: Thu, 12 Aug 2010 15:18:17 +0000 Subject: hg: lambda/lambda: 6 new changesets Message-ID: <20100812151818.3FB22470E9@hg.openjdk.java.net> Changeset: 86a3df41c0c7 Author: mikejwre Date: 2010-07-23 16:42 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/rev/86a3df41c0c7 Added tag jdk7-b102 for changeset a136a51f5113 ! .hgtags Changeset: f1ba69da5003 Author: ohair Date: 2010-07-26 14:14 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/rev/f1ba69da5003 6972274: Fix the use of egrep -ci in the top level makefile sanity checks Reviewed-by: prr ! make/sanity-rules.gmk Changeset: be2aedc4e3b1 Author: mikejwre Date: 2010-07-28 21:03 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/rev/be2aedc4e3b1 Merge Changeset: f8be576feefc Author: cl Date: 2010-07-29 13:33 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/rev/f8be576feefc Added tag jdk7-b103 for changeset be2aedc4e3b1 ! .hgtags Changeset: 9f96a4269d77 Author: cl Date: 2010-08-06 12:51 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/rev/9f96a4269d77 Added tag jdk7-b104 for changeset f8be576feefc ! .hgtags Changeset: 13a66b835c8f Author: mcimadamore Date: 2010-08-12 12:16 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/rev/13a66b835c8f merge with jdk7-b105 From maurizio.cimadamore at oracle.com Thu Aug 12 08:18:24 2010 From: maurizio.cimadamore at oracle.com (maurizio.cimadamore at oracle.com) Date: Thu, 12 Aug 2010 15:18:24 +0000 Subject: hg: lambda/lambda/corba: 4 new changesets Message-ID: <20100812151828.C1FD8470EA@hg.openjdk.java.net> Changeset: 11e7678c3eb1 Author: mikejwre Date: 2010-07-23 16:42 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/corba/rev/11e7678c3eb1 Added tag jdk7-b102 for changeset 78561a957790 ! .hgtags Changeset: 9607213481d4 Author: cl Date: 2010-07-29 13:33 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/corba/rev/9607213481d4 Added tag jdk7-b103 for changeset 11e7678c3eb1 ! .hgtags Changeset: 6f21b030092f Author: cl Date: 2010-08-06 12:51 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/corba/rev/6f21b030092f Added tag jdk7-b104 for changeset 9607213481d4 ! .hgtags Changeset: 8b33289e29e9 Author: mcimadamore Date: 2010-08-12 12:17 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/corba/rev/8b33289e29e9 merge with jdk7-b105 From maurizio.cimadamore at oracle.com Thu Aug 12 08:18:38 2010 From: maurizio.cimadamore at oracle.com (maurizio.cimadamore at oracle.com) Date: Thu, 12 Aug 2010 15:18:38 +0000 Subject: hg: lambda/lambda/hotspot: 22 new changesets Message-ID: <20100812151923.39EA0470EB@hg.openjdk.java.net> Changeset: cb4250ef73b2 Author: mikejwre Date: 2010-07-23 16:42 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/hotspot/rev/cb4250ef73b2 Added tag jdk7-b102 for changeset c5cadf1a0771 ! .hgtags Changeset: efd4401fab1d Author: cl Date: 2010-07-29 13:33 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/hotspot/rev/efd4401fab1d Added tag jdk7-b103 for changeset cb4250ef73b2 ! .hgtags Changeset: e7ec8cd4dd8a Author: tonyp Date: 2010-06-28 14:13 -0400 URL: http://hg.openjdk.java.net/lambda/lambda/hotspot/rev/e7ec8cd4dd8a 6962569: assembler_sparc.cpp:1969: assert(false) failed: error Summary: array_overlap_test() fails when the address range crosses the MSB boundary. Thanks to Tom and Vladimir for their help on this one. Reviewed-by: kvn, never, iveresov ! src/cpu/sparc/vm/stubGenerator_sparc.cpp Changeset: 4e5661ba9d98 Author: tonyp Date: 2010-06-28 14:13 -0400 URL: http://hg.openjdk.java.net/lambda/lambda/hotspot/rev/4e5661ba9d98 6944166: G1: explicit GCs are not always handled correctly Summary: G1 was not handling explicit GCs correctly in many ways. It does now. See the CR for the list of improvements contained in this changeset. Reviewed-by: iveresov, ysr, johnc ! src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp ! src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp ! src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp ! src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp ! src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp ! src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp ! src/share/vm/gc_implementation/g1/vm_operations_g1.cpp ! src/share/vm/gc_implementation/g1/vm_operations_g1.hpp ! src/share/vm/gc_implementation/includeDB_gc_g1 ! src/share/vm/gc_implementation/shared/vmGCOperations.hpp ! src/share/vm/gc_interface/gcCause.cpp ! src/share/vm/runtime/mutexLocker.cpp Changeset: 1a1ce2076047 Author: ysr Date: 2010-07-16 10:09 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/hotspot/rev/1a1ce2076047 Merge Changeset: ad7e433e2730 Author: ysr Date: 2010-07-20 16:09 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/hotspot/rev/ad7e433e2730 Merge - src/os/linux/vm/vtune_linux.cpp - src/os/solaris/vm/vtune_solaris.cpp - src/os/windows/vm/vtune_windows.cpp - src/share/vm/runtime/vtune.hpp Changeset: 131ed9a23d48 Author: ysr Date: 2010-07-21 09:57 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/hotspot/rev/131ed9a23d48 Merge Changeset: 083fde3b838e Author: jrose Date: 2010-07-15 18:40 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/hotspot/rev/083fde3b838e 6964498: JSR 292 invokedynamic sites need local bootstrap methods Summary: Add JVM_CONSTANT_InvokeDynamic records to constant pool to determine per-instruction BSMs. Reviewed-by: twisti ! agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java ! agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java ! agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java ! agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java ! agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java ! src/share/vm/classfile/classFileParser.cpp ! src/share/vm/classfile/systemDictionary.cpp ! src/share/vm/classfile/systemDictionary.hpp ! src/share/vm/classfile/verifier.cpp ! src/share/vm/interpreter/bytecodeTracer.cpp ! src/share/vm/interpreter/interpreterRuntime.cpp ! src/share/vm/interpreter/linkResolver.cpp ! src/share/vm/interpreter/linkResolver.hpp ! src/share/vm/interpreter/rewriter.cpp ! src/share/vm/interpreter/rewriter.hpp ! src/share/vm/oops/constantPoolKlass.cpp ! src/share/vm/oops/constantPoolOop.cpp ! src/share/vm/oops/constantPoolOop.hpp ! src/share/vm/oops/cpCacheOop.cpp ! src/share/vm/oops/cpCacheOop.hpp ! src/share/vm/prims/jvm.h ! src/share/vm/prims/methodHandles.cpp ! src/share/vm/runtime/globals.hpp ! src/share/vm/utilities/constantTag.cpp ! src/share/vm/utilities/constantTag.hpp Changeset: 01b172b8cd7c Author: never Date: 2010-07-16 08:29 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/hotspot/rev/01b172b8cd7c Merge Changeset: e0ba4e04c839 Author: jrose Date: 2010-07-16 18:14 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/hotspot/rev/e0ba4e04c839 6969574: invokedynamic call sites deoptimize instead of executing Reviewed-by: kvn ! src/share/vm/ci/ciEnv.cpp ! src/share/vm/ci/ciMethod.cpp ! src/share/vm/oops/cpCacheOop.cpp ! src/share/vm/oops/cpCacheOop.hpp ! src/share/vm/oops/methodOop.cpp ! src/share/vm/prims/methodHandleWalk.cpp Changeset: 7139e81efd2d Author: never Date: 2010-07-22 15:29 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/hotspot/rev/7139e81efd2d 6970566: runThese fails with SIGSEGV Reviewed-by: kvn ! src/share/vm/code/codeBlob.cpp ! src/share/vm/code/codeBlob.hpp Changeset: 5063ce716349 Author: never Date: 2010-07-23 10:21 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/hotspot/rev/5063ce716349 Merge Changeset: a93a9eda13f7 Author: jcoomes Date: 2010-07-16 21:33 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/hotspot/rev/a93a9eda13f7 6962947: shared TaskQueue statistics Reviewed-by: tonyp, ysr ! src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp ! src/share/vm/gc_implementation/parNew/parNewGeneration.cpp ! src/share/vm/gc_implementation/parNew/parNewGeneration.hpp ! src/share/vm/gc_implementation/parNew/parOopClosures.hpp ! src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp ! src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp ! src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp ! src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp ! src/share/vm/utilities/globalDefinitions.hpp ! src/share/vm/utilities/taskqueue.cpp ! src/share/vm/utilities/taskqueue.hpp Changeset: 5cbac8938c4c Author: johnc Date: 2010-07-19 11:06 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/hotspot/rev/5cbac8938c4c 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307 Summary: During concurrent refinment, filter cards in young regions after it has been determined that the region has been allocated from and the young type of the region has been set. Reviewed-by: iveresov, tonyp, jcoomes ! src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp ! src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp ! src/share/vm/gc_implementation/g1/g1RemSet.cpp ! src/share/vm/gc_implementation/g1/heapRegion.cpp ! src/share/vm/gc_implementation/g1/heapRegion.hpp Changeset: 4f1fffe08c63 Author: ysr Date: 2010-07-21 12:45 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/hotspot/rev/4f1fffe08c63 Merge Changeset: 1890dc9151da Author: ysr Date: 2010-07-23 14:31 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/hotspot/rev/1890dc9151da Merge Changeset: cc3fdfeb54b0 Author: trims Date: 2010-07-29 23:14 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/hotspot/rev/cc3fdfeb54b0 Merge Changeset: fd2645290e89 Author: trims Date: 2010-07-30 06:56 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/hotspot/rev/fd2645290e89 6973381: Bump the HS19 build number to 05 Summary: Update the HS19 build number to 05 Reviewed-by: jcoomes ! make/hotspot_version Changeset: 28abe3f6a5f6 Author: trims Date: 2010-08-03 19:01 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/hotspot/rev/28abe3f6a5f6 Merge Changeset: b4acf10eb134 Author: trims Date: 2010-08-05 02:48 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/hotspot/rev/b4acf10eb134 Added tag hs19-b04 for changeset e55900b5c1b8 ! .hgtags Changeset: 6709c14587c2 Author: cl Date: 2010-08-06 12:51 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/hotspot/rev/6709c14587c2 Added tag jdk7-b104 for changeset b4acf10eb134 ! .hgtags Changeset: 2cab8c34d64d Author: mcimadamore Date: 2010-08-12 12:17 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/hotspot/rev/2cab8c34d64d merge with jdk7-b105 From maurizio.cimadamore at oracle.com Thu Aug 12 08:19:30 2010 From: maurizio.cimadamore at oracle.com (maurizio.cimadamore at oracle.com) Date: Thu, 12 Aug 2010 15:19:30 +0000 Subject: hg: lambda/lambda/jaxp: 4 new changesets Message-ID: <20100812151930.50B64470EC@hg.openjdk.java.net> Changeset: b7722e878864 Author: mikejwre Date: 2010-07-23 16:42 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/jaxp/rev/b7722e878864 Added tag jdk7-b102 for changeset 15573625af97 ! .hgtags Changeset: d42c4acb6424 Author: cl Date: 2010-07-29 13:33 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/jaxp/rev/d42c4acb6424 Added tag jdk7-b103 for changeset b7722e878864 ! .hgtags Changeset: 3233b9a4c12e Author: cl Date: 2010-08-06 12:51 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/jaxp/rev/3233b9a4c12e Added tag jdk7-b104 for changeset d42c4acb6424 ! .hgtags Changeset: 0d817b4264d0 Author: mcimadamore Date: 2010-08-12 12:17 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/jaxp/rev/0d817b4264d0 merge with jdk7-b105 From maurizio.cimadamore at oracle.com Thu Aug 12 08:19:37 2010 From: maurizio.cimadamore at oracle.com (maurizio.cimadamore at oracle.com) Date: Thu, 12 Aug 2010 15:19:37 +0000 Subject: hg: lambda/lambda/jaxws: 4 new changesets Message-ID: <20100812151937.1D709470ED@hg.openjdk.java.net> Changeset: 267386d6b923 Author: mikejwre Date: 2010-07-23 16:42 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/jaxws/rev/267386d6b923 Added tag jdk7-b102 for changeset d8580443d181 ! .hgtags Changeset: bbc4cce6c20a Author: cl Date: 2010-07-29 13:33 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/jaxws/rev/bbc4cce6c20a Added tag jdk7-b103 for changeset 267386d6b923 ! .hgtags Changeset: 39eb4f3031f4 Author: cl Date: 2010-08-06 12:52 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/jaxws/rev/39eb4f3031f4 Added tag jdk7-b104 for changeset bbc4cce6c20a ! .hgtags Changeset: 6ce1e0024c39 Author: mcimadamore Date: 2010-08-12 12:17 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/jaxws/rev/6ce1e0024c39 merge with jdk7-b105 From maurizio.cimadamore at oracle.com Thu Aug 12 08:19:49 2010 From: maurizio.cimadamore at oracle.com (maurizio.cimadamore at oracle.com) Date: Thu, 12 Aug 2010 15:19:49 +0000 Subject: hg: lambda/lambda/jdk: 47 new changesets Message-ID: <20100812152740.5C86D470EE@hg.openjdk.java.net> Changeset: 6488b70a23cc Author: mikejwre Date: 2010-07-23 16:42 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/6488b70a23cc Added tag jdk7-b102 for changeset 13029a61b16b ! .hgtags Changeset: b839344245a9 Author: cl Date: 2010-07-29 13:33 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/b839344245a9 Added tag jdk7-b103 for changeset 6488b70a23cc ! .hgtags Changeset: 6950da80c75c Author: ohair Date: 2010-08-02 16:31 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/6950da80c75c 6973616: Update minimum boot jdk from 1.5 to 1.6 Reviewed-by: igor, jjg ! make/common/shared/Defs-versions.gmk Changeset: dd48c78218a7 Author: ohair Date: 2010-08-02 16:31 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/dd48c78218a7 6971426: jdk/make/docs docs target does not work on windows Reviewed-by: igor, jjg ! make/docs/Makefile Changeset: f46ec75b1663 Author: ohair Date: 2010-08-03 10:53 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/f46ec75b1663 6974239: Correct reference to jdk document site in javadoc Reviewed-by: skannan ! make/docs/Makefile Changeset: 1a92820132a0 Author: cl Date: 2010-08-04 22:02 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/1a92820132a0 Merge Changeset: d967f8507d9d Author: cl Date: 2010-08-06 12:52 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/d967f8507d9d Added tag jdk7-b104 for changeset 1a92820132a0 ! .hgtags Changeset: 539528c5d395 Author: lana Date: 2010-07-14 09:12 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/539528c5d395 Merge Changeset: cf0c23a99823 Author: lana Date: 2010-07-29 17:12 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/cf0c23a99823 Merge - src/linux/doc/man/ja/kinit.1 - src/linux/doc/man/ja/klist.1 - src/linux/doc/man/ja/ktab.1 - test/java/nio/channels/ServerSocketChannel/AcceptAddress.java - test/java/nio/charset/coders/Surrogate.java - test/tools/launcher/Makefile.SolarisRunpath - test/tools/launcher/lib/i386/lib32/lib32/liblibrary.so - test/tools/launcher/lib/i386/lib32/liblibrary.so - test/tools/launcher/lib/sparc/lib32/lib32/liblibrary.so - test/tools/launcher/lib/sparc/lib32/liblibrary.so - test/tools/launcher/lib/sparc/lib64/lib64/liblibrary.so - test/tools/launcher/lib/sparc/lib64/liblibrary.so Changeset: c6f443c3d96a Author: lana Date: 2010-08-02 19:41 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/c6f443c3d96a Merge Changeset: c38803ce0560 Author: uta Date: 2010-07-23 18:59 +0400 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/c38803ce0560 6969851: VM hangs/crashes in FileDialog test (VS2008/2010 build) Reviewed-by: prr, art ! src/windows/native/sun/windows/awt.h Changeset: 9bb8d5c093fc Author: lana Date: 2010-07-29 13:48 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/9bb8d5c093fc Merge - src/linux/doc/man/ja/kinit.1 - src/linux/doc/man/ja/klist.1 - src/linux/doc/man/ja/ktab.1 - test/java/nio/channels/ServerSocketChannel/AcceptAddress.java - test/java/nio/charset/coders/Surrogate.java - test/tools/launcher/Makefile.SolarisRunpath - test/tools/launcher/lib/i386/lib32/lib32/liblibrary.so - test/tools/launcher/lib/i386/lib32/liblibrary.so - test/tools/launcher/lib/sparc/lib32/lib32/liblibrary.so - test/tools/launcher/lib/sparc/lib32/liblibrary.so - test/tools/launcher/lib/sparc/lib64/lib64/liblibrary.so - test/tools/launcher/lib/sparc/lib64/liblibrary.so Changeset: 8a72583dc41d Author: lana Date: 2010-08-02 19:42 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/8a72583dc41d Merge Changeset: 65403b9bcb58 Author: peterz Date: 2010-07-13 17:26 +0400 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/65403b9bcb58 6462562: InternationalFormatter inserts text incorrectly 6578432: Currency format instance does not work with Swing's NumberFormatter Reviewed-by: rupashka ! src/share/classes/javax/swing/text/DefaultFormatter.java ! src/share/classes/javax/swing/text/InternationalFormatter.java + test/javax/swing/JFormattedTextField/Test6462562.java Changeset: a0d7b76abcd3 Author: alexp Date: 2010-07-29 19:34 +0400 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/a0d7b76abcd3 4743225: Size of JComboBox list is wrong when list is populated via PopupMenuListener Reviewed-by: rupashka ! src/share/classes/javax/swing/plaf/basic/BasicComboPopup.java + test/javax/swing/JComboBox/4743225/bug4743225.java Changeset: 0e8acbf12695 Author: lana Date: 2010-07-29 13:22 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/0e8acbf12695 Merge - src/linux/doc/man/ja/kinit.1 - src/linux/doc/man/ja/klist.1 - src/linux/doc/man/ja/ktab.1 - test/java/nio/channels/ServerSocketChannel/AcceptAddress.java - test/java/nio/charset/coders/Surrogate.java - test/tools/launcher/Makefile.SolarisRunpath - test/tools/launcher/lib/i386/lib32/lib32/liblibrary.so - test/tools/launcher/lib/i386/lib32/liblibrary.so - test/tools/launcher/lib/sparc/lib32/lib32/liblibrary.so - test/tools/launcher/lib/sparc/lib32/liblibrary.so - test/tools/launcher/lib/sparc/lib64/lib64/liblibrary.so - test/tools/launcher/lib/sparc/lib64/liblibrary.so Changeset: 951e46d93af0 Author: malenkov Date: 2010-07-30 19:21 +0400 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/951e46d93af0 6199676: REGRESSION: ColorChooser loses preview when change LandF in Java5 Reviewed-by: alexp, peterz ! src/share/classes/javax/swing/plaf/basic/BasicColorChooserUI.java + test/javax/swing/JColorChooser/Test6199676.java Changeset: f40de306ab66 Author: malenkov Date: 2010-07-30 19:40 +0400 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/f40de306ab66 6972468: Security manager should be used for tests in java/beans/XMLEncoder Reviewed-by: peterz ! test/java/beans/XMLEncoder/Test4631471.java ! test/java/beans/XMLEncoder/Test4903007.java ! test/java/beans/XMLEncoder/javax_swing_JLayeredPane.java Changeset: ce1e26600ab7 Author: lana Date: 2010-08-02 19:44 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/ce1e26600ab7 Merge Changeset: 25050030a320 Author: dsamersoff Date: 2010-07-13 15:32 +0400 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/25050030a320 6964714: NetworkInterface getInetAddresses enumerates IPv6 addresses if java.net.preferIPvStack property set Summary: User can disable ipv6 explicitly, have to check it Reviewed-by: chegar, alanb ! src/solaris/native/java/net/NetworkInterface.c + test/java/net/NetworkInterface/IPv4Only.java Changeset: f3a4c1947fd1 Author: weijun Date: 2010-07-13 20:27 +0800 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/f3a4c1947fd1 6670889: Keystore created under Hindi Locale causing ArrayIndexOutOfBoundsException Reviewed-by: chegar ! src/share/classes/sun/security/util/DerOutputStream.java + test/sun/security/util/DerOutputStream/LocaleInTime.java Changeset: ab65f46ae092 Author: darcy Date: 2010-07-15 18:02 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/ab65f46ae092 6963622: Project Coin: Refinements to suppressed exceptions Reviewed-by: alanb, forax, jjb ! src/share/classes/java/lang/AutoCloseable.java ! src/share/classes/java/lang/Throwable.java ! test/java/lang/Throwable/SuppressedExceptions.java Changeset: a3747592bdf7 Author: sherman Date: 2010-07-16 16:45 -0400 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/a3747592bdf7 6964313: Find sun/nio/cs/ext issue with CreateSymbols, then move sun/nio/cs/ext to charset.jar Summary: Removed the duplicate sun.nio.cs.ext entries from rt.jar and moved X11 charsets into charsets.jar Reviewed-by: ohair ! make/common/Release.gmk ! make/sun/nio/cs/Makefile Changeset: 9a1bd20fc71c Author: weijun Date: 2010-07-19 10:02 +0800 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/9a1bd20fc71c 6969683: Generify ResolverConfiguration codes Reviewed-by: alanb, chegar ! src/share/classes/com/sun/jndi/dns/DnsContextFactory.java ! src/share/classes/sun/net/dns/ResolverConfiguration.java ! src/share/classes/sun/net/spi/nameservice/dns/DNSNameService.java ! src/solaris/classes/sun/net/dns/ResolverConfigurationImpl.java ! src/windows/classes/sun/net/dns/ResolverConfigurationImpl.java Changeset: 4022e0c84507 Author: weijun Date: 2010-07-19 10:02 +0800 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/4022e0c84507 6969292: make DNS lookup for realm/kdc really work Reviewed-by: alanb, valeriep ! src/share/classes/sun/security/krb5/Config.java Changeset: 9d1994d53a67 Author: mullan Date: 2010-07-20 10:41 -0400 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/9d1994d53a67 6870553: X509Certificate.getSigAlgName method description uses non-standard algorithm name as example Reviewed-by: xuelei ! src/share/classes/java/security/cert/X509CRL.java ! src/share/classes/java/security/cert/X509Certificate.java Changeset: 58f325ba3e27 Author: chegar Date: 2010-07-21 13:29 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/58f325ba3e27 6969395: TEST_BUG: Tests in java/net sun/net problems Reviewed-by: alanb ! test/ProblemList.txt ! test/com/sun/net/httpserver/Test1.java ! test/com/sun/net/httpserver/Test11.java ! test/com/sun/net/httpserver/Test12.java ! test/com/sun/net/httpserver/Test13.java ! test/com/sun/net/httpserver/Test6a.java ! test/com/sun/net/httpserver/Test7a.java ! test/com/sun/net/httpserver/Test8a.java ! test/com/sun/net/httpserver/Test9.java ! test/com/sun/net/httpserver/Test9a.java ! test/com/sun/net/httpserver/bugs/B6361557.java ! test/com/sun/net/httpserver/bugs/B6373555.java ! test/java/net/DatagramSocket/DatagramTimeout.java ! test/java/net/DatagramSocket/SendSize.java ! test/java/net/Inet6Address/B6558853.java ! test/java/net/Inet6Address/serialize/Serialize.java ! test/java/net/InetAddress/CheckJNI.java ! test/java/net/MulticastSocket/SetOutgoingIf.java ! test/java/net/ResponseCache/B6181108.java ! test/java/net/ResponseCache/ResponseCacheTest.java ! test/java/net/ResponseCache/getResponseCode.java - test/java/net/Socket/AccurateTimeout.java ! test/java/net/Socket/CloseAvailable.java ! test/java/net/Socket/DeadlockTest.java ! test/java/net/Socket/LingerTest.java ! test/java/net/Socket/LinkLocal.java ! test/java/net/Socket/ProxyCons.java ! test/java/net/Socket/ReadTimeout.java ! test/java/net/Socket/SetReceiveBufferSize.java ! test/java/net/Socket/SetSoLinger.java ! test/java/net/Socket/ShutdownBoth.java ! test/java/net/Socket/SoTimeout.java ! test/java/net/Socket/Timeout.java ! test/java/net/Socket/UrgentDataTest.java ! test/java/net/Socket/asyncClose/BrokenPipe.java ! test/java/net/Socket/setReuseAddress/Restart.java ! test/java/net/SocketInputStream/SocketClosedException.java ! test/java/net/SocketInputStream/SocketTimeout.java ! test/java/net/URL/GetContent.java ! test/java/net/URLClassLoader/ClassLoad.java ! test/java/net/URLConnection/DisconnectAfterEOF.java ! test/java/net/URLConnection/HandleContentTypeWithAttrs.java ! test/java/net/URLConnection/HttpContinueStackOverflow.java ! test/java/net/URLConnection/Redirect307Test.java ! test/java/net/URLConnection/RedirectLimit.java ! test/java/net/URLConnection/ResendPostBody.java ! test/java/net/URLConnection/SetIfModifiedSince.java ! test/java/net/URLConnection/TimeoutTest.java ! test/java/net/URLConnection/URLConnectionHeaders.java ! test/java/net/URLConnection/ZeroContentLength.java ! test/java/net/ipv6tests/B6521014.java ! test/java/net/ipv6tests/TcpTest.java ! test/java/net/ipv6tests/Tests.java ! test/sun/net/ftp/FtpGetContent.java ! test/sun/net/ftp/FtpURL.java ! test/sun/net/www/http/ChunkedInputStream/ChunkedEncodingWithProgressMonitorTest.java ! test/sun/net/www/http/ChunkedOutputStream/Test.java ! test/sun/net/www/http/HttpClient/B6726695.java ! test/sun/net/www/http/HttpClient/MultiThreadTest.java ! test/sun/net/www/http/HttpClient/ProxyTest.java ! test/sun/net/www/http/KeepAliveCache/KeepAliveTimerThread.java ! test/sun/net/www/http/KeepAliveStream/KeepAliveStreamCloseWithWrongContentLength.java ! test/sun/net/www/httptest/HttpServer.java ! test/sun/net/www/protocol/http/DigestTest.java Changeset: f90999d7c404 Author: chegar Date: 2010-07-21 13:52 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/f90999d7c404 6970262: TEST_BUG: test/java/net/NetworkInterface/IPv4Only.java has wrong test name in @run tag Reviewed-by: alanb, dsamersoff ! test/java/net/NetworkInterface/IPv4Only.java Changeset: 3902c742b5b1 Author: alanb Date: 2010-07-21 18:08 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/3902c742b5b1 6963907: (so) Socket adapter need to implement sendUrgentData Reviewed-by: chegar ! make/java/nio/mapfile-linux ! make/java/nio/mapfile-solaris ! src/share/classes/sun/nio/ch/SocketAdaptor.java ! src/share/classes/sun/nio/ch/SocketChannelImpl.java ! src/solaris/native/sun/nio/ch/SocketChannelImpl.c ! src/windows/native/sun/nio/ch/SocketChannelImpl.c + test/java/nio/channels/SocketChannel/OutOfBand.java Changeset: d899526a187a Author: dcubed Date: 2010-07-21 16:58 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/d899526a187a 6941287: 4/4 jrunscriptTest.sh test does not work right under Cygwin Summary: Add golden_diff variable for doing proper golden file diffs on Cygwin. Reviewed-by: ohair, dholmes ! test/sun/tools/jrunscript/common.sh ! test/sun/tools/jrunscript/jrunscript-eTest.sh ! test/sun/tools/jrunscript/jrunscript-fTest.sh ! test/sun/tools/jrunscript/jrunscriptTest.sh Changeset: 946236dc5c96 Author: dcubed Date: 2010-07-21 16:59 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/946236dc5c96 6962804: 4/4 ShellScaffold tests can fail without a specific reason Summary: Add more diagnostics for failures. Only copy target file in grepForString when NL is missing. Reviewed-by: ohair, dholmes ! test/com/sun/jdi/ShellScaffold.sh Changeset: 9cb77130999f Author: dcubed Date: 2010-07-21 17:01 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/9cb77130999f 6964018: 3/4 AnonLoggerWeakRefLeak and LoggerWeakRefLeak can fail in JPRT Summary: Refactor test/sun/tools/common/* code and refactor AnonLoggerWeakRefLeak and LoggerWeakRefLeak to use it. Reviewed-by: ohair, alanb ! test/java/util/logging/AnonLoggerWeakRefLeak.java ! test/java/util/logging/AnonLoggerWeakRefLeak.sh ! test/java/util/logging/LoggerWeakRefLeak.java ! test/java/util/logging/LoggerWeakRefLeak.sh ! test/sun/tools/common/ApplicationSetup.sh ! test/sun/tools/common/CommonSetup.sh + test/sun/tools/common/CommonTests.sh ! test/sun/tools/common/ShutdownSimpleApplication.java ! test/sun/tools/common/SimpleApplication.java + test/sun/tools/common/SleeperApplication.java ! test/sun/tools/jhat/ParseTest.sh ! test/sun/tools/jinfo/Basic.sh ! test/sun/tools/jmap/Basic.sh ! test/sun/tools/jstack/Basic.sh Changeset: 748f004aeb5c Author: vinnie Date: 2010-07-23 17:41 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/748f004aeb5c 6676075: RegistryContext (com.sun.jndi.url.rmi.rmiURLContext) coding problem Reviewed-by: mullan ! src/share/classes/com/sun/jndi/rmi/registry/RegistryContext.java + test/com/sun/jndi/rmi/registry/RegistryContext/ContextWithNullProperties.java Changeset: 56217857ccd7 Author: xuelei Date: 2010-07-24 22:59 +0800 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/56217857ccd7 6867345: Turkish regional options cause NPE in sun.security.x509.AlgorithmId.algOID Reviewed-by: mullan, weijun ! src/share/classes/sun/security/krb5/Credentials.java ! src/share/classes/sun/security/pkcs/PKCS9Attribute.java ! src/share/classes/sun/security/pkcs11/P11Cipher.java ! src/share/classes/sun/security/pkcs11/P11RSACipher.java ! src/share/classes/sun/security/provider/certpath/URICertStore.java ! src/share/classes/sun/security/util/Debug.java ! src/share/classes/sun/security/x509/AVA.java ! src/share/classes/sun/security/x509/AlgorithmId.java ! src/share/classes/sun/security/x509/DNSName.java ! src/share/classes/sun/security/x509/RFC822Name.java + test/sun/security/x509/AlgorithmId/TurkishRegion.java Changeset: 402ff3e81922 Author: weijun Date: 2010-07-26 17:21 +0800 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/402ff3e81922 6972005: ConfPlusProp.java test failure when DNS has info for realm Reviewed-by: xuelei ! test/sun/security/krb5/ConfPlusProp.java ! test/sun/security/krb5/confplusprop.conf ! test/sun/security/krb5/confplusprop2.conf Changeset: db21b420d038 Author: martin Date: 2010-07-26 08:17 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/db21b420d038 6717780: (coll spec) LinkedList api documentation provides the wrong method name Summary: Cleanup by simply making Deque equal status with List Reviewed-by: darcy ! src/share/classes/java/util/LinkedList.java Changeset: 1bfa1c864553 Author: dcubed Date: 2010-07-26 09:06 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/1bfa1c864553 6971847: 4/4 jmap '-histo:live' option is necessary for proper leak detection Summary: Add work around for 6971851. Abort if 'histo:live' option isn't supported. Reviewed-by: alanb, darcy ! test/java/util/logging/AnonLoggerWeakRefLeak.sh ! test/java/util/logging/LoggerWeakRefLeak.sh Changeset: 83be262e654c Author: xuelei Date: 2010-07-27 16:07 +0800 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/83be262e654c 6870947: 15 sec delay detecting "socket closed" condition when a TCP connection is reset by an LDAP server Reviewed-by: weijun ! src/share/classes/com/sun/jndi/ldap/Connection.java Changeset: 5ff8b884a92c Author: vinnie Date: 2010-07-27 11:40 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/5ff8b884a92c 6972409: Cease emitting LDAP filter debug messages Reviewed-by: xuelei ! src/share/classes/com/sun/jndi/ldap/Filter.java Changeset: 24741c4bf300 Author: alanb Date: 2010-07-29 13:08 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/24741c4bf300 6934977: (bf) MappedByteBuffer.load can SIGBUS if file is truncated 6799037: (fs) MappedByteBuffer.load crash with unaligned file-mapping (sol) Reviewed-by: chegar, forax ! src/share/classes/java/nio/Bits.java ! src/share/classes/java/nio/MappedByteBuffer.java ! src/solaris/native/java/nio/MappedByteBuffer.c ! src/windows/native/java/nio/MappedByteBuffer.c ! test/java/nio/MappedByteBuffer/Basic.java + test/java/nio/MappedByteBuffer/Truncate.java Changeset: a8a79f5b669e Author: chegar Date: 2010-07-29 10:02 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/a8a79f5b669e 6972374: NetworkInterface.getNetworkInterfaces throws "java.net.SocketException" on Solaris zone Reviewed-by: alanb, dsamersoff ! src/solaris/native/java/net/NetworkInterface.c Changeset: d82ed433304e Author: chegar Date: 2010-07-29 17:04 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/d82ed433304e Merge Changeset: 48e6f4807e5f Author: lana Date: 2010-07-29 22:02 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/48e6f4807e5f Merge - src/linux/doc/man/ja/kinit.1 - src/linux/doc/man/ja/klist.1 - src/linux/doc/man/ja/ktab.1 ! test/ProblemList.txt Changeset: 4d72d0ec83f5 Author: michaelm Date: 2010-07-30 18:16 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/4d72d0ec83f5 6510892: com/sun/net/httpserver/bugs/B6361557.java fails Reviewed-by: chegar ! test/com/sun/net/httpserver/bugs/B6361557.java Changeset: 10e7e04d1e96 Author: lana Date: 2010-08-02 19:45 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/10e7e04d1e96 Merge - test/java/net/Socket/AccurateTimeout.java Changeset: 3b0abcb51280 Author: lana Date: 2010-08-09 16:02 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/3b0abcb51280 Merge - test/java/net/Socket/AccurateTimeout.java Changeset: 382c79be52e9 Author: mcimadamore Date: 2010-08-12 12:18 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/jdk/rev/382c79be52e9 merge with jdk7-b105 - test/java/net/Socket/AccurateTimeout.java From maurizio.cimadamore at oracle.com Thu Aug 12 08:27:51 2010 From: maurizio.cimadamore at oracle.com (maurizio.cimadamore at oracle.com) Date: Thu, 12 Aug 2010 15:27:51 +0000 Subject: hg: lambda/lambda/langtools: 26 new changesets Message-ID: <20100812152836.1CEB1470EF@hg.openjdk.java.net> Changeset: bd85271c580c Author: mikejwre Date: 2010-07-23 16:42 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/bd85271c580c Added tag jdk7-b102 for changeset ff9c0a0bf7ed ! .hgtags Changeset: fc7219517ec1 Author: cl Date: 2010-07-29 13:33 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/fc7219517ec1 Added tag jdk7-b103 for changeset bd85271c580c ! .hgtags Changeset: 49489c1d8fae Author: cl Date: 2010-08-06 12:52 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/49489c1d8fae Added tag jdk7-b104 for changeset fc7219517ec1 ! .hgtags Changeset: a5454419dd46 Author: jjg Date: 2010-07-13 19:14 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/a5454419dd46 6966732: replace use of static Log.getLocalizedString with non-static alternative where possible Reviewed-by: darcy ! src/share/classes/com/sun/tools/javac/jvm/ClassReader.java ! src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java ! src/share/classes/com/sun/tools/javac/main/JavaCompiler.java ! src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java ! src/share/classes/com/sun/tools/javac/util/Log.java Changeset: 0e1fab5cffc8 Author: jjg Date: 2010-07-13 19:17 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/0e1fab5cffc8 6968434: test CheckResourceKeys fails on control builds Reviewed-by: darcy ! test/tools/javac/diags/CheckResourceKeys.java Changeset: e57b27703e8b Author: jjg Date: 2010-07-13 19:20 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/e57b27703e8b 6968789: incorrect text in "diamond not supported" message Reviewed-by: darcy ! src/share/classes/com/sun/tools/javac/resources/compiler.properties Changeset: b49b0d72c071 Author: mcimadamore Date: 2010-07-15 16:31 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/b49b0d72c071 6967002: JDK7 b99 javac compilation error (java.lang.AssertionError) Summary: bug in JavacParser related to parsing of type annotations in varargs position Reviewed-by: jjg Contributed-by: mahmood at notnoop.com ! src/share/classes/com/sun/tools/javac/parser/JavacParser.java + test/tools/javac/typeAnnotations/6967002/T6967002.java + test/tools/javac/typeAnnotations/6967002/T6967002.out Changeset: 472e74211e11 Author: mcimadamore Date: 2010-07-15 16:31 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/472e74211e11 6964669: javac reports error on miranda methods Summary: synthetic name clash check should not apply to miranda methods Reviewed-by: jjg Contributed-by: tomas.zezula at sun.com ! src/share/classes/com/sun/tools/javac/comp/Check.java + test/tools/javac/miranda/6964669/T6964669.java + test/tools/javac/miranda/6964669/pkg/A.java + test/tools/javac/miranda/6964669/pkg/B.java + test/tools/javac/miranda/6964669/pkg/C.java Changeset: 13354e1abba7 Author: darcy Date: 2010-07-16 19:35 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/13354e1abba7 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler 6964740: Project Coin: More tests for ARM compiler changes 6965277: Project Coin: Correctness issues in ARM implementation 6967065: add -Xlint warning category for Automatic Resource Management (ARM) Reviewed-by: jjb, darcy, mcimadamore, jjg, briangoetz Contributed-by: tball at google.com ! make/build.properties ! src/share/classes/com/sun/source/tree/TryTree.java ! src/share/classes/com/sun/source/util/TreeScanner.java ! src/share/classes/com/sun/tools/javac/code/Lint.java ! src/share/classes/com/sun/tools/javac/code/Source.java ! src/share/classes/com/sun/tools/javac/code/Symbol.java ! src/share/classes/com/sun/tools/javac/code/Symtab.java ! src/share/classes/com/sun/tools/javac/comp/Attr.java ! src/share/classes/com/sun/tools/javac/comp/Check.java ! src/share/classes/com/sun/tools/javac/comp/Flow.java ! src/share/classes/com/sun/tools/javac/comp/Lower.java ! src/share/classes/com/sun/tools/javac/comp/TransTypes.java ! src/share/classes/com/sun/tools/javac/jvm/CRTable.java ! src/share/classes/com/sun/tools/javac/parser/JavacParser.java ! src/share/classes/com/sun/tools/javac/resources/compiler.properties ! src/share/classes/com/sun/tools/javac/tree/JCTree.java ! src/share/classes/com/sun/tools/javac/tree/Pretty.java ! src/share/classes/com/sun/tools/javac/tree/TreeCopier.java ! src/share/classes/com/sun/tools/javac/tree/TreeMaker.java ! src/share/classes/com/sun/tools/javac/tree/TreeScanner.java ! src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java ! src/share/classes/com/sun/tools/javac/util/Names.java + test/tools/javac/TryWithResources/ArmLint.java + test/tools/javac/TryWithResources/ArmLint.out + test/tools/javac/TryWithResources/BadTwr.java + test/tools/javac/TryWithResources/BadTwr.out + test/tools/javac/TryWithResources/BadTwrSyntax.java + test/tools/javac/TryWithResources/BadTwrSyntax.out + test/tools/javac/TryWithResources/DuplicateResource.java + test/tools/javac/TryWithResources/DuplicateResourceDecl.java + test/tools/javac/TryWithResources/DuplicateResourceDecl.out + test/tools/javac/TryWithResources/ImplicitFinal.java + test/tools/javac/TryWithResources/ImplicitFinal.out + test/tools/javac/TryWithResources/PlainTry.java + test/tools/javac/TryWithResources/PlainTry.out + test/tools/javac/TryWithResources/PlainTry6.out + test/tools/javac/TryWithResources/ResourceOutsideTry.java + test/tools/javac/TryWithResources/ResourceOutsideTry.out + test/tools/javac/TryWithResources/ResourceTypeVar.java + test/tools/javac/TryWithResources/TwrFlow.java + test/tools/javac/TryWithResources/TwrFlow.out + test/tools/javac/TryWithResources/TwrInference.java + test/tools/javac/TryWithResources/TwrIntersection.java + test/tools/javac/TryWithResources/TwrIntersection02.java + test/tools/javac/TryWithResources/TwrIntersection02.out + test/tools/javac/TryWithResources/TwrMultiCatch.java + test/tools/javac/TryWithResources/TwrOnNonResource.java + test/tools/javac/TryWithResources/TwrOnNonResource.out + test/tools/javac/TryWithResources/TwrTests.java + test/tools/javac/TryWithResources/WeirdTwr.java + test/tools/javac/processing/model/element/TestResourceVariable.java Changeset: 3640b60bd0f6 Author: jjg Date: 2010-07-22 11:02 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/3640b60bd0f6 6968063: provide examples of code that generate diagnostics Reviewed-by: mcimadamore ! make/build.xml + test/tools/javac/diags/CheckExamples.java + test/tools/javac/diags/Example.java + test/tools/javac/diags/FileManager.java + test/tools/javac/diags/HTMLWriter.java + test/tools/javac/diags/README.examples.txt + test/tools/javac/diags/RunExamples.java + test/tools/javac/diags/examples.not-yet.txt + test/tools/javac/diags/examples/AbstractCantBeAccessed.java + test/tools/javac/diags/examples/AbstractCantBeInstantiated.java + test/tools/javac/diags/examples/AbstractMethodCantHaveBody.java + test/tools/javac/diags/examples/AlreadyDefined.java + test/tools/javac/diags/examples/AlreadyDefinedImport.java + test/tools/javac/diags/examples/AlreadyDefinedStaticImport/AlreadDefinedStaticImport.java + test/tools/javac/diags/examples/AlreadyDefinedStaticImport/p/E1.java + test/tools/javac/diags/examples/AlreadyDefinedStaticImport/p/E2.java + test/tools/javac/diags/examples/AnnoNotApplicable.java + test/tools/javac/diags/examples/AnnoNotValidForType.java + test/tools/javac/diags/examples/AnnoValueMustBeAnnotation.java + test/tools/javac/diags/examples/AnnoValueMustBeClassLiteral.java + test/tools/javac/diags/examples/AnnosWithoutProcessors/AnnosWithoutProcessors.java + test/tools/javac/diags/examples/AnnosWithoutProcessors/processors/AnnoProc.java + test/tools/javac/diags/examples/AnnotationMissingValue.java + test/tools/javac/diags/examples/AnnotationMustBeNameValue.java + test/tools/javac/diags/examples/AnnotationsNotSupported.java + test/tools/javac/diags/examples/AnonClassImplInterfaceNoArgs.java + test/tools/javac/diags/examples/AnonClassImplInterfaceNoQualForNew.java + test/tools/javac/diags/examples/AnonClassImplInterfaceNoTypeArgs.java + test/tools/javac/diags/examples/AnonymousClass.java + test/tools/javac/diags/examples/ArrayAndVarargs.java + test/tools/javac/diags/examples/ArrayDimMissing.java + test/tools/javac/diags/examples/ArrayRequired.java + test/tools/javac/diags/examples/AssertAsIdentifier.java + test/tools/javac/diags/examples/AssertAsIdentifier2.java + test/tools/javac/diags/examples/AttrMustBeConstant.java + test/tools/javac/diags/examples/BadSourceFileHeader/BadSourceFileHeader.java + test/tools/javac/diags/examples/BadSourceFileHeader/sourcepath/p/A.java + test/tools/javac/diags/examples/BreakOutsideSwitchLoop.java + test/tools/javac/diags/examples/CallMustBeFirst.java + test/tools/javac/diags/examples/CannotCreateArrayWithTypeArgs.java + test/tools/javac/diags/examples/CantApplyDiamond.java + test/tools/javac/diags/examples/CantAssignToFinal.java + test/tools/javac/diags/examples/CantDeref.java + test/tools/javac/diags/examples/CantExtendIntfAnno.java + test/tools/javac/diags/examples/CantImplement.java + test/tools/javac/diags/examples/CantInheritDiffArg.java + test/tools/javac/diags/examples/CantRefBeforeConstr.java + test/tools/javac/diags/examples/CantResolve.java + test/tools/javac/diags/examples/CantResolveArgs.java + test/tools/javac/diags/examples/CantResolveArgsParams.java + test/tools/javac/diags/examples/CantResolveLocation.java + test/tools/javac/diags/examples/CantResolveLocationArgs.java + test/tools/javac/diags/examples/CantResolveLocationArgsParams.java + test/tools/javac/diags/examples/CantReturnValueForVoid.java + test/tools/javac/diags/examples/CatchWithoutTry.java + test/tools/javac/diags/examples/ClashesWith.java + test/tools/javac/diags/examples/ClassCantWrite.java + test/tools/javac/diags/examples/ClassPublicInFile.java + test/tools/javac/diags/examples/ConcreteInheritanceConflict.java + test/tools/javac/diags/examples/ConstExprRequired.java + test/tools/javac/diags/examples/ConstantSVUID.java + test/tools/javac/diags/examples/ContinueOutsideLoop.java + test/tools/javac/diags/examples/CountError.java + test/tools/javac/diags/examples/CountErrorPlural.java + test/tools/javac/diags/examples/CountWarn.java + test/tools/javac/diags/examples/CountWarnPlural.java + test/tools/javac/diags/examples/CyclicAnnoElement.java + test/tools/javac/diags/examples/CyclicInheritance.java + test/tools/javac/diags/examples/DefaultAllowedInIntfAnnotationMember.java + test/tools/javac/diags/examples/DeprecatedFilename.java + test/tools/javac/diags/examples/DeprecatedFilenameAdditional.java + test/tools/javac/diags/examples/DeprecatedPlural/DeprecatedClass.java + test/tools/javac/diags/examples/DeprecatedPlural/DeprecatedFilename.java + test/tools/javac/diags/examples/DeprecatedPlural/DeprecatedPlural.java + test/tools/javac/diags/examples/DeprecatedPluralAdditional/DeprecatedClass.java + test/tools/javac/diags/examples/DeprecatedPluralAdditional/DeprecatedFilename.java + test/tools/javac/diags/examples/DeprecatedPluralAdditional/DeprecatedPlural.java + test/tools/javac/diags/examples/DeprecatedPluralAdditional/DeprecatedPluralAdditional.java + test/tools/javac/diags/examples/DiamondInvalidArg.java + test/tools/javac/diags/examples/DiamondInvalidArgs.java + test/tools/javac/diags/examples/DiamondNotSupported.java + test/tools/javac/diags/examples/DirPathElementNotFound.java + test/tools/javac/diags/examples/DivZero.java + test/tools/javac/diags/examples/DoesNotOverride.java + test/tools/javac/diags/examples/DoesntExist.java + test/tools/javac/diags/examples/DotClassExpected.java + test/tools/javac/diags/examples/DuplicateAnnotation.java + test/tools/javac/diags/examples/DuplicateAnnotationMemberValue.java + test/tools/javac/diags/examples/DuplicateCaseLabel.java + test/tools/javac/diags/examples/DuplicateClass.java + test/tools/javac/diags/examples/DuplicateDefaultLabel.java + test/tools/javac/diags/examples/ElseWithoutIf.java + test/tools/javac/diags/examples/EmptyBytecodeIdent.java + test/tools/javac/diags/examples/EmptyCharLiteral.java + test/tools/javac/diags/examples/EmptyIf.java + test/tools/javac/diags/examples/EnclClassRequired.java + test/tools/javac/diags/examples/EnumAnnoValueMustBeEnumConst.java + test/tools/javac/diags/examples/EnumAsIdentifier.java + test/tools/javac/diags/examples/EnumAsIdentifier2.java + test/tools/javac/diags/examples/EnumCantBeInstantiated.java + test/tools/javac/diags/examples/EnumConstRequired.java + test/tools/javac/diags/examples/EnumLabelUnqualified.java + test/tools/javac/diags/examples/EnumNoFinalize.java + test/tools/javac/diags/examples/EnumNoSubclassing.java + test/tools/javac/diags/examples/EnumTypesNotExtensible.java + test/tools/javac/diags/examples/EnumsMustBeStatic.java + test/tools/javac/diags/examples/EnumsNotSupported.java + test/tools/javac/diags/examples/ErrProcMessager/ErrProcMessager.java + test/tools/javac/diags/examples/ErrProcMessager/processors/AnnoProc.java + test/tools/javac/diags/examples/ErrSyntheticNameConflict.java + test/tools/javac/diags/examples/Error.java + test/tools/javac/diags/examples/ErrorReadingFile.java + test/tools/javac/diags/examples/ExceptAlreadyCaught.java + test/tools/javac/diags/examples/ExceptNeverThrown.java + test/tools/javac/diags/examples/Expected2.java + test/tools/javac/diags/examples/Expected3.java + test/tools/javac/diags/examples/FinalParamCantBeAssigned.java + test/tools/javac/diags/examples/FinallyCannotComplete.java + test/tools/javac/diags/examples/FinallyWithoutTry.java + test/tools/javac/diags/examples/FloatNumberTooLarge.java + test/tools/javac/diags/examples/FloatNumberTooSmall.java + test/tools/javac/diags/examples/ForeachNotApplicable.java + test/tools/javac/diags/examples/ForeachNotSupported.java + test/tools/javac/diags/examples/GenericArrayCreation.java + test/tools/javac/diags/examples/GenericThrowable.java + test/tools/javac/diags/examples/GenericsNotSupported.java + test/tools/javac/diags/examples/HasBeenDeprecated.java + test/tools/javac/diags/examples/IdentifierExpected.java + test/tools/javac/diags/examples/IllegalBytecodeIdentChar.java + test/tools/javac/diags/examples/IllegalChar.java + test/tools/javac/diags/examples/IllegalComboModifiers.java + test/tools/javac/diags/examples/IllegalEnumStaticRef.java + test/tools/javac/diags/examples/IllegalEscapeChar.java + test/tools/javac/diags/examples/IllegalForwardRef.java + test/tools/javac/diags/examples/IllegalInitializer.java + test/tools/javac/diags/examples/IllegalLineEndInCharLit.java + test/tools/javac/diags/examples/IllegalNonAsciiDigit.java + test/tools/javac/diags/examples/IllegalQualNotIcls.java + test/tools/javac/diags/examples/IllegalSelfRef.java + test/tools/javac/diags/examples/IllegalStartOfExpr.java + test/tools/javac/diags/examples/IllegalUnderscore.java + test/tools/javac/diags/examples/IllegalUnicodeEscape.java + test/tools/javac/diags/examples/ImportRequiresCanonical/ImportRequiresCanonical.java + test/tools/javac/diags/examples/ImportRequiresCanonical/p/Base.java + test/tools/javac/diags/examples/ImportRequiresCanonical/p/ExtendsBase.java + test/tools/javac/diags/examples/ImproperSVUID.java + test/tools/javac/diags/examples/ImproperTypeInnerRawParam.java + test/tools/javac/diags/examples/ImproperTypeParamMissing.java + test/tools/javac/diags/examples/IncomparableTypes.java + test/tools/javac/diags/examples/IncompatibleTypes1.java + test/tools/javac/diags/examples/InconvertibleTypes.java + test/tools/javac/diags/examples/InexactVarargsCall.java + test/tools/javac/diags/examples/InferredDoNotConformToBounds.java + test/tools/javac/diags/examples/InheritFromFinal.java + test/tools/javac/diags/examples/InitializerMustComplete.java + test/tools/javac/diags/examples/InnerClassCantHaveStatic.java + test/tools/javac/diags/examples/IntNumberTooLarge.java + test/tools/javac/diags/examples/InterfaceExpected.java + test/tools/javac/diags/examples/InterfaceNotAllowed.java + test/tools/javac/diags/examples/IntfAnnotationCantHaveTypeParams.java + test/tools/javac/diags/examples/IntfAnnotationMemberClash.java + test/tools/javac/diags/examples/IntfAnnotationsCantHaveParams.java + test/tools/javac/diags/examples/IntfAnnotationsCantHaveTypeParams.java + test/tools/javac/diags/examples/IntfMethodCantHaveBody.java + test/tools/javac/diags/examples/InvalidAnnoMemberType.java + test/tools/javac/diags/examples/InvalidBinaryNumber.java + test/tools/javac/diags/examples/InvalidHexNumber.java + test/tools/javac/diags/examples/InvalidInferredTypes.java + test/tools/javac/diags/examples/InvalidInstanceof.java + test/tools/javac/diags/examples/InvalidMethodDecl.java + test/tools/javac/diags/examples/KindnameClass.java + test/tools/javac/diags/examples/KindnameConstructor.java + test/tools/javac/diags/examples/KindnameMethod.java + test/tools/javac/diags/examples/KindnameVariable.java + test/tools/javac/diags/examples/LabelInUse.java + test/tools/javac/diags/examples/LocalEnum.java + test/tools/javac/diags/examples/LocalVarNeedsFinal.java + test/tools/javac/diags/examples/LongSVUID.java + test/tools/javac/diags/examples/MalformedFpLit.java + test/tools/javac/diags/examples/MalformedSupported/MalformedSupported.java + test/tools/javac/diags/examples/MalformedSupported/processors/AnnoProc.java + test/tools/javac/diags/examples/MethodDoesNotOverride.java + test/tools/javac/diags/examples/MightBeAssignedInLoop.java + test/tools/javac/diags/examples/MissingDeprecatedAnnotation.java + test/tools/javac/diags/examples/MissingMethodBody.java + test/tools/javac/diags/examples/MissingReturnStatement.java + test/tools/javac/diags/examples/MissingReturnValue.java + test/tools/javac/diags/examples/MissingSVUID.java + test/tools/javac/diags/examples/ModifierNotAllowed.java + test/tools/javac/diags/examples/MulticatchCantBeAssigned.java + test/tools/javac/diags/examples/MulticatchMustBeFinal.java + test/tools/javac/diags/examples/MulticatchNotSupported.java + test/tools/javac/diags/examples/NameClashSameErasure.java + test/tools/javac/diags/examples/NameClashSameErasureNoOverride.java + test/tools/javac/diags/examples/NativeMethodCantHaveBody.java + test/tools/javac/diags/examples/NeitherConditionalSubtype.java + test/tools/javac/diags/examples/NewNotAllowedInAnno.java + test/tools/javac/diags/examples/NoArgs.java + test/tools/javac/diags/examples/NoExplicitAnnoProcRequested.java + test/tools/javac/diags/examples/NoInterfaceExpected.java + test/tools/javac/diags/examples/NoInterfaceHere.java + test/tools/javac/diags/examples/NoJavaLang.java + test/tools/javac/diags/examples/NoSuperclass.java + test/tools/javac/diags/examples/NonStaticCantBeRef.java + test/tools/javac/diags/examples/NotDefAccessClassIntfCantAccess/NotDefAccessClassIntfCantAccess.java + test/tools/javac/diags/examples/NotDefAccessClassIntfCantAccess/p/C.java + test/tools/javac/diags/examples/NotDefPublicCantAccess/NotDefPublicCantAccess.java + test/tools/javac/diags/examples/NotDefPublicCantAccess/p/C.java + test/tools/javac/diags/examples/NotEnclClass.java + test/tools/javac/diags/examples/NotLoopLabel.java + test/tools/javac/diags/examples/NotWithinBounds.java + test/tools/javac/diags/examples/Note.java + test/tools/javac/diags/examples/NoteProcMessager/NoteProcMessager.java + test/tools/javac/diags/examples/NoteProcMessager/processors/AnnoProc.java + test/tools/javac/diags/examples/OperatorCantBeApplied.java + test/tools/javac/diags/examples/Orphaned.java + test/tools/javac/diags/examples/OverrideDoesntThrow.java + test/tools/javac/diags/examples/OverrideIncompatibleReturn.java + test/tools/javac/diags/examples/OverrideMeth.java + test/tools/javac/diags/examples/OverrideStatic.java + test/tools/javac/diags/examples/OverrideUncheckedReturn.java + test/tools/javac/diags/examples/OverrideUncheckedThrown.java + test/tools/javac/diags/examples/OverrideVarargsExtra.java + test/tools/javac/diags/examples/OverrideVarargsMissing.java + test/tools/javac/diags/examples/OverrideWeakerAccess.java + test/tools/javac/diags/examples/PackageAnnos.java + test/tools/javac/diags/examples/PackageInfoAlreadySeen/p/package-info.java + test/tools/javac/diags/examples/PackageInfoAlreadySeen/package-info.java + test/tools/javac/diags/examples/PathElementNotFound.java + test/tools/javac/diags/examples/PkgClashWithClass/p/q.java + test/tools/javac/diags/examples/PkgClashWithClass/p/q/C.java + test/tools/javac/diags/examples/PossibleFallThrough.java + test/tools/javac/diags/examples/PossibleLossPrecision.java + test/tools/javac/diags/examples/PrematureEOF.java + test/tools/javac/diags/examples/PrintProcessorInfo/PrintProcessorInfo.java + test/tools/javac/diags/examples/PrintProcessorInfo/processors/AnnoProc.java + test/tools/javac/diags/examples/PrintRounds/PrintRounds.java + test/tools/javac/diags/examples/PrintRounds/processors/AnnoProc.java + test/tools/javac/diags/examples/ProcCantFindClass/ProcCantFindClass.java + test/tools/javac/diags/examples/ProcCantFindClass/processors/AnnoProc.java + test/tools/javac/diags/examples/ProcFileReopening/ProcFileReopening.java + test/tools/javac/diags/examples/ProcFileReopening/processors/AnnoProc.java + test/tools/javac/diags/examples/ProcIllegalFileName/ProcIllegalFileName.java + test/tools/javac/diags/examples/ProcIllegalFileName/processors/AnnoProc.java + test/tools/javac/diags/examples/ProcIncompatibleSourceVersion/ProcIncompatibleSourceVersion.java + test/tools/javac/diags/examples/ProcIncompatibleSourceVersion/processors/AnnoProc.java + test/tools/javac/diags/examples/ProcOnlyNoProcs.java + test/tools/javac/diags/examples/ProcPackageDoesNotExist/ProcPackageDoesNotExist.java + test/tools/javac/diags/examples/ProcPackageDoesNotExist/processors/AnnoProc.java + test/tools/javac/diags/examples/ProcTypeRecreate/ProcTypeRecreate.java + test/tools/javac/diags/examples/ProcTypeRecreate/processors/AnnoProc.java + test/tools/javac/diags/examples/ProcUnclosedTypeFiles/ProcUnclosedTypeFiles.java + test/tools/javac/diags/examples/ProcUnclosedTypeFiles/processors/AnnoProc.java + test/tools/javac/diags/examples/ProcUseImplicit/ProcUseImplicit.java + test/tools/javac/diags/examples/ProcUseImplicit/processors/AnnoProc.java + test/tools/javac/diags/examples/ProcUseImplicit/sourcepath/p/SomeClass.java + test/tools/javac/diags/examples/ProcUseProcOrImplicit/ProcUseProcOrImplicit.java + test/tools/javac/diags/examples/ProcUseProcOrImplicit/processors/AnnoProc.java + test/tools/javac/diags/examples/ProcUseProcOrImplicit/sourcepath/p/SomeClass.java + test/tools/javac/diags/examples/ProcessorCantInstantiate/ProcessorCantInstantiate.java + test/tools/javac/diags/examples/ProcessorCantInstantiate/processors/AnnoProc.java + test/tools/javac/diags/examples/ProcessorNotFound.java + test/tools/javac/diags/examples/ProcessorWrongType/ProcessorWrongType.java + test/tools/javac/diags/examples/ProcessorWrongType/processors/AnnoProc.java + test/tools/javac/diags/examples/QualifiedNewStaticClass.java + test/tools/javac/diags/examples/RawClassUse.java + test/tools/javac/diags/examples/RecursiveConstrInvocation.java + test/tools/javac/diags/examples/RedundantCast.java + test/tools/javac/diags/examples/RefAmbiguous.java + test/tools/javac/diags/examples/RepeatedAnnotationTarget.java + test/tools/javac/diags/examples/RepeatedInterface.java + test/tools/javac/diags/examples/RepeatedModifier.java + test/tools/javac/diags/examples/ReportAccess.java + test/tools/javac/diags/examples/ResourceClosed.java + test/tools/javac/diags/examples/ResourceMayNotBeAssigned.java + test/tools/javac/diags/examples/ResourceNotApplicableToType.java + test/tools/javac/diags/examples/ResourceNotReferenced.java + test/tools/javac/diags/examples/ReturnOutsideMethod.java + test/tools/javac/diags/examples/StaticImportNotSupported.java + test/tools/javac/diags/examples/StaticImportOnlyClassesAndInterfaces/Other.java + test/tools/javac/diags/examples/StaticImportOnlyClassesAndInterfaces/StaticImportOnlyClassesAndInterfaces.java + test/tools/javac/diags/examples/StaticNotQualifiedByType.java + test/tools/javac/diags/examples/StringConstRequired.java + test/tools/javac/diags/examples/StringSwitchNotSupported.java + test/tools/javac/diags/examples/SunApiFilename.java + test/tools/javac/diags/examples/SunApiFilenameAdditional.java + test/tools/javac/diags/examples/SunApiPlural/SunApiFilename.java + test/tools/javac/diags/examples/SunApiPlural/SunApiPlural.java + test/tools/javac/diags/examples/SunApiPluralAdditional/SunApiFilename.java + test/tools/javac/diags/examples/SunApiPluralAdditional/SunApiPlural.java + test/tools/javac/diags/examples/SunApiPluralAdditional/SunApiPluralAdditional.java + test/tools/javac/diags/examples/SunProprietary.java + test/tools/javac/diags/examples/SuperNotAllowedInEnum.java + test/tools/javac/diags/examples/ThrowsNotAllowedInAnno.java + test/tools/javac/diags/examples/TryResourceNotSupported.java + test/tools/javac/diags/examples/TryWithoutCatchOrFinally.java + test/tools/javac/diags/examples/TryWithoutCatchOrFinallyOrResource.java + test/tools/javac/diags/examples/TypeAnnotationsNotSupported.java + test/tools/javac/diags/examples/TypeFoundRequired.java + test/tools/javac/diags/examples/TypeNoParams.java + test/tools/javac/diags/examples/TypeReqClassArray.java + test/tools/javac/diags/examples/TypeReqRef.java + test/tools/javac/diags/examples/TypeVarCantBeDeref.java + test/tools/javac/diags/examples/TypeVarMayNotBeFollowedByOtherBounds.java + test/tools/javac/diags/examples/TypesIncompatible.java + test/tools/javac/diags/examples/UncheckedAssign.java + test/tools/javac/diags/examples/UncheckedAssignToVar.java + test/tools/javac/diags/examples/UncheckedCall.java + test/tools/javac/diags/examples/UncheckedCast.java + test/tools/javac/diags/examples/UncheckedClash.java + test/tools/javac/diags/examples/UncheckedFilename.java + test/tools/javac/diags/examples/UncheckedFilenameAdditional.java + test/tools/javac/diags/examples/UncheckedGenericArrayCreation.java + test/tools/javac/diags/examples/UncheckedImplement.java + test/tools/javac/diags/examples/UncheckedMethodInvocation.java + test/tools/javac/diags/examples/UncheckedPlural/UncheckedFilename.java + test/tools/javac/diags/examples/UncheckedPlural/UncheckedPlural.java + test/tools/javac/diags/examples/UncheckedPluralAdditional/UncheckedFilename1.java + test/tools/javac/diags/examples/UncheckedPluralAdditional/UncheckedFilename2.java + test/tools/javac/diags/examples/UncheckedPluralAdditional/UncheckedPluralAdditional.java + test/tools/javac/diags/examples/UnclosedBytecodeIdent.java + test/tools/javac/diags/examples/UnclosedCharLiteral.java + test/tools/javac/diags/examples/UnclosedComment.java + test/tools/javac/diags/examples/UnclosedStringLiteral.java + test/tools/javac/diags/examples/UndefinedLabel.java + test/tools/javac/diags/examples/UndeterminedType1.java + test/tools/javac/diags/examples/UnmatchedProcessorOptions/UnmatchedProcessorOptions.java + test/tools/javac/diags/examples/UnmatchedProcessorOptions/processors/AnnoProc.java + test/tools/javac/diags/examples/UnnamedPackage.java + test/tools/javac/diags/examples/UnreachableStatement.java + test/tools/javac/diags/examples/UnreportedException.java + test/tools/javac/diags/examples/UnreportedExceptionDefaultConstructor.java + test/tools/javac/diags/examples/UnsupportedBinaryLiteral.java + test/tools/javac/diags/examples/UnsupportedEncoding.java + test/tools/javac/diags/examples/UnsupportedFpLit.java + test/tools/javac/diags/examples/UnsupportedUnderscoreLiteral.java + test/tools/javac/diags/examples/VarMightAlreadyBeAssigned.java + test/tools/javac/diags/examples/VarMightNotHaveBeenInitialized.java + test/tools/javac/diags/examples/VarargsClash.java + test/tools/javac/diags/examples/VarargsFilename.java + test/tools/javac/diags/examples/VarargsFilenameAdditional.java + test/tools/javac/diags/examples/VarargsImplement.java + test/tools/javac/diags/examples/VarargsNonReifiableType.java + test/tools/javac/diags/examples/VarargsNotSupported.java + test/tools/javac/diags/examples/VarargsOverride.java + test/tools/javac/diags/examples/VarargsPlural/VarargsFilename.java + test/tools/javac/diags/examples/VarargsPlural/VarargsPlural.java + test/tools/javac/diags/examples/VarargsPluralAdditional/VarargsFilename.java + test/tools/javac/diags/examples/VarargsPluralAdditional/VarargsPlural.java + test/tools/javac/diags/examples/VarargsPluralAdditional/VarargsPluralAdditional.java + test/tools/javac/diags/examples/Verbose.java + test/tools/javac/diags/examples/VoidNotAllowed.java + test/tools/javac/diags/examples/WarnForwardRef.java + test/tools/javac/diags/examples/WarnProcMessager/WarnProcMessager.java + test/tools/javac/diags/examples/WarnProcMessager/processors/AnnoProc.java + test/tools/javac/diags/examples/WarnSelfRef.java + test/tools/javac/diags/examples/WarnSyntheticNameConflict.java + test/tools/javac/diags/examples/WarningAndWerror.java + test/tools/javac/diags/examples/WhereCaptured.java + test/tools/javac/diags/examples/WhereCaptured1.java + test/tools/javac/diags/examples/WhereIntersection.java + test/tools/javac/diags/examples/WhereTypeVar.java + test/tools/javac/diags/examples/WrongNumberTypeArgs.java Changeset: 4172cfff05f0 Author: jjg Date: 2010-07-26 14:18 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/4172cfff05f0 6971882: Remove -XDstdout from javac test Reviewed-by: darcy ! test/tools/javac/4980495/static/Test.java ! test/tools/javac/4980495/std/Test.java ! test/tools/javac/6304921/T6304921.java ! test/tools/javac/6330920/T6330920.java ! test/tools/javac/6491592/T6491592.java ! test/tools/javac/6717241/T6717241a.java ! test/tools/javac/6717241/T6717241b.java ! test/tools/javac/ClassFileModifiers/ClassModifiers.java ! test/tools/javac/ClassFileModifiers/MemberModifiers.java ! test/tools/javac/CyclicInheritance.java ! test/tools/javac/Digits.java ! test/tools/javac/ExtendArray.java ! test/tools/javac/ExtendsAccess/ExtendsAccess.java ! test/tools/javac/FloatingPointChanges/BadConstructorModifiers.java ! test/tools/javac/IllegalAnnotation.java ! test/tools/javac/InnerNamedConstant_2.java ! test/tools/javac/InterfaceMemberClassModifiers.java ! test/tools/javac/LocalClasses_2.java ! test/tools/javac/NameCollision.java ! test/tools/javac/NestedInnerClassNames.java ! test/tools/javac/NonStaticFieldExpr1.java ! test/tools/javac/NonStaticFieldExpr2.java ! test/tools/javac/NonStaticFieldExpr3.java ! test/tools/javac/OverridePosition.java ! test/tools/javac/QualifiedAccess/QualifiedAccess_1.java ! test/tools/javac/QualifiedAccess/QualifiedAccess_2.java ! test/tools/javac/QualifiedAccess/QualifiedAccess_3.java ! test/tools/javac/StringsInSwitch/BadlyTypedLabel1.java ! test/tools/javac/StringsInSwitch/BadlyTypedLabel2.java ! test/tools/javac/StringsInSwitch/NonConstantLabel.java ! test/tools/javac/StringsInSwitch/RepeatedStringCaseLabels1.java ! test/tools/javac/StringsInSwitch/RepeatedStringCaseLabels2.java ! test/tools/javac/SynchronizedClass.java ! test/tools/javac/T4093617/T4093617.java ! test/tools/javac/T4906100.java ! test/tools/javac/T4994049/T4994049.java ! test/tools/javac/T5003235/T5003235a.java ! test/tools/javac/T5003235/T5003235b.java ! test/tools/javac/T5003235/T5003235c.java ! test/tools/javac/T5024091/T5024091.java ! test/tools/javac/T5048776.java ! test/tools/javac/T6214885.java ! test/tools/javac/T6224167.java ! test/tools/javac/T6227617.java ! test/tools/javac/T6230128.java ! test/tools/javac/T6231847.java ! test/tools/javac/T6241723.java ! test/tools/javac/T6245591.java ! test/tools/javac/T6247324.java ! test/tools/javac/T6394563.java ! test/tools/javac/annotations/6214965/T6214965.java ! test/tools/javac/annotations/6365854/T6365854.java ! test/tools/javac/danglingDep/DepX.java ! test/tools/javac/danglingDep/NoDepX.java ! test/tools/javac/danglingDep/Test1.java ! test/tools/javac/depDocComment/DeprecatedDocComment.java ! test/tools/javac/depDocComment/SuppressDeprecation.java ! test/tools/javac/depOverrides/annotation/Test1.java ! test/tools/javac/depOverrides/annotation/Test2.java ! test/tools/javac/depOverrides/annotation/Test3.java ! test/tools/javac/depOverrides/doccomment/Test1.java ! test/tools/javac/depOverrides/doccomment/Test2.java ! test/tools/javac/depOverrides/doccomment/Test3.java ! test/tools/javac/enum/6384542/T6384542.java ! test/tools/javac/enum/6384542/T6384542a.java ! test/tools/javac/enum/forwardRef/T6425594.java ! test/tools/javac/generics/5009937/T5009937.java ! test/tools/javac/generics/6207386/T6207386.java ! test/tools/javac/generics/6359951/T6359951.java ! test/tools/javac/generics/6677785/T6677785.java ! test/tools/javac/generics/6723444/T6723444.java ! test/tools/javac/generics/inference/6611449/T6611449.java ! test/tools/javac/generics/inference/6718364/T6718364.java ! test/tools/javac/generics/wildcards/6437894/T6437894.java ! test/tools/javac/lint/NoWarn.java ! test/tools/javac/mandatoryWarnings/deprecated/Test.java ! test/tools/javac/mandatoryWarnings/unchecked/Test.java ! test/tools/javac/miranda/T4666866.java ! test/tools/javac/missingSuperRecovery/MissingSuperRecovery.java ! test/tools/javac/policy/test1/Test1a.java ! test/tools/javac/policy/test2/Test.java ! test/tools/javac/positions/T6253161.java ! test/tools/javac/positions/T6253161a.java ! test/tools/javac/positions/T6264029.java ! test/tools/javac/processing/messager/6362067/T6362067.java ! test/tools/javac/processing/warnings/TestSourceVersionWarnings.java ! test/tools/javac/protectedAccess/ProtectedMemberAccess2.java ! test/tools/javac/protectedAccess/ProtectedMemberAccess3.java ! test/tools/javac/protectedAccess/ProtectedMemberAccess4.java ! test/tools/javac/rawDiags/Error.java ! test/tools/javac/rawDiags/Note.java ! test/tools/javac/rawDiags/Warning.java ! test/tools/javac/unicode/UnicodeNewline.java ! test/tools/javac/warnings/Deprecation.java ! test/tools/javac/warnings/DivZero.java ! test/tools/javac/warnings/FallThrough.java ! test/tools/javac/warnings/Unchecked.java Changeset: d1bd93028447 Author: jjg Date: 2010-07-26 14:25 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/d1bd93028447 6957438: improve code for generating warning messages containing option names Reviewed-by: mcimadamore ! src/share/classes/com/sun/tools/javac/code/Lint.java ! src/share/classes/com/sun/tools/javac/comp/Attr.java ! src/share/classes/com/sun/tools/javac/comp/Check.java ! src/share/classes/com/sun/tools/javac/comp/Flow.java ! src/share/classes/com/sun/tools/javac/comp/Resolve.java ! src/share/classes/com/sun/tools/javac/file/Paths.java ! src/share/classes/com/sun/tools/javac/resources/compiler.properties ! src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java ! src/share/classes/com/sun/tools/javac/util/AbstractLog.java ! src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java ! src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java ! src/share/classes/com/sun/tools/javac/util/MandatoryWarningHandler.java ! test/tools/javac/diags/examples/CountWarn.java ! test/tools/javac/diags/examples/CountWarnPlural.java ! test/tools/javac/diags/examples/Error.java Changeset: b29160d1b3e0 Author: jjg Date: 2010-07-27 11:32 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/b29160d1b3e0 6972327: JCTree.pos incorrect for annotations without modifiers and package Reviewed-by: mcimadamore Contributed-by: jan.lahoda at sun.com ! src/share/classes/com/sun/tools/javac/parser/JavacParser.java ! src/share/classes/com/sun/tools/javac/tree/TreeMaker.java + test/tools/javac/T6972327.java Changeset: ed354a00f76b Author: jjg Date: 2010-07-27 11:52 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/ed354a00f76b 6403456: -Werror should work with annotation processing Reviewed-by: darcy ! src/share/classes/com/sun/tools/javac/processing/JavacMessager.java ! src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java + test/tools/javac/processing/werror/WError1.java + test/tools/javac/processing/werror/WError1.out + test/tools/javac/processing/werror/WErrorGen.java + test/tools/javac/processing/werror/WErrorGen.out + test/tools/javac/processing/werror/WErrorLast.java + test/tools/javac/processing/werror/WErrorLast.out Changeset: 36c4ec4525b4 Author: mcimadamore Date: 2010-07-29 15:56 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/36c4ec4525b4 6938454: Unable to determine generic type in program that compiles under Java 6 Summary: a redundant dubtyping check causes spurious inference failure Reviewed-by: jjg ! src/share/classes/com/sun/tools/javac/comp/Attr.java ! src/share/classes/com/sun/tools/javac/comp/Infer.java + test/tools/javac/generics/inference/6938454/T6938454a.java + test/tools/javac/generics/inference/6938454/T6938454b.java Changeset: e79e8efe1b3e Author: mcimadamore Date: 2010-07-29 15:57 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/e79e8efe1b3e 6972747: CheckExamples fail when assertions are enabled Summary: The test calls the wrong version of JavacMessage constructor Reviewed-by: jjg ! test/tools/javac/diags/Example.java Changeset: 62f3f07002ea Author: mcimadamore Date: 2010-07-29 15:57 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/62f3f07002ea 6970833: Try-with-resource implementation throws an NPE during Flow analysis Summary: Updated logic not to rely upon Symbol.implementation (which check in superinterfaces) Reviewed-by: jjg ! src/share/classes/com/sun/tools/javac/comp/Flow.java ! src/share/classes/com/sun/tools/javac/main/JavaCompiler.java + test/tools/javac/TryWithResources/ResourceInterface.java + test/tools/javac/TryWithResources/ResourceInterface.out Changeset: 4a7979c3ce15 Author: jjg Date: 2010-07-29 18:06 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/4a7979c3ce15 6972556: warning for using a file name instead of a binary name for Filer.createSourceFile Reviewed-by: darcy ! src/share/classes/com/sun/tools/javac/processing/JavacFiler.java ! src/share/classes/com/sun/tools/javac/resources/compiler.properties + test/tools/javac/diags/examples/ProcSuspiciousClassName/ProcSuspiciousClassName.java + test/tools/javac/diags/examples/ProcSuspiciousClassName/processors/AnnoProc.java Changeset: 8a5c98a695ae Author: jjg Date: 2010-07-29 19:27 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/8a5c98a695ae 6340549: javax.tools.JavaCompilerTool.getStandardFileManager().list() includes directories Reviewed-by: darcy + test/tools/javac/T6340549.java Changeset: 2cf925ad67ab Author: jjg Date: 2010-07-29 19:30 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/2cf925ad67ab 6966604: JavacFiler not correctly notified of lastRound Reviewed-by: darcy ! src/share/classes/com/sun/tools/javac/processing/JavacFiler.java ! src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java ! test/tools/javac/diags/examples.not-yet.txt + test/tools/javac/diags/examples/ProcFileCreateLastRound/ProcFileCreateLastRound.java + test/tools/javac/diags/examples/ProcFileCreateLastRound/processors/AnnoProc.java + test/tools/javac/processing/filer/TestLastRound.java + test/tools/javac/processing/filer/TestLastRound.out ! test/tools/javac/processing/werror/WErrorGen.java Changeset: 077eb94c912d Author: lana Date: 2010-07-29 22:04 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/077eb94c912d Merge Changeset: 38e2c23309f1 Author: darcy Date: 2010-08-02 13:35 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/38e2c23309f1 6971877: Project Coin: improve semantics of suppressed exceptions in try-with-resources Reviewed-by: jjb + test/tools/javac/TryWithResources/TwrSuppression.java Changeset: 6318230cdb82 Author: jjg Date: 2010-08-02 16:29 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/6318230cdb82 6973626: test/tools/javac/processing/* tests fail with assertions enabled Reviewed-by: darcy ! src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Changeset: 186feb2042f0 Author: lana Date: 2010-08-02 19:46 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/186feb2042f0 Merge Changeset: aaecac256d39 Author: lana Date: 2010-08-09 16:03 -0700 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/aaecac256d39 Merge Changeset: fd3c998a07b0 Author: mcimadamore Date: 2010-08-12 15:38 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/fd3c998a07b0 merge with jdk7-b105 ! make/build.properties ! make/build.xml ! src/share/classes/com/sun/source/util/TreeScanner.java ! src/share/classes/com/sun/tools/javac/code/Source.java ! src/share/classes/com/sun/tools/javac/code/Symbol.java ! src/share/classes/com/sun/tools/javac/code/Symtab.java ! src/share/classes/com/sun/tools/javac/comp/Attr.java ! src/share/classes/com/sun/tools/javac/comp/Check.java ! src/share/classes/com/sun/tools/javac/comp/Flow.java ! src/share/classes/com/sun/tools/javac/comp/Infer.java ! src/share/classes/com/sun/tools/javac/comp/Lower.java ! src/share/classes/com/sun/tools/javac/comp/Resolve.java ! src/share/classes/com/sun/tools/javac/comp/TransTypes.java ! src/share/classes/com/sun/tools/javac/jvm/CRTable.java ! src/share/classes/com/sun/tools/javac/jvm/ClassReader.java ! src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java ! src/share/classes/com/sun/tools/javac/main/JavaCompiler.java ! src/share/classes/com/sun/tools/javac/parser/JavacParser.java ! src/share/classes/com/sun/tools/javac/resources/compiler.properties ! src/share/classes/com/sun/tools/javac/tree/JCTree.java ! src/share/classes/com/sun/tools/javac/tree/Pretty.java ! src/share/classes/com/sun/tools/javac/tree/TreeCopier.java ! src/share/classes/com/sun/tools/javac/tree/TreeMaker.java ! src/share/classes/com/sun/tools/javac/tree/TreeScanner.java ! src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java ! src/share/classes/com/sun/tools/javac/util/Log.java ! src/share/classes/com/sun/tools/javac/util/Names.java + test/tools/javac/diags/examples.not-yet.txt + test/tools/javac/diags/examples/IllegalChar.java + test/tools/javac/diags/examples/LocalVarNeedsFinal.java + test/tools/javac/diags/examples/MulticatchCantBeAssigned.java From peter.levart at marand.si Thu Aug 12 09:25:39 2010 From: peter.levart at marand.si (Peter Levart) Date: Thu, 12 Aug 2010 18:25:39 +0200 Subject: Question on exception transparency In-Reply-To: <4C63EE79.4050200@oracle.com> References: <705619.2671.qm@web24208.mail.ird.yahoo.com> <201008121440.06446.peter.levart@marand.si> <4C63EE79.4050200@oracle.com> Message-ID: <201008121825.39276.peter.levart@marand.si> On 08/12/10, Maurizio Cimadamore wrote: > On 12/08/10 13:40, Peter Levart wrote: > > import java.util.*; > > > > public class Closures > > { > > public interface Block { void run(T param) throws E; } > > > > public static > > void forEach(Iterable iterable, Block block) throws E > > { > > for (T obj : iterable) block.run(obj); > > } > > > > public static void main(String[] args) > > { > > // example 1: > > forEach( > > Arrays.asList("a", "b", "c"), > > #(String s){ System.out.println("element: " + s); } > > ); > > > > // example 2 - javac throws NPE: > > // Closures.forEach( > > // Arrays.asList("a", "b", "c"), > > // Block #(String s){ System.out.println("element: " + s); } > > // ); > > } > > } > > > The following works for me: > > Closures.forEach( > Arrays.asList("a", "b", "c"), > Block #(s){ System.out.println("element: " + s); } > ); > > I guess the NPE has been fixed in the last push. > Yes, that works now. But the following: forEach( Arrays.asList("a", "b", "c"), #(String s){ System.out.println("element: " + s); } ); ... is currently no better than: forEach( Arrays.asList("a", "b", "c"), #(s){ System.out.println("element: " + s); } ); They both infer "Exception" as the thrown type. Can this be improved? Is specifying lambda expression's parameter type actualy doing any help here? My naive uninformed understanding is that If the algorithm for method resolution worked in 2 passes: 1st pass would resolve method without taking into account throws type parameters 2nd pass would "check and apply" throws type parameters for the resolved method ...then even in the presence of overloaded methods exception transparency could work without explicitly specifying type parameters either on method or prefixing lambda with target SAM type. Peter From maurizio.cimadamore at oracle.com Thu Aug 12 10:13:55 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 12 Aug 2010 18:13:55 +0100 Subject: Question on exception transparency In-Reply-To: <201008121825.39276.peter.levart@marand.si> References: <705619.2671.qm@web24208.mail.ird.yahoo.com> <201008121440.06446.peter.levart@marand.si> <4C63EE79.4050200@oracle.com> <201008121825.39276.peter.levart@marand.si> Message-ID: <4C642BD3.30907@oracle.com> Hi Peter, now that I look at your example more carefully (I was doing a bloody merge with b105 :-) ) I confirm that, at least in principle, the following should compile and infer 'void' instead of Exception: forEach( Arrays.asList("a", "b", "c"), #(String s){ System.out.println("element: " + s); } ); I will fix this soon. Maurizio On 12/08/10 17:25, Peter Levart wrote: > On 08/12/10, Maurizio Cimadamore wrote: > >> On 12/08/10 13:40, Peter Levart wrote: >> >>> import java.util.*; >>> >>> public class Closures >>> { >>> public interface Block { void run(T param) throws E; } >>> >>> public static >>> void forEach(Iterable iterable, Block block) throws E >>> { >>> for (T obj : iterable) block.run(obj); >>> } >>> >>> public static void main(String[] args) >>> { >>> // example 1: >>> forEach( >>> Arrays.asList("a", "b", "c"), >>> #(String s){ System.out.println("element: " + s); } >>> ); >>> >>> // example 2 - javac throws NPE: >>> // Closures.forEach( >>> // Arrays.asList("a", "b", "c"), >>> // Block #(String s){ System.out.println("element: " + s); } >>> // ); >>> } >>> } >>> >>> >> The following works for me: >> >> Closures.forEach( >> Arrays.asList("a", "b", "c"), >> Block #(s){ System.out.println("element: " + s); } >> ); >> >> I guess the NPE has been fixed in the last push. >> >> > Yes, that works now. But the following: > > forEach( > Arrays.asList("a", "b", "c"), > #(String s){ System.out.println("element: " + s); } > ); > > ... is currently no better than: > > forEach( > Arrays.asList("a", "b", "c"), > #(s){ System.out.println("element: " + s); } > ); > > > They both infer "Exception" as the thrown type. Can this be improved? Is specifying lambda expression's parameter type actualy doing any help here? > > My naive uninformed understanding is that If the algorithm for method resolution worked in 2 passes: > > 1st pass would resolve method without taking into account throws type parameters > 2nd pass would "check and apply" throws type parameters for the resolved method > > ...then even in the presence of overloaded methods exception transparency could work without explicitly specifying type parameters either on method or prefixing lambda with target SAM type. > > Peter > From marcus at thiesen.org Fri Aug 13 05:19:10 2010 From: marcus at thiesen.org (Marcus Thiesen) Date: Fri, 13 Aug 2010 14:19:10 +0200 Subject: A couple of questions about Project Lambda Message-ID: Hi Lambda-Devs, I toyed around a little bit with the latest Lambda prototype and got a couple of questions. I used the mercurial version as of today against jdk7 build 104 as described in [1]. SAM Conversion: The spec in [2] says "A SAM (Single Abstract Method) type is a top-level class or interface type with abstract member". I misread this as "top-level class or top-level interface", but the implementation actually works with member interfaces [3] which strikes me as inconstistent because I can use SAM conversion with a member interface but not with a member class, is there any reason for this? Function Types: Trying to compile [4] does not work: (master)->marcus at lindan:~/src/java7/lambda: ../../java/langtools/dist/bin/javac -source 7 -XDallowFunctionTypes FunctionTypes.java FunctionTypes.java:3: function types are not supported in -source 1.7 public String resolver( final String value, #String(String) function ) { ^ (use -source 7 or higher and -XDallowFunctionTypes to enable function types) 1 error I guess this is due to my setup but is it supposed to work like this or are the Function Types pure virtual types that I can not declare as the type of a variable? Defender Methods: Running [5] gives me an AbtractMethodError but compiles, somehow he is looking for an implementation of the actual method without the interface extra argument. Furthermore I would like to know if a Interface with only one single not defender Method should actually qualify for SAM conversion, apparently it does not work that way atm. Any feedback would be welcome, Marcus 1: http://mail.openjdk.java.net/pipermail/lambda-dev/2010-August/002179.html 2: http://mail.openjdk.java.net/pipermail/lambda-dev/attachments/20100122/3764c21a/attachment.txt 3: http://github.com/marcust/jdk7-examples/blob/master/lambda/SAM.java 4: http://github.com/marcust/jdk7-examples/blob/master/lambda/FunctionTypes.java 5: http://github.com/marcust/jdk7-examples/blob/master/lambda/DefenderMethods.java -- ?:: Marcus Thiesen :: www.thiesen.org :: ICQ#108989768 :: 0x754675F2 :: I've been to war. I've raised twins. If I had a choice, I'd rather go to war ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? George W. Bush From forax at univ-mlv.fr Fri Aug 13 05:48:02 2010 From: forax at univ-mlv.fr (=?UTF-8?B?UsOpbWkgRm9yYXg=?=) Date: Fri, 13 Aug 2010 14:48:02 +0200 Subject: A couple of questions about Project Lambda In-Reply-To: References: Message-ID: <4C653F02.6050308@univ-mlv.fr> Le 13/08/2010 14:19, Marcus Thiesen a ?crit : > Hi Lambda-Devs, > the lambda project is a moving target :) > I toyed around a little bit with the latest Lambda prototype and got a > couple of questions. I used the mercurial version as of today against > jdk7 build 104 as described in [1]. > > SAM Conversion: > The spec in [2] says "A SAM (Single Abstract Method) type is a > top-level class or interface > type with abstract member". I misread this as "top-level class or > top-level interface", but the implementation actually works with > member interfaces [3] which strikes me as inconstistent because I can > use SAM conversion with a member interface but not with a member > class, is there any reason for this? > A member class (not static) has a back reference to its enclosing class. > Function Types: > Trying to compile [4] does not work: > > (master)->marcus at lindan:~/src/java7/lambda: > ../../java/langtools/dist/bin/javac -source 7 -XDallowFunctionTypes > FunctionTypes.java > FunctionTypes.java:3: function types are not supported in -source 1.7 > public String resolver( final String value, #String(String) function ) { > ^ > (use -source 7 or higher and -XDallowFunctionTypes to enable function types) > 1 error > > I guess this is due to my setup but is it supposed to work like this > or are the Function Types pure virtual types that I can not declare as > the type of a variable? > You can't use function types anymore. As today, the spec doesn't include any function type notation anymore. > Defender Methods: > Running [5] gives me an AbtractMethodError but compiles, somehow he is > looking for an implementation of the actual method without the > interface extra argument. > The compiler knows what a defender method is, but currently the VM don't. You will have to wait a little bit :) > Furthermore I would like to know if a Interface with only one single > not defender Method should actually qualify for SAM conversion, > apparently it does not work that way atm. > > Any feedback would be welcome, > > Marcus > R?mi From maurizio.cimadamore at oracle.com Fri Aug 13 08:23:54 2010 From: maurizio.cimadamore at oracle.com (maurizio.cimadamore at oracle.com) Date: Fri, 13 Aug 2010 15:23:54 +0000 Subject: hg: lambda/lambda/langtools: More bug fixes: Message-ID: <20100813152359.DCE2747153@hg.openjdk.java.net> Changeset: cbf392027ba0 Author: mcimadamore Date: 2010-08-13 16:22 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/cbf392027ba0 More bug fixes: *) 'void' as explicit method type-parameter should be handled correctly *) nil-ary disjunctive types should be handled properly while inferring 'throws' type-vars from lambdas ! src/share/classes/com/sun/tools/javac/code/Types.java ! src/share/classes/com/sun/tools/javac/comp/Check.java ! src/share/classes/com/sun/tools/javac/comp/Infer.java ! src/share/classes/com/sun/tools/javac/comp/Resolve.java ! src/share/classes/com/sun/tools/javac/util/List.java + test/tools/javac/lambda/ExceptionTransparency02.java + test/tools/javac/transparency/Pos04.java From alex.buckley at oracle.com Fri Aug 13 11:58:38 2010 From: alex.buckley at oracle.com (Alex Buckley) Date: Fri, 13 Aug 2010 11:58:38 -0700 Subject: A couple of questions about Project Lambda In-Reply-To: <4C653F02.6050308@univ-mlv.fr> References: <4C653F02.6050308@univ-mlv.fr> Message-ID: <4C6595DE.90701@oracle.com> On 8/13/2010 5:48 AM, R?mi Forax wrote: > Le 13/08/2010 14:19, Marcus Thiesen a ?crit : >> SAM Conversion: >> The spec in [2] says "A SAM (Single Abstract Method) type is a >> top-level class or interface >> type with abstract member". I misread this as "top-level class or >> top-level interface", but the implementation actually works with >> member interfaces [3] which strikes me as inconstistent because I can >> use SAM conversion with a member interface but not with a member >> class, is there any reason for this? >> > > A member class (not static) has a back reference to its enclosing class. Yes. The aim is really to allow _non-inner_ classes, i.e. either a) top-level classes or b) nested classes which are static. Also, member interfaces are fine because they're implicitly static. Good catch, Marcus. Alex From howard.lovatt at gmail.com Sat Aug 14 04:02:34 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Sat, 14 Aug 2010 21:02:34 +1000 Subject: What am I doing wrong? hg: lambda/lambda/langtools: More bug fixes: Message-ID: Great work on updating JDK 7. I have been trying to use the method pointers but I get a what I think is a bug. I get: lambdas/Main.java:35: function types are not supported in -source 1.7 Arrays.sort( people, #Person.compareByAge ); ^ (use -source 7 or higher and -XDallowFunctionTypes to enable function types) lambdas/Main.java:35: '(' expected Arrays.sort( people, #Person.compareByAge ); ^ lambdas/Main.java:35: ')' expected Arrays.sort( people, #Person.compareByAge ); My runtime line is: $jdk/javac -Xlint:all -source 7 -XDallowFunctionTypes -d ../build/classes $package/*.java I built javac from the latest hg changeset on a Mac running 10.6. Therefore javac in the above is the script created by the makefile in the hg repository. The underling VM is MLVM from http://www.concord.org/~sbannasch/mlvm/. If I change to #Person.compareByAge() I get: lambdas/Main.java:35: function types are not supported in -source 1.7 Arrays.sort( people, #Person.compareByAge() ); ^ (use -source 7 or higher and -XDallowFunctionTypes to enable function types) 1 error If I change to #Person.compareByAge( Person, Person ) I get: lambdas/Main.java:35: function types are not supported in -source 1.7 Arrays.sort( people, #Person.compareByAge( Person, Person ) ); ^ (use -source 7 or higher and -XDallowFunctionTypes to enable function types) 1 error If I change to Person#compareByAge( Person, Person ) I get: An exception has occurred in the compiler (1.7.0-internal). Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport) after checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report. Thank you. com.sun.tools.javac.code.Symbol$CompletionFailure: class file for com.sun.runtime.ProxyHelper not found What am I doing wrong? ? -- Howard. From forax at univ-mlv.fr Sat Aug 14 06:51:48 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Sat, 14 Aug 2010 15:51:48 +0200 Subject: What am I doing wrong? hg: lambda/lambda/langtools: More bug fixes: In-Reply-To: References: Message-ID: <4C669F74.80908@univ-mlv.fr> Hi Howard, the syntax is Person#compareByAge() and not #Person.compareByAge(). #Person... is the starts the old syntax for function types. R?mi Le 14/08/2010 13:02, Howard Lovatt a ?crit : > Great work on updating JDK 7. > > I have been trying to use the method pointers but I get a what I think > is a bug. I get: > > > lambdas/Main.java:35: function types are not supported in -source 1.7 > Arrays.sort( people, #Person.compareByAge ); > ^ > (use -source 7 or higher and -XDallowFunctionTypes to enable function types) > lambdas/Main.java:35: '(' expected > Arrays.sort( people, #Person.compareByAge ); > ^ > lambdas/Main.java:35: ')' expected > Arrays.sort( people, #Person.compareByAge ); > > > My runtime line is: > > > $jdk/javac -Xlint:all -source 7 -XDallowFunctionTypes -d > ../build/classes $package/*.java > > > I built javac from the latest hg changeset on a Mac running 10.6. > Therefore javac in the above is the script created by the makefile in > the hg repository. The underling VM is MLVM from > http://www.concord.org/~sbannasch/mlvm/. > > If I change to #Person.compareByAge() I get: > > > lambdas/Main.java:35: function types are not supported in -source 1.7 > Arrays.sort( people, #Person.compareByAge() ); > ^ > (use -source 7 or higher and -XDallowFunctionTypes to enable function types) > 1 error > > > If I change to #Person.compareByAge( Person, Person ) I get: > > > lambdas/Main.java:35: function types are not supported in -source 1.7 > Arrays.sort( people, #Person.compareByAge( Person, Person ) ); > ^ > (use -source 7 or higher and -XDallowFunctionTypes to enable function types) > 1 error > > > If I change to Person#compareByAge( Person, Person ) I get: > > > An exception has occurred in the compiler (1.7.0-internal). Please > file a bug at the Java Developer Connection > (http://java.sun.com/webapps/bugreport) after checking the Bug Parade > for duplicates. Include your program and the following diagnostic in > your report. Thank you. > com.sun.tools.javac.code.Symbol$CompletionFailure: class file for > com.sun.runtime.ProxyHelper not found > > > > What am I doing wrong? > > -- Howard. > > From howard.lovatt at gmail.com Sun Aug 15 14:46:23 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Mon, 16 Aug 2010 07:46:23 +1000 Subject: What am I doing wrong? hg: lambda/lambda/langtools: More bug fixes: Message-ID: @Remi, The syntaxes (sp ?) Person#compareByAge and Person#compareByAge( Person, Person ) result in: An exception has occurred in the compiler (1.7.0-internal). Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport) after checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report. Thank you. com.sun.tools.javac.code.Symbol$CompletionFailure: class file for com.sun.runtime.ProxyHelper not found The syntax Person#compareByAge() results in: lambdas/Main.java:35: method compareByAge in class Person cannot be applied to given types Arrays.sort( people, Person#compareByAge() ); ^ required: Person,Person found: no arguments Implying that Person#compareByAge( Person, Person ) is the correct syntax, however that causes the above exception. -- ? -- Howard. From maurizio.cimadamore at oracle.com Mon Aug 16 00:59:52 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Mon, 16 Aug 2010 08:59:52 +0100 Subject: What am I doing wrong? hg: lambda/lambda/langtools: More bug fixes: In-Reply-To: References: Message-ID: <4C68EFF8.2020701@oracle.com> Hi From the message you are getting it seems like the special class com.sun.runtime.ProxyHelper is not included in the boot classpath, this causing the completion error to occur when the compiler tries to generate code that depends on such class. How are you invoking the lambda compiler? Maurizio On 15/08/10 22:46, Howard Lovatt wrote: > @Remi, > > The syntaxes (sp ?) Person#compareByAge and Person#compareByAge( > Person, Person ) result in: > > An exception has occurred in the compiler (1.7.0-internal). Please > file a bug at the Java Developer Connection > (http://java.sun.com/webapps/bugreport) after checking the Bug Parade > for duplicates. Include your program and the following diagnostic in > your report. Thank you. > com.sun.tools.javac.code.Symbol$CompletionFailure: class file for > com.sun.runtime.ProxyHelper not found > > The syntax Person#compareByAge() results in: > > lambdas/Main.java:35: method compareByAge in class Person cannot be > applied to given types > Arrays.sort( people, Person#compareByAge() ); > ^ > required: Person,Person > found: no arguments > > Implying that Person#compareByAge( Person, Person ) is the correct > syntax, however that causes the above exception. > > From maurizio.cimadamore at oracle.com Mon Aug 16 03:01:33 2010 From: maurizio.cimadamore at oracle.com (maurizio.cimadamore at oracle.com) Date: Mon, 16 Aug 2010 10:01:33 +0000 Subject: hg: lambda/lambda/langtools: Non-static selectors in method refs, such as instance creation expressions, should be handled correctly (prepended to argument list). Message-ID: <20100816100137.A9DF5471FD@hg.openjdk.java.net> Changeset: c3232ad98c72 Author: mcimadamore Date: 2010-08-16 11:00 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/c3232ad98c72 Non-static selectors in method refs, such as instance creation expressions, should be handled correctly (prepended to argument list). ! src/share/classes/com/sun/tools/javac/comp/Attr.java ! src/share/classes/com/sun/tools/javac/jvm/Gen.java ! src/share/classes/com/sun/tools/javac/tree/TreeInfo.java ! test/tools/javac/lambda/MethodReference09.out + test/tools/javac/lambda/MethodReference10.java From pbenedict at apache.org Mon Aug 16 08:25:21 2010 From: pbenedict at apache.org (Paul Benedict) Date: Mon, 16 Aug 2010 10:25:21 -0500 Subject: hg: lambda/lambda/langtools: Non-static selectors in method refs, such as instance creation expressions, should be handled correctly (prepended to argument list). In-Reply-To: <20100816100137.A9DF5471FD@hg.openjdk.java.net> References: <20100816100137.A9DF5471FD@hg.openjdk.java.net> Message-ID: Maurizio, In the MethodReference10 example, main() has this call: sortBy(c, new Foo()#getA); Has there been any further thought to making parentheses mandatory? sortBy(c, new Foo()#getA(Foo)); ... that is, to facilitate the language extending to field references. Paul On Mon, Aug 16, 2010 at 5:01 AM, wrote: > Changeset: c3232ad98c72 > Author: mcimadamore > Date: 2010-08-16 11:00 +0100 > URL: > http://hg.openjdk.java.net/lambda/lambda/langtools/rev/c3232ad98c72 > > Non-static selectors in method refs, such as instance creation expressions, > should be handled correctly (prepended to argument list). > > ! src/share/classes/com/sun/tools/javac/comp/Attr.java > ! src/share/classes/com/sun/tools/javac/jvm/Gen.java > ! src/share/classes/com/sun/tools/javac/tree/TreeInfo.java > ! test/tools/javac/lambda/MethodReference09.out > + test/tools/javac/lambda/MethodReference10.java > > > From maurizio.cimadamore at oracle.com Mon Aug 16 08:48:33 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Mon, 16 Aug 2010 16:48:33 +0100 Subject: hg: lambda/lambda/langtools: Non-static selectors in method refs, such as instance creation expressions, should be handled correctly (prepended to argument list). In-Reply-To: References: <20100816100137.A9DF5471FD@hg.openjdk.java.net> Message-ID: <4C695DD1.1030005@oracle.com> On 16/08/10 16:25, Paul Benedict wrote: > Maurizio, > > In the MethodReference10 example, main() has this call: > sortBy(c, new Foo()#getA); > > Has there been any further thought to making parentheses mandatory? > sortBy(c, new Foo()#getA(Foo)); > > ... that is, to facilitate the language extending to field references. Hi Paul Field references are an explicit non-priority for the forseeable future. Said that, we are being careful to choose a syntax and semantics that do not foreclose on the possibility of supporting field references in the future. Cheers Maurizio > > Paul > > On Mon, Aug 16, 2010 at 5:01 AM, > wrote: > > Changeset: c3232ad98c72 > Author: mcimadamore > Date: 2010-08-16 11:00 +0100 > URL: > http://hg.openjdk.java.net/lambda/lambda/langtools/rev/c3232ad98c72 > > Non-static selectors in method refs, such as instance creation > expressions, should be handled correctly (prepended to argument list). > > ! src/share/classes/com/sun/tools/javac/comp/Attr.java > ! src/share/classes/com/sun/tools/javac/jvm/Gen.java > ! src/share/classes/com/sun/tools/javac/tree/TreeInfo.java > ! test/tools/javac/lambda/MethodReference09.out > + test/tools/javac/lambda/MethodReference10.java > > > From brian.goetz at oracle.com Mon Aug 16 12:01:28 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Mon, 16 Aug 2010 15:01:28 -0400 Subject: Latest draft of Defender Methods Message-ID: <4C698B08.4080805@oracle.com> I've posted a new draft of Defender Methods at: http://cr.openjdk.java.net/~briangoetz/lambda/Defender%20Methods%20v3.pdf From pbenedict at apache.org Mon Aug 16 12:31:13 2010 From: pbenedict at apache.org (Paul Benedict) Date: Mon, 16 Aug 2010 14:31:13 -0500 Subject: Latest draft of Defender Methods In-Reply-To: <4C698B08.4080805@oracle.com> References: <4C698B08.4080805@oracle.com> Message-ID: Brian, I believe the need for the "extension" keyword is superfluous. Correct me if wrong, but you don't actually need an existing interface to use defender methods, right? I create a brand new interface with all default implementations provided? If so, then I put forth my opinion to remove the keyword. The use of "default" is enough -- the use of "extension" implies a use case that's not necessarily true: I don't need to augment an existing interface to add default methods. Paul On Mon, Aug 16, 2010 at 2:01 PM, Brian Goetz wrote: > I've posted a new draft of Defender Methods at: > > > http://cr.openjdk.java.net/~briangoetz/lambda/Defender%20Methods%20v3.pdf > > > From ola.bini at gmail.com Mon Aug 16 13:41:27 2010 From: ola.bini at gmail.com (Ola Bini) Date: Mon, 16 Aug 2010 15:41:27 -0500 Subject: Latest draft of Defender Methods In-Reply-To: <4C698B08.4080805@oracle.com> References: <4C698B08.4080805@oracle.com> Message-ID: <4C69A277.5060607@gmail.com> On 2010-08-16 14.01, Brian Goetz wrote: > I've posted a new draft of Defender Methods at: > > http://cr.openjdk.java.net/~briangoetz/lambda/Defender%20Methods%20v3.pdf > 1. Will it be possible to undefault a specific method? Say that Collection defines a default method for reduce(), will it be possible to create an interface derived from Collection that says that reduce() will have to be implemented by the implementing class after all? 2. When compiling a class that implements an extended interface, I assume it will act as if implementations for all default methods have been provided, when deciding if the class has to be abstract? Cheers -- Ola Bini (http://olabini.com) Ioke - JRuby - ThoughtWorks "Yields falsehood when quined" yields falsehood when quined. From brian.goetz at oracle.com Mon Aug 16 14:03:51 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Mon, 16 Aug 2010 17:03:51 -0400 Subject: Latest draft of Defender Methods In-Reply-To: <4C69A277.5060607@gmail.com> References: <4C698B08.4080805@oracle.com> <4C69A277.5060607@gmail.com> Message-ID: <4C69A7B7.7030407@oracle.com> >> I've posted a new draft of Defender Methods at: >> >> http://cr.openjdk.java.net/~briangoetz/lambda/Defender%20Methods%20v3.pdf >> > 1. Will it be possible to undefault a specific method? Say that > Collection defines a default method for reduce(), will it be possible > to create an interface derived from Collection that says that > reduce() will have to be implemented by the implementing class after all? This is analogous to re-abstracting a concrete instance method, and seems a desirable goal. > 2. When compiling a class that implements an extended interface, I > assume it will act as if implementations for all default methods have > been provided, when deciding if the class has to be abstract? Yes. Failing to provide an implementation for an extension method does not leave you only partially in completion of the interface contract. Combining this with (1) above, it is possible that a superclass is recompiled which re-abstracts an extension method, making subclasses fail at runtime to implement the interface contract. Again, this is analogous to the current situation, where re-abstracting an instance method is not a binary compatible change. From brian.goetz at oracle.com Mon Aug 16 14:09:34 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Mon, 16 Aug 2010 17:09:34 -0400 Subject: Latest draft of Defender Methods In-Reply-To: References: <4C698B08.4080805@oracle.com> Message-ID: <4C69A90E.2040401@oracle.com> You are technically correct, if our goal was to strip the syntax down to the absolute minimum, "extension" would not be needed. Several people on this list have already expressed the same viewpoint. And you are correct that extension methods can be used an on interface from day 1, without a pre-existing implementation. We believe, at this point, that the extra token adds sufficient value to leave the proposal as-is. As has been stated before, though, we would prefer to not engage in discussions over syntax when there are so much more important things to discuss. Syntax discussions are like an invasive species; once they get root, nothing else gets any oxygen. Trust that we've noted this concern and we've filed it away for future consideration when we are convinced we've covered the more important bits, like, "does this work", "is this a good idea", "can we implement it", "how does this interact with other language features", "how should conflicts be resolved", "what will the performance be like", "what is the specification impact", "can we make our schedule", etc. Cheers, -Brian On 8/16/2010 3:31 PM, Paul Benedict wrote: > Brian, > > I believe the need for the "extension" keyword is superfluous. Correct > me if wrong, but you don't actually need an existing interface to use > defender methods, right? I create a brand new interface with all default > implementations provided? If so, then I put forth my opinion to remove > the keyword. The use of "default" is enough -- the use of "extension" > implies a use case that's not necessarily true: I don't need to augment > an existing interface to add default methods. > > Paul > > On Mon, Aug 16, 2010 at 2:01 PM, Brian Goetz > wrote: > > I've posted a new draft of Defender Methods at: > > http://cr.openjdk.java.net/~briangoetz/lambda/Defender%20Methods%20v3.pdf > > > > From reinier at zwitserloot.com Mon Aug 16 15:00:27 2010 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 17 Aug 2010 00:00:27 +0200 Subject: Latest draft of Defender Methods In-Reply-To: <4C698B08.4080805@oracle.com> References: <4C698B08.4080805@oracle.com> Message-ID: Is there a changelog of some sort? PDF documents are kind of hard to diff. A second somewhat obscure note: The syntax for the default method does not include a parameter list. Instead, presumably, if the class+method name is not unique (i.e. its been overloaded), then the right method is deduced from the parameter list of the extension method. However, para 8.2 defines the relation between an extension method's signature and the implementation of it in terms of what the extension signature should look like given the implementation. That's catch-22, then - you can't check if the signature of the default method is legit until you know which exact implementation method is being pointed at via 'default X', but you can't know which method is pointed at until you've sorted out the signature of the extension method. That's just a spec technicality, but there's also a legitimate technical issue here: What if the method is overloaded, and more than one overloaded method would 'fit', i.e. I have: extension int foo(Integer n) default X.bar; as well as, in public class X: public static int foo(Number n) { return 0; } public static int foo(Integer n) { return 1; } it's fairly obvious that the intent is to 'find' the 1-returning variant. However, (A) is this clear in the spec, and (B) should the notion be supported that one might want to explicitly pick the Number variant? Writing your own static method that invokes the right 'foo' is not that hard to do, but on the other hand, the fix is simple: Allow an optional param type list. Thus, I could write: extension int foo(Integer n) default X.bar(Number); And, if this syntax is allowed, should a param-type-less default reference simply fail at compile time if the reference is ambiguous, instead of attempting the usual complicated method resolution algorithm? Some sort of 'ambiguous' error must always be an option. For example, if the interface's extension method signature reads (Integer, Integer), and there are 2 valid methods, one with signature (Integer, Number) and the other with (Number, Integer). --Reinier Zwitserloot On Mon, Aug 16, 2010 at 9:01 PM, Brian Goetz wrote: > I've posted a new draft of Defender Methods at: > > > http://cr.openjdk.java.net/~briangoetz/lambda/Defender%20Methods%20v3.pdf > > > From brian.goetz at oracle.com Mon Aug 16 15:09:44 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Mon, 16 Aug 2010 18:09:44 -0400 Subject: Latest draft of Defender Methods In-Reply-To: References: <4C698B08.4080805@oracle.com> Message-ID: <4C69B728.3060000@oracle.com> > A second somewhat obscure note: The syntax for the default method does > not include a parameter list. Instead, presumably, if the class+method > name is not unique (i.e. its been overloaded), then the right method is > deduced from the parameter list of the extension method. That is correct; the intention is that the correct method is deduced. However, this draft loosens the matching algorithm, which was previously just "receiver type prepended onto extension method argument list", to allow resolution using the method resolution algorithm. We could use the same scheme as we use for disambiguating method references (but only when needed), or we could require you to write a new method that resolves unambiguously. TBD. > However, para 8.2 defines the relation between an extension method's > signature and the implementation of it in terms of what the extension > signature should look like given the implementation. No. The extension signature is given explicitly in the class file. The default signature is the one that has to be resolved. There's no circularity here. > That's just a spec technicality, but there's also a legitimate technical > issue here: What if the method is overloaded, and more than one > overloaded method would 'fit', i.e. I have: > > extension int foo(Integer n) default X.bar; > > as well as, in public class X: > > public static int foo(Number n) { return 0; } > public static int foo(Integer n) { return 1; } Method resolution usually has an answer. We piggyback on that. > And, if this syntax is allowed, should a param-type-less default > reference simply fail at compile time if the reference is ambiguous, > instead of attempting the usual complicated method resolution algorithm? Paramless can always mean "try and figure it out for me", since default methods can never be nilary (they always require at least a receiver.) > Some sort of 'ambiguous' error must always be an option. For example, if > the interface's extension method signature reads (Integer, Integer), and > there are 2 valid methods, one with signature (Integer, Number) and the > other with (Number, Integer). The compiler is allowed to emit a compilation error if it cannot resolve the reference. From howard.lovatt at gmail.com Mon Aug 16 18:02:23 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Tue, 17 Aug 2010 11:02:23 +1000 Subject: What am I doing wrong? hg: lambda/lambda/langtools: More bug fixes: In-Reply-To: <4C68EFF8.2020701@oracle.com> References: <4C68EFF8.2020701@oracle.com> Message-ID: Hi Maurizio, I am using the script generated by running make from the?Mercurial repository, the pertinent line from the langtools/dist/bin/javac script is: "/System/Library/Frameworks/JavaVM.framework/Versions/1.7.0_2010_07_30/Home//bin/java" "${bcp:+-Xbootclasspath/p:"$bcp"}" ${ea} ${javaOpts} -jar "${mydir}"/../lib/javac.jar ${toolOpts} Where the java VM called is the MLVM from: http://www.concord.org/~sbannasch/mlvm/ The javac script mentioned above is called by: $jdk/javac -Xlint:all -source 7 -XDallowFunctionTypes -d ../build/classes $package/*.java Cheers, -- Howard. On 16 August 2010 17:59, Maurizio Cimadamore wrote: > > Hi > From the message you are getting it seems like the special class com.sun.runtime.ProxyHelper is not included in the boot classpath, this causing the completion error to occur when the compiler tries to generate code that depends on such class. How are you invoking the lambda compiler? > > Maurizio > > On 15/08/10 22:46, Howard Lovatt wrote: >> >> @Remi, >> >> The syntaxes (sp ?) Person#compareByAge and Person#compareByAge( >> Person, Person ) result in: >> >> An exception has occurred in the compiler (1.7.0-internal). Please >> file a bug at the Java Developer Connection >> (http://java.sun.com/webapps/bugreport) ?after checking the Bug Parade >> for duplicates. Include your program and the following diagnostic in >> your report. ?Thank you. >> com.sun.tools.javac.code.Symbol$CompletionFailure: class file for >> com.sun.runtime.ProxyHelper not found >> >> The syntax Person#compareByAge() results in: >> >> lambdas/Main.java:35: method compareByAge in class Person cannot be >> applied to given types >> ? ? Arrays.sort( people, Person#compareByAge() ); >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?^ >> ? required: Person,Person >> ? found: no arguments >> >> Implying that Person#compareByAge( Person, Person ) is the correct >> syntax, however that causes the above exception. >> >> > -- ? -- Howard. From maurizio.cimadamore at oracle.com Tue Aug 17 01:41:04 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Tue, 17 Aug 2010 09:41:04 +0100 Subject: What am I doing wrong? hg: lambda/lambda/langtools: More bug fixes: In-Reply-To: References: <4C68EFF8.2020701@oracle.com> Message-ID: <4C6A4B20.8030202@oracle.com> On 17/08/10 02:02, Howard Lovatt wrote: > Hi Maurizio, > > I am using the script generated by running make from the Mercurial > repository, the pertinent line from the langtools/dist/bin/javac > script is: > > "/System/Library/Frameworks/JavaVM.framework/Versions/1.7.0_2010_07_30/Home//bin/java" > "${bcp:+-Xbootclasspath/p:"$bcp"}" ${ea} ${javaOpts} -jar > "${mydir}"/../lib/javac.jar ${toolOpts} > the script assumes to be in a NetBeans like structure in which you have a dist/ folder with two subfolders, bin/ (where your javac/java scripts are) and lib/ where (javac.jar is). I guess that a failure to locate lib/javac.jar could cause the problem you are talking about - I'd suggest verifying that javac.jar is really accessible using the ../lib/javac.jar path (relative to the path in which the script you are calling is located). Maurizio > Where the java VM called is the MLVM from: > > http://www.concord.org/~sbannasch/mlvm/ > > The javac script mentioned above is called by: > > $jdk/javac -Xlint:all -source 7 -XDallowFunctionTypes -d > ../build/classes $package/*.java > > > Cheers, > > -- Howard. > > On 16 August 2010 17:59, Maurizio Cimadamore > wrote: > >> Hi >> From the message you are getting it seems like the special class com.sun.runtime.ProxyHelper is not included in the boot classpath, this causing the completion error to occur when the compiler tries to generate code that depends on such class. How are you invoking the lambda compiler? >> >> Maurizio >> >> On 15/08/10 22:46, Howard Lovatt wrote: >> >>> @Remi, >>> >>> The syntaxes (sp ?) Person#compareByAge and Person#compareByAge( >>> Person, Person ) result in: >>> >>> An exception has occurred in the compiler (1.7.0-internal). Please >>> file a bug at the Java Developer Connection >>> (http://java.sun.com/webapps/bugreport) after checking the Bug Parade >>> for duplicates. Include your program and the following diagnostic in >>> your report. Thank you. >>> com.sun.tools.javac.code.Symbol$CompletionFailure: class file for >>> com.sun.runtime.ProxyHelper not found >>> >>> The syntax Person#compareByAge() results in: >>> >>> lambdas/Main.java:35: method compareByAge in class Person cannot be >>> applied to given types >>> Arrays.sort( people, Person#compareByAge() ); >>> ^ >>> required: Person,Person >>> found: no arguments >>> >>> Implying that Person#compareByAge( Person, Person ) is the correct >>> syntax, however that causes the above exception. >>> >>> >>> >> > > > -- > -- Howard. > From howard.lovatt at gmail.com Tue Aug 17 19:33:28 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Wed, 18 Aug 2010 12:33:28 +1000 Subject: What am I doing wrong? hg: lambda/lambda/langtools: More bug fixes: In-Reply-To: <4C6A4B20.8030202@oracle.com> References: <4C68EFF8.2020701@oracle.com> <4C6A4B20.8030202@oracle.com> Message-ID: Hi Maurizio, If I set up a couple of variables to make commands shorter and clearer: howard-lovatts-computer-3:src lov080$ echo $jdk /Users/lov080/Dropbox/Personal/Java/JDK7/langtools/dist/bin howard-lovatts-computer-3:src lov080$ echo $hglibs /Users/lov080/Dropbox/Personal/Java/JDK7/langtools/dist/lib Check that javac.jar is present: howard-lovatts-computer-3:src lov080$ ls -l $hglibs/javac.jar -rw-r--r-- 1 lov080 515598196 1364115 14 Aug 18:36 /Users/lov080/Dropbox/Personal/Java/JDK7/langtools/dist/lib/javac.jar Run the command line entirely manually, I get: howard-lovatts-computer-3:src lov080$ $jdk/java -Xbootclasspath/p:$hglibs/javac.jar -ea -jar $hglibs/javac.jar -Xlint:all -source 7 -XDallowFunctionTypes -d ../build/classes lambdas/*.java VM option '+UnlockExperimentalVMOptions' VM option '+EnableMethodHandles' VM option '+EnableInvokeDynamic' An exception has occurred in the compiler (1.7.0-internal). Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport) after checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report. Thank you. com.sun.tools.javac.code.Symbol$CompletionFailure: class file for com.sun.runtime.ProxyHelper not found Check that ProxyHelper is in javac.jar: howard-lovatts-computer-3:src lov080$ jar tf $hglibs/javac.jar [snip] com/sun/source/tree/NewClassTree.class com/sun/source/tree/ParameterizedTypeTree.class com/sun/source/tree/ParenthesizedTree.class com/sun/source/tree/PrimitiveTypeTree.class com/sun/source/tree/ReturnTree.class [snip] Then I conclude that the problem is that ProxyHelper isn't in javac.jar. Is this the problem? Cheers, -- Howard. On 17 August 2010 18:41, Maurizio Cimadamore wrote: > On 17/08/10 02:02, Howard Lovatt wrote: >> >> Hi Maurizio, >> >> I am using the script generated by running make from the Mercurial >> repository, the pertinent line from the langtools/dist/bin/javac >> script is: >> >> >> "/System/Library/Frameworks/JavaVM.framework/Versions/1.7.0_2010_07_30/Home//bin/java" >> "${bcp:+-Xbootclasspath/p:"$bcp"}" ${ea} ${javaOpts} -jar >> "${mydir}"/../lib/javac.jar ${toolOpts} >> > > the script assumes to be in a NetBeans like structure in which you have a > dist/ folder with two subfolders, bin/ (where your javac/java scripts are) > and lib/ where (javac.jar is). I guess that a failure to locate > lib/javac.jar could cause the problem you are talking about - I'd suggest > verifying that javac.jar is really accessible using the ../lib/javac.jar > path (relative to the path in which the script you are calling is located). > > Maurizio > > >> Where the java VM called is the MLVM from: >> >> http://www.concord.org/~sbannasch/mlvm/ >> >> The javac script mentioned above is called by: >> >> $jdk/javac -Xlint:all -source 7 -XDallowFunctionTypes -d >> ../build/classes $package/*.java >> >> >> Cheers, >> >> ?-- Howard. >> >> On 16 August 2010 17:59, Maurizio Cimadamore >> ?wrote: >> >>> >>> Hi >>> ?From the message you are getting it seems like the special class >>> com.sun.runtime.ProxyHelper is not included in the boot classpath, this >>> causing the completion error to occur when the compiler tries to generate >>> code that depends on such class. How are you invoking the lambda compiler? >>> >>> Maurizio >>> >>> On 15/08/10 22:46, Howard Lovatt wrote: >>> >>>> >>>> @Remi, >>>> >>>> The syntaxes (sp ?) Person#compareByAge and Person#compareByAge( >>>> Person, Person ) result in: >>>> >>>> An exception has occurred in the compiler (1.7.0-internal). Please >>>> file a bug at the Java Developer Connection >>>> (http://java.sun.com/webapps/bugreport) ?after checking the Bug Parade >>>> for duplicates. Include your program and the following diagnostic in >>>> your report. ?Thank you. >>>> com.sun.tools.javac.code.Symbol$CompletionFailure: class file for >>>> com.sun.runtime.ProxyHelper not found >>>> >>>> The syntax Person#compareByAge() results in: >>>> >>>> lambdas/Main.java:35: method compareByAge in class Person cannot be >>>> applied to given types >>>> ? ? Arrays.sort( people, Person#compareByAge() ); >>>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?^ >>>> ? required: Person,Person >>>> ? found: no arguments >>>> >>>> Implying that Person#compareByAge( Person, Person ) is the correct >>>> syntax, however that causes the above exception. >>>> >>>> >>>> >>> >>> >> >> >> -- >> ? -- Howard. >> > > -- ? -- Howard. From thomas.andreas.jung at googlemail.com Wed Aug 18 07:52:48 2010 From: thomas.andreas.jung at googlemail.com (Thomas Jung) Date: Wed, 18 Aug 2010 16:52:48 +0200 Subject: SAM conversion of extended interfaces Message-ID: Hi, conversion to SAM types does not work for extended interfaces like A: interface A{ Object m(); extension void n() default E.n; //works with if this line is commented out } class E{ public static void n(A a){}; } A t = #{value}; //does not compile Error message: "invalid target type A for lambda conversion". Thomas From maurizio.cimadamore at oracle.com Wed Aug 18 08:15:03 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 18 Aug 2010 16:15:03 +0100 Subject: SAM conversion of extended interfaces In-Reply-To: References: Message-ID: <4C6BF8F7.707@oracle.com> On 18/08/10 15:52, Thomas Jung wrote: > Hi, > > conversion to SAM types does not work for extended interfaces like A: > > interface A{ > Object m(); > extension void n() default E.n; //works with if this line is commented out > } > > class E{ > public static void n(A a){}; > } > Nice one, thanks for the headsup. The routine that checks for well-formedness of SAM interfaces should obviously skip defender methods... Maurizio > A t = #{value}; //does not compile > > Error message: "invalid target type A for lambda conversion". > > Thomas > > From howard.lovatt at gmail.com Wed Aug 18 18:53:50 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Thu, 19 Aug 2010 11:53:50 +1000 Subject: What am I doing wrong? hg: lambda/lambda/langtools: More bug fixes: In-Reply-To: <4C6A4B20.8030202@oracle.com> References: <4C68EFF8.2020701@oracle.com> <4C6A4B20.8030202@oracle.com> Message-ID: Hi Maurizio, Latest push in Mercurial repository has ProxyHelper in javac.jar and hence it now works for me, thanks. However there is another issue, javac.jar has to be added to the runtime (because the runtime also needs ProxyHelper). Cheers, -- Howard. On 17 August 2010 18:41, Maurizio Cimadamore wrote: > On 17/08/10 02:02, Howard Lovatt wrote: >> >> Hi Maurizio, >> >> I am using the script generated by running make from the Mercurial >> repository, the pertinent line from the langtools/dist/bin/javac >> script is: >> >> >> "/System/Library/Frameworks/JavaVM.framework/Versions/1.7.0_2010_07_30/Home//bin/java" >> "${bcp:+-Xbootclasspath/p:"$bcp"}" ${ea} ${javaOpts} -jar >> "${mydir}"/../lib/javac.jar ${toolOpts} >> > > the script assumes to be in a NetBeans like structure in which you have a > dist/ folder with two subfolders, bin/ (where your javac/java scripts are) > and lib/ where (javac.jar is). I guess that a failure to locate > lib/javac.jar could cause the problem you are talking about - I'd suggest > verifying that javac.jar is really accessible using the ../lib/javac.jar > path (relative to the path in which the script you are calling is located). > > Maurizio > > >> Where the java VM called is the MLVM from: >> >> http://www.concord.org/~sbannasch/mlvm/ >> >> The javac script mentioned above is called by: >> >> $jdk/javac -Xlint:all -source 7 -XDallowFunctionTypes -d >> ../build/classes $package/*.java >> >> >> Cheers, >> >> ?-- Howard. >> >> On 16 August 2010 17:59, Maurizio Cimadamore >> ?wrote: >> >>> >>> Hi >>> ?From the message you are getting it seems like the special class >>> com.sun.runtime.ProxyHelper is not included in the boot classpath, this >>> causing the completion error to occur when the compiler tries to generate >>> code that depends on such class. How are you invoking the lambda compiler? >>> >>> Maurizio >>> >>> On 15/08/10 22:46, Howard Lovatt wrote: >>> >>>> >>>> @Remi, >>>> >>>> The syntaxes (sp ?) Person#compareByAge and Person#compareByAge( >>>> Person, Person ) result in: >>>> >>>> An exception has occurred in the compiler (1.7.0-internal). Please >>>> file a bug at the Java Developer Connection >>>> (http://java.sun.com/webapps/bugreport) ?after checking the Bug Parade >>>> for duplicates. Include your program and the following diagnostic in >>>> your report. ?Thank you. >>>> com.sun.tools.javac.code.Symbol$CompletionFailure: class file for >>>> com.sun.runtime.ProxyHelper not found >>>> >>>> The syntax Person#compareByAge() results in: >>>> >>>> lambdas/Main.java:35: method compareByAge in class Person cannot be >>>> applied to given types >>>> ? ? Arrays.sort( people, Person#compareByAge() ); >>>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?^ >>>> ? required: Person,Person >>>> ? found: no arguments >>>> >>>> Implying that Person#compareByAge( Person, Person ) is the correct >>>> syntax, however that causes the above exception. >>>> >>>> >>>> >>> >>> >> >> >> -- >> ? -- Howard. >> > > -- ? -- Howard. From thomas.andreas.jung at googlemail.com Thu Aug 19 00:59:00 2010 From: thomas.andreas.jung at googlemail.com (Thomas Jung) Date: Thu, 19 Aug 2010 09:59:00 +0200 Subject: extension method implementations for methods of java.lang.Object Message-ID: Hi, with the current prototype it's not possible to define a default implementation for Object#equals. interface A{ extension boolean xequals(Object obj) default As.eq; extension boolean equals(Object obj) default As.eq; } static class As{ public static boolean eq(A me, Object object){ throw new RuntimeException(); } } a.equals(new Object()); //passes a.xequals(new Object()); //throws exception This feature is useful if the equals implementation for some subtypes of A can be expressed based on the methods defined in A. Thomas From maurizio.cimadamore at oracle.com Thu Aug 19 01:39:45 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 19 Aug 2010 09:39:45 +0100 Subject: What am I doing wrong? hg: lambda/lambda/langtools: More bug fixes: In-Reply-To: References: <4C68EFF8.2020701@oracle.com> <4C6A4B20.8030202@oracle.com> Message-ID: <4C6CEDD1.9030701@oracle.com> On 19/08/10 02:53, Howard Lovatt wrote: > Hi Maurizio, > > Latest push in Mercurial repository has ProxyHelper in javac.jar and > hence it now works for me, thanks. However there is another issue, > javac.jar has to be added to the runtime (because the runtime also > needs ProxyHelper). > That's true - in fact both the 'java' script generated during the langtools build and the 'java' command generated during a full build of the lambda repo add ProxyHelper to the bootclasspath... Maurizio > Cheers, > > -- Howard. > > On 17 August 2010 18:41, Maurizio Cimadamore > wrote: > >> On 17/08/10 02:02, Howard Lovatt wrote: >> >>> Hi Maurizio, >>> >>> I am using the script generated by running make from the Mercurial >>> repository, the pertinent line from the langtools/dist/bin/javac >>> script is: >>> >>> >>> "/System/Library/Frameworks/JavaVM.framework/Versions/1.7.0_2010_07_30/Home//bin/java" >>> "${bcp:+-Xbootclasspath/p:"$bcp"}" ${ea} ${javaOpts} -jar >>> "${mydir}"/../lib/javac.jar ${toolOpts} >>> >>> >> the script assumes to be in a NetBeans like structure in which you have a >> dist/ folder with two subfolders, bin/ (where your javac/java scripts are) >> and lib/ where (javac.jar is). I guess that a failure to locate >> lib/javac.jar could cause the problem you are talking about - I'd suggest >> verifying that javac.jar is really accessible using the ../lib/javac.jar >> path (relative to the path in which the script you are calling is located). >> >> Maurizio >> >> >> >>> Where the java VM called is the MLVM from: >>> >>> http://www.concord.org/~sbannasch/mlvm/ >>> >>> The javac script mentioned above is called by: >>> >>> $jdk/javac -Xlint:all -source 7 -XDallowFunctionTypes -d >>> ../build/classes $package/*.java >>> >>> >>> Cheers, >>> >>> -- Howard. >>> >>> On 16 August 2010 17:59, Maurizio Cimadamore >>> wrote: >>> >>> >>>> Hi >>>> From the message you are getting it seems like the special class >>>> com.sun.runtime.ProxyHelper is not included in the boot classpath, this >>>> causing the completion error to occur when the compiler tries to generate >>>> code that depends on such class. How are you invoking the lambda compiler? >>>> >>>> Maurizio >>>> >>>> On 15/08/10 22:46, Howard Lovatt wrote: >>>> >>>> >>>>> @Remi, >>>>> >>>>> The syntaxes (sp ?) Person#compareByAge and Person#compareByAge( >>>>> Person, Person ) result in: >>>>> >>>>> An exception has occurred in the compiler (1.7.0-internal). Please >>>>> file a bug at the Java Developer Connection >>>>> (http://java.sun.com/webapps/bugreport) after checking the Bug Parade >>>>> for duplicates. Include your program and the following diagnostic in >>>>> your report. Thank you. >>>>> com.sun.tools.javac.code.Symbol$CompletionFailure: class file for >>>>> com.sun.runtime.ProxyHelper not found >>>>> >>>>> The syntax Person#compareByAge() results in: >>>>> >>>>> lambdas/Main.java:35: method compareByAge in class Person cannot be >>>>> applied to given types >>>>> Arrays.sort( people, Person#compareByAge() ); >>>>> ^ >>>>> required: Person,Person >>>>> found: no arguments >>>>> >>>>> Implying that Person#compareByAge( Person, Person ) is the correct >>>>> syntax, however that causes the above exception. >>>>> >>>>> >>>>> >>>>> >>>> >>>> >>> >>> -- >>> -- Howard. >>> >>> >> >> > > > From maurizio.cimadamore at oracle.com Thu Aug 19 01:50:10 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 19 Aug 2010 09:50:10 +0100 Subject: extension method implementations for methods of java.lang.Object In-Reply-To: References: Message-ID: <4C6CF042.2030109@oracle.com> On 19/08/10 08:59, Thomas Jung wrote: > Hi, > > with the current prototype it's not possible to define a default > implementation for Object#equals. > > interface A{ > extension boolean xequals(Object obj) default As.eq; > extension boolean equals(Object obj) default As.eq; > } > > static class As{ > public static boolean eq(A me, Object object){ > throw new RuntimeException(); > } > } > > a.equals(new Object()); //passes > a.xequals(new Object()); //throws exception > > This feature is useful if the equals implementation for some subtypes > of A can be expressed based on the methods defined in A. > The VM extension required to handle extension methods at runtime is not available yet - as a result it is not possible to get to execute the above code (or any code containing extension methods) with the right semantics... in fact, since the runtime infrastructure is missing, the VM gets method dispatching completely wrong - the invokevirtual targeting A.equals() is dispatched to Object.equals() while for A.xequals() the VM complains because it cannot find a suitable implementation of xequals() inside the instance 'a'. Maurizio > - > Thomas > > From thomas.andreas.jung at googlemail.com Thu Aug 19 04:35:24 2010 From: thomas.andreas.jung at googlemail.com (Thomas Jung) Date: Thu, 19 Aug 2010 13:35:24 +0200 Subject: extension method implementations for methods of java.lang.Object In-Reply-To: <4C6CF042.2030109@oracle.com> References: <4C6CF042.2030109@oracle.com> Message-ID: I thought this is due to the method resolution rules described in the latest draft of defender methods: > 3. Method dispatch > With an ordinary interface method invocation on a receiver of type D, first D is searched for a method implementation, then its superclass, and so on until we reach Object, and if an implementation is not found, a linkage exception is thrown. For an extension method, the search path is more complicated; first we search for actual implementations in D and its superclasses just as before, and if we do not find an implementation of the method in the implementation hierarchy, then we must search for the most specific default implementation among D?s interfaces (which is not a linear search), failing if we cannot find a unique most specific default. According to the described rules the order for B a subclass of A is: B#equals, java.lang.Object#equals , A#equals. So the implementation in java.lang.Object is chosen as the most specific one. Thomas On 19 August 2010 10:50, Maurizio Cimadamore wrote: > On 19/08/10 08:59, Thomas Jung wrote: >> >> Hi, >> >> with the current prototype it's not possible to define a default >> implementation for Object#equals. >> >> interface A{ >> ? ? ? ?extension boolean xequals(Object obj) default As.eq; >> ? ? ? ?extension boolean equals(Object obj) default As.eq; >> } >> >> static class As{ >> ? ? ? ?public static boolean eq(A me, Object object){ >> ? ? ? ? ? ? ? ?throw new RuntimeException(); >> ? ? ? ?} >> } >> >> a.equals(new Object()); ? ?//passes >> a.xequals(new Object()); ?//throws exception >> >> This feature is useful if the equals implementation for some subtypes >> of A can be expressed based on the methods defined in A. >> > > The VM extension required to handle extension methods at runtime is not > available yet - as a result it is not possible to get to execute the above > code (or any code containing extension methods) with the right semantics... > in fact, since the runtime infrastructure is missing, the VM gets method > dispatching completely wrong - the invokevirtual targeting A.equals() is > dispatched to Object.equals() while for A.xequals() the VM complains because > it cannot find a suitable implementation of xequals() inside the instance > 'a'. > > Maurizio >> >> ?- >> Thomas >> >> > > From maurizio.cimadamore at oracle.com Thu Aug 19 05:09:44 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 19 Aug 2010 13:09:44 +0100 Subject: extension method implementations for methods of java.lang.Object In-Reply-To: References: <4C6CF042.2030109@oracle.com> Message-ID: <4C6D1F08.4040705@oracle.com> Thomas I agree that this is a corner case of resolution rules described in the defender method draft - however the current behavior (the one you see when you execute the code compiled with the lambda compiler) has nothing to do with such rules, as they are not implemeneted yet - just wanted to make this clear. Regarding the spec corner case, I think that what the rules are saying here is that you have a class (B) that implicitly subclass from Object. As such, Object.equals() implicitly overrides A.equals() and, as such, must be chosen as the most specific implementation. At the end of the day, defender methods are there to provide a default implementation for an interface method where none is available in the superclass hierarchy; in the unfortunate case of Object.equals() an implementation is indeed available, as Object.equals() is a perfectly legal override for A.equals(). Note also that the following code works fine: interface A { boolean equals(Object o); } class Foo implements A {} and the VM is already dispatching incoming calls to Foo.equals() into Object.equals(), so I'm afraid that what you are proposing here would be an incompatible change... ... but I'm sure Brian will have a better answer for you ;-) Maurizio On 19/08/10 12:35, Thomas Jung wrote: > I thought this is due to the method resolution rules described in the > latest draft of defender methods: > > >> 3. Method dispatch >> With an ordinary interface method invocation on a receiver of type D, first D is searched for a method implementation, then its superclass, and so on until we reach Object, and if an implementation is not found, a linkage exception is thrown. For an extension method, the search path is more complicated; first we search for actual implementations in D and its superclasses just as before, and if we do not find an implementation of the method in the implementation hierarchy, then we must search for the most specific default implementation among D?s interfaces (which is not a linear search), failing if we cannot find a unique most specific default. >> > According to the described rules the order for B a subclass of A is: > B#equals, java.lang.Object#equals , A#equals. So the implementation in > java.lang.Object is chosen as the most specific one. > > Thomas > > On 19 August 2010 10:50, Maurizio Cimadamore > wrote: > >> On 19/08/10 08:59, Thomas Jung wrote: >> >>> Hi, >>> >>> with the current prototype it's not possible to define a default >>> implementation for Object#equals. >>> >>> interface A{ >>> extension boolean xequals(Object obj) default As.eq; >>> extension boolean equals(Object obj) default As.eq; >>> } >>> >>> static class As{ >>> public static boolean eq(A me, Object object){ >>> throw new RuntimeException(); >>> } >>> } >>> >>> a.equals(new Object()); //passes >>> a.xequals(new Object()); //throws exception >>> >>> This feature is useful if the equals implementation for some subtypes >>> of A can be expressed based on the methods defined in A. >>> >>> >> The VM extension required to handle extension methods at runtime is not >> available yet - as a result it is not possible to get to execute the above >> code (or any code containing extension methods) with the right semantics... >> in fact, since the runtime infrastructure is missing, the VM gets method >> dispatching completely wrong - the invokevirtual targeting A.equals() is >> dispatched to Object.equals() while for A.xequals() the VM complains because >> it cannot find a suitable implementation of xequals() inside the instance >> 'a'. >> >> Maurizio >> >>> - >>> Thomas >>> >>> >>> >> >> From maurizio.cimadamore at oracle.com Thu Aug 19 05:12:33 2010 From: maurizio.cimadamore at oracle.com (maurizio.cimadamore at oracle.com) Date: Thu, 19 Aug 2010 12:12:33 +0000 Subject: hg: lambda/lambda/langtools: Bug fixes: Message-ID: <20100819121239.33B1F472BA@hg.openjdk.java.net> Changeset: ce46b6012362 Author: mcimadamore Date: 2010-08-19 13:11 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/ce46b6012362 Bug fixes: *) check that the compiler emits meaningful diagnostics when the lambda body contains bad statements *) the routine that checks for SAM types should skip defender methods in extended interfaces *) failure of regression test CheckExamples.java depending on localization settings ! src/share/classes/com/sun/tools/javac/code/Types.java ! src/share/classes/com/sun/tools/javac/parser/JavacParser.java ! test/tools/javac/diags/examples/IllegalChar.java + test/tools/javac/lambda/BadStatementInLambda.java + test/tools/javac/lambda/BadStatementInLambda.out + test/tools/javac/lambda/Defender01.java From peter.levart at marand.si Thu Aug 19 06:00:51 2010 From: peter.levart at marand.si (Peter Levart) Date: Thu, 19 Aug 2010 15:00:51 +0200 Subject: hg: lambda/lambda/langtools: Bug fixes: In-Reply-To: <20100819121239.33B1F472BA@hg.openjdk.java.net> References: <20100819121239.33B1F472BA@hg.openjdk.java.net> Message-ID: <201008191500.51184.peter.levart@marand.si> On 08/19/10, maurizio.cimadamore at oracle.com wrote: > Changeset: ce46b6012362 > Author: mcimadamore > Date: 2010-08-19 13:11 +0100 > URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/ce46b6012362 > > Bug fixes: > *) check that the compiler emits meaningful diagnostics when the lambda body contains bad statements > *) the routine that checks for SAM types should skip defender methods in extended interfaces I don't know, but should this extended interface be considered a SAM type or not? public interface UncleSam { extension BigDecimal calculateTaxes(String taxPayerId) default Tax.calc; } Regards, Peter > *) failure of regression test CheckExamples.java depending on localization settings > > ! src/share/classes/com/sun/tools/javac/code/Types.java > ! src/share/classes/com/sun/tools/javac/parser/JavacParser.java > ! test/tools/javac/diags/examples/IllegalChar.java > + test/tools/javac/lambda/BadStatementInLambda.java > + test/tools/javac/lambda/BadStatementInLambda.out > + test/tools/javac/lambda/Defender01.java > > > From brian.goetz at oracle.com Thu Aug 19 06:04:08 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 19 Aug 2010 09:04:08 -0400 Subject: extension method implementations for methods of java.lang.Object In-Reply-To: References: Message-ID: <4C6D2BC8.2040607@oracle.com> That is correct, and does not bother me. The goal of extension methods did not include being able to reabstract existing concrete methods from Object. We're not trying to solve all the problems of the world in one go... On 8/19/2010 3:59 AM, Thomas Jung wrote: > Hi, > > with the current prototype it's not possible to define a default > implementation for Object#equals. > > interface A{ > extension boolean xequals(Object obj) default As.eq; > extension boolean equals(Object obj) default As.eq; > } > > static class As{ > public static boolean eq(A me, Object object){ > throw new RuntimeException(); > } > } > > a.equals(new Object()); //passes > a.xequals(new Object()); //throws exception > > This feature is useful if the equals implementation for some subtypes > of A can be expressed based on the methods defined in A. > > Thomas > From brian.goetz at oracle.com Thu Aug 19 06:05:14 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 19 Aug 2010 09:05:14 -0400 Subject: extension method implementations for methods of java.lang.Object In-Reply-To: <4C6CF042.2030109@oracle.com> References: <4C6CF042.2030109@oracle.com> Message-ID: <4C6D2C0A.50606@oracle.com> But, even given that, in this case the resolution for a call to equals() would go straight to Object.equals(), since we only consult defaults if the object does not already have an implementation from its inheritance hierarchy. All objects already have an equals(). On 8/19/2010 4:50 AM, Maurizio Cimadamore wrote: > On 19/08/10 08:59, Thomas Jung wrote: >> Hi, >> >> with the current prototype it's not possible to define a default >> implementation for Object#equals. >> >> interface A{ >> extension boolean xequals(Object obj) default As.eq; >> extension boolean equals(Object obj) default As.eq; >> } >> >> static class As{ >> public static boolean eq(A me, Object object){ >> throw new RuntimeException(); >> } >> } >> >> a.equals(new Object()); //passes >> a.xequals(new Object()); //throws exception >> >> This feature is useful if the equals implementation for some subtypes >> of A can be expressed based on the methods defined in A. >> > The VM extension required to handle extension methods at runtime is not > available yet - as a result it is not possible to get to execute the > above code (or any code containing extension methods) with the right > semantics... in fact, since the runtime infrastructure is missing, the > VM gets method dispatching completely wrong - the invokevirtual > targeting A.equals() is dispatched to Object.equals() while for > A.xequals() the VM complains because it cannot find a suitable > implementation of xequals() inside the instance 'a'. > > Maurizio >> - >> Thomas >> >> > > From thomas.andreas.jung at googlemail.com Thu Aug 19 06:10:45 2010 From: thomas.andreas.jung at googlemail.com (Thomas Jung) Date: Thu, 19 Aug 2010 15:10:45 +0200 Subject: extension method implementations for methods of java.lang.Object In-Reply-To: <4C6D2BC8.2040607@oracle.com> References: <4C6D2BC8.2040607@oracle.com> Message-ID: That's okay. Then the compiler should print a warning that this default method definition will never apply as all reference types extend java.lang.Object and the set of problematic methods signatures is (practically) fixed and known. It could even be considered invalid code. Thomas On 19 August 2010 15:04, Brian Goetz wrote: > That is correct, and does not bother me. ?The goal of extension methods did > not include being able to reabstract existing concrete methods from Object. > We're not trying to solve all the problems of the world in one go... > > On 8/19/2010 3:59 AM, Thomas Jung wrote: >> >> Hi, >> >> with the current prototype it's not possible to define a default >> implementation for Object#equals. >> >> interface A{ >> ? ? ? ?extension boolean xequals(Object obj) default As.eq; >> ? ? ? ?extension boolean equals(Object obj) default As.eq; >> } >> >> static class As{ >> ? ? ? ?public static boolean eq(A me, Object object){ >> ? ? ? ? ? ? ? ?throw new RuntimeException(); >> ? ? ? ?} >> } >> >> a.equals(new Object()); ? ?//passes >> a.xequals(new Object()); ?//throws exception >> >> This feature is useful if the equals implementation for some subtypes >> of A can be expressed based on the methods defined in A. >> >> Thomas >> > From thomas.andreas.jung at googlemail.com Thu Aug 19 06:12:13 2010 From: thomas.andreas.jung at googlemail.com (Thomas Jung) Date: Thu, 19 Aug 2010 15:12:13 +0200 Subject: extension method implementations for methods of java.lang.Object In-Reply-To: <4C6D2C0A.50606@oracle.com> References: <4C6CF042.2030109@oracle.com> <4C6D2C0A.50606@oracle.com> Message-ID: That's clear. To support this use cases the method resolution rules would have to be changed (i.e. complicated). Thomas On 19 August 2010 15:05, Brian Goetz wrote: > But, even given that, in this case the resolution for a call to equals() > would go straight to Object.equals(), since we only consult defaults if the > object does not already have an implementation from its inheritance > hierarchy. ?All objects already have an equals(). > > On 8/19/2010 4:50 AM, Maurizio Cimadamore wrote: >> >> On 19/08/10 08:59, Thomas Jung wrote: >>> >>> Hi, >>> >>> with the current prototype it's not possible to define a default >>> implementation for Object#equals. >>> >>> interface A{ >>> ? ? ? ?extension boolean xequals(Object obj) default As.eq; >>> ? ? ? ?extension boolean equals(Object obj) default As.eq; >>> } >>> >>> static class As{ >>> ? ? ? ?public static boolean eq(A me, Object object){ >>> ? ? ? ? ? ? ? ?throw new RuntimeException(); >>> ? ? ? ?} >>> } >>> >>> a.equals(new Object()); ? ?//passes >>> a.xequals(new Object()); ?//throws exception >>> >>> This feature is useful if the equals implementation for some subtypes >>> of A can be expressed based on the methods defined in A. >>> >> The VM extension required to handle extension methods at runtime is not >> available yet - as a result it is not possible to get to execute the >> above code (or any code containing extension methods) with the right >> semantics... in fact, since the runtime infrastructure is missing, the >> VM gets method dispatching completely wrong - the invokevirtual >> targeting A.equals() is dispatched to Object.equals() while for >> A.xequals() the VM complains because it cannot find a suitable >> implementation of xequals() inside the instance 'a'. >> >> Maurizio >>> >>> ? - >>> Thomas >>> >>> >> >> > From maurizio.cimadamore at oracle.com Thu Aug 19 06:12:36 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 19 Aug 2010 14:12:36 +0100 Subject: hg: lambda/lambda/langtools: Bug fixes: In-Reply-To: <201008191500.51184.peter.levart@marand.si> References: <20100819121239.33B1F472BA@hg.openjdk.java.net> <201008191500.51184.peter.levart@marand.si> Message-ID: <4C6D2DC4.9010705@oracle.com> On 19/08/10 14:00, Peter Levart wrote: > On 08/19/10, maurizio.cimadamore at oracle.com wrote: > >> Changeset: ce46b6012362 >> Author: mcimadamore >> Date: 2010-08-19 13:11 +0100 >> URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/ce46b6012362 >> >> Bug fixes: >> *) check that the compiler emits meaningful diagnostics when the lambda body contains bad statements >> *) the routine that checks for SAM types should skip defender methods in extended interfaces >> > I don't know, but should this extended interface be considered a SAM type or not? > > public interface UncleSam { > extension BigDecimal calculateTaxes(String taxPayerId) default Tax.calc; > } > It is not. A possible problem with down this road is: public interface UncleSam { extension BigDecimal calculateTaxes(String taxPayerId) default Tax.calc; extension BigDecimal calculateSomethingElse(String taxPayerId) default Tax.calc2; } What is the target method of the lambda conversion? Maurizio > Regards, Peter > > > >> *) failure of regression test CheckExamples.java depending on localization settings >> >> ! src/share/classes/com/sun/tools/javac/code/Types.java >> ! src/share/classes/com/sun/tools/javac/parser/JavacParser.java >> ! test/tools/javac/diags/examples/IllegalChar.java >> + test/tools/javac/lambda/BadStatementInLambda.java >> + test/tools/javac/lambda/BadStatementInLambda.out >> + test/tools/javac/lambda/Defender01.java >> >> >> >> From brian.goetz at oracle.com Thu Aug 19 06:24:07 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 19 Aug 2010 09:24:07 -0400 Subject: hg: lambda/lambda/langtools: Bug fixes: In-Reply-To: <201008191500.51184.peter.levart@marand.si> References: <20100819121239.33B1F472BA@hg.openjdk.java.net> <201008191500.51184.peter.levart@marand.si> Message-ID: <4C6D3077.8070102@oracle.com> I say no. This is a Zero Abstract Method (ZAM) type :) On 8/19/2010 9:00 AM, Peter Levart wrote: > On 08/19/10, maurizio.cimadamore at oracle.com wrote: >> Changeset: ce46b6012362 >> Author: mcimadamore >> Date: 2010-08-19 13:11 +0100 >> URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/ce46b6012362 >> >> Bug fixes: >> *) check that the compiler emits meaningful diagnostics when the lambda body contains bad statements >> *) the routine that checks for SAM types should skip defender methods in extended interfaces > > I don't know, but should this extended interface be considered a SAM type or not? > > public interface UncleSam { > extension BigDecimal calculateTaxes(String taxPayerId) default Tax.calc; > } > > Regards, Peter > > >> *) failure of regression test CheckExamples.java depending on localization settings >> >> ! src/share/classes/com/sun/tools/javac/code/Types.java >> ! src/share/classes/com/sun/tools/javac/parser/JavacParser.java >> ! test/tools/javac/diags/examples/IllegalChar.java >> + test/tools/javac/lambda/BadStatementInLambda.java >> + test/tools/javac/lambda/BadStatementInLambda.out >> + test/tools/javac/lambda/Defender01.java >> >> >> > From peter.levart at marand.si Thu Aug 19 07:34:33 2010 From: peter.levart at marand.si (Peter Levart) Date: Thu, 19 Aug 2010 16:34:33 +0200 Subject: hg: lambda/lambda/langtools: Bug fixes: In-Reply-To: <4C6D3077.8070102@oracle.com> References: <20100819121239.33B1F472BA@hg.openjdk.java.net> <201008191500.51184.peter.levart@marand.si> <4C6D3077.8070102@oracle.com> Message-ID: <201008191634.33541.peter.levart@marand.si> It's only for consistency if nothing else. Currently, for all other purposes, adding a default to a normal interface method (transforming it to a defender method) is a source and binary compatible change. Not with SAM interfaces though. What would be wrong with this definition of SAM types: SAM type is a reference type with a single non-Object abstract non-defender method and any number of abstract defender methods or a reference type with a single abstract defender method and no non-Object abstract non-defender methods. Regards, Peter On 08/19/10, Brian Goetz wrote: > I say no. This is a Zero Abstract Method (ZAM) type :) > > > On 8/19/2010 9:00 AM, Peter Levart wrote: > > On 08/19/10, maurizio.cimadamore at oracle.com wrote: > >> Changeset: ce46b6012362 > >> Author: mcimadamore > >> Date: 2010-08-19 13:11 +0100 > >> URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/ce46b6012362 > >> > >> Bug fixes: > >> *) check that the compiler emits meaningful diagnostics when the lambda body contains bad statements > >> *) the routine that checks for SAM types should skip defender methods in extended interfaces > > > > I don't know, but should this extended interface be considered a SAM type or not? > > > > public interface UncleSam { > > extension BigDecimal calculateTaxes(String taxPayerId) default Tax.calc; > > } > > > > Regards, Peter > > > > > >> *) failure of regression test CheckExamples.java depending on localization settings > >> > >> ! src/share/classes/com/sun/tools/javac/code/Types.java > >> ! src/share/classes/com/sun/tools/javac/parser/JavacParser.java > >> ! test/tools/javac/diags/examples/IllegalChar.java > >> + test/tools/javac/lambda/BadStatementInLambda.java > >> + test/tools/javac/lambda/BadStatementInLambda.out > >> + test/tools/javac/lambda/Defender01.java > >> > >> > >> > > > From brian.goetz at oracle.com Thu Aug 19 07:40:45 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 19 Aug 2010 10:40:45 -0400 Subject: hg: lambda/lambda/langtools: Bug fixes: In-Reply-To: <201008191634.33541.peter.levart@marand.si> References: <20100819121239.33B1F472BA@hg.openjdk.java.net> <201008191500.51184.peter.levart@marand.si> <4C6D3077.8070102@oracle.com> <201008191634.33541.peter.levart@marand.si> Message-ID: <4C6D426D.7060208@oracle.com> Under this definition, adding a method with a defender to a single-defender ZAM type becomes a binary-incompatible change :( On 8/19/2010 10:34 AM, Peter Levart wrote: > It's only for consistency if nothing else. Currently, for all other purposes, adding a default to a normal interface method (transforming it to a defender method) is a source and binary compatible change. Not with SAM interfaces though. > > What would be wrong with this definition of SAM types: > > SAM type is a reference type with a single non-Object abstract non-defender method and any number of abstract defender methods or a reference type with a single abstract defender method and no non-Object abstract non-defender methods. > > > Regards, Peter > > On 08/19/10, Brian Goetz wrote: >> I say no. This is a Zero Abstract Method (ZAM) type :) >> >> >> On 8/19/2010 9:00 AM, Peter Levart wrote: >>> On 08/19/10, maurizio.cimadamore at oracle.com wrote: >>>> Changeset: ce46b6012362 >>>> Author: mcimadamore >>>> Date: 2010-08-19 13:11 +0100 >>>> URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/ce46b6012362 >>>> >>>> Bug fixes: >>>> *) check that the compiler emits meaningful diagnostics when the lambda body contains bad statements >>>> *) the routine that checks for SAM types should skip defender methods in extended interfaces >>> >>> I don't know, but should this extended interface be considered a SAM type or not? >>> >>> public interface UncleSam { >>> extension BigDecimal calculateTaxes(String taxPayerId) default Tax.calc; >>> } >>> >>> Regards, Peter >>> >>> >>>> *) failure of regression test CheckExamples.java depending on localization settings >>>> >>>> ! src/share/classes/com/sun/tools/javac/code/Types.java >>>> ! src/share/classes/com/sun/tools/javac/parser/JavacParser.java >>>> ! test/tools/javac/diags/examples/IllegalChar.java >>>> + test/tools/javac/lambda/BadStatementInLambda.java >>>> + test/tools/javac/lambda/BadStatementInLambda.out >>>> + test/tools/javac/lambda/Defender01.java >>>> >>>> >>>> >>> >> From maurizio.cimadamore at oracle.com Thu Aug 19 07:41:15 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 19 Aug 2010 15:41:15 +0100 Subject: hg: lambda/lambda/langtools: Bug fixes: In-Reply-To: <201008191634.33541.peter.levart@marand.si> References: <20100819121239.33B1F472BA@hg.openjdk.java.net> <201008191500.51184.peter.levart@marand.si> <4C6D3077.8070102@oracle.com> <201008191634.33541.peter.levart@marand.si> Message-ID: <4C6D428B.8040706@oracle.com> On 19/08/10 15:34, Peter Levart wrote: > It's only for consistency if nothing else. Currently, for all other purposes, adding a default to a normal interface method (transforming it to a defender method) is a source and binary compatible change. Not with SAM interfaces though. > > What would be wrong with this definition of SAM types: > > SAM type is a reference type with a single non-Object abstract non-defender method and any number of abstract defender methods or a reference type with a single abstract defender method and no non-Object abstract non-defender methods. > Note that your alternate definition of SAM type is not free of problems: interface SAM { void m(); extension void n() .... } SAM s = #{ ... } If you add a default to m() you go back to the original problem: SAM conversion wouldn't work, as the target interface has two defender method, which is a scenario not covered by your rules. Maurizio > > Regards, Peter > > On 08/19/10, Brian Goetz wrote: > >> I say no. This is a Zero Abstract Method (ZAM) type :) >> >> >> On 8/19/2010 9:00 AM, Peter Levart wrote: >> >>> On 08/19/10, maurizio.cimadamore at oracle.com wrote: >>> >>>> Changeset: ce46b6012362 >>>> Author: mcimadamore >>>> Date: 2010-08-19 13:11 +0100 >>>> URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/ce46b6012362 >>>> >>>> Bug fixes: >>>> *) check that the compiler emits meaningful diagnostics when the lambda body contains bad statements >>>> *) the routine that checks for SAM types should skip defender methods in extended interfaces >>>> >>> I don't know, but should this extended interface be considered a SAM type or not? >>> >>> public interface UncleSam { >>> extension BigDecimal calculateTaxes(String taxPayerId) default Tax.calc; >>> } >>> >>> Regards, Peter >>> >>> >>> >>>> *) failure of regression test CheckExamples.java depending on localization settings >>>> >>>> ! src/share/classes/com/sun/tools/javac/code/Types.java >>>> ! src/share/classes/com/sun/tools/javac/parser/JavacParser.java >>>> ! test/tools/javac/diags/examples/IllegalChar.java >>>> + test/tools/javac/lambda/BadStatementInLambda.java >>>> + test/tools/javac/lambda/BadStatementInLambda.out >>>> + test/tools/javac/lambda/Defender01.java >>>> >>>> >>>> >>>> >>> >> > From peter.levart at marand.si Thu Aug 19 07:42:42 2010 From: peter.levart at marand.si (Peter Levart) Date: Thu, 19 Aug 2010 16:42:42 +0200 Subject: hg: lambda/lambda/langtools: Bug fixes: In-Reply-To: <201008191634.33541.peter.levart@marand.si> References: <20100819121239.33B1F472BA@hg.openjdk.java.net> <4C6D3077.8070102@oracle.com> <201008191634.33541.peter.levart@marand.si> Message-ID: <201008191642.42880.peter.levart@marand.si> I just noticed that this would not solve the problem, since the following transformation: public interface UncleSam { extension BigDecimal calculateTaxes(String taxPayerId) default Tax.calc; BigDecimal calculateSomethingElse(String taxPayerId); } into: public interface UncleSam { extension BigDecimal calculateTaxes(String taxPayerId) default Tax.calc; extension BigDecimal calculateSomethingElse(String taxPayerId) default Tax.calc2; } would allways change a SAM type into a non-SAM type. Peter On 08/19/10, Peter Levart wrote: > It's only for consistency if nothing else. Currently, for all other purposes, adding a default to a normal interface method (transforming it to a defender method) is a source and binary compatible change. Not with SAM interfaces though. > > What would be wrong with this definition of SAM types: > > SAM type is a reference type with a single non-Object abstract non-defender method and any number of abstract defender methods or a reference type with a single abstract defender method and no non-Object abstract non-defender methods. > > > Regards, Peter > > On 08/19/10, Brian Goetz wrote: > > I say no. This is a Zero Abstract Method (ZAM) type :) > > > > > > On 8/19/2010 9:00 AM, Peter Levart wrote: > > > On 08/19/10, maurizio.cimadamore at oracle.com wrote: > > >> Changeset: ce46b6012362 > > >> Author: mcimadamore > > >> Date: 2010-08-19 13:11 +0100 > > >> URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/ce46b6012362 > > >> > > >> Bug fixes: > > >> *) check that the compiler emits meaningful diagnostics when the lambda body contains bad statements > > >> *) the routine that checks for SAM types should skip defender methods in extended interfaces > > > > > > I don't know, but should this extended interface be considered a SAM type or not? > > > > > > public interface UncleSam { > > > extension BigDecimal calculateTaxes(String taxPayerId) default Tax.calc; > > > } > > > > > > Regards, Peter > > > > > > > > >> *) failure of regression test CheckExamples.java depending on localization settings > > >> > > >> ! src/share/classes/com/sun/tools/javac/code/Types.java > > >> ! src/share/classes/com/sun/tools/javac/parser/JavacParser.java > > >> ! test/tools/javac/diags/examples/IllegalChar.java > > >> + test/tools/javac/lambda/BadStatementInLambda.java > > >> + test/tools/javac/lambda/BadStatementInLambda.out > > >> + test/tools/javac/lambda/Defender01.java > > >> > > >> > > >> > > > > > > > From jordan.r.stewart at gmail.com Thu Aug 19 07:50:13 2010 From: jordan.r.stewart at gmail.com (Jordan Stewart) Date: Fri, 20 Aug 2010 02:50:13 +1200 Subject: extension method implementations for methods of java.lang.Object In-Reply-To: References: <4C6D2BC8.2040607@oracle.com> Message-ID: It may be dodgy, but I don't think it's invalid code. The default equals method declared in A should still apply in cases where equals is reabstracted by a superclass. E.g. if we extend your example with the following- abstract class B { abstract boolean equals(Object other); } class C extends B implements A { // .equals -> As.eq } Or, even- class D implements A { // .equals -> Object.equals } abstract class E extends D { abstract boolean equals(Object other); } class F extends E { // .equals -> As.eq } On Fri, Aug 20, 2010 at 1:10 AM, Thomas Jung < thomas.andreas.jung at googlemail.com> wrote: > That's okay. > > Then the compiler should print a warning that this default method > definition will never apply as all reference types extend > java.lang.Object and the set of problematic methods signatures is > (practically) fixed and known. It could even be considered invalid > code. > > Thomas > > On 19 August 2010 15:04, Brian Goetz wrote: > > That is correct, and does not bother me. The goal of extension methods > did > > not include being able to reabstract existing concrete methods from > Object. > > We're not trying to solve all the problems of the world in one go... > > > > On 8/19/2010 3:59 AM, Thomas Jung wrote: > >> > >> Hi, > >> > >> with the current prototype it's not possible to define a default > >> implementation for Object#equals. > >> > >> interface A{ > >> extension boolean xequals(Object obj) default As.eq; > >> extension boolean equals(Object obj) default As.eq; > >> } > >> > >> static class As{ > >> public static boolean eq(A me, Object object){ > >> throw new RuntimeException(); > >> } > >> } > >> > >> a.equals(new Object()); //passes > >> a.xequals(new Object()); //throws exception > >> > >> This feature is useful if the equals implementation for some subtypes > >> of A can be expressed based on the methods defined in A. > >> > >> Thomas > >> > > > > From collin.fagan at gmail.com Thu Aug 19 08:31:34 2010 From: collin.fagan at gmail.com (Collin Fagan) Date: Thu, 19 Aug 2010 10:31:34 -0500 Subject: hg: lambda/lambda/langtools: Bug fixes: In-Reply-To: <201008191642.42880.peter.levart@marand.si> References: <20100819121239.33B1F472BA@hg.openjdk.java.net> <4C6D3077.8070102@oracle.com> <201008191634.33541.peter.levart@marand.si> <201008191642.42880.peter.levart@marand.si> Message-ID: So you can be a SAM target OR use defender methods, but not both. That sounds rather limiting, why would anyone purposefully choose defender methods when it eliminates the possibility of ever using an interface as a SAM type? What about inherited methods? Does extending an interface that uses defender methods disallow SAM conversion? Sorry just confused. On Thu, Aug 19, 2010 at 9:42 AM, Peter Levart wrote: > I just noticed that this would not solve the problem, since the following > transformation: > > public interface UncleSam { > extension BigDecimal calculateTaxes(String taxPayerId) default Tax.calc; > BigDecimal calculateSomethingElse(String taxPayerId); > } > > into: > > public interface UncleSam { > extension BigDecimal calculateTaxes(String taxPayerId) default Tax.calc; > extension BigDecimal calculateSomethingElse(String taxPayerId) default > Tax.calc2; > } > > would allways change a SAM type into a non-SAM type. > > Peter > > On 08/19/10, Peter Levart wrote: > > It's only for consistency if nothing else. Currently, for all other > purposes, adding a default to a normal interface method (transforming it to > a defender method) is a source and binary compatible change. Not with SAM > interfaces though. > > > > What would be wrong with this definition of SAM types: > > > > SAM type is a reference type with a single non-Object abstract > non-defender method and any number of abstract defender methods or a > reference type with a single abstract defender method and no non-Object > abstract non-defender methods. > > > > > > Regards, Peter > > > > On 08/19/10, Brian Goetz wrote: > > > I say no. This is a Zero Abstract Method (ZAM) type :) > > > > > > > > > On 8/19/2010 9:00 AM, Peter Levart wrote: > > > > On 08/19/10, maurizio.cimadamore at oracle.com wrote: > > > >> Changeset: ce46b6012362 > > > >> Author: mcimadamore > > > >> Date: 2010-08-19 13:11 +0100 > > > >> URL: > http://hg.openjdk.java.net/lambda/lambda/langtools/rev/ce46b6012362 > > > >> > > > >> Bug fixes: > > > >> *) check that the compiler emits meaningful diagnostics when the > lambda body contains bad statements > > > >> *) the routine that checks for SAM types should skip defender > methods in extended interfaces > > > > > > > > I don't know, but should this extended interface be considered a SAM > type or not? > > > > > > > > public interface UncleSam { > > > > extension BigDecimal calculateTaxes(String taxPayerId) default > Tax.calc; > > > > } > > > > > > > > Regards, Peter > > > > > > > > > > > >> *) failure of regression test CheckExamples.java depending on > localization settings > > > >> > > > >> ! src/share/classes/com/sun/tools/javac/code/Types.java > > > >> ! src/share/classes/com/sun/tools/javac/parser/JavacParser.java > > > >> ! test/tools/javac/diags/examples/IllegalChar.java > > > >> + test/tools/javac/lambda/BadStatementInLambda.java > > > >> + test/tools/javac/lambda/BadStatementInLambda.out > > > >> + test/tools/javac/lambda/Defender01.java > > > >> > > > >> > > > >> > > > > > > > > > > > > > From brian.goetz at oracle.com Thu Aug 19 08:52:30 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 19 Aug 2010 11:52:30 -0400 Subject: hg: lambda/lambda/langtools: Bug fixes: In-Reply-To: References: <20100819121239.33B1F472BA@hg.openjdk.java.net> <4C6D3077.8070102@oracle.com> <201008191634.33541.peter.levart@marand.si> <201008191642.42880.peter.levart@marand.si> Message-ID: <4C6D533E.40302@oracle.com> No. You can be a SAM target and have defender methods: interface Printerator extends Iterable { public void printAll() default Util.printAll(); } Here, Printerator is a SAM (it extends Iterable, which is SAM) but adds more defended methods. That is OK, and adding more defended methods does not undermine its SAM-ness. Removing the defenders would, but that is a binary incompatible change just as re-abstracting a concrete method is. On 8/19/2010 11:31 AM, Collin Fagan wrote: > So you can be a SAM target OR use defender methods, but not both. That > sounds rather limiting, why would anyone purposefully choose defender > methods when it eliminates the possibility of ever using an interface as a > SAM type? What about inherited methods? Does extending an interface that > uses defender methods disallow SAM conversion? > > Sorry just confused. > > On Thu, Aug 19, 2010 at 9:42 AM, Peter Levartwrote: > >> I just noticed that this would not solve the problem, since the following >> transformation: >> >> public interface UncleSam { >> extension BigDecimal calculateTaxes(String taxPayerId) default Tax.calc; >> BigDecimal calculateSomethingElse(String taxPayerId); >> } >> >> into: >> >> public interface UncleSam { >> extension BigDecimal calculateTaxes(String taxPayerId) default Tax.calc; >> extension BigDecimal calculateSomethingElse(String taxPayerId) default >> Tax.calc2; >> } >> >> would allways change a SAM type into a non-SAM type. >> >> Peter >> >> On 08/19/10, Peter Levart wrote: >>> It's only for consistency if nothing else. Currently, for all other >> purposes, adding a default to a normal interface method (transforming it to >> a defender method) is a source and binary compatible change. Not with SAM >> interfaces though. >>> >>> What would be wrong with this definition of SAM types: >>> >>> SAM type is a reference type with a single non-Object abstract >> non-defender method and any number of abstract defender methods or a >> reference type with a single abstract defender method and no non-Object >> abstract non-defender methods. >>> >>> >>> Regards, Peter >>> >>> On 08/19/10, Brian Goetz wrote: >>>> I say no. This is a Zero Abstract Method (ZAM) type :) >>>> >>>> >>>> On 8/19/2010 9:00 AM, Peter Levart wrote: >>>>> On 08/19/10, maurizio.cimadamore at oracle.com wrote: >>>>>> Changeset: ce46b6012362 >>>>>> Author: mcimadamore >>>>>> Date: 2010-08-19 13:11 +0100 >>>>>> URL: >> http://hg.openjdk.java.net/lambda/lambda/langtools/rev/ce46b6012362 >>>>>> >>>>>> Bug fixes: >>>>>> *) check that the compiler emits meaningful diagnostics when the >> lambda body contains bad statements >>>>>> *) the routine that checks for SAM types should skip defender >> methods in extended interfaces >>>>> >>>>> I don't know, but should this extended interface be considered a SAM >> type or not? >>>>> >>>>> public interface UncleSam { >>>>> extension BigDecimal calculateTaxes(String taxPayerId) default >> Tax.calc; >>>>> } >>>>> >>>>> Regards, Peter >>>>> >>>>> >>>>>> *) failure of regression test CheckExamples.java depending on >> localization settings >>>>>> >>>>>> ! src/share/classes/com/sun/tools/javac/code/Types.java >>>>>> ! src/share/classes/com/sun/tools/javac/parser/JavacParser.java >>>>>> ! test/tools/javac/diags/examples/IllegalChar.java >>>>>> + test/tools/javac/lambda/BadStatementInLambda.java >>>>>> + test/tools/javac/lambda/BadStatementInLambda.out >>>>>> + test/tools/javac/lambda/Defender01.java >>>>>> >>>>>> >>>>>> >>>>> >>>> >>> >>> >> >> > From collin.fagan at gmail.com Thu Aug 19 09:52:40 2010 From: collin.fagan at gmail.com (Collin Fagan) Date: Thu, 19 Aug 2010 11:52:40 -0500 Subject: hg: lambda/lambda/langtools: Bug fixes: In-Reply-To: <4C6D533E.40302@oracle.com> References: <20100819121239.33B1F472BA@hg.openjdk.java.net> <4C6D3077.8070102@oracle.com> <201008191634.33541.peter.levart@marand.si> <201008191642.42880.peter.levart@marand.si> <4C6D533E.40302@oracle.com> Message-ID: Thank you for the clarification. The original question was about if a method with a defender can be the target of a SAM type correct? That answer is 'no' correct? And this is becouse once you give a method a defender it is no longer 'abstract'. Would this have ramifications on reflection, specifically what gets returned from getModifiers()? Thanks, Collin On Thu, Aug 19, 2010 at 10:52 AM, Brian Goetz wrote: > No. You can be a SAM target and have defender methods: > > interface Printerator extends Iterable { > public void printAll() default Util.printAll(); > } > > Here, Printerator is a SAM (it extends Iterable, which is SAM) but adds > more defended methods. That is OK, and adding more defended methods does > not undermine its SAM-ness. Removing the defenders would, but that is a > binary incompatible change just as re-abstracting a concrete method is. > > > On 8/19/2010 11:31 AM, Collin Fagan wrote: > >> So you can be a SAM target OR use defender methods, but not both. That >> sounds rather limiting, why would anyone purposefully choose defender >> methods when it eliminates the possibility of ever using an interface as a >> SAM type? What about inherited methods? Does extending an interface that >> uses defender methods disallow SAM conversion? >> >> Sorry just confused. >> >> On Thu, Aug 19, 2010 at 9:42 AM, Peter Levart> >wrote: >> >> I just noticed that this would not solve the problem, since the following >>> transformation: >>> >>> public interface UncleSam { >>> extension BigDecimal calculateTaxes(String taxPayerId) default >>> Tax.calc; >>> BigDecimal calculateSomethingElse(String taxPayerId); >>> } >>> >>> into: >>> >>> public interface UncleSam { >>> extension BigDecimal calculateTaxes(String taxPayerId) default >>> Tax.calc; >>> extension BigDecimal calculateSomethingElse(String taxPayerId) default >>> Tax.calc2; >>> } >>> >>> would allways change a SAM type into a non-SAM type. >>> >>> Peter >>> >>> On 08/19/10, Peter Levart wrote: >>> >>>> It's only for consistency if nothing else. Currently, for all other >>>> >>> purposes, adding a default to a normal interface method (transforming it >>> to >>> a defender method) is a source and binary compatible change. Not with SAM >>> interfaces though. >>> >>>> >>>> What would be wrong with this definition of SAM types: >>>> >>>> SAM type is a reference type with a single non-Object abstract >>>> >>> non-defender method and any number of abstract defender methods or a >>> reference type with a single abstract defender method and no non-Object >>> abstract non-defender methods. >>> >>>> >>>> >>>> Regards, Peter >>>> >>>> On 08/19/10, Brian Goetz wrote: >>>> >>>>> I say no. This is a Zero Abstract Method (ZAM) type :) >>>>> >>>>> >>>>> On 8/19/2010 9:00 AM, Peter Levart wrote: >>>>> >>>>>> On 08/19/10, maurizio.cimadamore at oracle.com wrote: >>>>>> >>>>>>> Changeset: ce46b6012362 >>>>>>> Author: mcimadamore >>>>>>> Date: 2010-08-19 13:11 +0100 >>>>>>> URL: >>>>>>> >>>>>> http://hg.openjdk.java.net/lambda/lambda/langtools/rev/ce46b6012362 >>> >>>> >>>>>>> Bug fixes: >>>>>>> *) check that the compiler emits meaningful diagnostics when the >>>>>>> >>>>>> lambda body contains bad statements >>> >>>> *) the routine that checks for SAM types should skip defender >>>>>>> >>>>>> methods in extended interfaces >>> >>>> >>>>>> I don't know, but should this extended interface be considered a SAM >>>>>> >>>>> type or not? >>> >>>> >>>>>> public interface UncleSam { >>>>>> extension BigDecimal calculateTaxes(String taxPayerId) default >>>>>> >>>>> Tax.calc; >>> >>>> } >>>>>> >>>>>> Regards, Peter >>>>>> >>>>>> >>>>>> *) failure of regression test CheckExamples.java depending on >>>>>>> >>>>>> localization settings >>> >>>> >>>>>>> ! src/share/classes/com/sun/tools/javac/code/Types.java >>>>>>> ! src/share/classes/com/sun/tools/javac/parser/JavacParser.java >>>>>>> ! test/tools/javac/diags/examples/IllegalChar.java >>>>>>> + test/tools/javac/lambda/BadStatementInLambda.java >>>>>>> + test/tools/javac/lambda/BadStatementInLambda.out >>>>>>> + test/tools/javac/lambda/Defender01.java >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>>> >>> >>> >> From brian.goetz at oracle.com Thu Aug 19 10:07:16 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 19 Aug 2010 13:07:16 -0400 Subject: hg: lambda/lambda/langtools: Bug fixes: In-Reply-To: References: <20100819121239.33B1F472BA@hg.openjdk.java.net> <4C6D3077.8070102@oracle.com> <201008191634.33541.peter.levart@marand.si> <201008191642.42880.peter.levart@marand.si> <4C6D533E.40302@oracle.com> Message-ID: <4C6D64C4.9090906@oracle.com> Almost certainly, but the details are not yet specified. The defender method doc describes some needed reflection changes but is almost certainly not complete. (In particular, we have not yet determined whether to describe defended methods as being non-abstract, or to choose another term.) On 8/19/2010 12:52 PM, Collin Fagan wrote: > Thank you for the clarification. The original question was about if a method > with a defender can be the target of a SAM type correct? That answer is 'no' > correct? And this is becouse once you give a method a defender it is no longer > 'abstract'. Would this have ramifications on reflection, specifically what > gets returned from getModifiers()? > > Thanks, > Collin > > On Thu, Aug 19, 2010 at 10:52 AM, Brian Goetz > wrote: > > No. You can be a SAM target and have defender methods: > > interface Printerator extends Iterable { > public void printAll() default Util.printAll(); > } > > Here, Printerator is a SAM (it extends Iterable, which is SAM) but adds > more defended methods. That is OK, and adding more defended methods does > not undermine its SAM-ness. Removing the defenders would, but that is a > binary incompatible change just as re-abstracting a concrete method is. > > > On 8/19/2010 11:31 AM, Collin Fagan wrote: > > So you can be a SAM target OR use defender methods, but not both. That > sounds rather limiting, why would anyone purposefully choose defender > methods when it eliminates the possibility of ever using an interface as a > SAM type? What about inherited methods? Does extending an interface that > uses defender methods disallow SAM conversion? > > Sorry just confused. > > On Thu, Aug 19, 2010 at 9:42 AM, Peter Levart >wrote: > > I just noticed that this would not solve the problem, since the > following > transformation: > > public interface UncleSam { > extension BigDecimal calculateTaxes(String taxPayerId) default > Tax.calc; > BigDecimal calculateSomethingElse(String taxPayerId); > } > > into: > > public interface UncleSam { > extension BigDecimal calculateTaxes(String taxPayerId) default > Tax.calc; > extension BigDecimal calculateSomethingElse(String taxPayerId) > default > Tax.calc2; > } > > would allways change a SAM type into a non-SAM type. > > Peter > > On 08/19/10, Peter Levart wrote: > > It's only for consistency if nothing else. Currently, for all > other > > purposes, adding a default to a normal interface method > (transforming it to > a defender method) is a source and binary compatible change. Not > with SAM > interfaces though. > > > What would be wrong with this definition of SAM types: > > SAM type is a reference type with a single non-Object abstract > > non-defender method and any number of abstract defender methods or a > reference type with a single abstract defender method and no > non-Object > abstract non-defender methods. > > > > Regards, Peter > > On 08/19/10, Brian Goetz wrote: > > I say no. This is a Zero Abstract Method (ZAM) type :) > > > On 8/19/2010 9:00 AM, Peter Levart wrote: > > On 08/19/10, maurizio.cimadamore at oracle.com > wrote: > > Changeset: ce46b6012362 > Author: mcimadamore > Date: 2010-08-19 13:11 +0100 > URL: > > http://hg.openjdk.java.net/lambda/lambda/langtools/rev/ce46b6012362 > > > Bug fixes: > *) check that the compiler emits meaningful > diagnostics when the > > lambda body contains bad statements > > *) the routine that checks for SAM types should > skip defender > > methods in extended interfaces > > > I don't know, but should this extended interface be > considered a SAM > > type or not? > > > public interface UncleSam { > extension BigDecimal calculateTaxes(String > taxPayerId) default > > Tax.calc; > > } > > Regards, Peter > > > *) failure of regression test CheckExamples.java > depending on > > localization settings > > > ! > src/share/classes/com/sun/tools/javac/code/Types.java > ! > src/share/classes/com/sun/tools/javac/parser/JavacParser.java > ! test/tools/javac/diags/examples/IllegalChar.java > + test/tools/javac/lambda/BadStatementInLambda.java > + test/tools/javac/lambda/BadStatementInLambda.out > + test/tools/javac/lambda/Defender01.java > > > > > > > > > > > From john.r.rose at oracle.com Fri Aug 20 23:03:36 2010 From: john.r.rose at oracle.com (John Rose) Date: Fri, 20 Aug 2010 23:03:36 -0700 Subject: hg: lambda/lambda/langtools: Handle non-static method references from static context. More specifically, if f is an instance method of Z whose signature is A, B->C, then #obj.f is of type A, B->C and #Z.f is of type Z, A, B->C. In-Reply-To: <4C5985A1.1080806@oracle.com> References: <20100804141331.E804747EDB@hg.openjdk.java.net> <4C597F30.7070200@oracle.com> <4C5984A7.1080401@univ-mlv.fr> <4C5985A1.1080806@oracle.com> Message-ID: On Aug 4, 2010, at 8:22 AM, Brian Goetz wrote: >> And the coolest thing is that #Employee.isPartTime is just a LDC. > > Yep! Tastes great AND less filling! > >> Predicate p = #Employee.isPartTime; >> >> will be compiled to >> >> ldc #Employee.isPartTime >> ldc Predicate.class >> invokestatic MethodHandles.asSam >> (Ljava/lang/MethodHandle;Ljava/lang/Class;)LObject; >> checkcast LPredicate; >> >> knowing that asSam() should always return an instance of the same class >> for the same SAM. > > Has the 292 EG made any progress in defining the semantics and nonfunctional > behavior (i.e., performance) of asSam()? I am curious to hear. Will > MethodHandles.asSam(methodHandle, clazz) allocate a fresh MH on each > invocation, or will they be cached somehow so that the above is > allocation-free (and subsequent invocation is indirection-free)? I expect to cache at least some of those adapted MHs in the Hotspot implementation. (The present rev. 0 draft implementation is a placeholder built on Proxy.) A one-element cache per direct method handle should be sufficient. Such things need to be invisible optimizations. In order for this to be so, the Lambda spec. has to be very "shy" about specifying when new objects are created, along the lines of Integer.valueOf. Of course, none of this needs to matter when a JIT gets the bytecode sequence above. It can use the right constant directly in the machine code. Expect the 292 performance to ramp up over time. It is a deep addition to the JVM, which will get faster with careful, empirically driven optimization work. -- John From oehrstroem at gmail.com Sat Aug 21 03:54:51 2010 From: oehrstroem at gmail.com (Fredrik Ohrstrom) Date: Sat, 21 Aug 2010 12:54:51 +0200 Subject: hg: lambda/lambda/langtools: Non-static selectors in method refs, such as instance creation expressions, should be handled correctly (prepended to argument list). In-Reply-To: References: <20100816100137.A9DF5471FD@hg.openjdk.java.net> Message-ID: 2010/8/16 Paul Benedict : > Maurizio, > > In the MethodReference10 example, main() has this call: > sortBy(c, new Foo()#getA); > > Has there been any further thought to making parentheses mandatory? > sortBy(c, new Foo()#getA(Foo)); > > ... that is, to facilitate the language extending to field references. You do not need to use the same syntax to acquire a field reference as a method reference. Parentheses should not be made mandatory. //Fredrik From howard.lovatt at gmail.com Sat Aug 21 17:55:20 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Sun, 22 Aug 2010 10:55:20 +1000 Subject: Problem with extension methods Message-ID: Hi, I am trying out extension methods: public interface NewList extends List { extension void sort( final Comparator c ) default Collections.sort; } public class MinimalIntegerList extends AbstractList implements NewList { [snip] // no sort method } 21: final MinimalIntegerList il = new MinimalIntegerList(); 22: out.println( il ); 23: il.sort( #( i1, i2 ) { i1 - i2 } ); 24: out.println( il ); I get: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] Exception in thread "main" java.lang.AbstractMethodError: lambdas.MinimalIntegerList.sort(Ljava/util/Comparator;)V at lambdas.Main.extensionMethods(Main.java:23) at lambdas.Main.main(Main.java:16) Any idea what's wrong? -- ? -- Howard. From brian.goetz at oracle.com Sat Aug 21 19:47:34 2010 From: brian.goetz at oracle.com (Brian Goetz) Date: Sat, 21 Aug 2010 19:47:34 -0700 Subject: Problem with extension methods In-Reply-To: References: Message-ID: <89FCF67F-A72F-4F38-9D34-6CD033982B32@oracle.com> Yes, the runtime part is not implemented -- only the compiler part at this time. On Aug 21, 2010, at 5:55 PM, Howard Lovatt wrote: > Hi, > > I am trying out extension methods: > > public interface NewList extends List { > extension void sort( final Comparator c ) default Collections.sort; > } > > public class MinimalIntegerList extends AbstractList > implements NewList { > [snip] // no sort method > } > > 21: final MinimalIntegerList il = new MinimalIntegerList(); > 22: out.println( il ); > 23: il.sort( #( i1, i2 ) { i1 - i2 } ); > 24: out.println( il ); > > I get: > > [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] > Exception in thread "main" java.lang.AbstractMethodError: > lambdas.MinimalIntegerList.sort(Ljava/util/Comparator;)V > at lambdas.Main.extensionMethods(Main.java:23) > at lambdas.Main.main(Main.java:16) > > Any idea what's wrong? > > -- > -- Howard. > From howard.lovatt at gmail.com Sat Aug 21 21:18:09 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Sun, 22 Aug 2010 14:18:09 +1000 Subject: Problem with extension methods In-Reply-To: <89FCF67F-A72F-4F38-9D34-6CD033982B32@oracle.com> References: <89FCF67F-A72F-4F38-9D34-6CD033982B32@oracle.com> Message-ID: Mant thanks On 22 August 2010 12:47, Brian Goetz wrote: > Yes, the runtime part is not implemented -- only the compiler part at this time. > > On Aug 21, 2010, at 5:55 PM, Howard Lovatt wrote: > >> Hi, >> >> I am trying out extension methods: >> >> public interface NewList extends List { >> ?extension void sort( final Comparator c ) default Collections.sort; >> } >> >> public class MinimalIntegerList extends AbstractList >> implements NewList { >> ?[snip] // no sort method >> } >> >> 21: ? ?final MinimalIntegerList il = new MinimalIntegerList(); >> 22: ? ?out.println( il ); >> 23: ? ?il.sort( #( i1, i2 ) { i1 - i2 } ); >> 24: ? ?out.println( il ); >> >> I get: >> >> [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] >> Exception in thread "main" java.lang.AbstractMethodError: >> lambdas.MinimalIntegerList.sort(Ljava/util/Comparator;)V >> ? ? ? at lambdas.Main.extensionMethods(Main.java:23) >> ? ? ? at lambdas.Main.main(Main.java:16) >> >> Any idea what's wrong? >> >> -- >> ? -- Howard. >> > > -- ? -- Howard. From howard.lovatt at gmail.com Sat Aug 21 21:50:02 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Sun, 22 Aug 2010 14:50:02 +1000 Subject: Generic parameters for Extension methods Message-ID: Hi, The position of a generic parameter for an extension method is currently before the context sensitive word extension, e.g.: extension void forEach( Method1 block ) throws E default Trait.forEach; This is odd because extension 'feels' like a qualifier, like public, and therefore I expected the syntax to be: extension void forEach( Method1 block ) throws E default Trait.forEach; Any reason? ? -- Howard. From howard.lovatt at gmail.com Sat Aug 21 21:58:14 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Sun, 22 Aug 2010 14:58:14 +1000 Subject: Problem with lambda expression Message-ID: For the extension method: extension void forEach( Method1 method ) throws E default Trait.forEach; Called with: il.forEach( #( i ) { 2 * i } ); // No exception, no try block Gives: lambdas/Main.java:30: integer number too large: i il.forEach( #( i ) { 2 * i } ); // No exception, no try block ^ (The arrow points to the 2 in a mon-spaced font.) Whereas: il.forEach( #( i ) { return 2 * i; } ); // No exception, no try block Works as expected. ? -- Howard. From howard.lovatt at gmail.com Sat Aug 21 23:09:05 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Sun, 22 Aug 2010 16:09:05 +1000 Subject: Trouble inferring type of lambda Message-ID: For: public interface Method1 { public R call( A1 a1 ) throws E; } and: public void forEach( final Method1 method ) throws E { ... } The compiler has trouble with: il.forEach( #( i ) { throw new Exception(); } ); // Need to catch checked exception Giving: lambdas/Main.java:34: method forEach in class IntList11 cannot be applied to given types il.forEach( #( i ) { throw new Exception(); } ); // Need to catch checked exception ^ required: Method1 found: #void(?)(Exception) where E is a type-variable: E extends Exception declared in method forEach(Method1) Qualifying doesn't help: Method1 #( i ) { throw new Exception(); } It gives: lambdas/Main.java:34: incompatible types; no instance(s) of type variable(s) ? exist so that #void(?)(Exception) conforms to Method1 il.forEach( Method1 #( i ) { throw new Exception(); } ); // Need to catch checked exception ^ required: Method1 found: #void(?)(Exception) Is the problem that the return type isn't expressible? It isn't really void, it is 'NeverReturns'. ? -- Howard. From howard.lovatt at gmail.com Sun Aug 22 00:14:45 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Sun, 22 Aug 2010 17:14:45 +1000 Subject: Exception catching not enforced Message-ID: For the extension method: ? extension void forEach( Method1 method ) throws E default Trait.forEach; Called with: ? ? il.forEach( #( i ) { if ( i < 3 ) { throw new Exception(); } return i * i; } ); // Should need to catch checked exception Without a try catch block around it compiles. Presumably it shouldn't? ? -- Howard. From maurizio.cimadamore at oracle.com Sun Aug 22 10:42:06 2010 From: maurizio.cimadamore at oracle.com (maurizio cimadamore) Date: Sun, 22 Aug 2010 18:42:06 +0100 Subject: Problem with lambda expression In-Reply-To: References: Message-ID: <4C71616E.7020909@oracle.com> Hi Howard thanks for playing with the prototype. Could you please post the fulle body of the interface containing the exrension method? it seems like it should be something like: interface MyIntf { ... } and that, possibly, your 'il' variable is something like MyIntf ? If it is so, it seems like a bug with type-inference for plain 'expression' lambdas - should be easily fixable. Thanks Maurizio On 22/08/2010 05:58, Howard Lovatt wrote: > For the extension method: > > extension void forEach( Method1 method ) throws > E default Trait.forEach; > > Called with: > > il.forEach( #( i ) { 2 * i } ); // No exception, no try block > > Gives: > > lambdas/Main.java:30: integer number too large: i > il.forEach( #( i ) { 2 * i } ); // No exception, no try block > ^ > (The arrow points to the 2 in a mon-spaced font.) Whereas: > > il.forEach( #( i ) { return 2 * i; } ); // No exception, no try block > > Works as expected. > > -- Howard. > > From maurizio.cimadamore at oracle.com Sun Aug 22 10:45:14 2010 From: maurizio.cimadamore at oracle.com (maurizio cimadamore) Date: Sun, 22 Aug 2010 18:45:14 +0100 Subject: Trouble inferring type of lambda In-Reply-To: References: Message-ID: <4C71622A.8040305@oracle.com> On 22/08/2010 07:09, Howard Lovatt wrote: > For: > > public interface Method1 { public R call( A1 a1 ) throws E; } > > and: > > public void forEach( final Method1 > method ) throws E { ... } > > The compiler has trouble with: > > il.forEach( #( i ) { throw new Exception(); } ); // Need to catch > checked exception > > Giving: > > lambdas/Main.java:34: method forEach in class IntList11 cannot be > applied to given types > il.forEach( #( i ) { throw new Exception(); } ); // Need to > catch checked exception > ^ > required: Method1 > found: #void(?)(Exception) > where E is a type-variable: > E extends Exception declared in method > forEach(Method1) > > Qualifying doesn't help: > > Method1 #( i ) { throw new Exception(); } > > It gives: > > lambdas/Main.java:34: incompatible types; no instance(s) of type > variable(s) ? exist so that #void(?)(Exception) conforms to > Method1 > il.forEach( Method1 #( i ) { throw > new Exception(); } ); // Need to catch checked exception > ^ > required: Method1 > found: #void(?)(Exception) > > Is the problem that the return type isn't expressible? It isn't really > void, it is 'NeverReturns'. > Uhmm the problem here seems more related with a failure in inference of the lambda parameter (the '?' that you are seeing). Again it would be helpful to see the declaration of the receiver class as well as the type of 'il'. Maurizio > -- Howard. > > From maurizio.cimadamore at oracle.com Sun Aug 22 10:47:36 2010 From: maurizio.cimadamore at oracle.com (maurizio cimadamore) Date: Sun, 22 Aug 2010 18:47:36 +0100 Subject: Exception catching not enforced In-Reply-To: References: Message-ID: <4C7162B8.4040502@oracle.com> On 22/08/2010 08:14, Howard Lovatt wrote: > For the extension method: > > extension void forEach( Method1 method ) throws > E default Trait.forEach; > > Called with: > > il.forEach( #( i ) { > if ( i< 3 ) { throw new Exception(); } > return i * i; > } ); // Should need to catch checked exception > > > Without a try catch block around it compiles. Presumably it shouldn't? > Yeah, it shouldn't - this is a bug. Thanks Maurizio > -- Howard. > > From scolebourne at joda.org Sun Aug 22 12:57:13 2010 From: scolebourne at joda.org (Stephen Colebourne) Date: Sun, 22 Aug 2010 20:57:13 +0100 Subject: Generic parameters for Extension methods In-Reply-To: References: Message-ID: Looking at Howard's code, I would also expect the generic part to be after the extension keyword (not that I like the extension keyword). Stephen On 22 August 2010 05:50, Howard Lovatt wrote: > Hi, > > The position of a generic parameter for an extension method is > currently before the context sensitive word extension, e.g.: > > ? extension void forEach( Method1 block ) throws E > default Trait.forEach; > > This is odd because extension 'feels' like a qualifier, like public, > and therefore I expected the syntax to be: > > ?extension void forEach( Method1 block ) throws E > default Trait.forEach; > > Any reason? > > ? -- Howard. > > From howard.lovatt at gmail.com Sun Aug 22 18:03:05 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Mon, 23 Aug 2010 11:03:05 +1000 Subject: Problem with Method Reference Message-ID: Hi, I think the following should not compile (because String.CASE_INSENSITIVE_ORDER isn't a class but an object): final String s1 = "Amy"; final String s2 = "Bec"; final String[] people = new String[] { s2, s1 }; Arrays.sort( people, String.CASE_INSENSITIVE_ORDER#compare( String, String ) ); but it does. However when run, you get: Exception in thread "main" java.dyn.WrongMethodTypeException: (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; cannot be called as (Ljava/dyn/MethodHandle;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; at java.dyn.MethodHandle.invokeVarargs(MethodHandle.java:330) at com.sun.runtime.ProxyHelper$1.invoke(ProxyHelper.java:57) at $Proxy0.compare(Unknown Source) at java.util.TimSort.countRunAndMakeAscending(TimSort.java:324) at java.util.TimSort.sort(TimSort.java:189) at java.util.TimSort.sort(TimSort.java:173) at java.util.Arrays.sort(Arrays.java:653) at lambdas.Main.lambdas(Main.java:67) at lambdas.Main.main(Main.java:19) ? -- Howard. PS Full source, as requested previously, to follow From howard.lovatt at gmail.com Sun Aug 22 22:31:09 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Mon, 23 Aug 2010 15:31:09 +1000 Subject: Trouble inferring type of lambda In-Reply-To: <4C71622A.8040305@oracle.com> References: <4C71622A.8040305@oracle.com> Message-ID: Hi Maurizio, As a bit of background I was thinking of giving a talk at the Sydney JUG, nothing arranged yet - just a thought, on the likely Java 7 features, hence the writing style of the code below. All the examples I am having trouble with, except String.String.CASE_INSENSITIVE_ORDER.compare( String, String ) - which is obvious anyway, are covered in the code below. Hence this one email covers all. I have also attached the files and the compile/run script. public interface Method1 { public R call( A1 a1 ) throws E; } public interface SortableList> extends List { extension void sort() default Collections.sort; extension void forEach( Method1 method ) throws E default Trait.forEach; static class Trait { public static , throws E> void forEach( final SortableList self, final Method1 method ) throws E { for ( int i = 0; i < self.size(); i++ ) { final T oldValue = self.get( i ); final T newValue = method.call( oldValue ); self.set( i, newValue ); } } } } public class IntList11 extends AbstractList implements SortableList { private final int[] values = new int[] { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; @Override public Integer get( final int index ) { return values[ index ]; } @Override public Integer set( final int index, final Integer newValue ) { final int old = values[ index ]; values[ index ] = newValue; return old; } @Override public int size() { return values.length; } @Override public void forEach( final Method1 method ) throws E { // for ( int i = 0; i < size(); i++ ) { for ( int i = 0; i < values.length; i++ ) { // final Integer oldValue = get( i ); final Integer oldValue = values[ i ]; final Integer newValue = method.call( oldValue ); // set( i, newValue ); values[ i ] = newValue; } } } public class Main { public static void main( final String... notUsed ) throws Throwable { // coin-dev // TODO // lambda-dev lambdas(); // extensionMethods(); - no runtime at present exceptionTransparency(); // mlvm-dev // TODO } private static void lambdas() throws Throwable { // SAM conversion, shorthand for an instance of an anonymous inner class // Syntax may change to { args -> body } // final Runnable r1 = new Runnable() { // public void run() { out.println( "Start" ); } // }; final Runnable r1 = #() { out.println( "Start" ) }; r1.run(); // Can have complex bodies as well as 'expressions', seperated by ; and ; on last line // See below for alternative final Runnable r2 = #() { int sum = 0; for ( int i = 1; i <= 4; i++) { sum += i; } out.println( "Sum 4 = " + sum ); }; r2.run(); // Can be an abstract class abstract class AbstractRun implements Runnable { AbstractRun() { throw new NullPointerException(); } } try { final AbstractRun r3 = #() { out.println( "Never called" ) }; r3.run(); } catch ( final NullPointerException notUsed ) { out.println( "Exception in constructor" ); } // Arguments and Target Typing // Argument type is ActionEvent final ActionListener al1 = #( notUsed ) { out.println( "ActionListener lambda 1 called" ) }; final JButton b1 = new JButton(); b1.addActionListener( al1 ); b1.doClick(); // Can type arguments but not return type, little point though - see below final ActionListener al2 = #( final ActionEvent notUsed ) { out.println( "ActionListener lambda 2 called" ) }; b1.addActionListener( al2 ); b1.doClick(); // More usefully you can add final. final ActionListener al3 = #( final notUsed ) { out.println( "ActionListener lambda 3 called" ) }; // Method References, syntax like Javadoc b1.addActionListener( Main#print( ActionEvent ) ); b1.doClick(); // Can be bound to an object class Print { void print( final ActionEvent notUsed ) { out.println( "Main.Print.print method called" ); } } b1.addActionListener( new Print()#print( ActionEvent ) ); b1.doClick(); // this out.println( "Class = " + al3.getClass() + ", instanceof ActionListener = " + (al3 instanceof ActionListener) + ", instance of enclosing class (Main) = " + (al3 instanceof Main) ); // Effectively final // No use to me, but others like it! String s = "Effectively final"; // not *declared* final, but effectively final final Callable cs = #() { s }; out.println( cs.call() ); } private static void print( final ActionEvent notUsed ) { out.println( "Main.print method called" ); } private static void extensionMethods() { final IntList11 il = new IntList11(); out.println( il ); il.sort(); out.println( il ); } private static void exceptionTransparency() { final IntList11 il = new IntList11(); out.println( il ); // il.forEach( #( i ) { 2 * i } ); // No exception; no try block - has syntax error il.forEach( #( i ) { return 2 * i; } ); // No exception, no try block out.println( il ); // try { il.forEach( #( i ) { if ( i < 3 ) { throw new Exception(); } return i * i; } ); // Should need to catch checked exception! // } catch (final Throwable notUsed) { // out.println( "Exception caught" ); // } out.println( il ); } } Keep up the good work, -- Howard. On 23 August 2010 03:45, maurizio cimadamore wrote: > On 22/08/2010 07:09, Howard Lovatt wrote: >> >> For: >> >> ? public interface Method1 ?{ public R call( A1 a1 ) >> throws E; } >> >> and: >> >> ? public ?void forEach( final Method1 >> method ) throws E { ... } >> >> The compiler has trouble with: >> >> ? ?il.forEach( #( i ) { throw new Exception(); } ); // Need to catch >> checked exception >> >> Giving: >> >> lambdas/Main.java:34: method forEach in class IntList11 cannot be >> applied to given types >> ? ? ? il.forEach( #( i ) { throw new Exception(); } ); // Need to >> catch checked exception >> ? ? ? ? ^ >> ? required: Method1 >> ? found: #void(?)(Exception) >> ? where E is a type-variable: >> ? ? E extends Exception declared in method >> forEach(Method1) >> >> Qualifying doesn't help: >> >> ? Method1 ?#( i ) { throw new Exception(); } >> >> It gives: >> >> lambdas/Main.java:34: incompatible types; no instance(s) of type >> variable(s) ? exist so that #void(?)(Exception) conforms to >> Method1 >> ? ? ? il.forEach( Method1 ?#( i ) { throw >> new Exception(); } ); // Need to catch checked exception >> ? ? ? ? ? ? ? ? ? ^ >> ? required: Method1 >> ? found: ? ?#void(?)(Exception) >> >> Is the problem that the return type isn't expressible? It isn't really >> void, it is 'NeverReturns'. >> > > Uhmm the problem here seems more related with a failure in inference of the > lambda parameter (the '?' that you are seeing). Again it would be helpful to > see the declaration of the receiver class as well as the type of 'il'. > > Maurizio >> >> ? -- Howard. From maurizio.cimadamore at oracle.com Mon Aug 23 01:12:53 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Mon, 23 Aug 2010 09:12:53 +0100 Subject: Problem with Method Reference In-Reply-To: References: Message-ID: <4C722D85.80207@oracle.com> On 23/08/10 02:03, Howard Lovatt wrote: > Hi, > > I think the following should not compile (because > String.CASE_INSENSITIVE_ORDER isn't a class but an object): > > final String s1 = "Amy"; > final String s2 = "Bec"; > final String[] people = new String[] { s2, s1 }; > Arrays.sort( people, String.CASE_INSENSITIVE_ORDER#compare( String, > String ) ); > I don't agree... the above code is not different w.r.t. to new Foo()#bar which should compile. The left hand side of an infix # operator can be either an expression or a qualified type. > but it does. However when run, you get: > > Exception in thread "main" java.dyn.WrongMethodTypeException: > (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; > cannot be called as > (Ljava/dyn/MethodHandle;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; > at java.dyn.MethodHandle.invokeVarargs(MethodHandle.java:330) > at com.sun.runtime.ProxyHelper$1.invoke(ProxyHelper.java:57) > at $Proxy0.compare(Unknown Source) > at java.util.TimSort.countRunAndMakeAscending(TimSort.java:324) > at java.util.TimSort.sort(TimSort.java:189) > at java.util.TimSort.sort(TimSort.java:173) > at java.util.Arrays.sort(Arrays.java:653) > at lambdas.Main.lambdas(Main.java:67) > at lambdas.Main.main(Main.java:19) > What happens here is that javac thinks (erroneously) that this is a static qualifier when it's not - as such it does not prepend the 'this' argument in the method call... (which is a bug) Maurizio > > -- Howard. > > PS Full source, as requested previously, to follow > From howard.lovatt at gmail.com Mon Aug 23 02:19:17 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Mon, 23 Aug 2010 19:19:17 +1000 Subject: Problem with Method Reference In-Reply-To: <4C722D85.80207@oracle.com> References: <4C722D85.80207@oracle.com> Message-ID: <2BF7C9E8-46EC-4C36-9BDB-4005E9D8C253@gmail.com> Yes, I was wrong it is a bug -- Howard Lovatt +61 419 971 263 (sent from my PDA) On 23/08/2010, at 6:12 PM, Maurizio Cimadamore wrote: > On 23/08/10 02:03, Howard Lovatt wrote: >> Hi, >> >> I think the following should not compile (because >> String.CASE_INSENSITIVE_ORDER isn't a class but an object): >> >> final String s1 = "Amy"; >> final String s2 = "Bec"; >> final String[] people = new String[] { s2, s1 }; >> Arrays.sort( people, String.CASE_INSENSITIVE_ORDER#compare( String, >> String ) ); >> > I don't agree... the above code is not different w.r.t. to > > new Foo()#bar > > which should compile. The left hand side of an infix # operator can be either an expression or a qualified type. >> but it does. However when run, you get: >> >> Exception in thread "main" java.dyn.WrongMethodTypeException: >> (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; >> cannot be called as >> (Ljava/dyn/MethodHandle;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; >> at java.dyn.MethodHandle.invokeVarargs(MethodHandle.java:330) >> at com.sun.runtime.ProxyHelper$1.invoke(ProxyHelper.java:57) >> at $Proxy0.compare(Unknown Source) >> at java.util.TimSort.countRunAndMakeAscending(TimSort.java:324) >> at java.util.TimSort.sort(TimSort.java:189) >> at java.util.TimSort.sort(TimSort.java:173) >> at java.util.Arrays.sort(Arrays.java:653) >> at lambdas.Main.lambdas(Main.java:67) >> at lambdas.Main.main(Main.java:19) >> > What happens here is that javac thinks (erroneously) that this is a static qualifier when it's not - as such it does not prepend the 'this' argument in the method call... (which is a bug) > > Maurizio >> >> -- Howard. >> >> PS Full source, as requested previously, to follow >> > From maurizio.cimadamore at oracle.com Mon Aug 23 03:35:18 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Mon, 23 Aug 2010 11:35:18 +0100 Subject: Trouble inferring type of lambda In-Reply-To: <4C71622A.8040305@oracle.com> References: <4C71622A.8040305@oracle.com> Message-ID: <4C724EE6.4000701@oracle.com> This is not a bug. You are trying to SAM convert the following lambda: #(x) { throws Exception(); } into the following target method: Integer call( Integer a1 ) throws E This is not possible, since the lambda expression is inferred to yield 'void' (no return expression found), while the target method returns Integer. Maurizio On 22/08/10 18:45, maurizio cimadamore wrote: > On 22/08/2010 07:09, Howard Lovatt wrote: > >> For: >> >> public interface Method1 { public R call( A1 a1 ) throws E; } >> >> and: >> >> public void forEach( final Method1 >> method ) throws E { ... } >> >> The compiler has trouble with: >> >> il.forEach( #( i ) { throw new Exception(); } ); // Need to catch >> checked exception >> >> Giving: >> >> lambdas/Main.java:34: method forEach in class IntList11 cannot be >> applied to given types >> il.forEach( #( i ) { throw new Exception(); } ); // Need to >> catch checked exception >> ^ >> required: Method1 >> found: #void(?)(Exception) >> where E is a type-variable: >> E extends Exception declared in method >> forEach(Method1) >> >> Qualifying doesn't help: >> >> Method1 #( i ) { throw new Exception(); } >> >> It gives: >> >> lambdas/Main.java:34: incompatible types; no instance(s) of type >> variable(s) ? exist so that #void(?)(Exception) conforms to >> Method1 >> il.forEach( Method1 #( i ) { throw >> new Exception(); } ); // Need to catch checked exception >> ^ >> required: Method1 >> found: #void(?)(Exception) >> >> Is the problem that the return type isn't expressible? It isn't really >> void, it is 'NeverReturns'. >> >> > Uhmm the problem here seems more related with a failure in inference of > the lambda parameter (the '?' that you are seeing). Again it would be > helpful to see the declaration of the receiver class as well as the type > of 'il'. > > Maurizio > >> -- Howard. >> >> >> > > From howard.lovatt at gmail.com Mon Aug 23 04:02:47 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Mon, 23 Aug 2010 21:02:47 +1000 Subject: Trouble inferring type of lambda In-Reply-To: <4C724EE6.4000701@oracle.com> References: <4C71622A.8040305@oracle.com> <4C724EE6.4000701@oracle.com> Message-ID: Hi Mauritzio, I think it is a bug, like I said in the original post the 'return type' is 'NeverReturns' not void, which should be assignable to anything (including Integer). Scala and BGGA handle this case, they both have a 'NeverReturns' type (Scala and BGGA Nothing). Cheers, -- Howard. On 23 August 2010 20:35, Maurizio Cimadamore wrote: > This is not a bug. You are trying to SAM convert the following lambda: > > #(x) { throws Exception(); } > > into the following target method: > > Integer call( Integer a1 ) throws E > > This is not possible, since the lambda expression is inferred to yield > 'void' (no return expression found), while the target method returns > Integer. > > Maurizio > > > > On 22/08/10 18:45, maurizio cimadamore wrote: >> >> On 22/08/2010 07:09, Howard Lovatt wrote: >> >>> >>> For: >>> >>> ? ?public interface Method1 ? { public R call( A1 a1 ) >>> throws E; } >>> >>> and: >>> >>> ? ?public ? void forEach( final Method1 >>> method ) throws E { ... } >>> >>> The compiler has trouble with: >>> >>> ? ? il.forEach( #( i ) { throw new Exception(); } ); // Need to catch >>> checked exception >>> >>> Giving: >>> >>> lambdas/Main.java:34: method forEach in class IntList11 cannot be >>> applied to given types >>> ? ? ? ?il.forEach( #( i ) { throw new Exception(); } ); // Need to >>> catch checked exception >>> ? ? ? ? ?^ >>> ? ?required: Method1 >>> ? ?found: #void(?)(Exception) >>> ? ?where E is a type-variable: >>> ? ? ?E extends Exception declared in method >>> forEach(Method1) >>> >>> Qualifying doesn't help: >>> >>> ? ?Method1 ? #( i ) { throw new Exception(); >>> } >>> >>> It gives: >>> >>> lambdas/Main.java:34: incompatible types; no instance(s) of type >>> variable(s) ? exist so that #void(?)(Exception) conforms to >>> Method1 >>> ? ? ? ?il.forEach( Method1 ? #( i ) { throw >>> new Exception(); } ); // Need to catch checked exception >>> ? ? ? ? ? ? ? ? ? ?^ >>> ? ?required: Method1 >>> ? ?found: ? ?#void(?)(Exception) >>> >>> Is the problem that the return type isn't expressible? It isn't really >>> void, it is 'NeverReturns'. >>> >>> >> >> Uhmm the problem here seems more related with a failure in inference of >> the lambda parameter (the '?' that you are seeing). Again it would be >> helpful to see the declaration of the receiver class as well as the type >> of 'il'. >> >> Maurizio >> >>> >>> ? ?-- Howard. >>> >>> >>> >> >> > > -- ? -- Howard. From maurizio.cimadamore at oracle.com Mon Aug 23 04:15:07 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Mon, 23 Aug 2010 12:15:07 +0100 Subject: Trouble inferring type of lambda In-Reply-To: References: <4C71622A.8040305@oracle.com> <4C724EE6.4000701@oracle.com> Message-ID: <4C72583B.2060803@oracle.com> On 23/08/10 12:02, Howard Lovatt wrote: > Hi Mauritzio, > > I think it is a bug, like I said in the original post the 'return > type' is 'NeverReturns' not void, which should be assignable to > anything (including Integer). Scala and BGGA handle this case, they > both have a 'NeverReturns' type (Scala and BGGA Nothing). > Let me clarify - it is not a bug, according to the current spec; quoting from the latest formal spec describing lambda conversion [1]: "A divergent lambda expression such as #(){throw new AssertionError();} has no return value, and its body completes abruptly by reason of a throw with an AssertionError object. For the purpose of calculating the type of the lambda expression, the body of the lambda expression is void." [1] - http://mail.openjdk.java.net/pipermail/lambda-dev/attachments/20100212/af8d2cc5/attachment-0001.txt Maurizio > Cheers, > > -- Howard. > > On 23 August 2010 20:35, Maurizio Cimadamore > wrote: > >> This is not a bug. You are trying to SAM convert the following lambda: >> >> #(x) { throws Exception(); } >> >> into the following target method: >> >> Integer call( Integer a1 ) throws E >> >> This is not possible, since the lambda expression is inferred to yield >> 'void' (no return expression found), while the target method returns >> Integer. >> >> Maurizio >> >> >> >> On 22/08/10 18:45, maurizio cimadamore wrote: >> >>> On 22/08/2010 07:09, Howard Lovatt wrote: >>> >>> >>>> For: >>>> >>>> public interface Method1 { public R call( A1 a1 ) >>>> throws E; } >>>> >>>> and: >>>> >>>> public void forEach( final Method1 >>>> method ) throws E { ... } >>>> >>>> The compiler has trouble with: >>>> >>>> il.forEach( #( i ) { throw new Exception(); } ); // Need to catch >>>> checked exception >>>> >>>> Giving: >>>> >>>> lambdas/Main.java:34: method forEach in class IntList11 cannot be >>>> applied to given types >>>> il.forEach( #( i ) { throw new Exception(); } ); // Need to >>>> catch checked exception >>>> ^ >>>> required: Method1 >>>> found: #void(?)(Exception) >>>> where E is a type-variable: >>>> E extends Exception declared in method >>>> forEach(Method1) >>>> >>>> Qualifying doesn't help: >>>> >>>> Method1 #( i ) { throw new Exception(); >>>> } >>>> >>>> It gives: >>>> >>>> lambdas/Main.java:34: incompatible types; no instance(s) of type >>>> variable(s) ? exist so that #void(?)(Exception) conforms to >>>> Method1 >>>> il.forEach( Method1 #( i ) { throw >>>> new Exception(); } ); // Need to catch checked exception >>>> ^ >>>> required: Method1 >>>> found: #void(?)(Exception) >>>> >>>> Is the problem that the return type isn't expressible? It isn't really >>>> void, it is 'NeverReturns'. >>>> >>>> >>>> >>> Uhmm the problem here seems more related with a failure in inference of >>> the lambda parameter (the '?' that you are seeing). Again it would be >>> helpful to see the declaration of the receiver class as well as the type >>> of 'il'. >>> >>> Maurizio >>> >>> >>>> -- Howard. >>>> >>>> >>>> >>>> >>> >>> >> >> > > > From howard.lovatt at gmail.com Mon Aug 23 04:34:03 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Mon, 23 Aug 2010 21:34:03 +1000 Subject: Trouble inferring type of lambda In-Reply-To: <4C72583B.2060803@oracle.com> References: <4C71622A.8040305@oracle.com> <4C724EE6.4000701@oracle.com> <4C72583B.2060803@oracle.com> Message-ID: Thanks for the clarification, I think it *should* be a bug! In the meantime, what is the recommended idiom for writing such a function. -- Howard. On 23 August 2010 21:15, Maurizio Cimadamore wrote: > On 23/08/10 12:02, Howard Lovatt wrote: > > Hi Mauritzio, > > I think it is a bug, like I said in the original post the 'return > type' is 'NeverReturns' not void, which should be assignable to > anything (including Integer). Scala and BGGA handle this case, they > both have a 'NeverReturns' type (Scala and BGGA Nothing). > > > Let me clarify - it is not a bug, according to the current spec; quoting > from the latest formal spec describing lambda conversion [1]: > > "A divergent lambda expression such as #(){throw new AssertionError();} > has no return value, and its body completes abruptly by reason of a > throw with an AssertionError object. For the purpose of calculating > the type of the lambda expression, the body of the lambda expression > is void." > > [1] - > http://mail.openjdk.java.net/pipermail/lambda-dev/attachments/20100212/af8d2cc5/attachment-0001.txt > > Maurizio > > Cheers, > > -- Howard. > > On 23 August 2010 20:35, Maurizio Cimadamore > wrote: > > > This is not a bug. You are trying to SAM convert the following lambda: > > #(x) { throws Exception(); } > > into the following target method: > > Integer call( Integer a1 ) throws E > > This is not possible, since the lambda expression is inferred to yield > 'void' (no return expression found), while the target method returns > Integer. > > Maurizio > > > > On 22/08/10 18:45, maurizio cimadamore wrote: > > > On 22/08/2010 07:09, Howard Lovatt wrote: > > > > For: > > ? ?public interface Method1 ? { public R call( A1 a1 ) > throws E; } > > and: > > ? ?public ? void forEach( final Method1 > method ) throws E { ... } > > The compiler has trouble with: > > ? ? il.forEach( #( i ) { throw new Exception(); } ); // Need to catch > checked exception > > Giving: > > lambdas/Main.java:34: method forEach in class IntList11 cannot be > applied to given types > ? ? ? ?il.forEach( #( i ) { throw new Exception(); } ); // Need to > catch checked exception > ? ? ? ? ?^ > ? ?required: Method1 > ? ?found: #void(?)(Exception) > ? ?where E is a type-variable: > ? ? ?E extends Exception declared in method > forEach(Method1) > > Qualifying doesn't help: > > ? ?Method1 ? #( i ) { throw new Exception(); > } > > It gives: > > lambdas/Main.java:34: incompatible types; no instance(s) of type > variable(s) ? exist so that #void(?)(Exception) conforms to > Method1 > ? ? ? ?il.forEach( Method1 ? #( i ) { throw > new Exception(); } ); // Need to catch checked exception > ? ? ? ? ? ? ? ? ? ?^ > ? ?required: Method1 > ? ?found: ? ?#void(?)(Exception) > > Is the problem that the return type isn't expressible? It isn't really > void, it is 'NeverReturns'. > > > > > Uhmm the problem here seems more related with a failure in inference of > the lambda parameter (the '?' that you are seeing). Again it would be > helpful to see the declaration of the receiver class as well as the type > of 'il'. > > Maurizio From maurizio.cimadamore at oracle.com Mon Aug 23 04:59:28 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Mon, 23 Aug 2010 12:59:28 +0100 Subject: Trouble inferring type of lambda In-Reply-To: References: <4C71622A.8040305@oracle.com> <4C724EE6.4000701@oracle.com> <4C72583B.2060803@oracle.com> Message-ID: <4C7262A0.8050905@oracle.com> On 23/08/10 12:34, Howard Lovatt wrote: > Thanks for the clarification, I think it *should* be a bug! > > In the meantime, what is the recommended idiom for writing such a function. > You could try with: interface SortableList> extends List { void forEach( Method1 method ) throws E; } this should do. Maurizio > -- Howard. > > On 23 August 2010 21:15, Maurizio Cimadamore > wrote: > >> On 23/08/10 12:02, Howard Lovatt wrote: >> >> Hi Mauritzio, >> >> I think it is a bug, like I said in the original post the 'return >> type' is 'NeverReturns' not void, which should be assignable to >> anything (including Integer). Scala and BGGA handle this case, they >> both have a 'NeverReturns' type (Scala and BGGA Nothing). >> >> >> Let me clarify - it is not a bug, according to the current spec; quoting >> from the latest formal spec describing lambda conversion [1]: >> >> "A divergent lambda expression such as #(){throw new AssertionError();} >> has no return value, and its body completes abruptly by reason of a >> throw with an AssertionError object. For the purpose of calculating >> the type of the lambda expression, the body of the lambda expression >> is void." >> >> [1] - >> http://mail.openjdk.java.net/pipermail/lambda-dev/attachments/20100212/af8d2cc5/attachment-0001.txt >> >> Maurizio >> >> Cheers, >> >> -- Howard. >> >> On 23 August 2010 20:35, Maurizio Cimadamore >> wrote: >> >> >> This is not a bug. You are trying to SAM convert the following lambda: >> >> #(x) { throws Exception(); } >> >> into the following target method: >> >> Integer call( Integer a1 ) throws E >> >> This is not possible, since the lambda expression is inferred to yield >> 'void' (no return expression found), while the target method returns >> Integer. >> >> Maurizio >> >> >> >> On 22/08/10 18:45, maurizio cimadamore wrote: >> >> >> On 22/08/2010 07:09, Howard Lovatt wrote: >> >> >> >> For: >> >> public interface Method1 { public R call( A1 a1 ) >> throws E; } >> >> and: >> >> public void forEach( final Method1 >> method ) throws E { ... } >> >> The compiler has trouble with: >> >> il.forEach( #( i ) { throw new Exception(); } ); // Need to catch >> checked exception >> >> Giving: >> >> lambdas/Main.java:34: method forEach in class IntList11 cannot be >> applied to given types >> il.forEach( #( i ) { throw new Exception(); } ); // Need to >> catch checked exception >> ^ >> required: Method1 >> found: #void(?)(Exception) >> where E is a type-variable: >> E extends Exception declared in method >> forEach(Method1) >> >> Qualifying doesn't help: >> >> Method1 #( i ) { throw new Exception(); >> } >> >> It gives: >> >> lambdas/Main.java:34: incompatible types; no instance(s) of type >> variable(s) ? exist so that #void(?)(Exception) conforms to >> Method1 >> il.forEach( Method1 #( i ) { throw >> new Exception(); } ); // Need to catch checked exception >> ^ >> required: Method1 >> found: #void(?)(Exception) >> >> Is the problem that the return type isn't expressible? It isn't really >> void, it is 'NeverReturns'. >> >> >> >> >> Uhmm the problem here seems more related with a failure in inference of >> the lambda parameter (the '?' that you are seeing). Again it would be >> helpful to see the declaration of the receiver class as well as the type >> of 'il'. >> >> Maurizio >> From howard.lovatt at gmail.com Mon Aug 23 05:49:44 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Mon, 23 Aug 2010 22:49:44 +1000 Subject: Trouble inferring type of lambda In-Reply-To: <4C7262A0.8050905@oracle.com> References: <4C71622A.8040305@oracle.com> <4C724EE6.4000701@oracle.com> <4C72583B.2060803@oracle.com> <4C7262A0.8050905@oracle.com> Message-ID: Thanks for the reply. Whilst this will work, it is hardly desirable. Effectively the return type of all lambdas has to 'free' variable then writing a method that uses them is awkward, e.g.: @Override public void forEach( final Method1 method ) throws E { for ( int i = 0; i < values.length; i++ ) { final Integer oldValue = values[ i ]; final R newValueTemp = method.call( oldValue ); if ( newValueTemp instanceof Integer ) { values[ i ] = (Integer) newValue; } } } Not great! Cheers, -- Howard. On 23 August 2010 21:59, Maurizio Cimadamore wrote: > On 23/08/10 12:34, Howard Lovatt wrote: >> >> Thanks for the clarification, I think it *should* be a bug! >> >> In the meantime, what is the recommended idiom for writing such a >> function. >> > > You could try with: > > interface SortableList> extends List { > > void forEach( Method1 method ) throws E; > > } > > this should do. > > Maurizio > >> ?-- Howard. >> >> On 23 August 2010 21:15, Maurizio Cimadamore >> ?wrote: >> >>> >>> On 23/08/10 12:02, Howard Lovatt wrote: >>> >>> Hi Mauritzio, >>> >>> I think it is a bug, like I said in the original post the 'return >>> type' is 'NeverReturns' not void, which should be assignable to >>> anything (including Integer). Scala and BGGA handle this case, they >>> both have a 'NeverReturns' type (Scala and BGGA Nothing). >>> >>> >>> Let me clarify - it is not a bug, according to the current spec; quoting >>> from the latest formal spec describing lambda conversion [1]: >>> >>> "A divergent lambda expression such as #(){throw new AssertionError();} >>> has no return value, and its body completes abruptly by reason of a >>> throw with an AssertionError object. For the purpose of calculating >>> the type of the lambda expression, the body of the lambda expression >>> is void." >>> >>> [1] - >>> >>> http://mail.openjdk.java.net/pipermail/lambda-dev/attachments/20100212/af8d2cc5/attachment-0001.txt >>> >>> Maurizio >>> >>> Cheers, >>> >>> ?-- Howard. >>> >>> On 23 August 2010 20:35, Maurizio Cimadamore >>> ?wrote: >>> >>> >>> This is not a bug. You are trying to SAM convert the following lambda: >>> >>> #(x) { throws Exception(); } >>> >>> into the following target method: >>> >>> ?Integer call( Integer a1 ) throws E >>> >>> This is not possible, since the lambda expression is inferred to yield >>> 'void' (no return expression found), while the target method returns >>> Integer. >>> >>> Maurizio >>> >>> >>> >>> On 22/08/10 18:45, maurizio cimadamore wrote: >>> >>> >>> On 22/08/2010 07:09, Howard Lovatt wrote: >>> >>> >>> >>> For: >>> >>> ? ?public interface Method1 ? ? { public R call( A1 a1 ) >>> throws E; } >>> >>> and: >>> >>> ? ?public ? ? void forEach( final Method1 >>> method ) throws E { ... } >>> >>> The compiler has trouble with: >>> >>> ? ? il.forEach( #( i ) { throw new Exception(); } ); // Need to catch >>> checked exception >>> >>> Giving: >>> >>> lambdas/Main.java:34: method forEach in class IntList11 cannot be >>> applied to given types >>> ? ? ? ?il.forEach( #( i ) { throw new Exception(); } ); // Need to >>> catch checked exception >>> ? ? ? ? ?^ >>> ? ?required: Method1 >>> ? ?found: #void(?)(Exception) >>> ? ?where E is a type-variable: >>> ? ? ?E extends Exception declared in method >>> forEach(Method1) >>> >>> Qualifying doesn't help: >>> >>> ? ?Method1 ? ? #( i ) { throw new >>> Exception(); >>> } >>> >>> It gives: >>> >>> lambdas/Main.java:34: incompatible types; no instance(s) of type >>> variable(s) ? exist so that #void(?)(Exception) conforms to >>> Method1 >>> ? ? ? ?il.forEach( Method1 ? ? #( i ) { >>> throw >>> new Exception(); } ); // Need to catch checked exception >>> ? ? ? ? ? ? ? ? ? ?^ >>> ? ?required: Method1 >>> ? ?found: ? ?#void(?)(Exception) >>> >>> Is the problem that the return type isn't expressible? It isn't really >>> void, it is 'NeverReturns'. >>> >>> >>> >>> >>> Uhmm the problem here seems more related with a failure in inference of >>> the lambda parameter (the '?' that you are seeing). Again it would be >>> helpful to see the declaration of the receiver class as well as the type >>> of 'il'. >>> >>> Maurizio >>> > > -- ? -- Howard. From maurizio.cimadamore at oracle.com Mon Aug 23 05:49:41 2010 From: maurizio.cimadamore at oracle.com (maurizio.cimadamore at oracle.com) Date: Mon, 23 Aug 2010 12:49:41 +0000 Subject: hg: lambda/lambda/langtools: Bug fixes: Message-ID: <20100823124947.C6066473AE@hg.openjdk.java.net> Changeset: 1bb5b46bb326 Author: mcimadamore Date: 2010-08-23 13:48 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/1bb5b46bb326 Bug fixes: *) binary expression in lambda expression is not parsed correctly (Scanner.popState fails to restore state) *) method references: static vs. non-static selection logic in method references does not always works *) failure to infer exception thrown types from lambda body causes checked exception to be skipped *) lambda expression body (when not a block) cannot be void ! src/share/classes/com/sun/tools/javac/code/Types.java ! src/share/classes/com/sun/tools/javac/comp/Attr.java ! src/share/classes/com/sun/tools/javac/parser/Scanner.java ! src/share/classes/com/sun/tools/javac/tree/TreeInfo.java + test/tools/javac/lambda/LambdaExpr05.java + test/tools/javac/lambda/LambdaExprNotVoid.java + test/tools/javac/lambda/LambdaExprNotVoid.out + test/tools/javac/lambda/MethodReference11.java + test/tools/javac/lambda/TargetType13.java + test/tools/javac/lambda/TargetType13.out From mwisnicki at gmail.com Sun Aug 22 16:17:26 2010 From: mwisnicki at gmail.com (=?UTF-8?Q?Marcin_Wi=C5=9Bnicki?=) Date: Mon, 23 Aug 2010 01:17:26 +0200 Subject: reuse 'do' keyword instead of hash sign (#) Message-ID: Would it be possible to change the clumsy '#' operator to 'do' keyword ? I.e.: do()(5) do(){return 5;} do(int x, int y) { if (x>y) return x; else return y; } button.onClick(do(Event e) { println("button clicked"); }); I find it more readable, OTOH using special characters feels a bit like perl (noisy), especially when combining multiple lambdas. It event makes sense if you parse it as english. Don't know what to do with anonymous function type but it could remain as '#'. Pros: - more readable - makes sense - like '#' needs only 1-lookahead to disambiguate from do-while '(' vs '{' [1] - did I mention it's more readable ? Cons: - none (that I could think of) [1] Automatic Resource Management from Coins wanted to use 'do' but I see they have switched to 'try' so no problem there. PS. Please CC me since I'm not subscribed, thanks. From collin.fagan at gmail.com Mon Aug 23 11:31:55 2010 From: collin.fagan at gmail.com (Collin Fagan) Date: Mon, 23 Aug 2010 13:31:55 -0500 Subject: reuse 'do' keyword instead of hash sign (#) In-Reply-To: References: Message-ID: Welcome Marcin, It has been requested that syntax discussions be put to the side for the time being in favor of spending more time using the prototype and giving more targeted feedback to the developers (who seem to be working long hours and on weekends). The participants on the list are divided about a number of issues, syntax being just one. I assume at some point this restriction will be lifted but I'm not sure as I'm not an Oracle employee. Collin 2010/8/22 Marcin Wi?nicki > Would it be possible to change the clumsy '#' operator to 'do' keyword ? > I.e.: > > do()(5) > do(){return 5;} > do(int x, int y) { if (x>y) return x; else return y; } > button.onClick(do(Event e) { println("button clicked"); }); > > I find it more readable, OTOH using special characters feels a bit > like perl (noisy), especially when combining multiple lambdas. > It event makes sense if you parse it as english. > > Don't know what to do with anonymous function type but it could remain as > '#'. > > Pros: > - more readable > - makes sense > - like '#' needs only 1-lookahead to disambiguate from do-while '(' vs '{' > [1] > - did I mention it's more readable ? > > Cons: > - none (that I could think of) > > [1] Automatic Resource Management from Coins wanted to use 'do' but I > see they have switched to 'try' so no problem there. > > PS. Please CC me since I'm not subscribed, thanks. > > From david at walend.net Mon Aug 23 19:09:05 2010 From: david at walend.net (David Walend) Date: Mon, 23 Aug 2010 22:09:05 -0400 Subject: Public defender methods and static inner classes in interfaces? Message-ID: Some style questions: Will it be good taste or bad to include static inner classes inside interfaces to provide the default implementation of public defender methods? For example public interface Outer { public extension void method(Object parameter) default Inner.method; //more extension methods ... public static final class Inner { private Inner() {} public static void method(Outer outer,Object parameter) { //some code } //more implementations of extension methods ... } } Does using a static inner class this way run counter to the goal of keeping code out of interfaces (mentioned at then end of section 2 in the defender method spec)? What (if anything) is broken if almost all of the methods declared in Outer are implemented by Inner? Thanks, Dave From pbenedict at apache.org Tue Aug 24 01:02:26 2010 From: pbenedict at apache.org (Paul Benedict) Date: Tue, 24 Aug 2010 03:02:26 -0500 Subject: suppressedException semantics In-Reply-To: <4C734EB0.7070103@oracle.com> References: <4C734EB0.7070103@oracle.com> Message-ID: Interest David! I never considered that the original exception should be thrown, and then just collect the suppressed exceptions. That's very interesting. As you point out, there's a difference between root cause vs. suppression. Perhaps what you pointed out is just crazy enough to work. :) Paul On Mon, Aug 23, 2010 at 11:46 PM, David Holmes wrote: > I realize that I am late to the game here but reading Joe's latest ARM > proposal (and having looked into the issues with pre-allocated > exceptions) I find that the semantics of suppressed exceptions for > try-with-resources are actually the opposite to what I initially thought. > > Taking regular Java as it stands, given: > > try { > ? throw new A(); > } > finally { > ? throw new B(); > } > > the try-finally will always complete by throwing B and the fact that A > occurred has been lost. Exception B has suppressed exception A in this > case. So I thought that the addition of suppressedExceptions was a way > for B to indicate that it has suppressed A. This could be considered a > general language extension independent of try-with-resources: it is > simply a way for exceptions that would be lost to be "chained" to the > exception that replaced them. (And in such an extension I probably would > not make addSuppressedException a generally available API.) > > What try-with-resources proposes is actually suppressing B (when it > comes from an AutoCloseable) and propagating A. I find this somewhat > confusing, especially when the argument of whether to suppress only > Exception but not Error etc is taken into account. It is not apparent to > me why the exception from the try block is more important than the > exception from the finally block? As long as A can be found from B does > it matter which is actually thrown? I would suggest that the > try-with-resources code transformation would be a lot simpler if it did > not change the exception that would naturally be thrown from the finally > clause. It would also make it a moot point whether to distinguish Error > from Exception etc. > > I just can't help but think that this is more complex than it needs to > be. And at the same time that the "suppressed exception" mechanism is > not as generally useful as it could be. > > And yes I've just donned my flak-jacket ;-) > > Cheers, > David Holmes > > From howard.lovatt at gmail.com Tue Aug 24 01:07:12 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Tue, 24 Aug 2010 18:07:12 +1000 Subject: Push 23 August 1bb5b46bb326 fixes one bug, but introduces another Message-ID: Hi Maurizio, il.forEach( #( i ) { if ( i < 3 ) { throw new Exception(); } return i * i; } ); // Need to catch the checked exception! Now needs a try block (as it should), but il.forEach( #( i ) { return 2 * i; } ); // No exception, no try block Also needs one and it shouldn't! I for one really appreciate all your hard work on this. ? -- Howard. From thomas.andreas.jung at googlemail.com Tue Aug 24 01:08:21 2010 From: thomas.andreas.jung at googlemail.com (Thomas Jung) Date: Tue, 24 Aug 2010 10:08:21 +0200 Subject: Public defender methods and static inner classes in interfaces? In-Reply-To: References: Message-ID: There has already been some discussion about the syntax of the defender methods. Numerous responses were not in favour of the delegation syntax. Inline syntax and delegation syntax are mostly interchangeable except that the delegation syntax can resolve the case better that multiple default method definitions for the same method (from different interfaces) actually delegate to the same static method (this is not ambiguous). And yes, inline static classes (that are public to the consumer of library) won't keep the implementation code out of the interface and in this regard the syntax is not perfect. It will be quite common for new interfaces to have there default implementations as inner classes. I'd say it is the best place to put them as long as they are only used by this one interface. It would be nice if the visibility of the class could be private (not sure this is backward compatible). On 24 August 2010 04:09, David Walend wrote: > Some style questions: Will it be good taste or bad to include static > inner classes inside interfaces to provide the default implementation > of public defender methods? For example > > public interface Outer { > > ? ? public extension void method(Object parameter) > ? ? ? ?default Inner.method; > > ? ? //more extension methods > ... > > ? ? public static final class Inner { > > ? ? ? ? private Inner() {} > > ? ? ? ? public static void method(Outer outer,Object parameter) { > ? ? ? ? ? ? ? ?//some code > ? ? ? ? } > ? ? ? ? //more implementations of extension methods > ... > ? ? } > > } > > Does using a static inner class this way run counter to the goal of > keeping code out of interfaces (mentioned at then end of section 2 in > the defender method spec)? > > What (if anything) is broken if almost all of the methods declared in > Outer are implemented by Inner? > > Thanks, > > Dave > > > From howard.lovatt at gmail.com Tue Aug 24 01:24:08 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Tue, 24 Aug 2010 18:24:08 +1000 Subject: Push 23 August 1bb5b46bb326 fixes one bug, but introduces another In-Reply-To: References: Message-ID: Forgot to mention, bug in: il.forEach( #( i ) { 2 * i } ); // No exception; no try block - has syntax error Also fixed, but as before now has to be in try block On 24 August 2010 18:07, Howard Lovatt wrote: > Hi Maurizio, > > ? ? ?il.forEach( #( i ) { > ? ? ? ?if ( i < 3 ) { throw new Exception(); } > ? ? ? ?return i * i; > ? ? ?} ); // Need to catch the checked exception! > > Now needs a try block (as it should), but > > ? ?il.forEach( #( i ) { return 2 * i; } ); // No exception, no try block > > ?Also needs one and it shouldn't! > > I for one really appreciate all your hard work on this. > > ? -- Howard. > -- ? -- Howard. From maurizio.cimadamore at oracle.com Tue Aug 24 01:24:48 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Tue, 24 Aug 2010 09:24:48 +0100 Subject: Push 23 August 1bb5b46bb326 fixes one bug, but introduces another In-Reply-To: References: Message-ID: <4C7381D0.8000802@oracle.com> On 24/08/10 09:07, Howard Lovatt wrote: > Hi Maurizio, > > il.forEach( #( i ) { > if ( i< 3 ) { throw new Exception(); } > return i * i; > } ); // Need to catch the checked exception! > > Now needs a try block (as it should), but > > il.forEach( #( i ) { return 2 * i; } ); // No exception, no try block > > Also needs one and it shouldn't! > Strictly speaking, this is not a bug - it is a limitation of the current inference scheme that has been noticed elsewhere in this forum; unfortunately, when the body of the lambda expression has resolution (e.g. operator/method) depending on the type of the parameter to be inferred, javac cannot infer the thrown types from the lambda body; as such, thrown types are inferred from the target type - in this case, the target types throws E, whose bound is Exception - since no constraint is found (from the lambda), E is simply instantiated to Exception. However I understand that this is something that needs to be improved - it is showing up now because of the bug I fixed in the compiler (the compiler was assuming that no exception where thrown when inference gave up - which is potentially unsafe). Maurizio > I for one really appreciate all your hard work on this. > > -- Howard. > > From maurizio.cimadamore at oracle.com Tue Aug 24 01:25:58 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Tue, 24 Aug 2010 09:25:58 +0100 Subject: Push 23 August 1bb5b46bb326 fixes one bug, but introduces another In-Reply-To: References: Message-ID: <4C738216.3070206@oracle.com> On 24/08/10 09:24, Howard Lovatt wrote: > Forgot to mention, bug in: > > il.forEach( #( i ) { 2 * i } ); // No exception; no try block - > has syntax error > See earlier email. Same issue. Adding explicit type for 'i' does the trick. Maurizio > Also fixed, but as before now has to be in try block > > On 24 August 2010 18:07, Howard Lovatt wrote: > >> Hi Maurizio, >> >> il.forEach( #( i ) { >> if ( i< 3 ) { throw new Exception(); } >> return i * i; >> } ); // Need to catch the checked exception! >> >> Now needs a try block (as it should), but >> >> il.forEach( #( i ) { return 2 * i; } ); // No exception, no try block >> >> Also needs one and it shouldn't! >> >> I for one really appreciate all your hard work on this. >> >> -- Howard. >> >> > > > From reinier at zwitserloot.com Tue Aug 24 03:25:54 2010 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 24 Aug 2010 12:25:54 +0200 Subject: Public defender methods and static inner classes in interfaces? In-Reply-To: References: Message-ID: We've covered this on the mailing list before, perhaps you might want to look at the archives. The conclusion of some was that this pattern will be rather common, whether encouraged or not, and this has in fact been used as an argument to allow specifying the default implementation directly on an interface method, because this pattern has an ugly wart in it: The inner class must necessarily be public, and is thus visible (because all members of an interface are forced public). Making implementation details visible is bad API design. One suggestion I made was that 'private' now be allowed on classes inside interfaces, which would be backwards compatible (package private and protected remain illegal, and if no access level keyword is given, it'll be public, in order to remain backwards compatible. The JVM can already do this), though this idea does depend on whether or not an extension method has to be visible from the caller, which I'm guessing it has to be, in which case it can't be private. I can't recall any response to this idea, however. --Reinier Zwitserloot On Tue, Aug 24, 2010 at 4:09 AM, David Walend wrote: > Some style questions: Will it be good taste or bad to include static > inner classes inside interfaces to provide the default implementation > of public defender methods? For example > > public interface Outer { > > public extension void method(Object parameter) > default Inner.method; > > //more extension methods > ... > > public static final class Inner { > > private Inner() {} > > public static void method(Outer outer,Object parameter) { > //some code > } > //more implementations of extension methods > ... > } > > } > > Does using a static inner class this way run counter to the goal of > keeping code out of interfaces (mentioned at then end of section 2 in > the defender method spec)? > > What (if anything) is broken if almost all of the methods declared in > Outer are implemented by Inner? > > Thanks, > > Dave > > > From alex.buckley at oracle.com Tue Aug 24 11:57:56 2010 From: alex.buckley at oracle.com (Alex Buckley) Date: Tue, 24 Aug 2010 11:57:56 -0700 Subject: suppressedException semantics In-Reply-To: References: <4C734EB0.7070103@oracle.com> Message-ID: <4C741634.5000305@oracle.com> I think the mail below was intended for coin-dev, not lambda-dev. (Just to note that exceptions from the literal try-finally below aren't changed; what's new is suppression in the synthesized catch and finally blocks due to AutoCloseable variables.) Alex On 8/24/2010 1:02 AM, Paul Benedict wrote: > Interest David! I never considered that the original exception should > be thrown, and then just collect the suppressed exceptions. That's > very interesting. As you point out, there's a difference between root > cause vs. suppression. Perhaps what you pointed out is just crazy > enough to work. :) > > Paul > > On Mon, Aug 23, 2010 at 11:46 PM, David Holmes wrote: >> I realize that I am late to the game here but reading Joe's latest ARM >> proposal (and having looked into the issues with pre-allocated >> exceptions) I find that the semantics of suppressed exceptions for >> try-with-resources are actually the opposite to what I initially thought. >> >> Taking regular Java as it stands, given: >> >> try { >> throw new A(); >> } >> finally { >> throw new B(); >> } >> >> the try-finally will always complete by throwing B and the fact that A >> occurred has been lost. Exception B has suppressed exception A in this >> case. So I thought that the addition of suppressedExceptions was a way >> for B to indicate that it has suppressed A. This could be considered a >> general language extension independent of try-with-resources: it is >> simply a way for exceptions that would be lost to be "chained" to the >> exception that replaced them. (And in such an extension I probably would >> not make addSuppressedException a generally available API.) >> >> What try-with-resources proposes is actually suppressing B (when it >> comes from an AutoCloseable) and propagating A. I find this somewhat >> confusing, especially when the argument of whether to suppress only >> Exception but not Error etc is taken into account. It is not apparent to >> me why the exception from the try block is more important than the >> exception from the finally block? As long as A can be found from B does >> it matter which is actually thrown? I would suggest that the >> try-with-resources code transformation would be a lot simpler if it did >> not change the exception that would naturally be thrown from the finally >> clause. It would also make it a moot point whether to distinguish Error >> from Exception etc. >> >> I just can't help but think that this is more complex than it needs to >> be. And at the same time that the "suppressed exception" mechanism is >> not as generally useful as it could be. >> >> And yes I've just donned my flak-jacket ;-) >> >> Cheers, >> David Holmes >> >> > From howard.lovatt at gmail.com Tue Aug 24 20:07:37 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Wed, 25 Aug 2010 13:07:37 +1000 Subject: Push 23 August 1bb5b46bb326 MethodHandle equals bug Message-ID: Hi, I think I might have found another bug: final ActionListener al4 = Main#print( ActionEvent ); b1.addActionListener( al4 ); b1.doClick(); b1.removeActionListener( al4 ); Where print is: private static void print( final ActionEvent notUsed ) { out.println( "Main.print method called" ); } and b1 is a JButton. It gives: Main.print method called Exception in thread "main" java.lang.ClassCastException: required class java.awt.event.ActionEvent but encountered class $Proxy0 at sun.dyn.MethodHandleImpl.raiseException(MethodHandleImpl.java:1246) at sun.dyn.FromGeneric$A2.invoke_I2(FromGeneric.java:531) at java.dyn.MethodHandle.invokeVarargs(MethodHandle.java:328) at com.sun.runtime.ProxyHelper$1.invoke(ProxyHelper.java:57) at $Proxy0.equals(Unknown Source) at javax.swing.event.EventListenerList.remove(EventListenerList.java:224) at javax.swing.AbstractButton.removeActionListener(AbstractButton.java:1935) at lambdas.Main.lambdas(Main.java:84) at lambdas.Main.main(Main.java:20) Therefore the method reference is added OK, but can't be removed. Seems to be something to do with the equals method implemented by the MethodHandle. Sorry to keep finding bugs, ? -- Howard. From howard.lovatt at gmail.com Tue Aug 24 22:00:03 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Wed, 25 Aug 2010 15:00:03 +1000 Subject: Trouble inferring type of lambda In-Reply-To: References: <4C71622A.8040305@oracle.com> <4C724EE6.4000701@oracle.com> <4C72583B.2060803@oracle.com> <4C7262A0.8050905@oracle.com> Message-ID: Having tried: @Override public void forEach( final Method1 method ) throws E { for ( int i = 0; i < values.length; i++ ) { final Integer oldValue = values[ i ]; final R newValueTemp = method.call( oldValue ); if ( newValueTemp instanceof Integer ) { values[ i ] = (Integer) newValue; } else { throw new IllegalArgumentException(); } } } To overcome the problem that: list.forEach( #( i ) { throw new Exception() } ); Wouldn't normally work (because the lambda returns void and not Integer). The problem with the above forEach implementation is that the return type is unconstrained and hence effectively unchecked by the compiler and generates runtime exceptions. Therefore the best I have come up with is: list.forEach( #( i ) { if ( alwaysTrue() ) { throw new Exception(); } return 0; } ); Which I am not really satisfied with, is there better? Cheers, -- Howard. On 23 August 2010 22:49, Howard Lovatt wrote: > Thanks for the reply. > > Whilst this will work, it is hardly desirable. Effectively the return > type of all lambdas has to 'free' variable then writing a method that > uses them is awkward, e.g.: > > ?@Override public void forEach( final Method1 Integer, E> method ) throws E { > ? ?for ( int i = 0; i < values.length; i++ ) { > ? ? ?final Integer oldValue = values[ i ]; > ? ? ?final R newValueTemp = method.call( oldValue ); > ? ? ?if ( newValueTemp instanceof Integer ) { values[ i ] = (Integer) > newValue; } > ? ?} > ?} > > Not great! > > Cheers, > > ?-- Howard. > > On 23 August 2010 21:59, Maurizio Cimadamore > wrote: >> On 23/08/10 12:34, Howard Lovatt wrote: >>> >>> Thanks for the clarification, I think it *should* be a bug! >>> >>> In the meantime, what is the recommended idiom for writing such a >>> function. >>> >> >> You could try with: >> >> interface SortableList> extends List { >> >> void forEach( Method1 method ) throws E; >> >> } >> >> this should do. >> >> Maurizio >> >>> ?-- Howard. >>> >>> On 23 August 2010 21:15, Maurizio Cimadamore >>> ?wrote: >>> >>>> >>>> On 23/08/10 12:02, Howard Lovatt wrote: >>>> >>>> Hi Mauritzio, >>>> >>>> I think it is a bug, like I said in the original post the 'return >>>> type' is 'NeverReturns' not void, which should be assignable to >>>> anything (including Integer). Scala and BGGA handle this case, they >>>> both have a 'NeverReturns' type (Scala and BGGA Nothing). >>>> >>>> >>>> Let me clarify - it is not a bug, according to the current spec; quoting >>>> from the latest formal spec describing lambda conversion [1]: >>>> >>>> "A divergent lambda expression such as #(){throw new AssertionError();} >>>> has no return value, and its body completes abruptly by reason of a >>>> throw with an AssertionError object. For the purpose of calculating >>>> the type of the lambda expression, the body of the lambda expression >>>> is void." >>>> >>>> [1] - >>>> >>>> http://mail.openjdk.java.net/pipermail/lambda-dev/attachments/20100212/af8d2cc5/attachment-0001.txt >>>> >>>> Maurizio >>>> >>>> Cheers, >>>> >>>> ?-- Howard. >>>> >>>> On 23 August 2010 20:35, Maurizio Cimadamore >>>> ?wrote: >>>> >>>> >>>> This is not a bug. You are trying to SAM convert the following lambda: >>>> >>>> #(x) { throws Exception(); } >>>> >>>> into the following target method: >>>> >>>> ?Integer call( Integer a1 ) throws E >>>> >>>> This is not possible, since the lambda expression is inferred to yield >>>> 'void' (no return expression found), while the target method returns >>>> Integer. >>>> >>>> Maurizio >>>> >>>> >>>> >>>> On 22/08/10 18:45, maurizio cimadamore wrote: >>>> >>>> >>>> On 22/08/2010 07:09, Howard Lovatt wrote: >>>> >>>> >>>> >>>> For: >>>> >>>> ? ?public interface Method1 ? ? { public R call( A1 a1 ) >>>> throws E; } >>>> >>>> and: >>>> >>>> ? ?public ? ? void forEach( final Method1 >>>> method ) throws E { ... } >>>> >>>> The compiler has trouble with: >>>> >>>> ? ? il.forEach( #( i ) { throw new Exception(); } ); // Need to catch >>>> checked exception >>>> >>>> Giving: >>>> >>>> lambdas/Main.java:34: method forEach in class IntList11 cannot be >>>> applied to given types >>>> ? ? ? ?il.forEach( #( i ) { throw new Exception(); } ); // Need to >>>> catch checked exception >>>> ? ? ? ? ?^ >>>> ? ?required: Method1 >>>> ? ?found: #void(?)(Exception) >>>> ? ?where E is a type-variable: >>>> ? ? ?E extends Exception declared in method >>>> forEach(Method1) >>>> >>>> Qualifying doesn't help: >>>> >>>> ? ?Method1 ? ? #( i ) { throw new >>>> Exception(); >>>> } >>>> >>>> It gives: >>>> >>>> lambdas/Main.java:34: incompatible types; no instance(s) of type >>>> variable(s) ? exist so that #void(?)(Exception) conforms to >>>> Method1 >>>> ? ? ? ?il.forEach( Method1 ? ? #( i ) { >>>> throw >>>> new Exception(); } ); // Need to catch checked exception >>>> ? ? ? ? ? ? ? ? ? ?^ >>>> ? ?required: Method1 >>>> ? ?found: ? ?#void(?)(Exception) >>>> >>>> Is the problem that the return type isn't expressible? It isn't really >>>> void, it is 'NeverReturns'. >>>> >>>> >>>> >>>> >>>> Uhmm the problem here seems more related with a failure in inference of >>>> the lambda parameter (the '?' that you are seeing). Again it would be >>>> helpful to see the declaration of the receiver class as well as the type >>>> of 'il'. >>>> >>>> Maurizio >>>> >> >> > > > > -- > ? -- Howard. > -- ? -- Howard. From maurizio.cimadamore at oracle.com Wed Aug 25 01:08:21 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 25 Aug 2010 09:08:21 +0100 Subject: Trouble inferring type of lambda In-Reply-To: References: <4C71622A.8040305@oracle.com> <4C724EE6.4000701@oracle.com> <4C72583B.2060803@oracle.com> <4C7262A0.8050905@oracle.com> Message-ID: <4C74CF75.6010804@oracle.com> On 25/08/10 06:00, Howard Lovatt wrote: > Having tried: > > @Override public void forEach( final Method1 E> method ) throws E { > for ( int i = 0; i< values.length; i++ ) { > final Integer oldValue = values[ i ]; > final R newValueTemp = method.call( oldValue ); > if ( newValueTemp instanceof Integer ) { values[ i ] = (Integer) > newValue; } > else { throw new IllegalArgumentException(); } > } > } > > To overcome the problem that: > > list.forEach( #( i ) { throw new Exception() } ); > > Wouldn't normally work (because the lambda returns void and not > Integer). The problem with the above forEach implementation is that > the return type is unconstrained and hence effectively unchecked by > the compiler and generates runtime exceptions. > > Therefore the best I have come up with is: > > list.forEach( #( i ) { > if ( alwaysTrue() ) { throw new Exception(); } > return 0; > } ); > > Which I am not really satisfied with, is there better? > The only option would be to provide explicit type-parameters in the method call, as in: list.forEach(...); Maurizio > Cheers, > > -- Howard. > > > On 23 August 2010 22:49, Howard Lovatt wrote: > >> Thanks for the reply. >> >> Whilst this will work, it is hardly desirable. Effectively the return >> type of all lambdas has to 'free' variable then writing a method that >> uses them is awkward, e.g.: >> >> @Override public void forEach( final Method1> Integer, E> method ) throws E { >> for ( int i = 0; i< values.length; i++ ) { >> final Integer oldValue = values[ i ]; >> final R newValueTemp = method.call( oldValue ); >> if ( newValueTemp instanceof Integer ) { values[ i ] = (Integer) >> newValue; } >> } >> } >> >> Not great! >> >> Cheers, >> >> -- Howard. >> >> On 23 August 2010 21:59, Maurizio Cimadamore >> wrote: >> >>> On 23/08/10 12:34, Howard Lovatt wrote: >>> >>>> Thanks for the clarification, I think it *should* be a bug! >>>> >>>> In the meantime, what is the recommended idiom for writing such a >>>> function. >>>> >>>> >>> You could try with: >>> >>> interface SortableList> extends List { >>> >>> void forEach( Method1 method ) throws E; >>> >>> } >>> >>> this should do. >>> >>> Maurizio >>> >>> >>>> -- Howard. >>>> >>>> On 23 August 2010 21:15, Maurizio Cimadamore >>>> wrote: >>>> >>>> >>>>> On 23/08/10 12:02, Howard Lovatt wrote: >>>>> >>>>> Hi Mauritzio, >>>>> >>>>> I think it is a bug, like I said in the original post the 'return >>>>> type' is 'NeverReturns' not void, which should be assignable to >>>>> anything (including Integer). Scala and BGGA handle this case, they >>>>> both have a 'NeverReturns' type (Scala and BGGA Nothing). >>>>> >>>>> >>>>> Let me clarify - it is not a bug, according to the current spec; quoting >>>>> from the latest formal spec describing lambda conversion [1]: >>>>> >>>>> "A divergent lambda expression such as #(){throw new AssertionError();} >>>>> has no return value, and its body completes abruptly by reason of a >>>>> throw with an AssertionError object. For the purpose of calculating >>>>> the type of the lambda expression, the body of the lambda expression >>>>> is void." >>>>> >>>>> [1] - >>>>> >>>>> http://mail.openjdk.java.net/pipermail/lambda-dev/attachments/20100212/af8d2cc5/attachment-0001.txt >>>>> >>>>> Maurizio >>>>> >>>>> Cheers, >>>>> >>>>> -- Howard. >>>>> >>>>> On 23 August 2010 20:35, Maurizio Cimadamore >>>>> wrote: >>>>> >>>>> >>>>> This is not a bug. You are trying to SAM convert the following lambda: >>>>> >>>>> #(x) { throws Exception(); } >>>>> >>>>> into the following target method: >>>>> >>>>> Integer call( Integer a1 ) throws E >>>>> >>>>> This is not possible, since the lambda expression is inferred to yield >>>>> 'void' (no return expression found), while the target method returns >>>>> Integer. >>>>> >>>>> Maurizio >>>>> >>>>> >>>>> >>>>> On 22/08/10 18:45, maurizio cimadamore wrote: >>>>> >>>>> >>>>> On 22/08/2010 07:09, Howard Lovatt wrote: >>>>> >>>>> >>>>> >>>>> For: >>>>> >>>>> public interface Method1 { public R call( A1 a1 ) >>>>> throws E; } >>>>> >>>>> and: >>>>> >>>>> public void forEach( final Method1 >>>>> method ) throws E { ... } >>>>> >>>>> The compiler has trouble with: >>>>> >>>>> il.forEach( #( i ) { throw new Exception(); } ); // Need to catch >>>>> checked exception >>>>> >>>>> Giving: >>>>> >>>>> lambdas/Main.java:34: method forEach in class IntList11 cannot be >>>>> applied to given types >>>>> il.forEach( #( i ) { throw new Exception(); } ); // Need to >>>>> catch checked exception >>>>> ^ >>>>> required: Method1 >>>>> found: #void(?)(Exception) >>>>> where E is a type-variable: >>>>> E extends Exception declared in method >>>>> forEach(Method1) >>>>> >>>>> Qualifying doesn't help: >>>>> >>>>> Method1 #( i ) { throw new >>>>> Exception(); >>>>> } >>>>> >>>>> It gives: >>>>> >>>>> lambdas/Main.java:34: incompatible types; no instance(s) of type >>>>> variable(s) ? exist so that #void(?)(Exception) conforms to >>>>> Method1 >>>>> il.forEach( Method1 #( i ) { >>>>> throw >>>>> new Exception(); } ); // Need to catch checked exception >>>>> ^ >>>>> required: Method1 >>>>> found: #void(?)(Exception) >>>>> >>>>> Is the problem that the return type isn't expressible? It isn't really >>>>> void, it is 'NeverReturns'. >>>>> >>>>> >>>>> >>>>> >>>>> Uhmm the problem here seems more related with a failure in inference of >>>>> the lambda parameter (the '?' that you are seeing). Again it would be >>>>> helpful to see the declaration of the receiver class as well as the type >>>>> of 'il'. >>>>> >>>>> Maurizio >>>>> >>>>> >>> >>> >> >> >> -- >> -- Howard. >> >> > > > From forax at univ-mlv.fr Wed Aug 25 01:54:20 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Wed, 25 Aug 2010 10:54:20 +0200 Subject: Push 23 August 1bb5b46bb326 MethodHandle equals bug In-Reply-To: References: Message-ID: <4C74DA3C.6080601@univ-mlv.fr> Le 25/08/2010 05:07, Howard Lovatt a ?crit : > Hi, > > I think I might have found another bug: > > final ActionListener al4 = Main#print( ActionEvent ); > b1.addActionListener( al4 ); > b1.doClick(); > b1.removeActionListener( al4 ); > > Where print is: > > private static void print( final ActionEvent notUsed ) { > out.println( "Main.print method called" ); > } > > and b1 is a JButton. It gives: > > Main.print method called > Exception in thread "main" java.lang.ClassCastException: required > class java.awt.event.ActionEvent but encountered class $Proxy0 > at sun.dyn.MethodHandleImpl.raiseException(MethodHandleImpl.java:1246) > at sun.dyn.FromGeneric$A2.invoke_I2(FromGeneric.java:531) > at java.dyn.MethodHandle.invokeVarargs(MethodHandle.java:328) > at com.sun.runtime.ProxyHelper$1.invoke(ProxyHelper.java:57) > at $Proxy0.equals(Unknown Source) > at javax.swing.event.EventListenerList.remove(EventListenerList.java:224) > at javax.swing.AbstractButton.removeActionListener(AbstractButton.java:1935) > at lambdas.Main.lambdas(Main.java:84) > at lambdas.Main.main(Main.java:20) > > Therefore the method reference is added OK, but can't be removed. > Seems to be something to do with the equals method implemented by the > MethodHandle. > > Sorry to keep finding bugs, > > -- Howard. > It's a standard j.l.r.Proxy problem :) proxy1.equals(proxy2) is translated to proxy1.mh1.equals(proxy2) instead of proxy1.mh1.equals(proxy2.mh2). the usual solution is to not propagate a call to equals to the underlying proxee (here the method handle) and don't forget to also trap calls to hashCode(). R?mi From maurizio.cimadamore at oracle.com Wed Aug 25 02:02:08 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 25 Aug 2010 10:02:08 +0100 Subject: Push 23 August 1bb5b46bb326 MethodHandle equals bug In-Reply-To: <4C74DA3C.6080601@univ-mlv.fr> References: <4C74DA3C.6080601@univ-mlv.fr> Message-ID: <4C74DC10.9010307@oracle.com> On 25/08/10 09:54, R?mi Forax wrote: > Le 25/08/2010 05:07, Howard Lovatt a ?crit : > >> Hi, >> >> I think I might have found another bug: >> >> final ActionListener al4 = Main#print( ActionEvent ); >> b1.addActionListener( al4 ); >> b1.doClick(); >> b1.removeActionListener( al4 ); >> >> Where print is: >> >> private static void print( final ActionEvent notUsed ) { >> out.println( "Main.print method called" ); >> } >> >> and b1 is a JButton. It gives: >> >> Main.print method called >> Exception in thread "main" java.lang.ClassCastException: required >> class java.awt.event.ActionEvent but encountered class $Proxy0 >> at sun.dyn.MethodHandleImpl.raiseException(MethodHandleImpl.java:1246) >> at sun.dyn.FromGeneric$A2.invoke_I2(FromGeneric.java:531) >> at java.dyn.MethodHandle.invokeVarargs(MethodHandle.java:328) >> at com.sun.runtime.ProxyHelper$1.invoke(ProxyHelper.java:57) >> at $Proxy0.equals(Unknown Source) >> at javax.swing.event.EventListenerList.remove(EventListenerList.java:224) >> at javax.swing.AbstractButton.removeActionListener(AbstractButton.java:1935) >> at lambdas.Main.lambdas(Main.java:84) >> at lambdas.Main.main(Main.java:20) >> >> Therefore the method reference is added OK, but can't be removed. >> Seems to be something to do with the equals method implemented by the >> MethodHandle. >> >> Sorry to keep finding bugs, >> >> -- Howard. >> >> > It's a standard j.l.r.Proxy problem :) > > proxy1.equals(proxy2) is translated to > proxy1.mh1.equals(proxy2) instead of proxy1.mh1.equals(proxy2.mh2). > > the usual solution is to not propagate a call to equals to > the underlying proxee (here the method handle) > and don't forget to also trap calls to hashCode(). > > R?mi > > > Yeah - I'm working on a fix - all Object.XXX calls should indeed dispatched to the underlying method handle instance (current impl erroneously call the handle invoke() method instead). Maurizio From maurizio.cimadamore at oracle.com Wed Aug 25 02:35:59 2010 From: maurizio.cimadamore at oracle.com (maurizio.cimadamore at oracle.com) Date: Wed, 25 Aug 2010 09:35:59 +0000 Subject: hg: lambda/lambda/langtools: Object methods are not dispatched correctly by the ProxyHelper class. Message-ID: <20100825093601.A2F5D4741D@hg.openjdk.java.net> Changeset: d66149a0e03c Author: mcimadamore Date: 2010-08-25 10:34 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/d66149a0e03c Object methods are not dispatched correctly by the ProxyHelper class. ! src/share/classes/com/sun/runtime/ProxyHelper.java ! test/tools/javac/lambda/MethodReference11.java + test/tools/javac/lambda/MethodReference12.java From maurizio.cimadamore at oracle.com Wed Aug 25 03:10:42 2010 From: maurizio.cimadamore at oracle.com (maurizio.cimadamore at oracle.com) Date: Wed, 25 Aug 2010 10:10:42 +0000 Subject: hg: lambda/lambda/langtools: Object methods are not dispatched correctly by the ProxyHelper class (part two). Message-ID: <20100825101044.268444741F@hg.openjdk.java.net> Changeset: 5b1354e63ad9 Author: mcimadamore Date: 2010-08-25 11:09 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/5b1354e63ad9 Object methods are not dispatched correctly by the ProxyHelper class (part two). Added proper dispatching for overloaded versions of Object.wait and enhanced regression test support. ! src/share/classes/com/sun/runtime/ProxyHelper.java ! test/tools/javac/lambda/MethodReference12.java From maurizio.cimadamore at oracle.com Wed Aug 25 03:25:30 2010 From: maurizio.cimadamore at oracle.com (maurizio.cimadamore at oracle.com) Date: Wed, 25 Aug 2010 10:25:30 +0000 Subject: hg: lambda/lambda/langtools: Object methods are not dispatched correctly by the ProxyHelper class (part three - last I hope ; -)). Message-ID: <20100825102532.3339147421@hg.openjdk.java.net> Changeset: 0ea4e43f5fc4 Author: mcimadamore Date: 2010-08-25 11:24 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/0ea4e43f5fc4 Object methods are not dispatched correctly by the ProxyHelper class (part three - last I hope ;-)). Updated ProxyHelper impl to reflect java.lang.reflect.Proxy behavior: "An invocation of the hashCode, equals, or toString methods declared in java.lang.Object on a proxy instance will be encoded and dispatched to the invocation handler's invoke method in the same manner as interface method invocations are encoded and dispatched, as described above. The declaring class of the Method object passed to invoke will be java.lang.Object. Other public methods of a proxy instance inherited from java.lang.Object are not overridden by a proxy class, so invocations of those methods behave like they do for instances of java.lang.Object." Which means ProxyHelper should really only handle hashCode, equals and toString. ! src/share/classes/com/sun/runtime/ProxyHelper.java ! test/tools/javac/lambda/MethodReference12.java From thomas.andreas.jung at googlemail.com Wed Aug 25 05:01:02 2010 From: thomas.andreas.jung at googlemail.com (Thomas Jung) Date: Wed, 25 Aug 2010 14:01:02 +0200 Subject: Cannot implement abstract method with extension method Message-ID: Hi, given the extension method m in interface A and abstract method m in the abstract class B. The definition of the extension method A.m is not used to "implement" B.m in C. interface A{ extension boolean m(Object object) default As.m; } abstract class B { public abstract boolean m(Object object); } class C extends B implements A{} C is not abstract and does not override abstract method m(Object) in B class C extends B implements A{} Interfaces have the same problem: interface A{ extension boolean m(Object object) default As.m; } interface B { boolean m(Object object); } class C implements A, B{} C is not abstract and does not override abstract method m(Object) in B class C implements A, B{} Thomas From thomas.andreas.jung at googlemail.com Wed Aug 25 05:54:47 2010 From: thomas.andreas.jung at googlemail.com (Thomas Jung) Date: Wed, 25 Aug 2010 14:54:47 +0200 Subject: SAM conversion of abstracted methods from java.lang.Object Message-ID: Hi, the SAM type conversion for a type A that abstracts a method from java.lang.Object abstract class A{ @Override public abstract boolean equals(Object object); } A a = #(x){true}; does not compile with: invalid target type A for lambda conversion A a = #(x){true}; The analogous definition for a method that is not defined in java.lang.Object works. C c = #{"y"}; class B{ String x(){ return "x"; } } abstract class C extends B{ @Override abstract String x(); } Thomas From maurizio.cimadamore at oracle.com Wed Aug 25 06:10:38 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 25 Aug 2010 14:10:38 +0100 Subject: Cannot implement abstract method with extension method In-Reply-To: References: Message-ID: <4C75164E.9020800@oracle.com> On 25/08/10 13:01, Thomas Jung wrote: > Hi, > > given the extension method m in interface A and abstract method m in > the abstract class B. The definition of the extension method A.m is > not used to "implement" B.m in C. > > interface A{ > extension boolean m(Object object) default As.m; > } > > abstract class B { > public abstract boolean m(Object object); > } > > class C extends B implements A{} > Uhmm, it's not crystal clear as to whether this should work as you expect - Brian any ideas? > C is not abstract and does not override abstract method m(Object) in B > class C extends B implements A{} > > Interfaces have the same problem: > > interface A{ > extension boolean m(Object object) default As.m; > } > interface B { > boolean m(Object object); > } > > class C implements A, B{} > > C is not abstract and does not override abstract method m(Object) in B > class C implements A, B{} > I see. This looks more like a bug, but what about the following: interface A{ extension boolean m(Object object) default As.m; } interface B { extension boolean m(Object object) default Bs.m; } class C implements A, B{} Maurizio > Thomas > > From maurizio.cimadamore at oracle.com Wed Aug 25 06:12:21 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 25 Aug 2010 14:12:21 +0100 Subject: SAM conversion of abstracted methods from java.lang.Object In-Reply-To: References: Message-ID: <4C7516B5.3080008@oracle.com> On 25/08/10 13:54, Thomas Jung wrote: > Hi, > > the SAM type conversion for a type A that abstracts a method from > java.lang.Object > > abstract class A{ > @Override public abstract boolean equals(Object object); > } > Hi, the current definition of SAM conversion does not consider Object methods as possible targets for lambda conversion. Maurizio > A a = #(x){true}; > > does not compile with: > invalid target type A for lambda conversion > A a = #(x){true}; > > The analogous definition for a method that is not defined in > java.lang.Object works. > > C c = #{"y"}; > > class B{ > String x(){ return "x"; } > } > > abstract class C extends B{ > @Override abstract String x(); > } > > Thomas > > From thomas.andreas.jung at googlemail.com Wed Aug 25 06:47:11 2010 From: thomas.andreas.jung at googlemail.com (Thomas Jung) Date: Wed, 25 Aug 2010 15:47:11 +0200 Subject: Cannot implement abstract method with extension method In-Reply-To: <4C75164E.9020800@oracle.com> References: <4C75164E.9020800@oracle.com> Message-ID: > I see. This looks more like a bug, but what about the following: > > interface A{ > ? ? ? ?extension boolean m(Object object) default As.m; > } > interface B { > ? ? ? ?extension boolean m(Object object) default Bs.m; > } > > class C ?implements A, B{} That's clearly ambiguous. Thomas From thomas.andreas.jung at googlemail.com Wed Aug 25 07:25:22 2010 From: thomas.andreas.jung at googlemail.com (Thomas Jung) Date: Wed, 25 Aug 2010 16:25:22 +0200 Subject: SAM conversion of inlined lambda expression In-Reply-To: <4C5D96D1.7070409@oracle.com> References: <4C5D5CCA.5090506@univ-mlv.fr> <4C5D96D1.7070409@oracle.com> Message-ID: I've checked if the current prototype solves the problem and it does not: Function a = Functions.compose(#(x){ x * x }, #(x){ x / 3 }); operator * cannot be applied to Object,Object Functions.compose(#(x){ x * x }, #(x){ x / 3 }); It works with the explicit type: Function a = Functions.compose(#(Integer x){ x * x }, #(x){ x / 3 }); Thomas On 7 August 2010 19:24, maurizio cimadamore wrote: > On 07/08/2010 15:57, Thomas Jung wrote: >> >> Hi R?mi, >> >> you're right. Defining >> >> public static ?Function ?simpleCompose(Function ?g, >> Function ?f){ >> ? ? return Functions.compose(g,f); >> } >> Function ?c = simpleCompose(#(x){ "a" + x }, #(x){ x + "b" >> }); >> >> works. Is there is way to get some debugging information of the type >> inferencer? >> >> Thomas >> > > Hi > as Remi pointed out in an earlier email, there's a bug when the target > method of a SAM conversion has a wildcard in return type position. Wildcards > in argument types work w/o problems - a fix for this problem will be > available soon. > > Thanks > Maurizio >> >> On 7 August 2010 15:16, R?mi Forax ?wrote: >> >>> >>> ?Le 07/08/2010 09:58, Thomas Jung a ?crit : >>> >>>> >>>> Hi, >>>> >>>> I'm playing a bit with the prototype (i.e. I've not read the specs in >>>> full) and I'm puzzled after my second step. >>>> >>>> The initial code that uses Function >>>> >>>> (http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/base/Function.html) >>>> is: >>>> >>>> Function ? ?a = #(x){ "a" + x }; >>>> Function ? ?b = #(x){ x + "b" }; >>>> assertEquals("axb", Functions.compose(a, b).apply("x")); >>>> >>>> This works with type inference and does the conversion to the type >>>> Function. But if I inline the lambda expression it won't convert >>>> them. >>>> >>>> Function ? ?c = Functions. >>>> compose(#(String x){ "a" + x }, #(String x){ x + "b" }); >>>> >>>> I've added all type annotations to rule out that this is the problem. >>>> The error message is: >>>> "method compose in class Functions cannot be applied to given types". >>>> (Can I get more information here about the types/problem?) >>>> >>>> Is this not supported? >>>> >>>> Thomas >>>> >>>> >>> >>> This is a bug, the prototype have a problem to infer types >>> if there is a wilcard in the middle. >>> >>> by example, this doesn't compile: >>> Function ?b = #(x){ x + "b" }; >>> >>> So you can't use compose which is declared:|* >>> *| >>> >>> <../../../../com/google/common/base/Functions.html#compose%28com.google.common.base.Function,%20com.google.common.base.Function%29>Function >>> <../../../../com/google/common/base/Function.html> ?|compose >>> >>> <../../../../com/google/common/base/Functions.html#compose%28com.google.common.base.Function,%20com.google.common.base.Function%29>(Function >>> <../../../../com/google/common/base/Function.html> ?g, Function >>> <../../../../com/google/common/base/Function.html> ?f)| >>> >>> R?mi >>> >>> >>> >>> >>> >> >> > > From thomas.andreas.jung at googlemail.com Wed Aug 25 07:29:28 2010 From: thomas.andreas.jung at googlemail.com (Thomas Jung) Date: Wed, 25 Aug 2010 16:29:28 +0200 Subject: SAM conversion of inlined lambda expression In-Reply-To: References: <4C5D5CCA.5090506@univ-mlv.fr> <4C5D96D1.7070409@oracle.com> Message-ID: Well, actually it works. But only for types that do not need unboxing, I suppose, as: Functions.compose(#(x){ "a" + x }, #(x){ x + "b"}).apply("x") works. On 25 August 2010 16:25, Thomas Jung wrote: > I've checked if the current prototype solves the problem and it does not: > > Function a = Functions.compose(#(x){ x * x }, #(x){ x / 3 }); > > operator * cannot be applied to Object,Object > ? ? ? ? ? ? ? ?Functions.compose(#(x){ x * x }, #(x){ x / 3 }); > > It works with the explicit type: > Function a = Functions.compose(#(Integer x){ x * x > }, #(x){ x / 3 }); > > Thomas > > > On 7 August 2010 19:24, maurizio cimadamore > wrote: >> On 07/08/2010 15:57, Thomas Jung wrote: >>> >>> Hi R?mi, >>> >>> you're right. Defining >>> >>> public static ?Function ?simpleCompose(Function ?g, >>> Function ?f){ >>> ? ? return Functions.compose(g,f); >>> } >>> Function ?c = simpleCompose(#(x){ "a" + x }, #(x){ x + "b" >>> }); >>> >>> works. Is there is way to get some debugging information of the type >>> inferencer? >>> >>> Thomas >>> >> >> Hi >> as Remi pointed out in an earlier email, there's a bug when the target >> method of a SAM conversion has a wildcard in return type position. Wildcards >> in argument types work w/o problems - a fix for this problem will be >> available soon. >> >> Thanks >> Maurizio >>> >>> On 7 August 2010 15:16, R?mi Forax ?wrote: >>> >>>> >>>> ?Le 07/08/2010 09:58, Thomas Jung a ?crit : >>>> >>>>> >>>>> Hi, >>>>> >>>>> I'm playing a bit with the prototype (i.e. I've not read the specs in >>>>> full) and I'm puzzled after my second step. >>>>> >>>>> The initial code that uses Function >>>>> >>>>> (http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/base/Function.html) >>>>> is: >>>>> >>>>> Function ? ?a = #(x){ "a" + x }; >>>>> Function ? ?b = #(x){ x + "b" }; >>>>> assertEquals("axb", Functions.compose(a, b).apply("x")); >>>>> >>>>> This works with type inference and does the conversion to the type >>>>> Function. But if I inline the lambda expression it won't convert >>>>> them. >>>>> >>>>> Function ? ?c = Functions. >>>>> compose(#(String x){ "a" + x }, #(String x){ x + "b" }); >>>>> >>>>> I've added all type annotations to rule out that this is the problem. >>>>> The error message is: >>>>> "method compose in class Functions cannot be applied to given types". >>>>> (Can I get more information here about the types/problem?) >>>>> >>>>> Is this not supported? >>>>> >>>>> Thomas >>>>> >>>>> >>>> >>>> This is a bug, the prototype have a problem to infer types >>>> if there is a wilcard in the middle. >>>> >>>> by example, this doesn't compile: >>>> Function ?b = #(x){ x + "b" }; >>>> >>>> So you can't use compose which is declared:|* >>>> *| >>>> >>>> <../../../../com/google/common/base/Functions.html#compose%28com.google.common.base.Function,%20com.google.common.base.Function%29>Function >>>> <../../../../com/google/common/base/Function.html> ?|compose >>>> >>>> <../../../../com/google/common/base/Functions.html#compose%28com.google.common.base.Function,%20com.google.common.base.Function%29>(Function >>>> <../../../../com/google/common/base/Function.html> ?g, Function >>>> <../../../../com/google/common/base/Function.html> ?f)| >>>> >>>> R?mi >>>> >>>> >>>> >>>> >>>> >>> >>> >> >> > From maurizio.cimadamore at oracle.com Wed Aug 25 07:50:32 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 25 Aug 2010 15:50:32 +0100 Subject: SAM conversion of inlined lambda expression In-Reply-To: References: <4C5D5CCA.5090506@univ-mlv.fr> <4C5D96D1.7070409@oracle.com> Message-ID: <4C752DB8.8070707@oracle.com> On 25/08/10 15:29, Thomas Jung wrote: > Well, actually it works. But only for types that do not need unboxing, > I suppose, as: > > Functions.compose(#(x){ "a" + x }, #(x){ x + "b"}).apply("x") > The problem is that the type-variable 'B' of Functions.compose is inferred to be 'Object' and not 'Integer' as you expect. As such, the expression 'x * x' (where x has type Object) is erroneous. On the other hand, if you use '+' for appending strings, an Object argument is perfectly fine. Note also that the 'B' type-variable is under-constrained, given that the return type of the second lambda expression in the call to 'compose' cannot be inferred from the lambda body (as it contains an expression like 'x/3' which has no meaning without a proper type for 'x'); moreover, since the called method is generic, the target type doesn't help much in inferring an useful type for the lambda return type. Maurizio > works. > > On 25 August 2010 16:25, Thomas Jung wrote: > >> I've checked if the current prototype solves the problem and it does not: >> >> Function a = Functions.compose(#(x){ x * x }, #(x){ x / 3 }); >> >> operator * cannot be applied to Object,Object >> Functions.compose(#(x){ x * x }, #(x){ x / 3 }); >> >> It works with the explicit type: >> Function a = Functions.compose(#(Integer x){ x * x >> }, #(x){ x / 3 }); >> >> Thomas >> >> >> On 7 August 2010 19:24, maurizio cimadamore >> wrote: >> >>> On 07/08/2010 15:57, Thomas Jung wrote: >>> >>>> Hi R?mi, >>>> >>>> you're right. Defining >>>> >>>> public static Function simpleCompose(Function g, >>>> Function f){ >>>> return Functions.compose(g,f); >>>> } >>>> Function c = simpleCompose(#(x){ "a" + x }, #(x){ x + "b" >>>> }); >>>> >>>> works. Is there is way to get some debugging information of the type >>>> inferencer? >>>> >>>> Thomas >>>> >>>> >>> Hi >>> as Remi pointed out in an earlier email, there's a bug when the target >>> method of a SAM conversion has a wildcard in return type position. Wildcards >>> in argument types work w/o problems - a fix for this problem will be >>> available soon. >>> >>> Thanks >>> Maurizio >>> >>>> On 7 August 2010 15:16, R?mi Forax wrote: >>>> >>>> >>>>> Le 07/08/2010 09:58, Thomas Jung a ?crit : >>>>> >>>>> >>>>>> Hi, >>>>>> >>>>>> I'm playing a bit with the prototype (i.e. I've not read the specs in >>>>>> full) and I'm puzzled after my second step. >>>>>> >>>>>> The initial code that uses Function >>>>>> >>>>>> (http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/base/Function.html) >>>>>> is: >>>>>> >>>>>> Function a = #(x){ "a" + x }; >>>>>> Function b = #(x){ x + "b" }; >>>>>> assertEquals("axb", Functions.compose(a, b).apply("x")); >>>>>> >>>>>> This works with type inference and does the conversion to the type >>>>>> Function. But if I inline the lambda expression it won't convert >>>>>> them. >>>>>> >>>>>> Function c = Functions. >>>>>> compose(#(String x){ "a" + x }, #(String x){ x + "b" }); >>>>>> >>>>>> I've added all type annotations to rule out that this is the problem. >>>>>> The error message is: >>>>>> "method compose in class Functions cannot be applied to given types". >>>>>> (Can I get more information here about the types/problem?) >>>>>> >>>>>> Is this not supported? >>>>>> >>>>>> Thomas >>>>>> >>>>>> >>>>>> >>>>> This is a bug, the prototype have a problem to infer types >>>>> if there is a wilcard in the middle. >>>>> >>>>> by example, this doesn't compile: >>>>> Function b = #(x){ x + "b" }; >>>>> >>>>> So you can't use compose which is declared:|* >>>>> *| >>>>> >>>>> <../../../../com/google/common/base/Functions.html#compose%28com.google.common.base.Function,%20com.google.common.base.Function%29>Function >>>>> <../../../../com/google/common/base/Function.html> |compose >>>>> >>>>> <../../../../com/google/common/base/Functions.html#compose%28com.google.common.base.Function,%20com.google.common.base.Function%29>(Function >>>>> <../../../../com/google/common/base/Function.html> g, Function >>>>> <../../../../com/google/common/base/Function.html> f)| >>>>> >>>>> R?mi >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>> >>>> >>> >>> >> From alex.buckley at oracle.com Wed Aug 25 16:43:10 2010 From: alex.buckley at oracle.com (Alex Buckley) Date: Wed, 25 Aug 2010 16:43:10 -0700 Subject: SAM conversion of abstracted methods from java.lang.Object In-Reply-To: <4C7516B5.3080008@oracle.com> References: <4C7516B5.3080008@oracle.com> Message-ID: <4C75AA8E.60209@oracle.com> On 8/25/2010 6:12 AM, Maurizio Cimadamore wrote: > the current definition of SAM conversion does not consider Object > methods as possible targets for lambda conversion. True. The current definition allows multiple abstract methods such that any non-Object methods are basically the same (this was to admit Comparator as SAM); but it doesn't require there to be an abstract _non-Object_ method in the first place (this matters for interfaces), and it discriminates against Object methods later (this matters for classes). So let's start from the beginning. Here is how things should be: abstract class Foo {} // Not a SAM type; not enough abstract methods interface Foo {} // Not a SAM type; no discernable abstract method abstract class Foo { public abstract boolean equals(Object object); } // SAM type; Foo has one abstract method abstract class Bar extends Foo { public abstract String toString(); } // Not a SAM type; too many abstract methods abstract class Quux { public abstract boolean equals(Object object); public abstract String toString(); } // Not a SAM type; too many abstract methods interface Foo { boolean equals(Object obj); } // Not a SAM type; too many abstract methods interface Bar extends Foo { int compare(T o1, T o2); } // SAM type; Bar has one abstract non-Object method interface Comparator { boolean equals(Object obj); int compare(T o1, T o2); } // SAM type; Comparator has one abstract non-Object method The definition becomes: -- A SAM (Single Abstract Method) type is an interface type or a top-level or member class type, that has zero generic abstract methods, and: - if a class type, the class is declared abstract, has a no-args constructor, and has exactly one non-generic abstract method; - if an interface type, the interface has one or more non-generic abstract methods M1..Mn (n>=1) that are not override-equivalent to any method in java.lang.Object; furthermore, if Mi is not override-equivalent to any method in java.lang.Object and Mj is not override-equivalent to any method in java.lang.Object, either i==j or the signatures of Mi and Mj are override-equivalent. In the type T obtained from applying capture conversion to the SAM type, let M be the set of abstract methods in T if T is a class type; otherwise, if T is an interface type, let M be the set of abstract methods in T that are not override-equivalent to any method in java.lang.Object. -- Alex From forax at univ-mlv.fr Wed Aug 25 17:32:48 2010 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Thu, 26 Aug 2010 02:32:48 +0200 Subject: SAM conversion of abstracted methods from java.lang.Object In-Reply-To: <4C75AA8E.60209@oracle.com> References: <4C7516B5.3080008@oracle.com> <4C75AA8E.60209@oracle.com> Message-ID: <4C75B630.605@univ-mlv.fr> Le 26/08/2010 01:43, Alex Buckley a ?crit : > On 8/25/2010 6:12 AM, Maurizio Cimadamore wrote: > >> the current definition of SAM conversion does not consider Object >> methods as possible targets for lambda conversion. >> > True. The current definition allows multiple abstract methods such that > any non-Object methods are basically the same (this was to admit > Comparator as SAM); but it doesn't require there to be an abstract > _non-Object_ method in the first place (this matters for interfaces), > and it discriminates against Object methods later (this matters for > classes). > > So let's start from the beginning. Here is how things should be: > > abstract class Foo {} // Not a SAM type; not enough abstract methods > interface Foo {} // Not a SAM type; no discernable abstract method > > abstract class Foo { public abstract boolean equals(Object object); } > // SAM type; Foo has one abstract method > > abstract class Bar extends Foo { public abstract String toString(); } > // Not a SAM type; too many abstract methods > > abstract class Quux { > public abstract boolean equals(Object object); > public abstract String toString(); > } > // Not a SAM type; too many abstract methods > > interface Foo { boolean equals(Object obj); } > // Not a SAM type; too many abstract methods > > interface Bar extends Foo { int compare(T o1, T o2); } > // SAM type; Bar has one abstract non-Object method > > interface Comparator { > boolean equals(Object obj); > int compare(T o1, T o2); > } > // SAM type; Comparator has one abstract non-Object method > > The definition becomes: > > -- > A SAM (Single Abstract Method) type is an interface type or a > top-level or member class type, that has zero generic abstract > methods, and: > > - if a class type, the class is declared abstract, has a no-args > constructor, and has exactly one non-generic abstract method; > > - if an interface type, the interface has one or more non-generic > abstract methods M1..Mn (n>=1) that are not override-equivalent to > any method in java.lang.Object; furthermore, if Mi is not > override-equivalent to any method in java.lang.Object and Mj is not > override-equivalent to any method in java.lang.Object, either i==j > or the signatures of Mi and Mj are override-equivalent. > > In the type T obtained from applying capture conversion to the SAM > type, let M be the set of abstract methods in T if T is a class type; > otherwise, if T is an interface type, let M be the set of abstract > methods in T that are not override-equivalent to any method in > java.lang.Object. > -- > > Alex > Alex, So K is not a SAM but K2 is a SAM ? interface I { I m(); } interface J { J m(); } interface K extends I, J { } interface K2 extends I, J { K2 m(); } This seems Ok. But with your definition class A is not a SAM. abstract class A implements I { public abstract A m(); } Here, I don't understand why ? R?mi From alex.buckley at oracle.com Wed Aug 25 17:59:27 2010 From: alex.buckley at oracle.com (Alex Buckley) Date: Wed, 25 Aug 2010 17:59:27 -0700 Subject: SAM conversion of abstracted methods from java.lang.Object In-Reply-To: <4C75B630.605@univ-mlv.fr> References: <4C7516B5.3080008@oracle.com> <4C75AA8E.60209@oracle.com> <4C75B630.605@univ-mlv.fr> Message-ID: <4C75BC6F.60103@oracle.com> On 8/25/2010 5:32 PM, R?mi Forax wrote: > So K is not a SAM but K2 is a SAM ? > interface I { I m(); } > interface J { J m(); } > interface K extends I, J { } > interface K2 extends I, J { K2 m(); } > This seems Ok. K is illegal since it inherits two override-equivalent methods (I.m and J.m) but neither is return-type-substitutable for the other. K2 is fine, and is a SAM. > But with your definition class A is not a SAM. > abstract class A implements I { > public abstract A m(); > } > Here, I don't understand why ? A.m overrides I.m, and happily A.m is return-type-substitutable for I.m, so there is exactly one non-generic abstract method in A. If A had a no-args constructor, it would be a SAM type. Alex From howard.lovatt at gmail.com Wed Aug 25 23:46:43 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Thu, 26 Aug 2010 16:46:43 +1000 Subject: Trouble inferring type of lambda In-Reply-To: <4C74CF75.6010804@oracle.com> References: <4C71622A.8040305@oracle.com> <4C724EE6.4000701@oracle.com> <4C72583B.2060803@oracle.com> <4C7262A0.8050905@oracle.com> <4C74CF75.6010804@oracle.com> Message-ID: Hi Maurizio, Not sure if the compiler should cope but the current one doesn't: il.forEach( #( i ) { throw new Exception(); } ); // Need to catch the checked exception! Gives: lambdas/Main.java:163: method forEach in class IntList11 cannot be applied to given types il.forEach( #( i ) { throw new Exception(); } ); // Need to catch the checked exception! ^ required: Method1 found: #void(?)(Exception) where E is a type-variable: E extends Exception declared in method forEach(Method1) 1 error And: il.forEach( Method1 #( i ) { throw new Exception(); } ); // Need to catch the checked exception! Gives: lambdas/Main.java:163: incompatible types; no instance(s) of type variable(s) ? exist so that #void(?)(Exception) conforms to Method1 il.forEach( Method1 #( i ) { throw new Exception(); } ); // Need to catch the checked exception! ^ required: Method1 found: #void(?)(Exception) 1 error So are these compiler bugs or is some other form of qualification possible. Cheers, -- Howard. On 25 August 2010 18:08, Maurizio Cimadamore wrote: > On 25/08/10 06:00, Howard Lovatt wrote: >> >> Having tried: >> >> @Override public ?void forEach( final Method1> E> ?method ) throws E { >> ? ?for ( int i = 0; i< ?values.length; i++ ) { >> ? ? ?final Integer oldValue = values[ i ]; >> ? ? ?final R newValueTemp = method.call( oldValue ); >> ? ? ?if ( newValueTemp instanceof Integer ) { values[ i ] = (Integer) >> newValue; } >> ? ? ?else { throw new IllegalArgumentException(); } >> ? ?} >> ?} >> >> To overcome the problem that: >> >> ? list.forEach( #( i ) { throw new Exception() } ); >> >> Wouldn't normally work (because the lambda returns void and not >> Integer). The problem with the above forEach implementation is that >> the return type is unconstrained and hence effectively unchecked by >> the compiler and generates runtime exceptions. >> >> Therefore the best I have come up with is: >> >> ? list.forEach( #( i ) { >> ? ? if ( alwaysTrue() ) { throw new Exception(); } >> ? ? return 0; >> ? } ); >> >> Which I am not really satisfied with, is there better? >> > > The only option would be to provide explicit type-parameters in the method > call, as in: > > list.forEach(...); > > Maurizio > > > >> Cheers, >> >> ?-- Howard. >> >> >> On 23 August 2010 22:49, Howard Lovatt ?wrote: >> >>> >>> Thanks for the reply. >>> >>> Whilst this will work, it is hardly desirable. Effectively the return >>> type of all lambdas has to 'free' variable then writing a method that >>> uses them is awkward, e.g.: >>> >>> ?@Override public ?void forEach( final Method1>> Integer, E> ?method ) throws E { >>> ? ?for ( int i = 0; i< ?values.length; i++ ) { >>> ? ? ?final Integer oldValue = values[ i ]; >>> ? ? ?final R newValueTemp = method.call( oldValue ); >>> ? ? ?if ( newValueTemp instanceof Integer ) { values[ i ] = (Integer) >>> newValue; } >>> ? ?} >>> ?} >>> >>> Not great! >>> >>> Cheers, >>> >>> ?-- Howard. >>> >>> On 23 August 2010 21:59, Maurizio Cimadamore >>> ?wrote: >>> >>>> >>>> On 23/08/10 12:34, Howard Lovatt wrote: >>>> >>>>> >>>>> Thanks for the clarification, I think it *should* be a bug! >>>>> >>>>> In the meantime, what is the recommended idiom for writing such a >>>>> function. >>>>> >>>>> >>>> >>>> You could try with: >>>> >>>> interface SortableList> ?extends List >>>> ?{ >>>> >>>> ?void forEach( Method1 ?method ) throws E; >>>> >>>> } >>>> >>>> this should do. >>>> >>>> Maurizio >>>> >>>> >>>>> >>>>> ?-- Howard. >>>>> >>>>> On 23 August 2010 21:15, Maurizio Cimadamore >>>>> ? ?wrote: >>>>> >>>>> >>>>>> >>>>>> On 23/08/10 12:02, Howard Lovatt wrote: >>>>>> >>>>>> Hi Mauritzio, >>>>>> >>>>>> I think it is a bug, like I said in the original post the 'return >>>>>> type' is 'NeverReturns' not void, which should be assignable to >>>>>> anything (including Integer). Scala and BGGA handle this case, they >>>>>> both have a 'NeverReturns' type (Scala and BGGA Nothing). >>>>>> >>>>>> >>>>>> Let me clarify - it is not a bug, according to the current spec; >>>>>> quoting >>>>>> from the latest formal spec describing lambda conversion [1]: >>>>>> >>>>>> "A divergent lambda expression such as #(){throw new >>>>>> AssertionError();} >>>>>> has no return value, and its body completes abruptly by reason of a >>>>>> throw with an AssertionError object. For the purpose of calculating >>>>>> the type of the lambda expression, the body of the lambda expression >>>>>> is void." >>>>>> >>>>>> [1] - >>>>>> >>>>>> >>>>>> http://mail.openjdk.java.net/pipermail/lambda-dev/attachments/20100212/af8d2cc5/attachment-0001.txt >>>>>> >>>>>> Maurizio >>>>>> >>>>>> Cheers, >>>>>> >>>>>> ?-- Howard. >>>>>> >>>>>> On 23 August 2010 20:35, Maurizio Cimadamore >>>>>> ? ?wrote: >>>>>> >>>>>> >>>>>> This is not a bug. You are trying to SAM convert the following lambda: >>>>>> >>>>>> #(x) { throws Exception(); } >>>>>> >>>>>> into the following target method: >>>>>> >>>>>> ? ?Integer call( Integer a1 ) throws E >>>>>> >>>>>> This is not possible, since the lambda expression is inferred to yield >>>>>> 'void' (no return expression found), while the target method returns >>>>>> Integer. >>>>>> >>>>>> Maurizio >>>>>> >>>>>> >>>>>> >>>>>> On 22/08/10 18:45, maurizio cimadamore wrote: >>>>>> >>>>>> >>>>>> On 22/08/2010 07:09, Howard Lovatt wrote: >>>>>> >>>>>> >>>>>> >>>>>> For: >>>>>> >>>>>> ? ?public interface Method1 ? ? ? { public R call( A1 >>>>>> a1 ) >>>>>> throws E; } >>>>>> >>>>>> and: >>>>>> >>>>>> ? ?public ? ? ? void forEach( final Method1>>>>> Integer, E> >>>>>> method ) throws E { ... } >>>>>> >>>>>> The compiler has trouble with: >>>>>> >>>>>> ? ? il.forEach( #( i ) { throw new Exception(); } ); // Need to catch >>>>>> checked exception >>>>>> >>>>>> Giving: >>>>>> >>>>>> lambdas/Main.java:34: method forEach in class IntList11 cannot be >>>>>> applied to given types >>>>>> ? ? ? ?il.forEach( #( i ) { throw new Exception(); } ); // Need to >>>>>> catch checked exception >>>>>> ? ? ? ? ?^ >>>>>> ? ?required: Method1 >>>>>> ? ?found: #void(?)(Exception) >>>>>> ? ?where E is a type-variable: >>>>>> ? ? ?E extends Exception declared in method >>>>>> forEach(Method1) >>>>>> >>>>>> Qualifying doesn't help: >>>>>> >>>>>> ? ?Method1 ? ? ? #( i ) { throw new >>>>>> Exception(); >>>>>> } >>>>>> >>>>>> It gives: >>>>>> >>>>>> lambdas/Main.java:34: incompatible types; no instance(s) of type >>>>>> variable(s) ? exist so that #void(?)(Exception) conforms to >>>>>> Method1 >>>>>> ? ? ? ?il.forEach( Method1 ? ? ? #( i ) { >>>>>> throw >>>>>> new Exception(); } ); // Need to catch checked exception >>>>>> ? ? ? ? ? ? ? ? ? ?^ >>>>>> ? ?required: Method1 >>>>>> ? ?found: ? ?#void(?)(Exception) >>>>>> >>>>>> Is the problem that the return type isn't expressible? It isn't really >>>>>> void, it is 'NeverReturns'. >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> Uhmm the problem here seems more related with a failure in inference >>>>>> of >>>>>> the lambda parameter (the '?' that you are seeing). Again it would be >>>>>> helpful to see the declaration of the receiver class as well as the >>>>>> type >>>>>> of 'il'. >>>>>> >>>>>> Maurizio >>>>>> >>>>>> >>>> >>>> >>> >>> >>> -- >>> ? -- Howard. >>> >>> >> >> >> > > -- ? -- Howard. From howard.lovatt at gmail.com Thu Aug 26 00:00:26 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Thu, 26 Aug 2010 17:00:26 +1000 Subject: hg: lambda/lambda/langtools: Object methods are not dispatched correctly by the ProxyHelper class (part three - last I hope ; -)). Message-ID: @Maurizio, I can't compile the latest push. build-bootstrap-javac: [javac] Compiling 1 source file to /Users/lov080/Dropbox/Personal/Java/JDK7/langtools/build/bootstrap/classes [javac] /Users/lov080/Dropbox/Personal/Java/JDK7/langtools/src/share/classes/com/sun/runtime/ProxyHelper.java:66: strings in switch are not supported in -source 1.6 [javac] switch(method.getName()) { [javac] ^ [javac] (use -source 7 or higher to enable strings in switch) [javac] 1 error BUILD FAILED /Users/lov080/Dropbox/Personal/Java/JDK7/langtools/make/build.xml:412: The following error occurred while executing this line: /Users/lov080/Dropbox/Personal/Java/JDK7/langtools/make/build.xml:775: Compile failed; see the compiler error output for details. Cheers, ? -- Howard. From maurizio.cimadamore at oracle.com Thu Aug 26 01:05:41 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 26 Aug 2010 09:05:41 +0100 Subject: hg: lambda/lambda/langtools: Object methods are not dispatched correctly by the ProxyHelper class (part three - last I hope ; -)). In-Reply-To: References: Message-ID: <4C762055.5030007@oracle.com> On 26/08/10 08:00, Howard Lovatt wrote: > @Maurizio, > > I can't compile the latest push. > > build-bootstrap-javac: > [javac] Compiling 1 source file to > /Users/lov080/Dropbox/Personal/Java/JDK7/langtools/build/bootstrap/classes > [javac] /Users/lov080/Dropbox/Personal/Java/JDK7/langtools/src/share/classes/com/sun/runtime/ProxyHelper.java:66: > strings in switch are not supported in -source 1.6 > [javac] switch(method.getName()) { > [javac] ^ > [javac] (use -source 7 or higher to enable strings in switch) > [javac] 1 error > This is a bit weird - of course I can update the code in no time so that it compiles against JDK 6, however the compiler build is supposed to compile that bit against the target JDK which is supposed to be a JDK 7 repo... what are the env variables you are passing to ant? Thanks Maurizio > BUILD FAILED > /Users/lov080/Dropbox/Personal/Java/JDK7/langtools/make/build.xml:412: > The following error occurred while executing this line: > /Users/lov080/Dropbox/Personal/Java/JDK7/langtools/make/build.xml:775: > Compile failed; see the compiler error output for details. > > > > Cheers, > > -- Howard. > From maurizio.cimadamore at oracle.com Thu Aug 26 01:18:15 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 26 Aug 2010 09:18:15 +0100 Subject: Trouble inferring type of lambda In-Reply-To: References: <4C71622A.8040305@oracle.com> <4C724EE6.4000701@oracle.com> <4C72583B.2060803@oracle.com> <4C7262A0.8050905@oracle.com> <4C74CF75.6010804@oracle.com> Message-ID: <4C762347.5030108@oracle.com> On 26/08/10 07:46, Howard Lovatt wrote: > Hi Maurizio, > > Not sure if the compiler should cope but the current one doesn't: > > il.forEach( #( i ) { throw new Exception(); } ); // > Need to catch the checked exception! > Hi Howard, this is similar to another example we discussed - the inferred return type is 'void' and, since return type and argument type should match (same type-variable in forEach() signature) inference fails here. However I noticed that there's a glitch - from your error message I have inferred that maybe you are compiling against this signature of forEach (again, please post full source, or at least all relevant bits): void forEach( Method1 method ) throws E; In that case, the compiler should reject a call such as: il.forEach( #( i ) { throw new Exception(); } ); //Need to catch the checked exception! because there are not enough explicit type-parameters in the method call - I guess that a nil-ary type-parameter is being detected here, but an explicit 'void' should be used for that one. That's what's causing the compiler to fail. If you remove the explicit type as in: il.forEach( #( i ) { throw new Exception(); } ); //Need to catch the checked exception! The program compiles fine. Maurizio > Gives: > > lambdas/Main.java:163: method forEach in class IntList11 cannot be > applied to given types > il.forEach( #( i ) { throw new Exception(); } ); // > Need to catch the checked exception! > ^ > required: Method1 > found: #void(?)(Exception) > where E is a type-variable: > E extends Exception declared in method > forEach(Method1) > 1 error > > And: > > il.forEach( Method1 #( i ) { throw > new Exception(); } ); // Need to catch the checked exception! > > Gives: > > lambdas/Main.java:163: incompatible types; no instance(s) of type > variable(s) ? exist so that #void(?)(Exception) conforms to > Method1 > il.forEach( Method1 #( i ) { throw > new Exception(); } ); // Need to catch the checked exception! > ^ > required: Method1 > found: #void(?)(Exception) > 1 error > > So are these compiler bugs or is some other form of qualification possible. > > Cheers, > > -- Howard. > > On 25 August 2010 18:08, Maurizio Cimadamore > wrote: > >> On 25/08/10 06:00, Howard Lovatt wrote: >> >>> Having tried: >>> >>> @Override public void forEach( final Method1>> E> method ) throws E { >>> for ( int i = 0; i< values.length; i++ ) { >>> final Integer oldValue = values[ i ]; >>> final R newValueTemp = method.call( oldValue ); >>> if ( newValueTemp instanceof Integer ) { values[ i ] = (Integer) >>> newValue; } >>> else { throw new IllegalArgumentException(); } >>> } >>> } >>> >>> To overcome the problem that: >>> >>> list.forEach( #( i ) { throw new Exception() } ); >>> >>> Wouldn't normally work (because the lambda returns void and not >>> Integer). The problem with the above forEach implementation is that >>> the return type is unconstrained and hence effectively unchecked by >>> the compiler and generates runtime exceptions. >>> >>> Therefore the best I have come up with is: >>> >>> list.forEach( #( i ) { >>> if ( alwaysTrue() ) { throw new Exception(); } >>> return 0; >>> } ); >>> >>> Which I am not really satisfied with, is there better? >>> >>> >> The only option would be to provide explicit type-parameters in the method >> call, as in: >> >> list.forEach(...); >> >> Maurizio >> >> >> >> >>> Cheers, >>> >>> -- Howard. >>> >>> >>> On 23 August 2010 22:49, Howard Lovatt wrote: >>> >>> >>>> Thanks for the reply. >>>> >>>> Whilst this will work, it is hardly desirable. Effectively the return >>>> type of all lambdas has to 'free' variable then writing a method that >>>> uses them is awkward, e.g.: >>>> >>>> @Override public void forEach( final Method1>>> Integer, E> method ) throws E { >>>> for ( int i = 0; i< values.length; i++ ) { >>>> final Integer oldValue = values[ i ]; >>>> final R newValueTemp = method.call( oldValue ); >>>> if ( newValueTemp instanceof Integer ) { values[ i ] = (Integer) >>>> newValue; } >>>> } >>>> } >>>> >>>> Not great! >>>> >>>> Cheers, >>>> >>>> -- Howard. >>>> >>>> On 23 August 2010 21:59, Maurizio Cimadamore >>>> wrote: >>>> >>>> >>>>> On 23/08/10 12:34, Howard Lovatt wrote: >>>>> >>>>> >>>>>> Thanks for the clarification, I think it *should* be a bug! >>>>>> >>>>>> In the meantime, what is the recommended idiom for writing such a >>>>>> function. >>>>>> >>>>>> >>>>>> >>>>> You could try with: >>>>> >>>>> interface SortableList> extends List >>>>> { >>>>> >>>>> void forEach( Method1 method ) throws E; >>>>> >>>>> } >>>>> >>>>> this should do. >>>>> >>>>> Maurizio >>>>> >>>>> >>>>> >>>>>> -- Howard. >>>>>> >>>>>> On 23 August 2010 21:15, Maurizio Cimadamore >>>>>> wrote: >>>>>> >>>>>> >>>>>> >>>>>>> On 23/08/10 12:02, Howard Lovatt wrote: >>>>>>> >>>>>>> Hi Mauritzio, >>>>>>> >>>>>>> I think it is a bug, like I said in the original post the 'return >>>>>>> type' is 'NeverReturns' not void, which should be assignable to >>>>>>> anything (including Integer). Scala and BGGA handle this case, they >>>>>>> both have a 'NeverReturns' type (Scala and BGGA Nothing). >>>>>>> >>>>>>> >>>>>>> Let me clarify - it is not a bug, according to the current spec; >>>>>>> quoting >>>>>>> from the latest formal spec describing lambda conversion [1]: >>>>>>> >>>>>>> "A divergent lambda expression such as #(){throw new >>>>>>> AssertionError();} >>>>>>> has no return value, and its body completes abruptly by reason of a >>>>>>> throw with an AssertionError object. For the purpose of calculating >>>>>>> the type of the lambda expression, the body of the lambda expression >>>>>>> is void." >>>>>>> >>>>>>> [1] - >>>>>>> >>>>>>> >>>>>>> http://mail.openjdk.java.net/pipermail/lambda-dev/attachments/20100212/af8d2cc5/attachment-0001.txt >>>>>>> >>>>>>> Maurizio >>>>>>> >>>>>>> Cheers, >>>>>>> >>>>>>> -- Howard. >>>>>>> >>>>>>> On 23 August 2010 20:35, Maurizio Cimadamore >>>>>>> wrote: >>>>>>> >>>>>>> >>>>>>> This is not a bug. You are trying to SAM convert the following lambda: >>>>>>> >>>>>>> #(x) { throws Exception(); } >>>>>>> >>>>>>> into the following target method: >>>>>>> >>>>>>> Integer call( Integer a1 ) throws E >>>>>>> >>>>>>> This is not possible, since the lambda expression is inferred to yield >>>>>>> 'void' (no return expression found), while the target method returns >>>>>>> Integer. >>>>>>> >>>>>>> Maurizio >>>>>>> >>>>>>> >>>>>>> >>>>>>> On 22/08/10 18:45, maurizio cimadamore wrote: >>>>>>> >>>>>>> >>>>>>> On 22/08/2010 07:09, Howard Lovatt wrote: >>>>>>> >>>>>>> >>>>>>> >>>>>>> For: >>>>>>> >>>>>>> public interface Method1 { public R call( A1 >>>>>>> a1 ) >>>>>>> throws E; } >>>>>>> >>>>>>> and: >>>>>>> >>>>>>> public void forEach( final Method1>>>>>> Integer, E> >>>>>>> method ) throws E { ... } >>>>>>> >>>>>>> The compiler has trouble with: >>>>>>> >>>>>>> il.forEach( #( i ) { throw new Exception(); } ); // Need to catch >>>>>>> checked exception >>>>>>> >>>>>>> Giving: >>>>>>> >>>>>>> lambdas/Main.java:34: method forEach in class IntList11 cannot be >>>>>>> applied to given types >>>>>>> il.forEach( #( i ) { throw new Exception(); } ); // Need to >>>>>>> catch checked exception >>>>>>> ^ >>>>>>> required: Method1 >>>>>>> found: #void(?)(Exception) >>>>>>> where E is a type-variable: >>>>>>> E extends Exception declared in method >>>>>>> forEach(Method1) >>>>>>> >>>>>>> Qualifying doesn't help: >>>>>>> >>>>>>> Method1 #( i ) { throw new >>>>>>> Exception(); >>>>>>> } >>>>>>> >>>>>>> It gives: >>>>>>> >>>>>>> lambdas/Main.java:34: incompatible types; no instance(s) of type >>>>>>> variable(s) ? exist so that #void(?)(Exception) conforms to >>>>>>> Method1 >>>>>>> il.forEach( Method1 #( i ) { >>>>>>> throw >>>>>>> new Exception(); } ); // Need to catch checked exception >>>>>>> ^ >>>>>>> required: Method1 >>>>>>> found: #void(?)(Exception) >>>>>>> >>>>>>> Is the problem that the return type isn't expressible? It isn't really >>>>>>> void, it is 'NeverReturns'. >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> Uhmm the problem here seems more related with a failure in inference >>>>>>> of >>>>>>> the lambda parameter (the '?' that you are seeing). Again it would be >>>>>>> helpful to see the declaration of the receiver class as well as the >>>>>>> type >>>>>>> of 'il'. >>>>>>> >>>>>>> Maurizio >>>>>>> >>>>>>> >>>>>>> >>>>> >>>>> >>>> >>>> -- >>>> -- Howard. >>>> >>>> >>>> >>> >>> >>> >> >> > > > From howard.lovatt at gmail.com Thu Aug 26 02:26:18 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Thu, 26 Aug 2010 19:26:18 +1000 Subject: hg: lambda/lambda/langtools: Object methods are not dispatched correctly by the ProxyHelper class (part three - last I hope ; -)). In-Reply-To: <4C762055.5030007@oracle.com> References: <4C762055.5030007@oracle.com> Message-ID: My ant line is: howard-lovatts-computer-3:make lov080$ ant -Dboot.java.home=/System/Library/Frameworks/JavaVM.framework/Versions/1.7.0_2010_07_30/Home -Dtarget.java.home=/System/Library/Frameworks/JavaVM.framework/Versions/1.7.0_2010_07_30/Home build-all-tools -- Howard. On 26 August 2010 18:05, Maurizio Cimadamore wrote: > On 26/08/10 08:00, Howard Lovatt wrote: >> >> @Maurizio, >> >> I can't compile the latest push. >> >> build-bootstrap-javac: >> ? ? [javac] Compiling 1 source file to >> /Users/lov080/Dropbox/Personal/Java/JDK7/langtools/build/bootstrap/classes >> ? ? [javac] >> /Users/lov080/Dropbox/Personal/Java/JDK7/langtools/src/share/classes/com/sun/runtime/ProxyHelper.java:66: >> strings in switch are not supported in -source 1.6 >> ? ? [javac] ? ? ? ? ? ? ? ? switch(method.getName()) { >> ? ? [javac] ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?^ >> ? ? [javac] ? (use -source 7 or higher to enable strings in switch) >> ? ? [javac] 1 error >> > > This is a bit weird - of course I can update the code in no time so that it > compiles against JDK 6, however the compiler build is supposed to compile > that bit against the target JDK which is supposed to be a JDK 7 repo... what > are the env variables you are passing to ant? > > Thanks > Maurizio >> >> BUILD FAILED >> /Users/lov080/Dropbox/Personal/Java/JDK7/langtools/make/build.xml:412: >> The following error occurred while executing this line: >> /Users/lov080/Dropbox/Personal/Java/JDK7/langtools/make/build.xml:775: >> Compile failed; see the compiler error output for details. >> >> >> >> Cheers, >> >> ? -- Howard. >> > > -- ? -- Howard. From howard.lovatt at gmail.com Thu Aug 26 02:44:20 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Thu, 26 Aug 2010 19:44:20 +1000 Subject: Trouble inferring type of lambda In-Reply-To: <4C762347.5030108@oracle.com> References: <4C71622A.8040305@oracle.com> <4C724EE6.4000701@oracle.com> <4C72583B.2060803@oracle.com> <4C7262A0.8050905@oracle.com> <4C74CF75.6010804@oracle.com> <4C762347.5030108@oracle.com> Message-ID: Hi Maurizio, It is the same source as before but to save you looking things up I have repeated the relevant bits below: public interface Method1 { public R call( A1 a1 ) throws E; } public class IntList11 extends AbstractList implements SortableList { ... @Override public void forEach( final Method1 method ) throws E { ... } } I am not wanting to use (your suggestion): public void forEach( final Method1 method ) throws E { ... } because R can now be anything and hence prevents the compiler catching type errors (see earlier posts for more details). If I add R it does indeed compile, but as I said I find the 'cure' worse than the 'problem'. However I am not satisfied with 'my' solution either: il.forEach( #( i ) { if ( alwaysTrue() ) { throw new Exception(); } return 0; } ); //Need to catch the checked exception! and hence still searching for something better. Therefore: il.forEach( #( i ) { throw new Exception(); } ); //Need to catch the checked exception! is correct for my signature, the only generic parameter is E, and: il.forEach( #( i ) { throw new Exception(); } ); //Need to catch the checked exception! doesn't compile and I also don't seem to be able to qualify the statement to 'help' the compiler out (as shown previously). Your responses are much appreciated, -- Howard. On 26 August 2010 18:18, Maurizio Cimadamore wrote: > On 26/08/10 07:46, Howard Lovatt wrote: >> >> Hi Maurizio, >> >> Not sure if the compiler should cope but the current one doesn't: >> >> ? ? ? il.forEach( #( i ) { throw new Exception(); } ); // >> Need to catch the checked exception! >> > > Hi Howard, > this is similar to another example we discussed - the inferred return type > is 'void' and, since return type and argument type should match (same > type-variable in forEach() signature) inference fails here. > > However I noticed that there's a glitch - from your error message I have > inferred that maybe you are compiling against this signature of forEach > (again, please post full source, or at least all relevant bits): > > void forEach( Method1 method ) throws > E; > > In that case, the compiler should reject a call such as: > > il.forEach( #( i ) { throw new Exception(); } ); //Need to catch > the checked exception! > > because there are not enough explicit type-parameters in the method call - I > guess that a nil-ary type-parameter is being detected here, but an explicit > 'void' should be used for that one. That's what's causing the compiler to > fail. If you remove the explicit type as in: > > il.forEach( #( i ) { throw new Exception(); } ); //Need to catch the checked > exception! > > The program compiles fine. > > Maurizio >> >> Gives: >> >> lambdas/Main.java:163: method forEach in class IntList11 cannot be >> applied to given types >> ? ? ? il.forEach( #( i ) { throw new Exception(); } ); // >> Need to catch the checked exception! >> ? ? ? ? ^ >> ? required: Method1 >> ? found: #void(?)(Exception) >> ? where E is a type-variable: >> ? ? E extends Exception declared in method >> forEach(Method1) >> 1 error >> >> And: >> >> ? ? ? il.forEach( Method1 ?#( i ) { throw >> new Exception(); } ); // Need to catch the checked exception! >> >> Gives: >> >> lambdas/Main.java:163: incompatible types; no instance(s) of type >> variable(s) ? exist so that #void(?)(Exception) conforms to >> Method1 >> ? ? ? il.forEach( Method1 ?#( i ) { throw >> new Exception(); } ); // Need to catch the checked exception! >> ? ? ? ? ? ? ? ? ? ^ >> ? required: Method1 >> ? found: ? ?#void(?)(Exception) >> 1 error >> >> So are these compiler bugs or is some other form of qualification >> possible. >> >> Cheers, >> >> ?-- Howard. >> >> On 25 August 2010 18:08, Maurizio Cimadamore >> ?wrote: >> >>> >>> On 25/08/10 06:00, Howard Lovatt wrote: >>> >>>> >>>> Having tried: >>>> >>>> @Override public ? ?void forEach( final Method1>>> E> ? ?method ) throws E { >>>> ? ?for ( int i = 0; i< ? ?values.length; i++ ) { >>>> ? ? ?final Integer oldValue = values[ i ]; >>>> ? ? ?final R newValueTemp = method.call( oldValue ); >>>> ? ? ?if ( newValueTemp instanceof Integer ) { values[ i ] = (Integer) >>>> newValue; } >>>> ? ? ?else { throw new IllegalArgumentException(); } >>>> ? ?} >>>> ?} >>>> >>>> To overcome the problem that: >>>> >>>> ? list.forEach( #( i ) { throw new Exception() } ); >>>> >>>> Wouldn't normally work (because the lambda returns void and not >>>> Integer). The problem with the above forEach implementation is that >>>> the return type is unconstrained and hence effectively unchecked by >>>> the compiler and generates runtime exceptions. >>>> >>>> Therefore the best I have come up with is: >>>> >>>> ? list.forEach( #( i ) { >>>> ? ? if ( alwaysTrue() ) { throw new Exception(); } >>>> ? ? return 0; >>>> ? } ); >>>> >>>> Which I am not really satisfied with, is there better? >>>> >>>> >>> >>> The only option would be to provide explicit type-parameters in the >>> method >>> call, as in: >>> >>> list.forEach(...); >>> >>> Maurizio >>> >>> >>> >>> >>>> >>>> Cheers, >>>> >>>> ?-- Howard. >>>> >>>> >>>> On 23 August 2010 22:49, Howard Lovatt >>>> ?wrote: >>>> >>>> >>>>> >>>>> Thanks for the reply. >>>>> >>>>> Whilst this will work, it is hardly desirable. Effectively the return >>>>> type of all lambdas has to 'free' variable then writing a method that >>>>> uses them is awkward, e.g.: >>>>> >>>>> ?@Override public ? ?void forEach( final Method1>>>> Integer, E> ? ?method ) throws E { >>>>> ? ?for ( int i = 0; i< ? ?values.length; i++ ) { >>>>> ? ? ?final Integer oldValue = values[ i ]; >>>>> ? ? ?final R newValueTemp = method.call( oldValue ); >>>>> ? ? ?if ( newValueTemp instanceof Integer ) { values[ i ] = (Integer) >>>>> newValue; } >>>>> ? ?} >>>>> ?} >>>>> >>>>> Not great! >>>>> >>>>> Cheers, >>>>> >>>>> ?-- Howard. >>>>> >>>>> On 23 August 2010 21:59, Maurizio Cimadamore >>>>> ? ?wrote: >>>>> >>>>> >>>>>> >>>>>> On 23/08/10 12:34, Howard Lovatt wrote: >>>>>> >>>>>> >>>>>>> >>>>>>> Thanks for the clarification, I think it *should* be a bug! >>>>>>> >>>>>>> In the meantime, what is the recommended idiom for writing such a >>>>>>> function. >>>>>>> >>>>>>> >>>>>>> >>>>>> >>>>>> You could try with: >>>>>> >>>>>> interface SortableList> ? ?extends >>>>>> List >>>>>> ?{ >>>>>> >>>>>> ? ?void forEach( Method1 ? ?method ) throws E; >>>>>> >>>>>> } >>>>>> >>>>>> this should do. >>>>>> >>>>>> Maurizio >>>>>> >>>>>> >>>>>> >>>>>>> >>>>>>> ?-- Howard. >>>>>>> >>>>>>> On 23 August 2010 21:15, Maurizio Cimadamore >>>>>>> ? ? ?wrote: >>>>>>> >>>>>>> >>>>>>> >>>>>>>> >>>>>>>> On 23/08/10 12:02, Howard Lovatt wrote: >>>>>>>> >>>>>>>> Hi Mauritzio, >>>>>>>> >>>>>>>> I think it is a bug, like I said in the original post the 'return >>>>>>>> type' is 'NeverReturns' not void, which should be assignable to >>>>>>>> anything (including Integer). Scala and BGGA handle this case, they >>>>>>>> both have a 'NeverReturns' type (Scala and BGGA Nothing). >>>>>>>> >>>>>>>> >>>>>>>> Let me clarify - it is not a bug, according to the current spec; >>>>>>>> quoting >>>>>>>> from the latest formal spec describing lambda conversion [1]: >>>>>>>> >>>>>>>> "A divergent lambda expression such as #(){throw new >>>>>>>> AssertionError();} >>>>>>>> has no return value, and its body completes abruptly by reason of a >>>>>>>> throw with an AssertionError object. For the purpose of calculating >>>>>>>> the type of the lambda expression, the body of the lambda expression >>>>>>>> is void." >>>>>>>> >>>>>>>> [1] - >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> http://mail.openjdk.java.net/pipermail/lambda-dev/attachments/20100212/af8d2cc5/attachment-0001.txt >>>>>>>> >>>>>>>> Maurizio >>>>>>>> >>>>>>>> Cheers, >>>>>>>> >>>>>>>> ?-- Howard. >>>>>>>> >>>>>>>> On 23 August 2010 20:35, Maurizio Cimadamore >>>>>>>> ? ? ?wrote: >>>>>>>> >>>>>>>> >>>>>>>> This is not a bug. You are trying to SAM convert the following >>>>>>>> lambda: >>>>>>>> >>>>>>>> #(x) { throws Exception(); } >>>>>>>> >>>>>>>> into the following target method: >>>>>>>> >>>>>>>> ? ? ?Integer call( Integer a1 ) throws E >>>>>>>> >>>>>>>> This is not possible, since the lambda expression is inferred to >>>>>>>> yield >>>>>>>> 'void' (no return expression found), while the target method returns >>>>>>>> Integer. >>>>>>>> >>>>>>>> Maurizio >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> On 22/08/10 18:45, maurizio cimadamore wrote: >>>>>>>> >>>>>>>> >>>>>>>> On 22/08/2010 07:09, Howard Lovatt wrote: >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> For: >>>>>>>> >>>>>>>> ? ?public interface Method1 ? ? ? ? { public R >>>>>>>> call( A1 >>>>>>>> a1 ) >>>>>>>> throws E; } >>>>>>>> >>>>>>>> and: >>>>>>>> >>>>>>>> ? ?public ? ? ? ? void forEach( final Method1>>>>>>> Integer, E> >>>>>>>> method ) throws E { ... } >>>>>>>> >>>>>>>> The compiler has trouble with: >>>>>>>> >>>>>>>> ? ? il.forEach( #( i ) { throw new Exception(); } ); // Need to >>>>>>>> catch >>>>>>>> checked exception >>>>>>>> >>>>>>>> Giving: >>>>>>>> >>>>>>>> lambdas/Main.java:34: method forEach in class IntList11 cannot be >>>>>>>> applied to given types >>>>>>>> ? ? ? ?il.forEach( #( i ) { throw new Exception(); } ); // Need to >>>>>>>> catch checked exception >>>>>>>> ? ? ? ? ?^ >>>>>>>> ? ?required: Method1 >>>>>>>> ? ?found: #void(?)(Exception) >>>>>>>> ? ?where E is a type-variable: >>>>>>>> ? ? ?E extends Exception declared in method >>>>>>>> forEach(Method1) >>>>>>>> >>>>>>>> Qualifying doesn't help: >>>>>>>> >>>>>>>> ? ?Method1 ? ? ? ? #( i ) { throw new >>>>>>>> Exception(); >>>>>>>> } >>>>>>>> >>>>>>>> It gives: >>>>>>>> >>>>>>>> lambdas/Main.java:34: incompatible types; no instance(s) of type >>>>>>>> variable(s) ? exist so that #void(?)(Exception) conforms to >>>>>>>> Method1 >>>>>>>> ? ? ? ?il.forEach( Method1 ? ? ? ? #( i >>>>>>>> ) { >>>>>>>> throw >>>>>>>> new Exception(); } ); // Need to catch checked exception >>>>>>>> ? ? ? ? ? ? ? ? ? ?^ >>>>>>>> ? ?required: Method1 >>>>>>>> ? ?found: ? ?#void(?)(Exception) >>>>>>>> >>>>>>>> Is the problem that the return type isn't expressible? It isn't >>>>>>>> really >>>>>>>> void, it is 'NeverReturns'. >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> Uhmm the problem here seems more related with a failure in inference >>>>>>>> of >>>>>>>> the lambda parameter (the '?' that you are seeing). Again it would >>>>>>>> be >>>>>>>> helpful to see the declaration of the receiver class as well as the >>>>>>>> type >>>>>>>> of 'il'. >>>>>>>> >>>>>>>> Maurizio >>>>>>>> >>>>>>>> >>>>>>>> >>>>>> >>>>>> >>>>> >>>>> -- >>>>> ? -- Howard. >>>>> >>>>> >>>>> >>>> >>>> >>>> >>> >>> >> >> >> > > -- ? -- Howard. From maurizio.cimadamore at oracle.com Thu Aug 26 02:55:04 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 26 Aug 2010 10:55:04 +0100 Subject: hg: lambda/lambda/langtools: Object methods are not dispatched correctly by the ProxyHelper class (part three - last I hope ; -)). In-Reply-To: References: <4C762055.5030007@oracle.com> Message-ID: <4C7639F8.6020708@oracle.com> On 26/08/10 10:26, Howard Lovatt wrote: > My ant line is: > > howard-lovatts-computer-3:make lov080$ ant > -Dboot.java.home=/System/Library/Frameworks/JavaVM.framework/Versions/1.7.0_2010_07_30/Home > -Dtarget.java.home=/System/Library/Frameworks/JavaVM.framework/Versions/1.7.0_2010_07_30/Home > build-all-tools > Thanks, as i suspected, there's a build problem when your boot.java is set to a JDK 7 build - the build process ends up trying to compile JDK 7 classes with the -source 6 option. As a short-trem fix, I will change ProxyHelper to be JDK 6 friendly, and, in the meanwhile, I will work so that this underlying build problem is fixed in baseline javac. Thanks Maurizio > -- Howard. > > On 26 August 2010 18:05, Maurizio Cimadamore > wrote: > >> On 26/08/10 08:00, Howard Lovatt wrote: >> >>> @Maurizio, >>> >>> I can't compile the latest push. >>> >>> build-bootstrap-javac: >>> [javac] Compiling 1 source file to >>> /Users/lov080/Dropbox/Personal/Java/JDK7/langtools/build/bootstrap/classes >>> [javac] >>> /Users/lov080/Dropbox/Personal/Java/JDK7/langtools/src/share/classes/com/sun/runtime/ProxyHelper.java:66: >>> strings in switch are not supported in -source 1.6 >>> [javac] switch(method.getName()) { >>> [javac] ^ >>> [javac] (use -source 7 or higher to enable strings in switch) >>> [javac] 1 error >>> >>> >> This is a bit weird - of course I can update the code in no time so that it >> compiles against JDK 6, however the compiler build is supposed to compile >> that bit against the target JDK which is supposed to be a JDK 7 repo... what >> are the env variables you are passing to ant? >> >> Thanks >> Maurizio >> >>> BUILD FAILED >>> /Users/lov080/Dropbox/Personal/Java/JDK7/langtools/make/build.xml:412: >>> The following error occurred while executing this line: >>> /Users/lov080/Dropbox/Personal/Java/JDK7/langtools/make/build.xml:775: >>> Compile failed; see the compiler error output for details. >>> >>> >>> >>> Cheers, >>> >>> -- Howard. >>> >>> >> >> > > > From maurizio.cimadamore at oracle.com Thu Aug 26 04:15:45 2010 From: maurizio.cimadamore at oracle.com (maurizio.cimadamore at oracle.com) Date: Thu, 26 Aug 2010 11:15:45 +0000 Subject: hg: lambda/lambda/langtools: Bug fixes: Message-ID: <20100826111551.DC96747463@hg.openjdk.java.net> Changeset: 1805864c6a0f Author: mcimadamore Date: 2010-08-26 12:14 +0100 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/1805864c6a0f Bug fixes: *) javac complains about missing overrides when defender methods are available *) lambda return type should not be inferred to 'void' if lambda expression cannot return normally *) build problem when boot.java.home points to a JDK 7 build ! src/share/classes/com/sun/runtime/ProxyHelper.java ! src/share/classes/com/sun/tools/javac/code/Symbol.java ! src/share/classes/com/sun/tools/javac/code/Types.java ! src/share/classes/com/sun/tools/javac/comp/Attr.java ! src/share/classes/com/sun/tools/javac/comp/Check.java ! src/share/classes/com/sun/tools/javac/comp/Flow.java ! src/share/classes/com/sun/tools/javac/resources/compiler.properties ! test/tools/javac/defender/Neg01.java ! test/tools/javac/defender/Neg01.out ! test/tools/javac/defender/Pos02.java + test/tools/javac/defender/Pos03.java + test/tools/javac/defender/Pos04.java ! test/tools/javac/diags/examples.not-yet.txt + test/tools/javac/lambda/ExceptionTransparency03.java + test/tools/javac/lambda/ExceptionTransparency03.out From neal at gafter.com Thu Aug 26 15:39:43 2010 From: neal at gafter.com (Neal Gafter) Date: Thu, 26 Aug 2010 15:39:43 -0700 Subject: Latest draft of Defender Methods In-Reply-To: <4C698B08.4080805@oracle.com> References: <4C698B08.4080805@oracle.com> Message-ID: Brian- I've posted comments on this draft to http://gafter.blogspot.com/2010/08/couple-of-comments-on-defender-methods.html, along with an explanation for why the comments are not yet mailed to this list. Cheers, Neal On Mon, Aug 16, 2010 at 12:01 PM, Brian Goetz wrote: > I've posted a new draft of Defender Methods at: > > > http://cr.openjdk.java.net/~briangoetz/lambda/Defender%20Methods%20v3.pdf > > > From neal at gafter.com Thu Aug 26 17:02:17 2010 From: neal at gafter.com (Neal Gafter) Date: Thu, 26 Aug 2010 17:02:17 -0700 Subject: hg: lambda/lambda/langtools: Bug fixes: In-Reply-To: <20100826111551.DC96747463@hg.openjdk.java.net> References: <20100826111551.DC96747463@hg.openjdk.java.net> Message-ID: On Thu, Aug 26, 2010 at 4:15 AM, wrote: > Bug fixes: > *) lambda return type should not be inferred to 'void' if lambda expression > cannot return normally > The specification defines the return type to be 'void' if the lambda body cannot complete normally. Has that changed? From maurizio.cimadamore at oracle.com Fri Aug 27 01:20:03 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Fri, 27 Aug 2010 09:20:03 +0100 Subject: hg: lambda/lambda/langtools: Bug fixes: In-Reply-To: References: <20100826111551.DC96747463@hg.openjdk.java.net> Message-ID: <4C777533.8000704@oracle.com> On 27/08/10 01:02, Neal Gafter wrote: > On Thu, Aug 26, 2010 at 4:15 AM, > wrote: > > Bug fixes: > *) lambda return type should not be inferred to 'void' if lambda > expression cannot return normally > > > The specification defines the return type to be 'void' if the lambda > body cannot complete normally. Has that changed? Hi Neal, what I've done goes a bit outside the spec here. Since now we have target typing I think there could be some value in leaving the return type 'open' (so that it can be inferred from the target type) when the lambda body cannot complete normally. Maurizio From peter.levart at marand.si Fri Aug 27 02:03:23 2010 From: peter.levart at marand.si (Peter Levart) Date: Fri, 27 Aug 2010 11:03:23 +0200 Subject: Push 23 August 1bb5b46bb326 fixes one bug, but introduces another In-Reply-To: <4C7381D0.8000802@oracle.com> References: <4C7381D0.8000802@oracle.com> Message-ID: <201008271103.24176.peter.levart@marand.si> On 08/24/10, Maurizio Cimadamore wrote: > On 24/08/10 09:07, Howard Lovatt wrote: > > Hi Maurizio, > > > > il.forEach( #( i ) { > > if ( i< 3 ) { throw new Exception(); } > > return i * i; > > } ); // Need to catch the checked exception! > > > > Now needs a try block (as it should), but > > > > il.forEach( #( i ) { return 2 * i; } ); // No exception, no try block > > > > Also needs one and it shouldn't! > > > Strictly speaking, this is not a bug - it is a limitation of the current > inference scheme that has been noticed elsewhere in this forum; Hi Maurizio, Yes, I think that inference scheme has to be improved too. I haven't looked into the details yet. Maybe that is why I don't entirely understand this reasoning: > unfortunately, when the body of the lambda expression has resolution > (e.g. operator/method) depending on the type of the parameter to be > inferred, javac cannot infer the thrown types from the lambda body; as > such, thrown types are inferred from the target type - in this case, the > target types throws E, whose bound is Exception - since no constraint is > found (from the lambda), E is simply instantiated to Exception. Do you have to infer the thrown types of the lambda body even before the lambda body is "resolved" ? Can't this be done afterwards? Maybe it's because you are considering lambda's thrown types in the resolution of the code surrounding the lambda expression (for example in the resolution of the invocation of the overloaded method where the lambda expression is one of it's parameters). For example this program: public class Closures { public interface IoSam { void run(String s) throws java.io.IOException; } public interface TxtSam { void run(String s) throws java.text.ParseException; } public static void doIt(IoSam ioSam) throws java.io.IOException { ioSam.run("IoSam"); } public static void doIt(TxtSam txtSam) throws java.text.ParseException { txtSam.run("TxtSam"); } public static void main(String[] args) throws Exception { try { doIt(#(String s){ System.out.println("Ivoked via " + s); throw new java.io.IOException(); }); } catch (java.io.IOException e) {} try { doIt(#(String s){ System.out.println("Ivoked via " + s); throw new java.text.ParseException(null, 0); }); } catch (java.text.ParseException e) {} } } prints: Ivoked via IoSam Ivoked via TxtSam Which shows that the resolution of overloaded method is taking the throws types of lambda expression into the consideration. I don't think this is something that is desirable. Lambda return type and parameter types yes, but not throws types. They should just be checked and always inferred in direction "lambda expression" -> SAM method throws type parameter... That is my simplified view of the matter. What do you think? Regards, Peter > > However I understand that this is something that needs to be improved - > it is showing up now because of the bug I fixed in the compiler (the > compiler was assuming that no exception where thrown when inference gave > up - which is potentially unsafe). > > Maurizio From maurizio.cimadamore at oracle.com Fri Aug 27 03:22:03 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Fri, 27 Aug 2010 11:22:03 +0100 Subject: Push 23 August 1bb5b46bb326 fixes one bug, but introduces another In-Reply-To: <201008271103.24176.peter.levart@marand.si> References: <4C7381D0.8000802@oracle.com> <201008271103.24176.peter.levart@marand.si> Message-ID: <4C7791CB.8060205@oracle.com> Hi Peter > Do you have to infer the thrown types of the lambda body even before the lambda body is "resolved" ? Can't this be done afterwards? > Doing it 'before' resolution has the advantage of narrowing down the set of potential applicable methods - which means less ambiguity errors and less need for explicit types at the call site. > Maybe it's because you are considering lambda's thrown types in the resolution of the code surrounding the lambda expression (for example in the resolution of the invocation of the overloaded method where the lambda expression is one of it's parameters). > > For example this program: > > > public class Closures > { > public interface IoSam { void run(String s) throws java.io.IOException; } > > public interface TxtSam { void run(String s) throws java.text.ParseException; } > > public static void doIt(IoSam ioSam) throws java.io.IOException > { > ioSam.run("IoSam"); > } > > public static void doIt(TxtSam txtSam) throws java.text.ParseException > { > txtSam.run("TxtSam"); > } > > public static void main(String[] args) throws Exception > { > try > { > doIt(#(String s){ System.out.println("Ivoked via " + s); throw new java.io.IOException(); }); > } > catch (java.io.IOException e) {} > > try > { > doIt(#(String s){ System.out.println("Ivoked via " + s); throw new java.text.ParseException(null, 0); }); > } > catch (java.text.ParseException e) {} > } > } > > > prints: > > > Ivoked via IoSam > Ivoked via TxtSam > > > Which shows that the resolution of overloaded method is taking the throws types of lambda expression into the consideration. > > I don't think this is something that is desirable. Lambda return type and parameter types yes, but not throws types. They should just be checked and always inferred in direction "lambda expression" -> SAM method throws type parameter... > Which means in the above case you have no other option than issuing an ambiguity error, since both methods are applicable (unless you look at thrown types). Maurizio From peter.levart at marand.si Fri Aug 27 05:06:18 2010 From: peter.levart at marand.si (Peter Levart) Date: Fri, 27 Aug 2010 14:06:18 +0200 Subject: Push 23 August 1bb5b46bb326 fixes one bug, but introduces another In-Reply-To: <4C7791CB.8060205@oracle.com> References: <201008271103.24176.peter.levart@marand.si> <4C7791CB.8060205@oracle.com> Message-ID: <201008271406.18704.peter.levart@marand.si> On 08/27/10, Maurizio Cimadamore wrote: > Hi Peter > > Do you have to infer the thrown types of the lambda body even before the lambda body is "resolved" ? Can't this be done afterwards? > > > Doing it 'before' resolution has the advantage of narrowing down the set > of potential applicable methods - which means less ambiguity errors and > less need for explicit types at the call site. > > Maybe it's because you are considering lambda's thrown types in the resolution of the code surrounding the lambda expression (for example in the resolution of the invocation of the overloaded method where the lambda expression is one of it's parameters). > > > > For example this program: > > > > > > public class Closures > > { > > public interface IoSam { void run(String s) throws java.io.IOException; } > > > > public interface TxtSam { void run(String s) throws java.text.ParseException; } > > > > public static void doIt(IoSam ioSam) throws java.io.IOException > > { > > ioSam.run("IoSam"); > > } > > > > public static void doIt(TxtSam txtSam) throws java.text.ParseException > > { > > txtSam.run("TxtSam"); > > } > > > > public static void main(String[] args) throws Exception > > { > > try > > { > > doIt(#(String s){ System.out.println("Ivoked via " + s); throw new java.io.IOException(); }); > > } > > catch (java.io.IOException e) {} > > > > try > > { > > doIt(#(String s){ System.out.println("Ivoked via " + s); throw new java.text.ParseException(null, 0); }); > > } > > catch (java.text.ParseException e) {} > > } > > } > > > > > > prints: > > > > > > Ivoked via IoSam > > Ivoked via TxtSam > > > > > > Which shows that the resolution of overloaded method is taking the throws types of lambda expression into the consideration. > > > > I don't think this is something that is desirable. Lambda return type and parameter types yes, but not throws types. They should just be checked and always inferred in direction "lambda expression" -> SAM method throws type parameter... > > > Which means in the above case you have no other option than issuing an > ambiguity error, since both methods are applicable (unless you look at > thrown types). Yes, and that is, in my opinion, a better choice. Designing an API with overloaded methods on the grounds of throws types of lambda expressions passed to those methods, is very prone to errors. Changing the body of the lambda expression slightly can have adverse effects on the resolution of overloaded method. The same is true when the return type of lambda expression changes, but that is much less likely to happen - if lambda was written to return a String, one will very rarely change it into something that returns say a Number. On the other hand, inferred throws types from lambda body can change very rapidly when you add or remove methods to/from the lambda body. > > Maurizio > Peter From jordan.r.stewart at gmail.com Fri Aug 27 06:09:23 2010 From: jordan.r.stewart at gmail.com (Jordan Stewart) Date: Sat, 28 Aug 2010 01:09:23 +1200 Subject: Cannot implement abstract method with extension method In-Reply-To: <4C75164E.9020800@oracle.com> References: <4C75164E.9020800@oracle.com> Message-ID: On Thu, Aug 26, 2010 at 1:10 AM, Maurizio Cimadamore < maurizio.cimadamore at oracle.com> wrote: > On 25/08/10 13:01, Thomas Jung wrote: > > Hi, > > > > given the extension method m in interface A and abstract method m in > > the abstract class B. The definition of the extension method A.m is > > not used to "implement" B.m in C. > > > > interface A{ > > extension boolean m(Object object) default As.m; > > } > > > > abstract class B { > > public abstract boolean m(Object object); > > } > > > > class C extends B implements A{} > > > Uhmm, it's not crystal clear as to whether this should work as you > expect - Brian any ideas? > > Hi Maurizio, Is the implementation meant to conform to the Defender Methods draft? The Method dispatch section of the draft lists a four step process- 1. standard search for an implementation 2. determine the set of interfaces that provide a default 3. discard superinterfaces from the set that have subinterfaces in the set 4. if there's one member in the set use its default implementation, otherwise throw an exception Perhaps I'm missing/misunderstanding something (very possible given that it's after 1am here in New Zealand!), have misread, or the current implementation isn't meant to conform to the draft, but if not then in this case As.m should be used as the implementation of m for instances of C. Cheers, Jordan From maurizio.cimadamore at oracle.com Fri Aug 27 06:22:14 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Fri, 27 Aug 2010 14:22:14 +0100 Subject: Cannot implement abstract method with extension method In-Reply-To: References: <4C75164E.9020800@oracle.com> Message-ID: <4C77BC06.3060905@oracle.com> On 27/08/10 14:09, Jordan Stewart wrote: > On Thu, Aug 26, 2010 at 1:10 AM, Maurizio Cimadamore > > wrote: > > On 25/08/10 13:01, Thomas Jung wrote: > > Hi, > > > > given the extension method m in interface A and abstract method m in > > the abstract class B. The definition of the extension method A.m is > > not used to "implement" B.m in C. > > > > interface A{ > > extension boolean m(Object object) default As.m; > > } > > > > abstract class B { > > public abstract boolean m(Object object); > > } > > > > class C extends B implements A{} > > > Uhmm, it's not crystal clear as to whether this should work as you > expect - Brian any ideas? > > > Hi Maurizio, > > Is the implementation meant to conform to the Defender Methods draft? > The Method dispatch section of the draft lists a four step process- > 1. standard search for an implementation > 2. determine the set of interfaces that provide a default > 3. discard superinterfaces from the set that have subinterfaces in the set > 4. if there's one member in the set use its default implementation, > otherwise throw an exception > > Perhaps I'm missing/misunderstanding something (very possible given > that it's after 1am here in New Zealand!), have misread, or the > current implementation isn't meant to conform to the draft, but if not > then in this case As.m should be used as the implementation of m for > instances of C. Hi, the rules you are referring to describe a runtime lookup and not the static checks carried out by javac. However in the latest push I've changed javac to be more liberal so that it now accepts cases that will in fact succeed given the above runtime resolution rules. Thanks Maurizio > > Cheers, > Jordan > From howard.lovatt at gmail.com Sun Aug 29 17:55:36 2010 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Mon, 30 Aug 2010 10:55:36 +1000 Subject: hg: lambda/lambda/langtools: Bug fixes: Message-ID: Hi Maurizio, Latest push is great progress. I particularly like that: il.forEach( #( notUsed ) { throw new Exception(); } ); // Need to catch the checked exception! now works; but note that it has to be statement (i.e. ; required), any chance of eliminating the semi-colon? The latest push has a regression: 88: // Method References, syntax like Javadoc 89: final ActionListener al4 = Main#print( ActionEvent ); 90: b1.addActionListener( al4 ); 91: b1.doClick(); This compiles, but when run I get: Exception in thread "main" java.dyn.WrongMethodTypeException: (Ljava/dyn/MethodHandle;Ljava/awt/event/ActionEvent;)V cannot be called as (Ljava/dyn/MethodHandle;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; at sun.dyn.FromGeneric$A2.invoke_I2(FromGeneric.java:533) at java.dyn.MethodHandle.invokeVarargs(MethodHandle.java:332) at com.sun.runtime.ProxyHelper$1.invoke(ProxyHelper.java:61) at $Proxy0.actionPerformed(Unknown Source) at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2015) at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2338) at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402) at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259) at javax.swing.AbstractButton.doClick(AbstractButton.java:376) at javax.swing.AbstractButton.doClick(AbstractButton.java:356) at lambdas.Main.lambdas(Main.java:91) at lambdas.Main.main(Main.java:22) Note that: // Method References, syntax like Javadoc final ActionListener al4 = Main#print( ActionEvent ); b1.addActionListener( al4 ); // b1.doClick(); b1.removeActionListener( al4 ); Now runs OK (thanks), i.e. the remove now works (the error above is caused when doClick runs). Cheers, ? -- Howard. From maurizio.cimadamore at oracle.com Mon Aug 30 01:35:12 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Mon, 30 Aug 2010 09:35:12 +0100 Subject: hg: lambda/lambda/langtools: Bug fixes: In-Reply-To: References: Message-ID: <4C7B6D40.7070000@oracle.com> On 30/08/10 01:55, Howard Lovatt wrote: > Hi Maurizio, > > Latest push is great progress. I particularly like that: > > il.forEach( #( notUsed ) { throw new Exception(); } ); // Need > to catch the checked exception! > > now works; but note that it has to be statement (i.e. ; required), any > chance of eliminating the semi-colon? > Not sure - the idea is that the body of a lambda can be either an expression (w/o terminating semi) or a statement (one or more, terminated by semi). In case of a method call, since a method call is an expression statement, you can have both the semi-terminated and the non-semi-terminated options; in the case of 'throw' which is a plain statement, I think your only option is to use a terminating semi-colon. > The latest push has a regression: > > 88: // Method References, syntax like Javadoc > 89: final ActionListener al4 = Main#print( ActionEvent ); > 90: b1.addActionListener( al4 ); > 91: b1.doClick(); > > This compiles, but when run I get: > > Exception in thread "main" java.dyn.WrongMethodTypeException: > (Ljava/dyn/MethodHandle;Ljava/awt/event/ActionEvent;)V cannot be > called as (Ljava/dyn/MethodHandle;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; > at sun.dyn.FromGeneric$A2.invoke_I2(FromGeneric.java:533) > at java.dyn.MethodHandle.invokeVarargs(MethodHandle.java:332) > at com.sun.runtime.ProxyHelper$1.invoke(ProxyHelper.java:61) > at $Proxy0.actionPerformed(Unknown Source) > at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2015) > at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2338) > at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402) > at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259) > at javax.swing.AbstractButton.doClick(AbstractButton.java:376) > at javax.swing.AbstractButton.doClick(AbstractButton.java:356) > at lambdas.Main.lambdas(Main.java:91) > at lambdas.Main.main(Main.java:22) > Damn :-) thanks again for the feedback! > Note that: > > // Method References, syntax like Javadoc > final ActionListener al4 = Main#print( ActionEvent ); > b1.addActionListener( al4 ); > // b1.doClick(); > b1.removeActionListener( al4 ); > > Now runs OK (thanks), i.e. the remove now works (the error above is > caused when doClick runs). > > Maurizio > Cheers, > > -- Howard. > From maurizio.cimadamore at oracle.com Mon Aug 30 03:50:17 2010 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Mon, 30 Aug 2010 11:50:17 +0100 Subject: hg: lambda/lambda/langtools: Bug fixes: In-Reply-To: <4C7B6D40.7070000@oracle.com> References: <4C7B6D40.7070000@oracle.com> Message-ID: <4C7B8CE9.1020500@oracle.com> >> The latest push has a regression: >> >> 88: // Method References, syntax like Javadoc >> 89: final ActionListener al4 = Main#print( ActionEvent ); >> 90: b1.addActionListener( al4 ); >> 91: b1.doClick(); >> >> This compiles, but when run I get: >> >> Exception in thread "main" java.dyn.WrongMethodTypeException: >> (Ljava/dyn/MethodHandle;Ljava/awt/event/ActionEvent;)V cannot be >> called as (Ljava/dyn/MethodHandle;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; >> at sun.dyn.FromGeneric$A2.invoke_I2(FromGeneric.java:533) >> at java.dyn.MethodHandle.invokeVarargs(MethodHandle.java:332) >> at com.sun.runtime.ProxyHelper$1.invoke(ProxyHelper.java:61) >> at $Proxy0.actionPerformed(Unknown Source) >> at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2015) >> at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2338) >> at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402) >> at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259) >> at javax.swing.AbstractButton.doClick(AbstractButton.java:376) >> at javax.swing.AbstractButton.doClick(AbstractButton.java:356) >> at lambdas.Main.lambdas(Main.java:91) >> at lambdas.Main.main(Main.java:22) >> >> > The following works for me (no exception): import java.awt.event.*; import javax.swing.JButton; class Test { public static void print(ActionEvent e) { System.out.println("Hello!"); } public static void main(String[] args) { final ActionListener al4 = Test#print( ActionEvent ); JButton b = new JButton(); b.addActionListener(al4); b.doClick(); b.removeActionListener(al4); } } Is it close enough to your test case? Maurizio From lordpixel+lamda-dev at mac.com Tue Aug 31 19:45:59 2010 From: lordpixel+lamda-dev at mac.com (Andrew Thompson) Date: Tue, 31 Aug 2010 22:45:59 -0400 Subject: Public defender methods and static inner classes in interfaces? In-Reply-To: References: Message-ID: <96F9EF1E-4E8A-4456-BC9F-4E75EA7C9B5E@mac.com> On Aug 24, 2010, at 6:25 AM, Reinier Zwitserloot wrote: > The conclusion of some was that this pattern will be rather common, whether > encouraged or not, and this has in fact been used as an argument to allow > specifying the default implementation directly on an interface method, > because this pattern has an ugly wart in it: The inner class must > necessarily be public, and is thus visible (because all members of an > interface are forced public). Making implementation details visible is bad > API design. Will the following compile in the prototype, assuming the whole thing is placed in Example.java? public interface Example { public extension void method(Object parameter) default Trait.method; } class Trait { public void method(Example outer, Object parameter) { } } People often forget Java allows multiple non-public types in a compilation unit (File). So this at least pushes the implementation to be package private. Personally I think the body should be allowed inline with the above as the de-sugaring. AndyT (lordpixel - the cat who walks through walls) A little bigger on the inside (see you later space cowboy, you can't take the sky from me) From reinier at zwitserloot.com Tue Aug 31 19:48:51 2010 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 1 Sep 2010 04:48:51 +0200 Subject: Public defender methods and static inner classes in interfaces? In-Reply-To: <96F9EF1E-4E8A-4456-BC9F-4E75EA7C9B5E@mac.com> References: <96F9EF1E-4E8A-4456-BC9F-4E75EA7C9B5E@mac.com> Message-ID: Nice solution. That still depends on the question: Does the default method have to be visible and/or accessible from the caller? If yes, then a package-private class won't work. --Reinier Zwitserloot On Wed, Sep 1, 2010 at 4:45 AM, Andrew Thompson > wrote: > > On Aug 24, 2010, at 6:25 AM, Reinier Zwitserloot wrote: > > > The conclusion of some was that this pattern will be rather common, > whether > > encouraged or not, and this has in fact been used as an argument to allow > > specifying the default implementation directly on an interface method, > > because this pattern has an ugly wart in it: The inner class must > > necessarily be public, and is thus visible (because all members of an > > interface are forced public). Making implementation details visible is > bad > > API design. > > > Will the following compile in the prototype, assuming the whole thing is > placed in Example.java? > > public interface Example { > public extension void method(Object parameter) default Trait.method; > } > > class Trait { > public void method(Example outer, Object parameter) { > > } > } > > People often forget Java allows multiple non-public types in a compilation > unit (File). > > So this at least pushes the implementation to be package private. > > Personally I think the body should be allowed inline with the above as the > de-sugaring. > > > AndyT (lordpixel - the cat who walks through walls) > A little bigger on the inside > > (see you later space cowboy, you can't take the sky from me) > > > From kevinb at google.com Tue Aug 31 19:56:42 2010 From: kevinb at google.com (Kevin Bourrillion) Date: Tue, 31 Aug 2010 19:56:42 -0700 Subject: Public defender methods and static inner classes in interfaces? In-Reply-To: <96F9EF1E-4E8A-4456-BC9F-4E75EA7C9B5E@mac.com> References: <96F9EF1E-4E8A-4456-BC9F-4E75EA7C9B5E@mac.com> Message-ID: On Tue, Aug 31, 2010 at 7:45 PM, Andrew Thompson < lordpixel+lamda-dev at mac.com > wrote: People often forget Java allows multiple non-public types in a compilation > unit (File). > We should all forget it. :-) It's a bad idea, because nothing will stop you from creating another class called Trait in another file in that package, and which Trait.class you'll actually end up with is nondeterministic! -- Kevin Bourrillion @ Google http://guava-libraries.googlecode.com From peter.levart at marand.si Tue Aug 31 23:16:59 2010 From: peter.levart at marand.si (Peter Levart) Date: Wed, 1 Sep 2010 08:16:59 +0200 Subject: Public defender methods and static inner classes in interfaces? In-Reply-To: References: <96F9EF1E-4E8A-4456-BC9F-4E75EA7C9B5E@mac.com> Message-ID: <201009010817.00184.peter.levart@marand.si> On 09/01/10, Reinier Zwitserloot wrote: > Nice solution. That still depends on the question: Does the default method > have to be visible and/or accessible from the caller? If yes, then a > package-private class won't work. I think that (havent checked the spec, but from my experience) the JVM does allow calling public method in an otherwise unaccessible class. It's just javac that does not allow compiling such program. Regards, Peter > > --Reinier Zwitserloot > > > > On Wed, Sep 1, 2010 at 4:45 AM, Andrew Thompson > > > wrote: > > > > > On Aug 24, 2010, at 6:25 AM, Reinier Zwitserloot wrote: > > > > > The conclusion of some was that this pattern will be rather common, > > whether > > > encouraged or not, and this has in fact been used as an argument to allow > > > specifying the default implementation directly on an interface method, > > > because this pattern has an ugly wart in it: The inner class must > > > necessarily be public, and is thus visible (because all members of an > > > interface are forced public). Making implementation details visible is > > bad > > > API design. > > > > > > Will the following compile in the prototype, assuming the whole thing is > > placed in Example.java? > > > > public interface Example { > > public extension void method(Object parameter) default Trait.method; > > } > > > > class Trait { > > public void method(Example outer, Object parameter) { > > > > } > > } > > > > People often forget Java allows multiple non-public types in a compilation > > unit (File). > > > > So this at least pushes the implementation to be package private. > > > > Personally I think the body should be allowed inline with the above as the > > de-sugaring. > > > > > > AndyT (lordpixel - the cat who walks through walls) > > A little bigger on the inside > > > > (see you later space cowboy, you can't take the sky from me) > > > > > > > >