From stephan.herrmann at berlin.de Sun Dec 1 06:07:36 2013 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Sun, 01 Dec 2013 15:07:36 +0100 Subject: type variables from enclosing types? Message-ID: <529B42A8.5010706@berlin.de> Hi, I couldn't find how type inference would handle type variables of an enclosing type. Looking at this example: class Outer { class Inner {} static void method(Outer.Inner x) {} } public class ExtendedOuter extends Outer { class ExtendedInner extends Inner { void foo() { method(this); } } } Current compilers accept this program, but playing strictly by the inference spec, I get funny results: 1) We have an initial constraint ?this -> Outer.Inner? where a naive implementation might consider "Inner" as a proper type. Should a note be added to the definition of "proper type", to the effect that enclosing types (explicit or implicit) should also be considered when looking for a mention of any inference variables? Otherwise the initial constraint directly reduces to FALSE. 2) If we interpret Outer.Inner as an improper type the inference variable I#0 will be inferred to Object, but that seems to be the wrong outcome: - "this" is an instance of ExtendedOuter.ExtendedInner - thus I#0 should be inferred to be E 3) Interestingly, when I modify the program so that the inference of I#0 to Object would trigger an error, the usage of I forces the inference into better results. Does this mean, the "wrong" inference result is acceptable because it is irrelevant to the current inference task? 4) I made experiments with pulling E into the inference by augmenting 18.2.3 bullet 5.2: I added corresponding constraints also for the type variables of enclosing types of C and C. This directed the inference into the expected solution, but then it caused regressions in situations of nested diamonds like new <>Outer.<>Inner() new Outer.<>Inner() I haven't yet analyzed the details of these regressions, though. Should some rules be added for handling type variables from enclosing types, or can we rely on the assumption that type variables that are only implicitly referenced need not be resolved to their optimal solution? thanks, Stephan From stephan.herrmann at berlin.de Sun Dec 1 07:22:27 2013 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Sun, 01 Dec 2013 16:22:27 +0100 Subject: inference trouble with recursive generics and raw types In-Reply-To: <1385579667.645288-13242@martha.daybyday.de> References: <1385579667.645288-13242@martha.daybyday.de> Message-ID: <529B5433.5060101@berlin.de> I made some experiments, because this is currently the most relevant open question regarding our inference implementation. We now have a flag to toggle the following two changes: (1): In 18.2.3 I made an addition similar to the new (as of 0.7.0) 18.2.2 bullet 4 (2): If Invocation Type Inference fails, I go back to the results from Applicability Inference and if that produces a return type whose erasure is compatible with the target type I proceed with this solution and an unchecked warning. Results: When expecting results similar to javac: (1) fixes 17 regressions in the current test suite (of 1494 tests) (2) fixes 6 regressions in that suite Both changes together cause 6 new regressions. It seems my changes go in the right direction, but use the wrong size of a drill. I'm running out of ideas how to let ECJ approximate the buggy javac behavior in the 1.8 era. I could really use some help in capturing the exact extent of that bug. Let me know if you'd like to see specimen of the regressions in different directions, mentioned above. thanks, Stephan On 11/27/2013 08:14 PM, Stephan Herrmann wrote: > Hi Dan, > > Thanks for letting us know. > > Given we (Eclipse) now have an implementation of type inference > that is very close to the new spec, and thus *doesn't* exhibit the bug, > do you have any hints on how we should add this bug on top of this > new implementation? > What exactly is the extent of the bug? In which situations does javac > check for convertibility where it actually should check for subtyping? > > Ideally, I could use an inofficial addendum to the inference spec, > that makes the spec conform to javac, so we have a realistic chance > to make ecj conform to both. > > best, > Stephan > > ----- urspr?ngliche Nachricht --------- > > Subject: Re: inference trouble with recursive generics and raw types > Date: Mi 27 Nov 2013 01:39:03 CET > From: Dan Smith > To: Stephan Herrmann<stephan.herrmann at berlin.de> > > On Nov 5, 2013, at 11:03 AM, Dan Smith wrote: > >> I'll have some conversations internally about how we feel about the unchecked conversion bug > > Following up. > > Here's the javac bug: > https://bugs.openjdk.java.net/browse/JDK-8026527 > > There's a consensus that this is far too risky to cram late into 8, and a sense that this is probably something we will change in 9. (This sort of change in the set of accepted programs is not something we generally allow in update releases.) > > ?Dan > > ---- urspr?ngliche Nachricht Ende ---- > From stephan.herrmann at berlin.de Sun Dec 1 08:27:11 2013 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Sun, 01 Dec 2013 17:27:11 +0100 Subject: capturing array of wildcard? Message-ID: <529B635F.4020904@berlin.de> Me again, Javac accepts the following example, I don't know why: interface OO {} interface TO extends OO {} interface TT extends TO {} public class X { TO combine(final TO x, final OO[] y) { return null; } void foo(TT tt, TO[] too) { combine(tt, too); } } How would the spec allow this? Looking at the second parameter ("too") being passed into combine(), I see this sequence of reduction: - ?too -> OO[]? - ?TO[] -> OO[]? - ?TO[] <: OO[]? - ?TO <: OO? -- ?java.lang.String <= E#0? -- ?? super java.lang.Object <= T#1? --- FALSE Type argument containment in 18.2.3 with wildcard and type yields FALSE. If we omit the array dimension in the example, we start with - ?too -> OO? - ?TO -> OO? and all will be well. To the best of my knowledge, capture of an array type is the identity function, and inference does not perform additional capture, right? That would mean the correct behavior is to reject the above? thanks, Stephan From stephan.herrmann at berlin.de Tue Dec 3 07:26:07 2013 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Tue, 03 Dec 2013 16:26:07 +0100 Subject: intersection type compatibility Message-ID: <529DF80F.6020908@berlin.de> Consider this program: import java.util.ArrayList; import java.util.List; public class Compile { public > Exp typedNull() { return null; } public void call() { ArrayList list = typedNull(); } } May I safely assume that the following error issued by javac b117 is a bug, or am I missing a subtle issue about intersection types? Compile.java:11: error: incompatible types: inferred type does not conform to upper bound(s) ArrayList list = typedNull(); ^ inferred: INT#1 upper bound(s): List,ArrayList where INT#1 is an intersection type: INT#1 extends ArrayList,List 1 error BTW, javac 7 gives a less puzzling error, but the new inference seems to obsolete this error: Compile.java:11: error: invalid inferred types for T,Exp; inferred type does not conform to declared bound(s) ArrayList list = typedNull(); ^ inferred: ArrayList bound(s): List where T,Exp are type-variables: T extends Object declared in method typedNull() Exp extends List declared in method typedNull() 1 error thanks, Stephan From daniel.smith at oracle.com Fri Dec 6 09:25:27 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Fri, 6 Dec 2013 10:25:27 -0700 Subject: Part F - Question In-Reply-To: References: Message-ID: Yes, there's a spec/implementation discrepancy right now. We're discussing internally how we'd like to handle this. (Any comments here are welcome, too, of course.) ?Dan On Nov 27, 2013, at 9:35 PM, Srikanth S Adayapalam wrote: > > From: Srikanth S Adayapalam/India/IBM > > Subject: Part F - Question > > > > Hello ! > > > > 1. javac 8b116 refuses to compile this program ("reference to goo is > > ambiguous"): > > Per my reading, the reference compiler is indeed closely following > > the letter of > > the specification in this test case: > > Actually, I think I am mistaken and this looks like a bug in javac 8b115. > (My earlier mail mistakenly mentioned 8b116 - I tested only with 8b115) > Per 15.12.2.1, goo(J) is not a potentially applicable method to the method > invocation given J's function type requires a void return and the argument > lambda expression is not void compatible. > > Dan &| Maurizio, could you confirm this is a bug in the RI or if I have > overlooked something ? > > Thanks! > Srikanth > > > // -- > interface I { > String foo(String [] x, String y); > } > interface J { > void foo(int x, int y); > } > public class X { > static void goo(J j) { > System.out.println("goo(J)"); > } > static void goo(I i) { > System.out.println("goo(I)"); > } > public static void main(String[] args) throws InterruptedException { > goo((x, y) -> { return x[0] += 1; }); > } > } > From daniel.smith at oracle.com Fri Dec 6 09:35:13 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Fri, 6 Dec 2013 10:35:13 -0700 Subject: inference trouble with recursive generics and raw types In-Reply-To: <529B5433.5060101@berlin.de> References: <1385579667.645288-13242@martha.daybyday.de> <529B5433.5060101@berlin.de> Message-ID: <6CAA6945-AAED-41DA-9092-73D87736A76E@oracle.com> I'm not an expert on exactly what javac does internally to implement bounds checking and incorporation during inference. Which is really what you need, if you're trying to prove that you've got identical behavior. I think how I would try to approach it is to treat declared upper bounds as "soft" bounds (via some sort of flag). The when comparing this upper bound to a lower or eq bound, I would allow for unchecked conversion. That strategy would allow your example at the start of the thread to compile, and seems to be close to what javac is doing, which is (again, as best I can tell) to allow unchecked conversion during checking of declared bounds. ?Dan On Dec 1, 2013, at 8:22 AM, Stephan Herrmann wrote: > I made some experiments, because this is currently the most > relevant open question regarding our inference implementation. > > We now have a flag to toggle the following two changes: > (1): In 18.2.3 I made an addition similar to the new (as of 0.7.0) > 18.2.2 bullet 4 > (2): If Invocation Type Inference fails, I go back to the results > from Applicability Inference and if that produces a return type > whose erasure is compatible with the target type I proceed > with this solution and an unchecked warning. > > Results: > When expecting results similar to javac: > (1) fixes 17 regressions in the current test suite (of 1494 tests) > (2) fixes 6 regressions in that suite > Both changes together cause 6 new regressions. > > It seems my changes go in the right direction, but use the wrong > size of a drill. I'm running out of ideas how to let ECJ approximate > the buggy javac behavior in the 1.8 era. I could really use some help > in capturing the exact extent of that bug. > > Let me know if you'd like to see specimen of the regressions in > different directions, mentioned above. > > thanks, > Stephan > > > On 11/27/2013 08:14 PM, Stephan Herrmann wrote: >> Hi Dan, >> >> Thanks for letting us know. >> >> Given we (Eclipse) now have an implementation of type inference >> that is very close to the new spec, and thus *doesn't* exhibit the bug, >> do you have any hints on how we should add this bug on top of this >> new implementation? >> What exactly is the extent of the bug? In which situations does javac >> check for convertibility where it actually should check for subtyping? >> >> Ideally, I could use an inofficial addendum to the inference spec, >> that makes the spec conform to javac, so we have a realistic chance >> to make ecj conform to both. >> >> best, >> Stephan >> >> ----- urspr?ngliche Nachricht --------- >> >> Subject: Re: inference trouble with recursive generics and raw types >> Date: Mi 27 Nov 2013 01:39:03 CET >> From: Dan Smith >> To: Stephan Herrmann<stephan.herrmann at berlin.de> >> >> On Nov 5, 2013, at 11:03 AM, Dan Smith wrote: >> >>> I'll have some conversations internally about how we feel about the unchecked conversion bug >> >> Following up. >> >> Here's the javac bug: >> https://bugs.openjdk.java.net/browse/JDK-8026527 >> >> There's a consensus that this is far too risky to cram late into 8, and a sense that this is probably something we will change in 9. (This sort of change in the set of accepted programs is not something we generally allow in update releases.) >> >> ?Dan >> >> ---- urspr?ngliche Nachricht Ende ---- >> > From daniel.smith at oracle.com Fri Dec 6 10:01:47 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Fri, 6 Dec 2013 11:01:47 -0700 Subject: capturing array of wildcard? In-Reply-To: <529B635F.4020904@berlin.de> References: <529B635F.4020904@berlin.de> Message-ID: <893D23A6-38C0-4CAA-BA56-21313A03B867@oracle.com> On Dec 1, 2013, at 9:27 AM, Stephan Herrmann wrote: > Me again, > > Javac accepts the following example, I don't know why: > > interface OO {} > interface TO extends OO {} > interface TT extends TO {} > > public class X { > TO combine(final TO x, final OO[] y) { return null; } > void foo(TT tt, TO[] too) { > combine(tt, too); > } > } > > How would the spec allow this? > Looking at the second parameter ("too") being passed into combine(), > I see this sequence of reduction: > - ?too -> OO[]? > - ?TO[] -> OO[]? > - ?TO[] <: OO[]? > - ?TO <: OO? > -- ?java.lang.String <= E#0? > -- ?? super java.lang.Object <= T#1? > --- FALSE > > Type argument containment in 18.2.3 with wildcard and type > yields FALSE. > > If we omit the array dimension in the example, we start with > - ?too -> OO? > - ?TO -> OO? > and all will be well. > > To the best of my knowledge, capture of an array type is > the identity function, and inference does not perform > additional capture, right? > That would mean the correct behavior is to reject the above? The problem is in the vaguely-defined notion of the supertypes of a wildcard-parameterized type. Here's the current spec text (18.2.3): "If T is a parameterized class type, C, then among the supertypes of S that are parameterizations of C, a most-specific type is identified: C" In JLS 7 (15.12.2.7), the same concept is invoked with phrases like "if A has a supertype of the form G<..., Xk-1, V, Xk+1, ...>". You might recall we considered doing something to define exactly how this supertype computation worked, but decided against it for now. Something to clean up next time around... The easy answers are wrong. For example: 1) It's incorrect to perform substitution with a wildcard. Type variables represent _types_; wildcards are not types, and make no sense if used as arbitrary types. So a substitution like [ E := ? super Object ] is just wrong. Just one example: interface A { T get(); void put(T arg); } class B extends A> { ... } B b = new B(); A> a = b; // wrong! a.put(new ArrayList()); 2) It's incorrect to perform capture to find the supertypes of a wildcard-parameterized type. Capture is useful when reasoning about subtyping -- e.g., S <: T if capture(S) <: T. But the capture of a type is not its own supertype. ArrayList <: List // wrong! --- The right answer is probably to do something like this: take the capture, derive the supertype, then "uncapture" the type by inserting some wildcards and removing capture variables. The details would need to be specified, since there's more than one way to do it. The key, though, is that the result must actually be a supertype of the type you started with. In the meantime, what javac does right now is more or less #2 -- take the capture of the type, and then just keep going. As you've seen, these leads to some logical errors like in your example. I imagine Eclipse has historically done something similar. ?Dan From daniel.smith at oracle.com Fri Dec 6 10:50:22 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Fri, 6 Dec 2013 11:50:22 -0700 Subject: type variables from enclosing types? In-Reply-To: <529B42A8.5010706@berlin.de> References: <529B42A8.5010706@berlin.de> Message-ID: On Dec 1, 2013, at 7:07 AM, Stephan Herrmann wrote: > Hi, > > I couldn't find how type inference would handle type variables > of an enclosing type. > > Looking at this example: > > class Outer { > class Inner {} > > static void method(Outer.Inner x) {} > } > > public class ExtendedOuter extends Outer { > class ExtendedInner extends Inner { > void foo() { > method(this); > } > } > } > > Current compilers accept this program, but playing strictly > by the inference spec, I get funny results: > > 1) We have an initial constraint ?this -> Outer.Inner? > where a naive implementation might consider "Inner" > as a proper type. Should a note be added to the definition > of "proper type", to the effect that enclosing types > (explicit or implicit) should also be considered when looking > for a mention of any inference variables? > Otherwise the initial constraint directly reduces to FALSE. I agree that the treatment of inner classes of parameterized types is generally lacking in JLS. But in this case, I don't see a problem: "proper types" are defined as types that do not "mention inference variables". The Type Outer.Inner clearly mentions an inference variable. > > 2) If we interpret Outer.Inner as an improper type > the inference variable I#0 will be inferred to Object, > but that seems to be the wrong outcome: > - "this" is an instance of ExtendedOuter.ExtendedInner > - thus I#0 should be inferred to be E The type of 'this' is ExtendedOuter.ExtendedInner. (Again, the spec here is somewhat lacking for inner classes of parameterized types, and for parameterized types in general, but I've tried to clarify in the lambda spec: "The type of 'this' is the class or interface type T within which the keyword this occurs.") So we have [ ExtendedOuter.ExtendedInner <: Outer.Inner ] [ Outer.Inner <: Outer.Inner ] E = I#0 I'll agree that the relationship between ExtendedOuter.ExtendedInner and Outer.Inner is not very well spelled out, but that's how subtyping has to work. I also agree that 18.2.3 does not properly account for this case, because Outer.Inner is not, per 4.5, a "parameterized type". I've created a bug: https://bugs.openjdk.java.net/browse/JDK-8029704 > 3) Interestingly, when I modify the program so that the > inference of I#0 to Object would trigger an error, the > usage of I forces the inference into better results. > Does this mean, the "wrong" inference result is acceptable > because it is irrelevant to the current inference task? Not entirely clear about what you're saying, but here are some points that I think are relevant: - If you mean that you tried returning the result and assigning it to something, then yes, it's possible for applicability testing (18.5.1) to come up with one answer for an ivar and for invocation type inference (18.5.2) to get a different one. This is illustrated in the discussion in those sections. But keep in mind that the fact that you've allowed Object as a result of 18.5.1 is a bug. - A good way to observe inference behavior _without_ influencing the results is to invoke a method of the result rather than assigning it. (E.g., 'genericMethod(arg).foo()'.) - It is always an error if, when we're all done, the type of an argument is incompatible with the corresponding parameter type of the invocation type. (The invocation type is a proper type, and is the result of instantiating inference variables.) See Part F, 15.12.3: "It is a compile-time error if an argument to a method invocation is not compatible with its target type, as derived from the invocation type." For arguments that are "pertinent to applicability", you don't need to worry about that if the inference algorithm is sound -- it's implicit in the inferred bounds. And if the inference algorithm is not sound, that's a bug. > 4) I made experiments with pulling E into the inference > by augmenting 18.2.3 bullet 5.2: I added corresponding > constraints also for the type variables of enclosing types > of C and C. This directed the > inference into the expected solution, Yep, that's the right approach. The 5.2 bullet is meant to cover this case, too. > but then it caused > regressions in situations of nested diamonds like > new <>Outer.<>Inner() > new Outer.<>Inner() > I haven't yet analyzed the details of these regressions, > though. Looks like an implementation detail to fix. That's clearly a syntax error in the JLS. (As is new Outer<>.Inner().) ?Dan From daniel.smith at oracle.com Fri Dec 6 11:01:11 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Fri, 6 Dec 2013 12:01:11 -0700 Subject: intersection type compatibility In-Reply-To: <529DF80F.6020908@berlin.de> References: <529DF80F.6020908@berlin.de> Message-ID: <64AD5C3D-9C65-4F95-A01A-9D75AB9E2D1D@oracle.com> On Dec 3, 2013, at 8:26 AM, Stephan Herrmann wrote: > Consider this program: > > import java.util.ArrayList; > import java.util.List; > > public class Compile { > > public > Exp typedNull() { > return null; > } > > public void call() { > ArrayList list = typedNull(); > } > } > > May I safely assume that the following error issued by > javac b117 is a bug, or am I missing a subtle issue > about intersection types? Well, it's a spec bug, but one that's already been identified: https://bugs.openjdk.java.net/browse/JDK-8028813 What javac is trying to say is that it can't resolve the inference bounds. And this is consistent with the spec. When testing for applicability (18.5.1), we get these bounds (trivially): { t <: Object, exp <: Object, exp <: List } And that can be resolved (18.4) to [ t:= Object, exp := List ]. (Note that exp depends on the resolution of t.) Then, for invocation type inference (18.5.2), we have an additional constraint: [ exp -> ArrayList ] Giving us bounds: { t <: Object, exp <: ArrayList, exp <: List } It would be nice if we could then infer something about t... But we don't, and so resolution finds t := Object, and then there's no solution for exp. We're planning to come up with an extra incorporation rule that will handle cases like this. ?Dan From srikanth_sankaran at in.ibm.com Fri Dec 6 15:34:03 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Sat, 7 Dec 2013 05:04:03 +0530 Subject: Part F - Question In-Reply-To: References: Message-ID: > From: Dan Smith > Subject: Re: Part F - Question > > Yes, there's a spec/implementation discrepancy right now. We're > discussing internally how we'd like to handle this. (Any comments > here are welcome, too, of course.) Is there more to this than that it is just a compiler bug that needs to be fixed ? ECJ can compile or reject this program based on where I put two lines of code. This looks cut and dry - are there any wider ramifications here that I am completely overlooking ? Srikanth -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20131207/111be4db/attachment.html From daniel.smith at oracle.com Fri Dec 6 16:33:09 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Fri, 6 Dec 2013 17:33:09 -0700 Subject: Part F - Question In-Reply-To: References: Message-ID: <42DA358C-4C6F-4DF4-8051-9CBB9F8EE302@oracle.com> On Dec 6, 2013, at 4:34 PM, Srikanth S Adayapalam wrote: > > From: Dan Smith > > Subject: Re: Part F - Question > > > > Yes, there's a spec/implementation discrepancy right now. We're > > discussing internally how we'd like to handle this. (Any comments > > here are welcome, too, of course.) > > Is there more to this than that it is just a compiler bug that needs to be fixed ? > ECJ can compile or reject this program based on where I put two lines of code. > This looks cut and dry - are there any wider ramifications here that I am completely > overlooking ? We just wanted to make sure the specification reflected the actually-intended behavior. After conferring, we've agreed this is a javac bug: https://bugs.openjdk.java.net/browse/JDK-8029718 ?Dan From stephan.herrmann at berlin.de Sat Dec 7 07:29:29 2013 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Sat, 07 Dec 2013 16:29:29 +0100 Subject: intersection type compatibility In-Reply-To: <64AD5C3D-9C65-4F95-A01A-9D75AB9E2D1D@oracle.com> References: <529DF80F.6020908@berlin.de> <64AD5C3D-9C65-4F95-A01A-9D75AB9E2D1D@oracle.com> Message-ID: <52A33ED9.2060100@berlin.de> Comments inline ... On 12/06/2013 08:01 PM, Dan Smith wrote: > On Dec 3, 2013, at 8:26 AM, Stephan Herrmann wrote: > >> Consider this program: >> >> import java.util.ArrayList; >> import java.util.List; >> >> public class Compile { >> >> public > Exp typedNull() { >> return null; >> } >> >> public void call() { >> ArrayList list = typedNull(); >> } >> } >> >> May I safely assume that the following error issued by >> javac b117 is a bug, or am I missing a subtle issue >> about intersection types? > > Well, it's a spec bug, but one that's already been identified: > https://bugs.openjdk.java.net/browse/JDK-8028813 Thanks for the reference. BTW, are there other open bugs against spec part G that I should know about? > What javac is trying to say is that it can't resolve the inference bounds. And this is consistent with the spec. > > When testing for applicability (18.5.1), we get these bounds (trivially): > { t <: Object, exp <: Object, exp <: List } > > And that can be resolved (18.4) to [ t:= Object, exp := List ]. (Note that exp depends on the resolution of t.) > > Then, for invocation type inference (18.5.2), we have an additional constraint: > [ exp -> ArrayList ] > > Giving us bounds: > { t <: Object, exp <: ArrayList, exp <: List } > > It would be nice if we could then infer something about t... But we don't, and so resolution finds t := Object, and then there's no solution for exp. I see I had a bug here. Just to double check: when we create fresh type variables for t and exp (say z-t and z-exp) where z-exp has upper bounds ArrayList and List: Is it a proper application of the well-formedness constraint in 18.4 to skip this solution candidate and continue? > We're planning to come up with an extra incorporation rule that will handle cases like this. Will you post on this list when a draft of the new rule is available? thanks, Stephan From stephan.herrmann at berlin.de Sat Dec 7 16:10:16 2013 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Sun, 08 Dec 2013 01:10:16 +0100 Subject: type variables from enclosing types? In-Reply-To: References: <529B42A8.5010706@berlin.de> Message-ID: <52A3B8E8.1010305@berlin.de> On 12/06/2013 07:50 PM, Dan Smith wrote: > - A good way to observe inference behavior _without_ influencing the results is to invoke a method of the result rather than assigning it. (E.g., 'genericMethod(arg).foo()'.) Thanks, yes this pattern helps to better test without cheating. >> 4) I made experiments with pulling E into the inference >> by augmenting 18.2.3 bullet 5.2: I added corresponding >> constraints also for the type variables of enclosing types >> of C and C. This directed the >> inference into the expected solution, > > Yep, that's the right approach. The 5.2 bullet is meant to cover this case, too. I take your word for it, because I don't see this at all in the existing text. >> but then it caused >> regressions in situations of nested diamonds like >> new <>Outer.<>Inner() >> new Outer.<>Inner() >> I haven't yet analyzed the details of these regressions, >> though. > > Looks like an implementation detail to fix. That's clearly a syntax error in the JLS. (As is new Outer<>.Inner().) Sorry for the outrageous typos. The most interesting case looks like this: X.Y x2 = new X().new Y<>("",""); (cf. http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7046778 :) After your confirmation I took on the challenge to debug this and found&fixed the bug in our implementation. BTW: finding a solution for X.Y x2 = new X<>().new Y<>("",""); seems to be out of scope for Java 8 type inference, right? thanks, Stephan From stephan.herrmann at berlin.de Sun Dec 8 07:14:52 2013 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Sun, 08 Dec 2013 16:14:52 +0100 Subject: exception constraints for explicitly-typed lambdas Message-ID: <52A48CEC.7080105@berlin.de> I may have a bug here, but from all I can see there's s.t. inconsistent as demonstrated by the following example: class A {} class B extends A { void bar() {} } public class X { public static void main(String[] argv) { someWithIndex(getList(), (B b) -> b.bar()); // HERE } interface ItemWithIndexVisitor { public void visit(E item); } public static void someWithIndex(List list, ItemWithIndexVisitor visitor) {} static List getList() { return null; } } javac accepts this program, but I don't see how: During invocation type inference for the marked call I get the following: The set C contains: constraint1: ?getList() ?throws java.util.List? constraint2: ?(B b) -> b.bar() ?throws X.ItemWithIndexVisitor? Input variables: constraint1: none constraint2: none Output variables: constraint1: G#0 constraint2: G#0 No input-output dependencies, so both constraints are picked. The union of input variables is empty, nothing gets resolved nor substituted => constraints remain as given above. During reduction of constraint2 we fail because of the unsubstituted inference variable G#0. This happens at 18.2.5 bullet 3: one "of the function type's parameter types is not a proper type" -> FALSE I must admit that I don't have a good intuition for the terms "input" and "output variables", so I only have a "mechanical" guess as to where the conflict lies; the following don't harmonize: [a] excluding parameters of explicitly-typed lambdas from input variables ("... the input variables include i) if the lambda expression is implicitly-typed...") [b] checking parameters of all lambdas in 18.2.5 My guess is that [b] is wrong in some way (completely bogus or should add condition "if lambda expression is implicitly-typed" as done in 18.2.1.1). Which is it? best, Stephan From stephan.herrmann at berlin.de Sun Dec 8 07:56:04 2013 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Sun, 08 Dec 2013 16:56:04 +0100 Subject: Change regarding conditional expression & capture & lub? Message-ID: <52A49694.9070406@berlin.de> This doesn't seem directly connected to JSR 335 but I wonder if the following change in behavior has s.t. to do with the type checking we are discussing here: class A{/**/} class B extends A {/**/} class G { G gb=null; G gsa=null; G l = (true)? gsa : gb; } javac7- rejects this, which corresponds to my understanding of the JLS: (1) capture the types of gsa and gb, respectively. (2) compute the lub (3) detect type mismatch javac8, OTOH, accepts the snippet. Has the specification for any of the three steps been changed? I suspect that conditional expressions no longer capture before lub computation?? Wouldn't that require a change in 15.11.1 et al: "the type of the field access expression is the type of the member field after capture conversion" ? Or has lub computation been changed in some way? (spec and/or implementation?) Either way the effect would probably be relevant for my work on inference :) best, Stephan From daniel.smith at oracle.com Mon Dec 9 12:25:49 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Mon, 9 Dec 2013 13:25:49 -0700 Subject: intersection type compatibility In-Reply-To: <52A33ED9.2060100@berlin.de> References: <529DF80F.6020908@berlin.de> <64AD5C3D-9C65-4F95-A01A-9D75AB9E2D1D@oracle.com> <52A33ED9.2060100@berlin.de> Message-ID: On Dec 7, 2013, at 8:29 AM, Stephan Herrmann wrote: >> Giving us bounds: >> { t <: Object, exp <: ArrayList, exp <: List } >> >> It would be nice if we could then infer something about t... But we don't, and so resolution finds t := Object, and then there's no solution for exp. > > I see I had a bug here. Just to double check: when we create fresh type variables > for t and exp (say z-t and z-exp) where z-exp has upper bounds ArrayList > and List: Is it a proper application of the well-formedness constraint in 18.4 > to skip this solution candidate and continue? Yes, this is exactly the kind of thing that is meant to be detected by that check. I see that the "else" branch of the well-formedness condition doesn't actually appear in the paragraph. I'll have to fix that. If the fresh type variable is not well-formed, resolution must simply give up. >> Well, it's a spec bug, but one that's already been identified: >> https://bugs.openjdk.java.net/browse/JDK-8028813 > > Thanks for the reference. > BTW, are there other open bugs against spec part G > that I should know about? >> We're planning to come up with an extra incorporation rule that will handle cases like this. > > Will you post on this list when a draft of the new rule is available? Later this week, watch for a summary of all Public Review feedback and changes, along with an updated spec. ?Dan From daniel.smith at oracle.com Mon Dec 9 12:30:35 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Mon, 9 Dec 2013 13:30:35 -0700 Subject: type variables from enclosing types? In-Reply-To: <52A3B8E8.1010305@berlin.de> References: <529B42A8.5010706@berlin.de> <52A3B8E8.1010305@berlin.de> Message-ID: <5FC12EF3-ACC4-4642-8779-07EC04A164BA@oracle.com> On Dec 7, 2013, at 5:10 PM, Stephan Herrmann wrote: >>> 4) I made experiments with pulling E into the inference >>> by augmenting 18.2.3 bullet 5.2: I added corresponding >>> constraints also for the type variables of enclosing types >>> of C and C. This directed the >>> inference into the expected solution, >> >> Yep, that's the right approach. The 5.2 bullet is meant to cover this case, too. > > I take your word for it, because I don't see this at all in the existing text. Yes, this is the point of the new bug I mentioned, https://bugs.openjdk.java.net/browse/JDK-8029704. > BTW: finding a solution for > X.Y x2 = new X<>().new Y<>("",""); > seems to be out of scope for Java 8 type inference, right? Yep. "new X<>()" is a standalone expression, so you'll get an X. ?Dan From daniel.smith at oracle.com Mon Dec 9 12:40:17 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Mon, 9 Dec 2013 13:40:17 -0700 Subject: Change regarding conditional expression & capture & lub? In-Reply-To: <52A49694.9070406@berlin.de> References: <52A49694.9070406@berlin.de> Message-ID: <7C8A3B4B-B7D0-4BA2-8FD8-B0FF52754E80@oracle.com> On Dec 8, 2013, at 8:56 AM, Stephan Herrmann wrote: > This doesn't seem directly connected to JSR 335 but I wonder > if the following change in behavior has s.t. to do with the > type checking we are discussing here: > > class A{/**/} > class B extends A {/**/} > > class G { > G gb=null; > G gsa=null; > G l = (true)? gsa : gb; > } > > javac7- rejects this, which corresponds to my understanding of the JLS: > > (1) capture the types of gsa and gb, respectively. > (2) compute the lub > (3) detect type mismatch > > javac8, OTOH, accepts the snippet. > > Has the specification for any of the three steps been changed? Yes! Conditional expressions can be poly expressions. See Part D, 15.25. The relevant change is that poly conditionals do not perform lub at all. Instead, they simply check that each branch is compatible with the target type, and then consider the expression to have the same type as its target type. ?Dan From stephan.herrmann at berlin.de Mon Dec 9 17:21:21 2013 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Tue, 10 Dec 2013 02:21:21 +0100 Subject: Missing substitution in 18.3? Message-ID: <52A66C91.1010106@berlin.de> I'm looking at a complex example where inference fails (contrary to javac behavior). The most likely problem is in 18.3., sedond list, bullet 5: "If Ai is not a wildcard, the bound ?i = Ai is immediately implied." I believe sustitution ? must be applied to Ai, here! (prefix or postfix as you like :) ) Alternatively, there could be s.t. wrong with how the capture bound was first created in 18.5.2 (rhs here has no substitution either). The point is we are leaking type variables into the inference, for which inference variables have been defined -> FAIL. Do you agree? Stephan From stephan.herrmann at berlin.de Mon Dec 9 17:28:26 2013 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Tue, 10 Dec 2013 02:28:26 +0100 Subject: Change regarding conditional expression & capture & lub? In-Reply-To: <7C8A3B4B-B7D0-4BA2-8FD8-B0FF52754E80@oracle.com> References: <52A49694.9070406@berlin.de> <7C8A3B4B-B7D0-4BA2-8FD8-B0FF52754E80@oracle.com> Message-ID: <52A66E3A.2040004@berlin.de> On 12/09/2013 09:40 PM, Dan Smith wrote: > On Dec 8, 2013, at 8:56 AM, Stephan Herrmann wrote: > >> This doesn't seem directly connected to JSR 335 but I wonder >> if the following change in behavior has s.t. to do with the >> type checking we are discussing here: >> >> class A{/**/} >> class B extends A {/**/} >> >> class G { >> G gb=null; >> G gsa=null; >> G l = (true)? gsa : gb; >> } >> >> javac7- rejects this, which corresponds to my understanding of the JLS: >> >> (1) capture the types of gsa and gb, respectively. >> (2) compute the lub >> (3) detect type mismatch >> >> javac8, OTOH, accepts the snippet. >> >> Has the specification for any of the three steps been changed? > > Yes! Conditional expressions can be poly expressions. See Part D, 15.25. I've seen that, but couldn't see a connection because ... > The relevant change is that poly conditionals do not perform lub at all. Instead, they simply check that each branch is compatible with the target type, and then consider the expression to have the same type as its target type. ... it seems javac applies that rule also to standalone expressions. Or it considers a variable access as a poly expression... or ... IOW, is it expected that the example above is affected by the spec changes? thanks, Stephan From daniel.smith at oracle.com Mon Dec 9 20:05:41 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Mon, 9 Dec 2013 21:05:41 -0700 Subject: Change regarding conditional expression & capture & lub? In-Reply-To: <52A66E3A.2040004@berlin.de> References: <52A49694.9070406@berlin.de> <7C8A3B4B-B7D0-4BA2-8FD8-B0FF52754E80@oracle.com> <52A66E3A.2040004@berlin.de> Message-ID: <3B96CDA0-B0D7-4958-8C63-6AEC5CB9A658@oracle.com> On Dec 9, 2013, at 6:28 PM, Stephan Herrmann wrote: > On 12/09/2013 09:40 PM, Dan Smith wrote: >> On Dec 8, 2013, at 8:56 AM, Stephan Herrmann wrote: >> >>> This doesn't seem directly connected to JSR 335 but I wonder >>> if the following change in behavior has s.t. to do with the >>> type checking we are discussing here: >>> >>> class A{/**/} >>> class B extends A {/**/} >>> >>> class G { >>> G gb=null; >>> G gsa=null; >>> G l = (true)? gsa : gb; >>> } >>> >>> javac7- rejects this, which corresponds to my understanding of the JLS: >>> >>> (1) capture the types of gsa and gb, respectively. >>> (2) compute the lub >>> (3) detect type mismatch >>> >>> javac8, OTOH, accepts the snippet. >>> >>> Has the specification for any of the three steps been changed? >> >> Yes! Conditional expressions can be poly expressions. See Part D, 15.25. > > I've seen that, but couldn't see a connection because ... > >> The relevant change is that poly conditionals do not perform lub at all. Instead, they simply check that each branch is compatible with the target type, and then consider the expression to have the same type as its target type. > > ... it seems javac applies that rule also to standalone expressions. > Or it considers a variable access as a poly expression... or ... > > IOW, is it expected that the example above is affected by the > spec changes? Yes. A conditional expression does not have to wrap a poly expression to _be_ a poly expression. "A reference conditional expression is a poly expression ***if it appears in an assignment context (5.2) or an invocation context (5.3)***. Otherwise, it is a standalone expression. "Where a poly reference conditional expression appears in a context of a particular kind with target type T (5), its second and third operand expressions similarly appear in a context of the same kind with target type T. "The type of a poly reference conditional expression is the same as its target type. "The type of a standalone reference conditional expression is determined as follows: ..." ?Dan From srikanth_sankaran at in.ibm.com Mon Dec 9 21:10:27 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Tue, 10 Dec 2013 10:40:27 +0530 Subject: Part F - Question In-Reply-To: References: Message-ID: > From: Dan Smith > Subject: Re: Part F - Question > > Yes, there's a spec/implementation discrepancy right now. We're > discussing internally how we'd like to handle this. (Any comments > here are welcome, too, of course.) OK, Here is some input: The present definition of value/void compatibility matches that of "regular" or "vanilla" methods. That has its merits as far as language regularity/consistency goes, but can be a tad too pedantic when carried over to lambdas: I wonder if things get much simplified for compiler implementers [*] if we choose to adopt a pragmatic definition that would not amount IMO to any loss of useful functionality: So the suggestion: For lambda's with expression body - no change is required. For lambda's with block bodies - what would it mean if the definition is tweaked to say: For the purposes of applicability checks *only* - A block bodied lambda is void compatible if every return in its body lacks an expression (or there are no return statements in its body) - A block bodied lambda is value compatible if every return in its body is of the form "return expression" - A block bodied lambda is also value compatible if the last statement in its body is a throw statement. I see two ramifications of such a change: 1. Lambda's of the form: (x) -> { if (x > 10) return x; } would be seen to be value compatible for the purposes of potential applicability checks instead of being declared as being neither value nor void compatible per the present rules. So, what ? This is a distinction without a difference - This is a broken lambda and by declaring it as value compatible for potential applicability checks, we are simply but surely deferring the error reporting to a later stage. (It could even result in better error messages in some cases based on an implementation) 2. A lambda of the form: () -> { while (true); } would not be seen to be value compatible. Again, it appears to be that there is no major loss of functionality due to this. In general, there is value (sorry for overloading the term :)) to deducing/treating methods that don't complete normally as being value compatible (assuming otherwise they are well formed), as this supports a bunch of use cases such as - "abstract virtual methods" in a concrete class. You often don't want to introduce a new abstract method in a concrete class because that would burden the entire hierarchy while the new method could be pertinent only to a few parts of the hierarchy. So provide an implementation that just throws an exception to shut up the compiler. - Invalid inputs: A switch case statement may handle variety of valid inputs and the ultimate statement in the method could be a throw for invalid values. - while (true) server loops. I think the special allowance to treat a lambda as being value compatible if its last statement throws an exception would cover these cases adequately. The present definition makes (as the spec calls out) value-void compatibility a non-structural property - necessarily calling for control/data flow analysis to be performed to determine the shape. It is not clear to me that the benefits outweigh the cost to an implementation. With the suggested changes even a basic AST visitor would suffice. (As an aside: (non-compiler) tool builders have some interesting challenges here too: Compiler have it easy - they see a broken program and they reject it. Right now I am working on providing code completion support for type elided parameters - the lambda is being written "just now", the programmer is requesting code assistant support to write the lambda - now if a tool builder implements the spec rigorously and holds a lambda as being not value compatible because the return statement has not been yet written, the method invocation may never be resolved and the elided types will never be inferred.) [*] We have solved this problem in the Eclipse compiler. Thanks! Srikanth -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20131210/a7de5189/attachment-0001.html From stephan.herrmann at berlin.de Tue Dec 10 03:31:22 2013 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Tue, 10 Dec 2013 12:31:22 +0100 Subject: Change regarding conditional expression & capture & lub? In-Reply-To: <3B96CDA0-B0D7-4958-8C63-6AEC5CB9A658@oracle.com> References: <52A49694.9070406@berlin.de> <7C8A3B4B-B7D0-4BA2-8FD8-B0FF52754E80@oracle.com> <52A66E3A.2040004@berlin.de> <3B96CDA0-B0D7-4958-8C63-6AEC5CB9A658@oracle.com> Message-ID: <52A6FB8A.5050102@berlin.de> Sorry for being slow in making the connections. Perfectly clear now, Thanks, Stephan On 12/10/2013 05:05 AM, Dan Smith wrote: > On Dec 9, 2013, at 6:28 PM, Stephan Herrmann wrote: > >> On 12/09/2013 09:40 PM, Dan Smith wrote: >>> On Dec 8, 2013, at 8:56 AM, Stephan Herrmann wrote: >>> >>>> This doesn't seem directly connected to JSR 335 but I wonder >>>> if the following change in behavior has s.t. to do with the >>>> type checking we are discussing here: >>>> >>>> class A{/**/} >>>> class B extends A {/**/} >>>> >>>> class G { >>>> G gb=null; >>>> G gsa=null; >>>> G l = (true)? gsa : gb; >>>> } >>>> >>>> javac7- rejects this, which corresponds to my understanding of the JLS: >>>> >>>> (1) capture the types of gsa and gb, respectively. >>>> (2) compute the lub >>>> (3) detect type mismatch >>>> >>>> javac8, OTOH, accepts the snippet. >>>> >>>> Has the specification for any of the three steps been changed? >>> >>> Yes! Conditional expressions can be poly expressions. See Part D, 15.25. >> >> I've seen that, but couldn't see a connection because ... >> >>> The relevant change is that poly conditionals do not perform lub at all. Instead, they simply check that each branch is compatible with the target type, and then consider the expression to have the same type as its target type. >> >> ... it seems javac applies that rule also to standalone expressions. >> Or it considers a variable access as a poly expression... or ... >> >> IOW, is it expected that the example above is affected by the >> spec changes? > > Yes. > > A conditional expression does not have to wrap a poly expression to _be_ a poly expression. > > "A reference conditional expression is a poly expression ***if it appears in an assignment context (5.2) or an invocation context (5.3)***. Otherwise, it is a standalone expression. > > "Where a poly reference conditional expression appears in a context of a particular kind with target type T (5), its second and third operand expressions similarly appear in a context of the same kind with target type T. > > "The type of a poly reference conditional expression is the same as its target type. > > "The type of a standalone reference conditional expression is determined as follows: ..." > > ?Dan > From daniel.smith at oracle.com Tue Dec 10 07:40:37 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Tue, 10 Dec 2013 08:40:37 -0700 Subject: Change regarding conditional expression & capture & lub? In-Reply-To: <52A6FB8A.5050102@berlin.de> References: <52A49694.9070406@berlin.de> <7C8A3B4B-B7D0-4BA2-8FD8-B0FF52754E80@oracle.com> <52A66E3A.2040004@berlin.de> <3B96CDA0-B0D7-4958-8C63-6AEC5CB9A658@oracle.com> <52A6FB8A.5050102@berlin.de> Message-ID: <2D7C8FC0-B532-4C93-BEDE-4C9D52AF1472@oracle.com> No problem. Looks like a section that could use a clarifying example or two. ?Dan On Dec 10, 2013, at 4:31 AM, Stephan Herrmann wrote: > Sorry for being slow in making the connections. Perfectly clear now, > > Thanks, > Stephan > > On 12/10/2013 05:05 AM, Dan Smith wrote: >> On Dec 9, 2013, at 6:28 PM, Stephan Herrmann wrote: >> >>> On 12/09/2013 09:40 PM, Dan Smith wrote: >>>> On Dec 8, 2013, at 8:56 AM, Stephan Herrmann wrote: >>>> >>>>> This doesn't seem directly connected to JSR 335 but I wonder >>>>> if the following change in behavior has s.t. to do with the >>>>> type checking we are discussing here: >>>>> >>>>> class A{/**/} >>>>> class B extends A {/**/} >>>>> >>>>> class G { >>>>> G gb=null; >>>>> G gsa=null; >>>>> G l = (true)? gsa : gb; >>>>> } >>>>> >>>>> javac7- rejects this, which corresponds to my understanding of the JLS: >>>>> >>>>> (1) capture the types of gsa and gb, respectively. >>>>> (2) compute the lub >>>>> (3) detect type mismatch >>>>> >>>>> javac8, OTOH, accepts the snippet. >>>>> >>>>> Has the specification for any of the three steps been changed? >>>> >>>> Yes! Conditional expressions can be poly expressions. See Part D, 15.25. >>> >>> I've seen that, but couldn't see a connection because ... >>> >>>> The relevant change is that poly conditionals do not perform lub at all. Instead, they simply check that each branch is compatible with the target type, and then consider the expression to have the same type as its target type. >>> >>> ... it seems javac applies that rule also to standalone expressions. >>> Or it considers a variable access as a poly expression... or ... >>> >>> IOW, is it expected that the example above is affected by the >>> spec changes? >> >> Yes. >> >> A conditional expression does not have to wrap a poly expression to _be_ a poly expression. >> >> "A reference conditional expression is a poly expression ***if it appears in an assignment context (5.2) or an invocation context (5.3)***. Otherwise, it is a standalone expression. >> >> "Where a poly reference conditional expression appears in a context of a particular kind with target type T (5), its second and third operand expressions similarly appear in a context of the same kind with target type T. >> >> "The type of a poly reference conditional expression is the same as its target type. >> >> "The type of a standalone reference conditional expression is determined as follows: ..." >> >> ?Dan >> > From stephan.herrmann at berlin.de Thu Dec 12 16:19:13 2013 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Fri, 13 Dec 2013 01:19:13 +0100 Subject: Assignment context defined ? Message-ID: <52AA5281.3040705@berlin.de> Skimming through old communication I stumbled upon http://mail.openjdk.java.net/pipermail/lambda-spec-experts/2013-February/000235.html I couldn't yet find any of what had been promised back then, am I looking in the wrong places? :) On a different note, when reading 18.5.1, which says: "Where P1, ..., Pp (p ? 1) are the type parameters of m" it still isn't clear from the immediate context that these P1... may include type parameters of the declaring class of a constructor invoked using diamond. Meanwhile 18.2.1 has a reference to 15.9.3, which helps. Maybe a similar note would also improve 18.5.1, given that there's no direct connection from/to 18.2.1. best, Stephan From daniel.smith at oracle.com Mon Dec 16 16:06:25 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Mon, 16 Dec 2013 17:06:25 -0700 Subject: Assignment context defined ? In-Reply-To: <52AA5281.3040705@berlin.de> References: <52AA5281.3040705@berlin.de> Message-ID: <67104515-F67F-4E22-9262-191B8261BDD9@oracle.com> On Dec 12, 2013, at 5:19 PM, Stephan Herrmann wrote: > Skimming through old communication I stumbled upon > > http://mail.openjdk.java.net/pipermail/lambda-spec-experts/2013-February/000235.html > > I couldn't yet find any of what had been promised back then, > am I looking in the wrong places? :) Just came across it on my loose ends list. Since this is not a new problem, I've decided to punt on it while reporting a bug against the JLS: https://bugs.openjdk.java.net/browse/JDK-8030361 > On a different note, when reading 18.5.1, which says: > "Where P1, ..., Pp (p ? 1) are the type parameters of m" > it still isn't clear from the immediate context that these > P1... may include type parameters of the declaring class of > a constructor invoked using diamond. > Meanwhile 18.2.1 has a reference to 15.9.3, which helps. > Maybe a similar note would also improve 18.5.1, given that > there's no direct connection from/to 18.2.1. I appreciate the confusion, but this is too many levels deep to put an explanation here. The mapping from constructors to "methods" happens way back in 15.9.3. This refers to 15.12.2, which steps through 15.12.2.1 and 15.12.2.2 (or more), which refers to 18.5.1. That's a lot of surface area to be adding extra reminders about "by the way, we might be talking about notional methods derived from constructors here". I think it's better just to leave that stuff in 15.9. (An even better solution would be to somehow generalize about methods and constructors, rather than doing this "as if it were a method" business, but oh well...) ?Dan From daniel.smith at oracle.com Mon Dec 16 16:09:25 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Mon, 16 Dec 2013 17:09:25 -0700 Subject: Part F - Question In-Reply-To: References: Message-ID: <52710B7F-86E9-49CF-8F96-3E0BA8192486@oracle.com> I have seen this suggestion; I think it's probably too late to act on it, but I will explore/consult a little further before deciding definitively what should be done. ?Dan On Dec 9, 2013, at 10:10 PM, Srikanth S Adayapalam wrote: > > From: Dan Smith > > Subject: Re: Part F - Question > > > > Yes, there's a spec/implementation discrepancy right now. We're > > discussing internally how we'd like to handle this. (Any comments > > here are welcome, too, of course.) > > OK, Here is some input: > > The present definition of value/void compatibility matches that of > "regular" or "vanilla" methods. That has its merits as far as language > regularity/consistency goes, but can be a tad too pedantic when carried > over to lambdas: I wonder if things get much simplified for compiler > implementers [*] if we choose to adopt a pragmatic definition that would > not amount IMO to any loss of useful functionality: > > So the suggestion: > > For lambda's with expression body - no change is required. > For lambda's with block bodies - what would it mean if the definition > is tweaked to say: > > For the purposes of applicability checks *only* > - A block bodied lambda is void compatible if every return in its > body lacks an expression (or there are no return statements in its body) > - A block bodied lambda is value compatible if every return in its > body is of the form "return expression" > - A block bodied lambda is also value compatible if the last statement > in its body is a throw statement. > > I see two ramifications of such a change: > > 1. Lambda's of the form: > > (x) -> { if (x > 10) return x; } > > would be seen to be value compatible for the purposes of potential applicability > checks instead of being declared as being neither value nor void compatible per the > present rules. So, what ? This is a distinction without a difference - This is a > broken lambda and by declaring it as value compatible for potential applicability > checks, we are simply but surely deferring the error reporting to a later stage. > (It could even result in better error messages in some cases based on an implementation) > > 2. A lambda of the form: > > () -> { while (true); } > > would not be seen to be value compatible. > > Again, it appears to be that there is no major loss of functionality due to this. > > In general, there is value (sorry for overloading the term :)) to deducing/treating > methods that don't complete normally as being value compatible (assuming otherwise > they are well formed), as this supports a bunch of use cases such as > > - "abstract virtual methods" in a concrete class. You often don't want to introduce > a new abstract method in a concrete class because that would burden the entire hierarchy > while the new method could be pertinent only to a few parts of the hierarchy. So provide > an implementation that just throws an exception to shut up the compiler. > > - Invalid inputs: A switch case statement may handle variety of valid inputs and > the ultimate statement in the method could be a throw for invalid values. > > - while (true) server loops. > > I think the special allowance to treat a lambda as being value compatible if its last statement > throws an exception would cover these cases adequately. > > The present definition makes (as the spec calls out) value-void compatibility a non-structural > property - necessarily calling for control/data flow analysis to be performed to determine the > shape. It is not clear to me that the benefits outweigh the cost to an implementation. With the > suggested changes even a basic AST visitor would suffice. > > (As an aside: (non-compiler) tool builders have some interesting challenges here too: Compiler > have it easy - they see a broken program and they reject it. Right now I am working on providing > code completion support for type elided parameters - the lambda is being written "just now", > the programmer is requesting code assistant support to write the lambda - now if a tool builder > implements the spec rigorously and holds a lambda as being not value compatible because the > return statement has not been yet written, the method invocation may never be resolved and the > elided types will never be inferred.) > > > [*] We have solved this problem in the Eclipse compiler. > > Thanks! > Srikanth From daniel.smith at oracle.com Mon Dec 16 16:13:43 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Mon, 16 Dec 2013 17:13:43 -0700 Subject: Missing substitution in 18.3? In-Reply-To: <52A66C91.1010106@berlin.de> References: <52A66C91.1010106@berlin.de> Message-ID: <68FD530F-0169-44A1-B43D-E4512123A18D@oracle.com> The substitution should not be applied to Ai -- it's for the declared bounds, not the (use-site) type arguments. Can you provide an example so I can explore whether there's something wrong with 18.5.2? ?Dan On Dec 9, 2013, at 6:21 PM, Stephan Herrmann wrote: > I'm looking at a complex example where inference fails > (contrary to javac behavior). > The most likely problem is in 18.3., sedond list, bullet 5: > > "If Ai is not a wildcard, the bound ?i = Ai is immediately implied." > > I believe sustitution ? must be applied to Ai, here! > (prefix or postfix as you like :) ) > Alternatively, there could be s.t. wrong with how the capture bound > was first created in 18.5.2 (rhs here has no substitution either). > The point is we are leaking type variables into the inference, > for which inference variables have been defined -> FAIL. > > Do you agree? > Stephan From daniel.smith at oracle.com Mon Dec 16 16:18:42 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Mon, 16 Dec 2013 17:18:42 -0700 Subject: exception constraints for explicitly-typed lambdas In-Reply-To: <52A48CEC.7080105@berlin.de> References: <52A48CEC.7080105@berlin.de> Message-ID: <4BD8BD18-4A58-4806-85CF-00569197E7F0@oracle.com> Yes, looks like there's something wrong. I'll explore further; I've created a bug: https://bugs.openjdk.java.net/browse/JDK-8030478 On Dec 8, 2013, at 8:14 AM, Stephan Herrmann wrote: > I may have a bug here, but from all I can see there's s.t. > inconsistent as demonstrated by the following example: > > class A {} > class B extends A { void bar() {} } > public class X { > public static void main(String[] argv) { > someWithIndex(getList(), (B b) -> b.bar()); // HERE > } > interface ItemWithIndexVisitor { > public void visit(E item); > } > public static void someWithIndex(List list, ItemWithIndexVisitor visitor) {} > static List getList() { return null; } > } > > javac accepts this program, but I don't see how: > > During invocation type inference for the marked call I get the following: > > The set C contains: > constraint1: ?getList() ?throws java.util.List? > constraint2: ?(B b) -> b.bar() ?throws X.ItemWithIndexVisitor? > > Input variables: > constraint1: none > constraint2: none > > Output variables: > constraint1: G#0 > constraint2: G#0 > > No input-output dependencies, so both constraints are picked. > > The union of input variables is empty, nothing gets resolved nor substituted > => constraints remain as given above. > > During reduction of constraint2 we fail because of the unsubstituted > inference variable G#0. > This happens at 18.2.5 bullet 3: > one "of the function type's parameter types is not a proper type" -> FALSE > > > I must admit that I don't have a good intuition for the terms "input" > and "output variables", so I only have a "mechanical" guess as to where > the conflict lies; the following don't harmonize: > > [a] excluding parameters of explicitly-typed lambdas from input variables > ("... the input variables include i) if the lambda expression is implicitly-typed...") > > [b] checking parameters of all lambdas in 18.2.5 > > My guess is that [b] is wrong in some way (completely bogus or should add > condition "if lambda expression is implicitly-typed" as done in 18.2.1.1). > > Which is it? > > best, > Stephan From daniel.smith at oracle.com Mon Dec 16 18:47:10 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Mon, 16 Dec 2013 19:47:10 -0700 Subject: Public Review bug fixes Message-ID: <315C798A-5EE8-474E-946C-1F0D74069664@oracle.com> The Public Review period for JSR 335 completed Dec 4. This included the 0.7.0 version of the language/VM spec document. I've had a lot of great feedback from the Expert Group, internally at Oracle, and from other contributors. I've also been working on integrating the documents with the rest of JLS 8 and JVMS 8. During this period I've addressed a number of bugs in the specification. As we approach the final draft, I've been tracking these changes more carefully. A list of all spec bugs (defined as semantically-meaningful changes) appears below. See bugs.openjdk.java.net to find the full bug report and discussion (e.g., updated specification text). The complete list can be found here: https://bugs.openjdk.java.net/issues/?jql=labels%3Dlambda-pr Some, marked with an asterisk (*), have not yet been resolved. They will be addressed this week prior to the final draft. I believe all known issues have been filed. Watch for two related emails shortly: - The 0.8.0 specification and diff - A summary of feedback from lambda-spec-comments Lambdas & method references JDK-8030352 Lambda Spec: Mention lambdas and method refs in 15.7.5 JDK-8029640 Lambda Spec: Require unchecked warnings for parameter/return types of method ref JDK-8029632 Lambda Spec: Raw inner class constructor ref should not attempt diamond inference JDK-8029573 Lambda Spec: Target function type of a lambda expression cannot be generic JDK-8029571 Lambda Spec: Array types cannot be used for static method references JDK-8029568 Lambda Spec: Clarify the return type of a reference to method getClass JDK-8029306 Lambda Spec: Capture for method references like Optional::get JDK-8027798 Lambda Spec: RawType::new is an inexact method reference JDK-8027738 Lambda Spec: Disallow arrays in intersection cast targets JDK-8030355* Lambda Spec: Grammar for lambda expressions is ambiguous JDK-8030356* Lambda Spec: Prohibit RawClass::new JDK-8030351* Lambda Spec: Add method references to 13.1 JDK-8029660* Lambda Spec: Define lambda class behavior for generics/bridges JDK-8028690* Lambda Spec: Clarify how parameter/return types are derived for MethodHandle::invoke JDK-8030358* Lambda Spec: Most-specific for an exact method reference targeting different parameter types Type inference JDK-8030148 Lambda Spec: Reduction for Foo = Foo JDK-8030018 Lambda Spec: Inference should generate an eq bound from an unboxing constraint JDK-8030012 Lambda Spec: Allow assignment conversion of lambda results during inference JDK-8028805 Lambda Spec: Clarify where unchecked conversions occur during inference JDK-8027859 Lambda Spec: S <= T should lead to = constraints, not <: constraints JDK-8030478* Lambda Spec: Perform appropriate substitutions on constraint target types in 18.5.2 JDK-8030349* Lambda Spec: Move 'lub' from 15.12.2.7 JDK-8029866* Lambda Spec: Despite unchecked invocation, parameter types should be inferred JDK-8029704* Lambda Spec: Fix subtype inference for a non-parameterized inner class of a generic type JDK-8028813* Lambda Spec: Take multiple upper bounds into account in incorporation JDK-8028800* Lambda Spec: Support capture when a nested invocation returns an inference variable Default methods (JLS) JDK-8030220 Lambda Spec: Define runtime behavior for default methods in 15.12.4.4 JDK-8030137 Lambda Spec: Error if inherited static method hides an interface method JDK-8030015 Lambda Spec: Error for TypeVariable.super.m() JDK-8030150* Lambda Spec: Error for static interface method invocation via an expression Default methods (JVMS) JDK-8030281 Lambda Spec: Allow static/special MethodHandles to reference InterfaceMethodrefs JDK-8027740 Lambda Spec: JVMS 5.4.3.3 "maximally-specific superinterface method" should be defined for interfaces JDK-8027581 Lambda Spec: method accessibility checking on invokeinterface of j.l.Object methods From stephan.herrmann at berlin.de Tue Dec 17 07:27:18 2013 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Tue, 17 Dec 2013 16:27:18 +0100 Subject: Missing substitution in 18.3? In-Reply-To: <68FD530F-0169-44A1-B43D-E4512123A18D@oracle.com> References: <52A66C91.1010106@berlin.de> <68FD530F-0169-44A1-B43D-E4512123A18D@oracle.com> Message-ID: <52B06D56.3090202@berlin.de> Here's an example: import java.util.*; import java.util.stream.*; public class X { public void test() { List roster = new ArrayList<>(); Map map = roster .stream() .collect( Collectors.toMap( p -> p.getLast(), p -> p )); } } class Person { public String getLast() { return null; } } Appling 18.5.2 for toMap has R = Collector> A1 = T Thus T goes into this capture bound: Collector = capture (Collector>) In the implementation ?1 print here as T#5. In 18.3 incorporating the capture bounds has A1 = T T is not a wildcard, hence the bound T#5 = T is added. During incorporation we combine the bounds T#5 :> Person (reduced from ?G ? S?) T#5 = T creating the constraint ?T :> Person?, which reduces to FALSE, but we should find a solution. At some point the type variables T,K,U of toMap must be substituted with their inference variables, but neither 18.5.2 nor 18.3 say so, or am I missing anything? best, Stephan On 12/17/2013 01:13 AM, Dan Smith wrote: > The substitution should not be applied to Ai -- it's for the declared bounds, not the (use-site) type arguments. > > Can you provide an example so I can explore whether there's something wrong with 18.5.2? > > ?Dan > > On Dec 9, 2013, at 6:21 PM, Stephan Herrmann wrote: > >> I'm looking at a complex example where inference fails >> (contrary to javac behavior). >> The most likely problem is in 18.3., sedond list, bullet 5: >> >> "If Ai is not a wildcard, the bound ?i = Ai is immediately implied." >> >> I believe sustitution ? must be applied to Ai, here! >> (prefix or postfix as you like :) ) >> Alternatively, there could be s.t. wrong with how the capture bound >> was first created in 18.5.2 (rhs here has no substitution either). >> The point is we are leaking type variables into the inference, >> for which inference variables have been defined -> FAIL. >> >> Do you agree? >> Stephan > From daniel.smith at oracle.com Tue Dec 17 09:21:01 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Tue, 17 Dec 2013 10:21:01 -0700 Subject: JSR 335 Lambda Specification, 0.8.0 Message-ID: An updated specification can be found here: http://cr.openjdk.java.net/~dlsmith/jsr335-0.8.0/ Other links Diff: http://cr.openjdk.java.net/~dlsmith/jsr335-0.8.0-diff.html One-page HTML: http://cr.openjdk.java.net/~dlsmith/jsr335-0.8.0.html Downloadable zip: http://cr.openjdk.java.net/~dlsmith/jsr335-0.8.0.zip The list of bugs identified since 0.7.0 is here; bugs that were resolved on or before December 16 are included in version 0.8.0. https://bugs.openjdk.java.net/issues/?jql=labels%3Dlambda-pr Full change log, from the document: > Poly Expressions: Prohibited arrays in intersection casts. > > Typing and Evaluation: Made lambdas incompatible with generic targeted function types. Performed capture before the method reference method search. Avoided diamond inference for inner classes of raw types. Defined method references requiring inference as inexact. Specified unchecked warnings for method reference assignment. Added lambdas and method references to 15.7.5. > > Overload Resolution: Clarified the invocation type of the getClass method. Clarified that unchecked invocation does not cause target parameter types to be erased. > > Type Inference: No longer require a bound set as input to reduction. Allowed narrowing of primitive constants in lambda bodies. Clarified when unchecked conversion occurs during inference. Cleaned up reduction of containment/equality constraints involving wildcards. Fixed minor notational problems. > > Default Methods: Added the runtime behavior of default method invocation (15.12.4.4). Defined concrete methods. Updated the definition of hiding (by static methods), consistent with previous changes to overriding. Clarified that TypeName.super cannot be used to refer to a type variable. Clarified that the type to search, for InterfaceName.super, is provided by the implements clause. > > Java Virtual Machine: Allowed invokeStatic and invokeSpecial MethodHandles to use InterfaceMethodrefs. Prohibited static and non-public methods of class Object from being the resolution of an InterfaceMethodref. > ?Dan From daniel.smith at oracle.com Tue Dec 17 14:27:01 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Tue, 17 Dec 2013 15:27:01 -0700 Subject: Reader mail bag, 2nd edition Message-ID: Here's a summary of feedback received on the lambda-spec-comments mailing list, and how it has been addressed. This covers the last few months, including the Public Review period. For the first edition, see http://mail.openjdk.java.net/pipermail/lambda-spec-experts/2013-August/000357.html 22 Aug 2013, Alex Buckley , "Default methods containing local/anonymous classes" This interaction between two different spec changes will be resolved as JSR 335 is incorporated with the rest of JLS 8. 8 Oct 2013, Jan Lahoda , "Enabling/disabling asserts in interface default methods" Not a new problem -- interfaces can contain nested or anonymous classes -- but a JLS bug has been reported. https://bugs.openjdk.java.net/browse/JDK-8030678 29 Oct 2013, Jon Rafkind "clarification of 18.2.3" The text was cleaned up as suggested in 0.8.0 (maybe in 0.7.0, too?...). 18 Nov 2013, Jon Rafkind , "18.2.3 subtyping constraints" A phrase similar to what Jon suggested appears in the 0.8.0 spec. 18 Nov 2013, Markus Keller , "Lambda expressions keeping a reference to the enclosing instance" The lack of a commitment one way or another on whether the value of a lambda expression retains a reference to 'this' is intentional: we want implementations to be free to discard the reference, but also want an implementation that directly translates to anonymous inner classes to be valid. 3 Dec 2013, Markus Keller , "Self-reference to field from lambda expression in initializer" I've had quite a few discussions about this, and concluded that it is best not to do anything until we flesh out a potential "recursive lambda expression" feature in the future. (In 8, local variables initialized with lambdas have a similar inability to directly refer to themselves.) 3 Dec 2013, Markus Keller , "Can an annotation type be a functional interface?" Reported as a javac bug: https://bugs.openjdk.java.net/browse/JDK-8030663 ?Dan From daniel.smith at oracle.com Tue Dec 17 15:26:39 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Tue, 17 Dec 2013 16:26:39 -0700 Subject: Missing substitution in 18.3? In-Reply-To: <52B06D56.3090202@berlin.de> References: <52A66C91.1010106@berlin.de> <68FD530F-0169-44A1-B43D-E4512123A18D@oracle.com> <52B06D56.3090202@berlin.de> Message-ID: <272C2324-FBB3-4EB4-B1C8-A8AD1A7917C3@oracle.com> On Dec 17, 2013, at 8:27 AM, Stephan Herrmann wrote: > At some point the type variables T,K,U of toMap must be > substituted with their inference variables, but neither 18.5.2 > nor 18.3 say so, or am I missing anything? Okay, yes. The capture bound should already have the substitution applied in 18.5.2: G = capture(G) I'll fix that. I also noticed that, since we've established that the invocation is a poly expression, the return type must contain an inference variable (after substitution) -- per 15.12 in Part D. So it can't be void. I've eliminated that case. ?Dan From daniel.smith at oracle.com Tue Dec 17 16:38:18 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Tue, 17 Dec 2013 17:38:18 -0700 Subject: exception constraints for explicitly-typed lambdas In-Reply-To: <4BD8BD18-4A58-4806-85CF-00569197E7F0@oracle.com> References: <52A48CEC.7080105@berlin.de> <4BD8BD18-4A58-4806-85CF-00569197E7F0@oracle.com> Message-ID: <334B3F77-4886-4FB6-829F-4AD686BFCFC4@oracle.com> I've resolved the bug. The problem is not that there are inference variables present, but instead that reduction is too eager to give up when it encounters inference variables. In your example, it doesn't matter that the parameter type is an inference variable, because we already know the parameter type from the declaration in the lambda expression. I've updated the reduction rules to be more permissive. ?Dan On Dec 16, 2013, at 5:18 PM, Dan Smith wrote: > Yes, looks like there's something wrong. I'll explore further; I've created a bug: > https://bugs.openjdk.java.net/browse/JDK-8030478 > > On Dec 8, 2013, at 8:14 AM, Stephan Herrmann wrote: > >> I may have a bug here, but from all I can see there's s.t. >> inconsistent as demonstrated by the following example: >> >> class A {} >> class B extends A { void bar() {} } >> public class X { >> public static void main(String[] argv) { >> someWithIndex(getList(), (B b) -> b.bar()); // HERE >> } >> interface ItemWithIndexVisitor { >> public void visit(E item); >> } >> public static void someWithIndex(List list, ItemWithIndexVisitor visitor) {} >> static List getList() { return null; } >> } >> >> javac accepts this program, but I don't see how: >> >> During invocation type inference for the marked call I get the following: >> >> The set C contains: >> constraint1: ?getList() ?throws java.util.List? >> constraint2: ?(B b) -> b.bar() ?throws X.ItemWithIndexVisitor? >> >> Input variables: >> constraint1: none >> constraint2: none >> >> Output variables: >> constraint1: G#0 >> constraint2: G#0 >> >> No input-output dependencies, so both constraints are picked. >> >> The union of input variables is empty, nothing gets resolved nor substituted >> => constraints remain as given above. >> >> During reduction of constraint2 we fail because of the unsubstituted >> inference variable G#0. >> This happens at 18.2.5 bullet 3: >> one "of the function type's parameter types is not a proper type" -> FALSE >> >> >> I must admit that I don't have a good intuition for the terms "input" >> and "output variables", so I only have a "mechanical" guess as to where >> the conflict lies; the following don't harmonize: >> >> [a] excluding parameters of explicitly-typed lambdas from input variables >> ("... the input variables include i) if the lambda expression is implicitly-typed...") >> >> [b] checking parameters of all lambdas in 18.2.5 >> >> My guess is that [b] is wrong in some way (completely bogus or should add >> condition "if lambda expression is implicitly-typed" as done in 18.2.1.1). >> >> Which is it? >> >> best, >> Stephan > From stephan.herrmann at berlin.de Thu Dec 19 08:39:59 2013 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Thu, 19 Dec 2013 17:39:59 +0100 Subject: reduction is too strict for =?UTF-8?B?4p+oTWV0aG9kUmVmZXJlbmNlIOKGkg==?= =?UTF-8?B?ICBhbHBoYeKfqQ==?= Message-ID: <52B3215F.3020401@berlin.de> From this program interface Functional { int foo(); } class X { static int bar() { return -1; } static T consume(T t) { return null; } public static void main(String[] args) { Functional f = consume(X::bar); } } we create this constraint: ?X::bar ? T#0? 18.2.1.2 says: "If T is not a functional interface type (9.8), or if T is a functional interface type but does not have a function type, the constraint reduces to false." Inference fails because T#0 (in inference variable) is not a functional interface type, nor does it have a sam. javac accepts the program, so it seems to use an additional reduction rule here? Stephan From daniel.smith at oracle.com Thu Dec 19 12:39:52 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Thu, 19 Dec 2013 13:39:52 -0700 Subject: =?utf-8?Q?Re=3A_reduction_is_too_strict_for_=E2=9F=A8MethodRefer?= =?utf-8?Q?ence_=E2=86=92__alpha=E2=9F=A9?= In-Reply-To: <52B3215F.3020401@berlin.de> References: <52B3215F.3020401@berlin.de> Message-ID: <7D9AE6EF-470A-49EC-A1CE-114D02CC9207@oracle.com> The argument should not be treated as pertinent to applicability. This statement from 15.12.2.2 is meant to apply to exact method references too: "If m is a generic method and the method invocation does not provide explicit type arguments, an explicitly-typed lambda expression ***or an exact method reference*** for which the corresponding target type (as derived from the signature of m) is a type parameter of m." (The part in asterisks is currently missing.) ?Dan On Dec 19, 2013, at 9:39 AM, Stephan Herrmann wrote: > From this program > > interface Functional { int foo(); } > > class X { > static int bar() { > return -1; > } > static T consume(T t) { return null; } > > public static void main(String[] args) { > Functional f = consume(X::bar); > } > } > > we create this constraint: > > ?X::bar ? T#0? > > 18.2.1.2 says: > > "If T is not a functional interface type (9.8), or if T is a functional interface type but does not have a function type, the constraint reduces to false." > > Inference fails because T#0 (in inference variable) is not a functional interface type, nor does it have a sam. > > javac accepts the program, so it seems to use an additional reduction rule here? > > Stephan From stephan.herrmann at berlin.de Thu Dec 19 13:07:58 2013 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Thu, 19 Dec 2013 22:07:58 +0100 Subject: reduction is too strict for =?UTF-8?B?4p+oTWV0aG9kUmVmZXJlbmM=?= =?UTF-8?B?ZSDihpIgIGFscGhh4p+p?= In-Reply-To: <7D9AE6EF-470A-49EC-A1CE-114D02CC9207@oracle.com> References: <52B3215F.3020401@berlin.de> <7D9AE6EF-470A-49EC-A1CE-114D02CC9207@oracle.com> Message-ID: <52B3602E.8000902@berlin.de> Yes, that explains, thanks, Stephan On 12/19/2013 09:39 PM, Dan Smith wrote: > The argument should not be treated as pertinent to applicability. This statement from 15.12.2.2 is meant to apply to exact method references too: > > "If m is a generic method and the method invocation does not provide explicit type arguments, an explicitly-typed lambda expression ***or an exact method reference*** for which the corresponding target type (as derived from the signature of m) is a type parameter of m." > > (The part in asterisks is currently missing.) > > ?Dan > > On Dec 19, 2013, at 9:39 AM, Stephan Herrmann wrote: > >> From this program >> >> interface Functional { int foo(); } >> >> class X { >> static int bar() { >> return -1; >> } >> static T consume(T t) { return null; } >> >> public static void main(String[] args) { >> Functional f = consume(X::bar); >> } >> } >> >> we create this constraint: >> >> ?X::bar ? T#0? >> >> 18.2.1.2 says: >> >> "If T is not a functional interface type (9.8), or if T is a functional interface type but does not have a function type, the constraint reduces to false." >> >> Inference fails because T#0 (in inference variable) is not a functional interface type, nor does it have a sam. >> >> javac accepts the program, so it seems to use an additional reduction rule here? >> >> Stephan > From srikanth_sankaran at in.ibm.com Thu Dec 19 21:59:24 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Fri, 20 Dec 2013 11:29:24 +0530 Subject: Eclipse + Java 8 Early access release II Message-ID: A brief note here that Eclipse announced availability of early access builds with improved support for Java 8: Announcement can be seen here: http://dev.eclipse.org/mhonarc/lists/eclipse-dev/msg09699.html. For 335, we still have advanced parts of Part G under development, but most of the rest should work. We expect to be feature complete by Jan 31st 2014, allowing for a 45 day beta program against a feature complete SDK. Any and all follow ups to eclipse newsgroups/bugzilla/mailing lists please. Thanks! Srikanth. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20131220/7e27fbc5/attachment.html From daniel.smith at oracle.com Fri Dec 20 16:33:47 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Fri, 20 Dec 2013 17:33:47 -0700 Subject: JSR 335 Lambda Specification, 0.9.0 Message-ID: <769DA1D4-ACEB-485B-AA70-8C752D4BCF61@oracle.com> An updated specification can be found here: http://cr.openjdk.java.net/~dlsmith/jsr335-0.9.0/ This is also the Proposed Final Draft; full materials (including API specs) can be found here: http://cr.openjdk.java.net/~dlsmith/jsr335-pfd/ Other links Diff: http://cr.openjdk.java.net/~dlsmith/jsr335-0.9.0-diff.html One-page HTML: http://cr.openjdk.java.net/~dlsmith/jsr335-0.9.0.html Downloadable zip: http://cr.openjdk.java.net/~dlsmith/jsr335-0.8.0.zip Downloadable PFD zip: http://cr.openjdk.java.net/~dlsmith/jsr335-pfd.zip The list of bugs identified since 0.7.0 is here; all have been resolved. https://bugs.openjdk.java.net/issues/?jql=labels%3Dlambda-pr Full change log, from the document: > Functional Interfaces: Introduced the term non-wildcard parameterization as an intermediate step when deriving a function type. Clarified when intersection types are used. Cleanup of some old discussion. > > Lambda Expressions: Cleanup of some old discussion. > > Method References: Prohibited use of constructor type arguments with diamond inference. Separated TypeName::m and ReferenceType::m as two distinct grammatical forms. > > Poly Expressions: Grammatical changes so that a LambdaExpression is no longer a Primary, in order to address ambiguities. > > Typing and Evaluation: Introduced the ground target type as an intermediate step towards deriving a function type. Checked that there are no overriding errors when the lambda or method reference overrides the methods of this type. Described exactly which methods are overridden, and which (erasure-based) casts occur at runtime. Accommodated the additionalTypeName::m syntactic form of a method reference. Described how references to signature-polymorphic methods are handled. Added new changes to 13.1 to account for method references. > > Overload Resolution: Asserted that, for a more-specific test of two functional interfaces targeted by an exact method references, the parameter types are the same. Cleaned up the rules for deriving the actual target types of invocation arguments when unchecked conversion was necessary. > > Type Inference: Mirrored the changes in Parts E and F. Clarified how inference variables in a wildcard-parameterized target type of an explicitly-typed lambda expression are handled, and cleaned up the section describing functional interface parameterization inference. Clarified how subtyping and equality constraints handle non-parameterized inner classes of parameterized types. Added an incorporation rule to check consistency of parameterized upper bounds. Cleaned up the treatment of ? extends Object, which should be equivalent to ?. Added some overlooked resolution dependencies on capture inference variables. Added rules to invocation type inference to special-case when the return type is an inference variable, and may end up either being wildcard-parameterized or requiring unchecked conversion. Explicitly moved the definition of lub to 4.10.4. > > Default Methods: Prohibited invoking a static interface method with an expression qualifier. ?Dan