From stephan.herrmann at berlin.de Fri Nov 1 07:59:39 2013 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Fri, 01 Nov 2013 15:59:39 +0100 Subject: Defaut methods are not visible if -source 1.7 is set In-Reply-To: <526FEFC3.30909@univ-mlv.fr> References: <526FEFC3.30909@univ-mlv.fr> Message-ID: <5273C1DB.5010500@berlin.de> In terms of coordinating the behavior of javac and the Eclipse compiler I'm happy this issue has been raised here. I couldn't see any real conclusion, yet. Did I miss a relevant post? How do you think a compiler at -source 1.7 *should* handle default methods? Here's another example from an earlier instance of this discussion: Compile at -source 1.8: public interface I { default void foo() {} } and consuming the .class of the above compile at -source 1.7: public class CI implements I { void test(I i) { this.foo(); i.foo(); } } From two calls to the same method, javac (all versions) flags one: CI.java:3: error: cannot find symbol this.foo(); ^ symbol: method foo() 1 error Will this be the final behavior of javac? For comparison, the Eclipse compiler (beta) currently reports only this: public class CI implements I { ^^ The type CI must implement the inherited abstract method I.foo() ---------- 1 problem (1 error) Whereas the latest release version reports nothing. Stephan On 10/29/2013 06:26 PM, Remi Forax wrote: > This is from enhanced-metadata-spec-discuss mailing list > but I think this issue can interest this audience because it seems > that javac doesn't respect the spec we have drafted or the spec has changed without me noticing it. > Anyway there is a discrepancy somewhere. > > From Joe Darcy: > >>> Wouldn't this risk the same issues as when we turned isAnnotationPresent() into a default? >>> >>> >> >> No; we don't have the same hazard here as with isAnnotationPresent. The issue we ran into with making isAnnotationPresent a >> default method was that isAnnotationPresent was part of the original AnnotatedElement interface defined way back in Java SE 5. In >> implementation decision in javac did not expose the existence of default methods to code being compiled under source levels less >> than 8. That is a pragmatic choice and usually gives the desired result, but not in this case. >> > > So it seems that javac 8 doesn't see default methods if source level is 1.7 (-source 1.7) > and as Joe notice this hamper to transform any existing abstract method to a default method. > > I'm pretty sure that we have talked about that and said that adding default to a method should be > source compatible when we have discussed about Iterator.remove. > Otherwise it goes against the intuition that providing a body to an existing abstract method is harmless. > > So either javac8 implementation is not correct (BTW, javac7 see default methods) > or the spec shoud be changed to say that adding a default implementation is not a compatible change > and Iterator.remove should be re-abstracted. > > regards, > R?mi > From stephan.herrmann at berlin.de Sun Nov 3 09:27:53 2013 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Sun, 03 Nov 2013 18:27:53 +0100 Subject: inference trouble with recursive generics and raw types Message-ID: <52768799.9030409@berlin.de> Working on the latest spec I'm seeing a discrepancy between the spec and actual javac behavior. interface Foo> { } class Bar { } public class X { void readDatabase() { Bar bar = new Bar(); read(bar, "sadasd"); // infer this call! }

, D extends Bar

> D read(D d, String s) { return d; } } I see type inferencing regarding the invocation of read(..) producing the following: (a) declaration of type variable P produces this dependency: P#0 <: Foo (where P#0 is an inference variable representing P) (b) declaration of type variable D produces this type bound: D#1 <: Bar (c) the constraint formula for the argument expression 'bar' yields: D#1 :> Bar (d) incorporation of (b) and (c) yields this constraint: ?Bar <: Bar? (e) reduction on (d) yields this type bound: P#0 :> Foo (f) incorporating (a) with (e) yields this type constraint: ?Foo <: Foo? At this point inference fails because the raw type Foo is not recognized as a legal subtype of Foo: In 18.2.3 the 5.2nd bullet applies: We need to find the parameterization of Foo that is a supertype of Foo, which, however, cannot be determined since Foo (substitute for S) is a raw type. Is there a mistake in my derivation? OTOH, all compilers that I tested accept the above program (from javac 1.5 to 8b112 as well as ecj). In spite of all talk about reducing the support for raw types, the above example seems to be a relevant pattern, were avoidance of raw types is not as easy as just filling in some type parameters (or is the above program actually unsafe and thus can only be written using raw types?) Unless I'm missing s.t.: Either the spec needs to be extended to gracefully handle raw types in at least this particular rule. Or all compilers have a bug and must be fixed :) best, Stephan From daniel.smith at oracle.com Mon Nov 4 08:38:55 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Mon, 4 Nov 2013 09:38:55 -0700 Subject: inference trouble with recursive generics and raw types In-Reply-To: <52768799.9030409@berlin.de> References: <52768799.9030409@berlin.de> Message-ID: <55B8B9C4-85C7-47F8-A670-5E4637A929CC@oracle.com> On Nov 3, 2013, at 10:27 AM, Stephan Herrmann wrote: > Working on the latest spec I'm seeing a discrepancy between > the spec and actual javac behavior. > > interface Foo> { > } > > class Bar { > } > > public class X { > void readDatabase() { > Bar bar = new Bar(); > read(bar, "sadasd"); // infer this call! > } > >

, D extends Bar

> > D read(D d, String s) { > return d; > } > } This is essentially the same issue that you reported on October 10, right? public class X { public static void main(String[] args) { EntityKey entityKey = null; new EntityCondenser().condense(entityKey); } public static class EntityCondenser { , K extends EntityKey> void condense(K entityKey) { } } public class EntityKey {} public interface EntityType< I, E extends EntityType, K extends EntityKey> { } } > I see type inferencing regarding the invocation of read(..) > producing the following: > (a) declaration of type variable P produces this dependency: > P#0 <: Foo > (where P#0 is an inference variable representing P) > (b) declaration of type variable D produces this type bound: > D#1 <: Bar > (c) the constraint formula for the argument expression 'bar' yields: > D#1 :> Bar > (d) incorporation of (b) and (c) yields this constraint: > ?Bar <: Bar? > (e) reduction on (d) yields this type bound: > P#0 :> Foo > (f) incorporating (a) with (e) yields this type constraint: > ?Foo <: Foo? > At this point inference fails because the raw type Foo is not > recognized as a legal subtype of Foo: In 18.2.3 the > 5.2nd bullet applies: We need to find the parameterization > of Foo that is a supertype of Foo, which, however, cannot be > determined since Foo (substitute for S) is a raw type. > > Is there a mistake in my derivation? Nope, I agree with your explanation (except step (e) should be an eq bound, not a lower bound). Crucially, raw Foo is not within the upper bound of P#0. > OTOH, all compilers that I tested accept the above program > (from javac 1.5 to 8b112 as well as ecj). Yes, I identified this as a bug in your last report. Significantly, an invocation of the form 'this.>read(bar, "sadasd")' will compile. So this isn't really specifically an inference issue: the compilers simply believe that a raw type is "within" a bound that is a parameterization of that type. And that interpretation is flat-out wrong. Bounds are subtyping assertions. JLS is consistent about this -- see 4.5 and 15.12.2.2-4. Here's my javac bug report: https://bugs.openjdk.java.net/browse/JDK-8026527 > In spite of all talk about reducing the support for raw types, the > above example seems to be a relevant pattern, were avoidance of > raw types is not as easy as just filling in some type parameters > (or is the above program actually unsafe and thus can only be > written using raw types?) > > Unless I'm missing s.t.: > > Either the spec needs to be extended to gracefully handle raw > types in at least this particular rule. > > Or all compilers have a bug and must be fixed :) The compilers have a bug. It might make sense to reexamine the spec here if there were some sort of lack of clarity, but there's really not. And making a change in the interpretation of bounds would be a big deal, because the use of subtyping here is fundamental to a lot of things (like inference, type variable subtyping, etc.) that are built on top. ?Dan From stephan.herrmann at berlin.de Tue Nov 5 03:01:46 2013 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Tue, 05 Nov 2013 12:01:46 +0100 Subject: inference trouble with recursive generics and raw types In-Reply-To: <55B8B9C4-85C7-47F8-A670-5E4637A929CC@oracle.com> References: <52768799.9030409@berlin.de> <55B8B9C4-85C7-47F8-A670-5E4637A929CC@oracle.com> Message-ID: <5278D01A.3070109@berlin.de> On 11/04/2013 05:38 PM, Dan Smith wrote: > This is essentially the same issue that you reported on October 10, right? I'm sorry, I thought these might be independent bugs for different combinations of ingredients. Looking at the JDK bug it indeed looks more like one general problem indeed. In that case I only disagree with ranking that bug at P4. We want to reject programs that can be compiled with all known compilers. People won't like this, but perhaps this can be communicated as a task connected to the migration from Java 7- to Java 8. OTOH, people already have a Java 8 EA in their hands and don't see this migration task. Is there a way we can coordinate this step between compilers and ensure this happens clearly before shipping? Here's a little statistic to show relevance of this issue: from a particular test suite of ~8000 test cases, ~2000 currently trigger type inference, 132 are failing, 97 trigger the situation where inference tries to match a parameterized type against a raw type. A _assume_ that most of these cases have been written in response to various bug reports from users, reflecting occurrences in real world software. >> I see type inferencing regarding the invocation of read(..) >> producing the following: >> [...] >> (d) incorporation of (b) and (c) yields this constraint: >> ?Bar <: Bar? >> (e) reduction on (d) yields this type bound: >> P#0 :> Foo >> [...] >> >> Is there a mistake in my derivation? > > Nope, I agree with your explanation (except step (e) should be an eq bound, not a lower bound). Oops, really? From ?Bar <: Bar?, 18.2.3 creates ?Foo <= P#0?. Since neither Foo nor P#0 are wildcards I see 18.2.3 producing ?Foo <: P#0?, further reduced to the bound Foo <: P#0 because P#0 is an inference variable. What am I missing? thanks, Stephan From daniel.smith at oracle.com Tue Nov 5 10:03:46 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Tue, 5 Nov 2013 11:03:46 -0700 Subject: inference trouble with recursive generics and raw types In-Reply-To: <5278D01A.3070109@berlin.de> References: <52768799.9030409@berlin.de> <55B8B9C4-85C7-47F8-A670-5E4637A929CC@oracle.com> <5278D01A.3070109@berlin.de> Message-ID: <996D3BF5-A822-4304-B231-5470D4D30065@oracle.com> On Nov 5, 2013, at 4:01 AM, Stephan Herrmann wrote: >> Nope, I agree with your explanation (except step (e) should be an eq bound, not a lower bound). > > Oops, really? > > From ?Bar <: Bar?, 18.2.3 creates ?Foo <= P#0?. > Since neither Foo nor P#0 are wildcards I see 18.2.3 producing ?Foo <: P#0?, > further reduced to the bound Foo <: P#0 because P#0 is an inference variable. > > What am I missing? I'll have some conversations internally about how we feel about the unchecked conversion bug, but here's a response to this part: This is just the guy who wrote the rules having a blerk moment. Sorry about that. Glad you caught it! It has to be equality -- that's the way subtyping works (see JLS 4.10): List <: List implies foo = bar. ?Dan From stephan.herrmann at berlin.de Tue Nov 5 10:19:17 2013 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Tue, 05 Nov 2013 19:19:17 +0100 Subject: inference trouble with recursive generics and raw types In-Reply-To: <996D3BF5-A822-4304-B231-5470D4D30065@oracle.com> References: <52768799.9030409@berlin.de> <55B8B9C4-85C7-47F8-A670-5E4637A929CC@oracle.com> <5278D01A.3070109@berlin.de> <996D3BF5-A822-4304-B231-5470D4D30065@oracle.com> Message-ID: <527936A5.2080506@berlin.de> On 11/05/2013 07:03 PM, Dan Smith wrote: > On Nov 5, 2013, at 4:01 AM, Stephan Herrmann wrote: >> From ?Bar <: Bar?, 18.2.3 creates ?Foo <= P#0?. >> Since neither Foo nor P#0 are wildcards I see 18.2.3 producing ?Foo <: P#0?, >> further reduced to the bound Foo <: P#0 because P#0 is an inference variable. >> > [...] > It has to be equality -- that's the way subtyping works (see JLS 4.10): List <: List implies foo = bar. Good :) So, since reduction happens in several steps (via the type argument containment), which step needs correcting? Drop the type argument containment and go directly to equality? In that case type argument containment constraints seem to be unused in the spec, right? thanks, Stephan From daniel.smith at oracle.com Tue Nov 5 10:28:52 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Tue, 5 Nov 2013 11:28:52 -0700 Subject: inference trouble with recursive generics and raw types In-Reply-To: <527936A5.2080506@berlin.de> References: <52768799.9030409@berlin.de> <55B8B9C4-85C7-47F8-A670-5E4637A929CC@oracle.com> <5278D01A.3070109@berlin.de> <996D3BF5-A822-4304-B231-5470D4D30065@oracle.com> <527936A5.2080506@berlin.de> Message-ID: On Nov 5, 2013, at 11:19 AM, Stephan Herrmann wrote: > On 11/05/2013 07:03 PM, Dan Smith wrote: >> On Nov 5, 2013, at 4:01 AM, Stephan Herrmann wrote: >>> From ?Bar <: Bar?, 18.2.3 creates ?Foo <= P#0?. >>> Since neither Foo nor P#0 are wildcards I see 18.2.3 producing ?Foo <: P#0?, >>> further reduced to the bound Foo <: P#0 because P#0 is an inference variable. >>> > > [...] >> It has to be equality -- that's the way subtyping works (see JLS 4.10): List <: List implies foo = bar. > > Good :) > > So, since reduction happens in several steps (via the type argument containment), > which step needs correcting? Drop the type argument containment and go > directly to equality? In that case type argument containment constraints > seem to be unused in the spec, right? No, containment is a convenient generalization (because it can handle wildcards). It's just that (where S and T are types) S <= T should reduce to S = T, while S <= ? extends T should reduce to S <: T. I've fixed the containment reduction rule. ?Dan From stephan.herrmann at berlin.de Thu Nov 14 12:07:08 2013 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Thu, 14 Nov 2013 21:07:08 +0100 Subject: undeclared symbol in 18.5.2? Message-ID: <52852D6C.100@berlin.de> This should be an easy one: in 18.5.2 we have these fragments in order: "... and let S be the invocation's target type." "* For all i (1 ? i ? k), the set contains ?ei ?throws T?." "... the target type, T, ..." Are all three supposed to refer to "the invocation's target type"? In the 2nd fragment "T" doesn't seem to resolve to any declaration :) (Why "S" ?) best, Stephan From stephan.herrmann at berlin.de Tue Nov 19 13:01:18 2013 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Tue, 19 Nov 2013 22:01:18 +0100 Subject: undeclared symbol in 18.5.2? In-Reply-To: <52852D6C.100@berlin.de> References: <52852D6C.100@berlin.de> Message-ID: <528BD19E.6000202@berlin.de> Pondering more about this I no longer think this is only a trivial question of notation: On 11/14/2013 09:07 PM, Stephan Herrmann wrote: > This should be an easy one: > > in 18.5.2 we have these fragments in order: > > "... and let S be the invocation's target type." This is guarded by "If the invocation is a poly expression" so we know that a context exists that defines a target type. OK. > "* For all i (1 ? i ? k), the set contains ?ei ?throws T?." This one is not guarded, so we expect to have a T even in standalone situations. Something seems to be missing here. This spec throws NPE :). Please clarify. > "... the target type, T, ..." Although using the same term "target type" as above, this seems to actually refer to the T introduced in this sentence: "Invocation type inference may require carefully sequencing the reduction of constraint formulas of the form ?Expression ? T? and ?Expression ?throws T?. To facilitate this sequencing, the input variables of these constraints are defined as follows:" Is this guess correct? Stephan From stephan.herrmann at berlin.de Tue Nov 19 13:21:57 2013 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Tue, 19 Nov 2013 22:21:57 +0100 Subject: meaning of "current bound set" in 18.5.2 Message-ID: <528BD675.7020003@berlin.de> Here's another one regarding 18.5.2: For most of this section the spec is careful in defining which bounds are incorporated into which bound set, building up a sequence of B1, B2 and B3. (Note, that B2 is constructed only conditionally). Then at the end of the 5th bullet, more bounds are said to be incorporated with "the current bound set". The use of B1 ... gives the impression we speak about distinct sets, but my intuitive understanding suggests we are instead speaking about *one* bound set that is incrementally filled with more bounds as the analysis proceeds. If distinct sets are intended, than I'm missing - any use of the constructed set B2 - a definition for "current bound set" If accumulation into one bound set is intended, then all talk of B1, B2, B3 seems to confuse more than it helps, IMHO. please clarify, thanks, Stephan From stephan.herrmann at berlin.de Thu Nov 21 06:40:03 2013 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Thu, 21 Nov 2013 15:40:03 +0100 Subject: typo in 18.4? Message-ID: <528E1B43.4080707@berlin.de> not sure whether this has been mentioned before (by me?): This sentence in 18.4: For all i, (1 ? i ? n), where ?i has upper bounds U1, ..., Uk, then define the upper bound of Zi as glb(L1?, ..., Lk?). should probably say "glb(U1?, ..., Uk?).", right? Stephan From stephan.herrmann at berlin.de Thu Nov 21 07:38:50 2013 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Thu, 21 Nov 2013 16:38:50 +0100 Subject: 18.5.2 "the resulting instantiations are not considered part of B1." Message-ID: <528E290A.5060508@berlin.de> I'm looking at this example: public static void myMethod(final List fileList) { Collections.sort(fileList, new Comparator(){ public int compare(File f1, File f2) { return 0; } }); } Check for applicability creates these type bounds (where T#0 stands for an inference variable for T): T#0 = capture#1-of ? extends File T#0 <: File T#0 <: java.lang.Object We have a solution, so we proceed to inferring the invocation type. Now 18.5.2 says I should use the above bounds (B1) but "the resulting instantiations are not considered part of B1." I see two possible interpretations of this, neither of which produces the desired result. (1) I could drop the first bound entirely (because this effectively instantiates T#0. Result: T#0 will be inferred to File with is the wrong result, sort(List,Comparator) does not accept the argument of type List. (2) I could keep all the bounds but forget the fact that one of them actually comprises an instantiation. Now resolution will continue: - (first attempt) add T#0 = File, which is in conflict with the existing bound - (second attempt) add T#0 = Z, where Z is a fresh type variable Also this fails the inference because of this constraint: Z = capture#1-of ? extends File Ergo, this variant produces no solution. Only by ignoring that sentence of the spec (i.e., keeping the instantiation from B1) can I make inference succeed. All compilers accept the example without warning/error, but I don't see how the inference can make this work. what am I missing? Stephan From daniel.smith at oracle.com Thu Nov 21 15:55:51 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Thu, 21 Nov 2013 16:55:51 -0700 Subject: 18.5.2 "the resulting instantiations are not considered part of B1." In-Reply-To: <528E290A.5060508@berlin.de> References: <528E290A.5060508@berlin.de> Message-ID: <76D21C20-307D-49C8-91DF-9E085A7EA17A@oracle.com> On Nov 21, 2013, at 8:38 AM, Stephan Herrmann wrote: > I'm looking at this example: > > public static void myMethod(final List fileList) { > Collections.sort(fileList, new Comparator(){ > public int compare(File f1, File f2) { return 0; } > }); > } > > Check for applicability creates these type bounds > (where T#0 stands for an inference variable for T): > T#0 = capture#1-of ? extends File > T#0 <: File > T#0 <: java.lang.Object > We have a solution, so we proceed to inferring the invocation type. > > Now 18.5.2 says I should use the above bounds (B1) but "the resulting > instantiations are not considered part of B1." Lets try this instead: "(While, as a final step in 18.5.1, it was necessary to demonstrate that the inference variables in B1 could be resolved in order to establish applicability, an instantiation produced by this resolution step is not considered part of B1.)" The instantiation for T#0 sticks around because we already knew it when B1 was defined, before the resolution step. Put another way, the resolution step described as the final step of 18.5.1 is tentative, and its results are immediately discarded. ?Dan From daniel.smith at oracle.com Thu Nov 21 15:56:21 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Thu, 21 Nov 2013 16:56:21 -0700 Subject: typo in 18.4? In-Reply-To: <528E1B43.4080707@berlin.de> References: <528E1B43.4080707@berlin.de> Message-ID: <36202EB2-9B5B-4729-B68C-C29895895C10@oracle.com> Yes, thanks. Somebody else pointed that out to me this week, too. ?Dan On Nov 21, 2013, at 7:40 AM, Stephan Herrmann wrote: > not sure whether this has been mentioned before (by me?): > > This sentence in 18.4: > > For all i, (1 ? i ? n), where ?i has upper bounds U1, ..., Uk, > then define the upper bound of Zi as glb(L1?, ..., Lk?). > > should probably say "glb(U1?, ..., Uk?).", right? > > Stephan From daniel.smith at oracle.com Thu Nov 21 16:22:47 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Thu, 21 Nov 2013 17:22:47 -0700 Subject: undeclared symbol in 18.5.2? In-Reply-To: <528BD19E.6000202@berlin.de> References: <52852D6C.100@berlin.de> <528BD19E.6000202@berlin.de> Message-ID: <1B582DB8-7FCA-4D58-8A7E-DE9878BB8C85@oracle.com> Even worse, I seem to have garbled the prefix vs. postfix use of substitutions again in this section. :-) Apparently my brain is incapable of adapting to postfix. On Nov 19, 2013, at 2:01 PM, Stephan Herrmann wrote: > Pondering more about this I no longer think this is only > a trivial question of notation: > > On 11/14/2013 09:07 PM, Stephan Herrmann wrote: >> This should be an easy one: >> >> in 18.5.2 we have these fragments in order: >> >> "... and let S be the invocation's target type." > > This is guarded by "If the invocation is a poly expression" > so we know that a context exists that defines a target type. > OK. Yep. I think I chose S because it comes after R, by T does seem like a nicer alternative, so I'll change it. > >> "* For all i (1 ? i ? k), the set contains ?ei ?throws T?." > > This one is not guarded, so we expect to have a T even in > standalone situations. Something seems to be missing here. > This spec throws NPE :). Please clarify. Right, copy-paste error. Should be ei inthrows Fi theta That is, the RHS is the same as in the previous bullet -- the ith formal parameter type (after substitution). > >> "... the target type, T, ..." > > Although using the same term "target type" as above, this > seems to actually refer to the T introduced in this sentence: > > "Invocation type inference may require carefully sequencing > the reduction of constraint formulas of the form ?Expression ? T? > and ?Expression ?throws T?. To facilitate this sequencing, the > input variables of these constraints are defined as follows:" > > Is this guess correct? Yep. Let's try this: "The ''output variables'' of these constraints are all inference variables mentioned by the type on the right-hand side of the constraint, T, that are not input variables." ?Dan From daniel.smith at oracle.com Thu Nov 21 16:35:30 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Thu, 21 Nov 2013 17:35:30 -0700 Subject: meaning of "current bound set" in 18.5.2 In-Reply-To: <528BD675.7020003@berlin.de> References: <528BD675.7020003@berlin.de> Message-ID: On Nov 19, 2013, at 2:21 PM, Stephan Herrmann wrote: > Here's another one regarding 18.5.2: > > For most of this section the spec is careful in defining > which bounds are incorporated into which bound set, > building up a sequence of B1, B2 and B3. > (Note, that B2 is constructed only conditionally). > > Then at the end of the 5th bullet, more bounds are said > to be incorporated with "the current bound set". Yes, I should introduce this in the sentence "While C is not empty..." (it's essentially a loop variable that holds immutable sets). Its initial value is B2 (or B1, if we've skipped the 3rd bullet). > The use of B1 ... gives the impression we speak about > distinct sets, but my intuitive understanding suggests > we are instead speaking about *one* bound set that is > incrementally filled with more bounds as the analysis > proceeds. > > If distinct sets are intended, than I'm missing > - any use of the constructed set B2 > - a definition for "current bound set" Both solved by defining the current bound set at the start of the loop. > If accumulation into one bound set is intended, > then all talk of B1, B2, B3 seems to confuse more > than it helps, IMHO. It's reasonable to model this as accumulation into a mutating set, but then the names are necessary in order to express distinct points in time in that accumulation. B1 is defined by reference to B1 in 18.5.1. B2 is referenced from 18.2.1 and 18.2.1.2. ?Dan From brian.goetz at oracle.com Mon Nov 25 16:41:25 2013 From: brian.goetz at oracle.com (Brian Goetz) Date: Mon, 25 Nov 2013 19:41:25 -0500 Subject: @FunctionalInterface and Javadoc Message-ID: <5293EE35.2050807@oracle.com> A long time ago, we agreed that the Javadoc for a functional interface should say something like "This is a functional interface." This is done using a structural analysis of the interface, just as when used as the target of a lambda. Later in time, we arrived at @FunctionalInterface, which is optional to use. It is closest in spirit to @Override, since: - It captures design intent - It enlists the compiler's aid in catching violations of such intent; an @FI-marked method that is not a functional interface will merit a compile error. It has recently been pointed out that perhaps we should adjust the Javadoc generation, to trigger off of @FI rather than structurally, since there are functional interfaces in the JDK that are not marked @FI (deliberately) but which still bear the "This is a functional interface" blurb. From brian.goetz at oracle.com Mon Nov 25 16:41:49 2013 From: brian.goetz at oracle.com (Brian Goetz) Date: Mon, 25 Nov 2013 19:41:49 -0500 Subject: @FunctionalInterface and Javadoc Message-ID: <5293EE4D.6010905@oracle.com> A long time ago, we agreed that the Javadoc for a functional interface should say something like "This is a functional interface." This is done using a structural analysis of the interface, just as when used as the target of a lambda. Later in time, we arrived at @FunctionalInterface, which is optional to use. It is closest in spirit to @Override, since: - It captures design intent - It enlists the compiler's aid in catching violations of such intent; an @FI-marked method that is not a functional interface will merit a compile error. It has recently been pointed out that perhaps we should adjust the Javadoc generation, to trigger off of @FI rather than structurally, since there are functional interfaces in the JDK that are not marked @FI (deliberately) but which still bear the "This is a functional interface" blurb. From david.holmes at oracle.com Mon Nov 25 16:53:47 2013 From: david.holmes at oracle.com (David Holmes) Date: Tue, 26 Nov 2013 10:53:47 +1000 Subject: @FunctionalInterface and Javadoc In-Reply-To: <5293EE35.2050807@oracle.com> References: <5293EE35.2050807@oracle.com> Message-ID: <5293F11B.6060409@oracle.com> On 26/11/2013 10:41 AM, Brian Goetz wrote: > A long time ago, we agreed that the Javadoc for a functional interface > should say something like "This is a functional interface." This is > done using a structural analysis of the interface, just as when used as > the target of a lambda. > > Later in time, we arrived at @FunctionalInterface, which is optional to > use. It is closest in spirit to @Override, since: > - It captures design intent > - It enlists the compiler's aid in catching violations of such intent; > an @FI-marked method that is not a functional interface will merit a > compile error. > > It has recently been pointed out that perhaps we should adjust the > Javadoc generation, to trigger off of @FI rather than structurally, > since there are functional interfaces in the JDK that are not marked @FI > (deliberately) but which still bear the "This is a functional interface" > blurb. I would think you still want both as discussed in the email thread, but with different wording, also as discussed. I can imagine existing libraries being used across 7 and 8 and so not being able to apply @FI. I think something like: "In its current form this is implicitly a functional interface." which captures the implicit-ness and that in the future, should the interface be enhanced, it may no longer be a functional interface. David From srikanth_sankaran at in.ibm.com Tue Nov 26 00:16:42 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Tue, 26 Nov 2013 13:46:42 +0530 Subject: Part F - Question Message-ID: 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: // -- 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; }); } } But looking at the interfaces involved, I is "obviously" the "right" choice and the call is dismissed as being ambiguous only because the spec says so ? That is a good enough reason to reject, but just checking. 2. 15.12.2.5 introduces the notation References: <526FEFC3.30909@univ-mlv.fr> <5273C1DB.5010500@berlin.de> Message-ID: <32AFFFFA-A20A-4057-BA97-2A73A0E94F74@oracle.com> I finally had a chance to dig a little deeper into what's actually happening here. It's a narrower problem than I expected. javac does a lot of work to ensure that, under -source 7, default methods are "visible" at appropriate times, but don't get in the way: - You can @Override the method from any subtype - You never have to implement the method in a subtype - You can invoke the method as a member of the interface, or a subinterface, or an implementing abstract class The only exception is that you can't invoke the method as a member of a concrete class: interface I { default void m() {} } interface J extends I {} abstract class A implements I {} class B implements I {} // compile with -source 7: class Test { public static void test(I i, J j, A a, B b) { i.m(); // ok j.m(); // ok a.m(); // ok b.m(); // error } } So this looks much less like a design decision and much more like an overlooked corner case. I've created a bug: https://bugs.openjdk.java.net/browse/JDK-8029240 I expect this will likely be addressed in an update release of Java 8. ?Dan On Nov 1, 2013, at 8:59 AM, Stephan Herrmann wrote: > In terms of coordinating the behavior of javac and the Eclipse compiler > I'm happy this issue has been raised here. > I couldn't see any real conclusion, yet. Did I miss a relevant post? > How do you think a compiler at -source 1.7 *should* handle default methods? > > Here's another example from an earlier instance of this discussion: > > Compile at -source 1.8: > > public interface I { > default void foo() {} > } > > and consuming the .class of the above compile at -source 1.7: > > public class CI implements I { > void test(I i) { > this.foo(); > i.foo(); > } > } > > From two calls to the same method, javac (all versions) flags one: > > CI.java:3: error: cannot find symbol > this.foo(); > ^ > symbol: method foo() > 1 error > > Will this be the final behavior of javac? > > For comparison, the Eclipse compiler (beta) currently reports only this: > > public class CI implements I { > ^^ > The type CI must implement the inherited abstract method I.foo() > ---------- > 1 problem (1 error) > > Whereas the latest release version reports nothing. > > Stephan > > > On 10/29/2013 06:26 PM, Remi Forax wrote: >> This is from enhanced-metadata-spec-discuss mailing list >> but I think this issue can interest this audience because it seems >> that javac doesn't respect the spec we have drafted or the spec has changed without me noticing it. >> Anyway there is a discrepancy somewhere. >> >> From Joe Darcy: >> >>>> Wouldn't this risk the same issues as when we turned isAnnotationPresent() into a default? >>>> >>>> >>> >>> No; we don't have the same hazard here as with isAnnotationPresent. The issue we ran into with making isAnnotationPresent a >>> default method was that isAnnotationPresent was part of the original AnnotatedElement interface defined way back in Java SE 5. In >>> implementation decision in javac did not expose the existence of default methods to code being compiled under source levels less >>> than 8. That is a pragmatic choice and usually gives the desired result, but not in this case. >>> >> >> So it seems that javac 8 doesn't see default methods if source level is 1.7 (-source 1.7) >> and as Joe notice this hamper to transform any existing abstract method to a default method. >> >> I'm pretty sure that we have talked about that and said that adding default to a method should be >> source compatible when we have discussed about Iterator.remove. >> Otherwise it goes against the intuition that providing a body to an existing abstract method is harmless. >> >> So either javac8 implementation is not correct (BTW, javac7 see default methods) >> or the spec shoud be changed to say that adding a default implementation is not a compatible change >> and Iterator.remove should be re-abstracted. >> >> regards, >> R?mi >> > From daniel.smith at oracle.com Tue Nov 26 16:38:52 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Tue, 26 Nov 2013 17:38:52 -0700 Subject: inference trouble with recursive generics and raw types In-Reply-To: <996D3BF5-A822-4304-B231-5470D4D30065@oracle.com> References: <52768799.9030409@berlin.de> <55B8B9C4-85C7-47F8-A670-5E4637A929CC@oracle.com> <5278D01A.3070109@berlin.de> <996D3BF5-A822-4304-B231-5470D4D30065@oracle.com> Message-ID: 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 From stephan.herrmann at berlin.de Wed Nov 27 11:14:27 2013 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Wed, 27 Nov 2013 20:14:27 +0100 (CET) Subject: inference trouble with recursive generics and raw types Message-ID: <1385579667.645288-13242@martha.daybyday.de> 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 srikanth_sankaran at in.ibm.com Wed Nov 27 20:35:52 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Thu, 28 Nov 2013 10:05:52 +0530 Subject: Part F - Question In-Reply-To: References: Message-ID: > 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; }); } } -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20131128/508cb5a8/attachment.html From stephan.herrmann at berlin.de Thu Nov 28 06:01:50 2013 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Thu, 28 Nov 2013 15:01:50 +0100 Subject: 18.5.2 "the resulting instantiations are not considered part of B1." In-Reply-To: <76D21C20-307D-49C8-91DF-9E085A7EA17A@oracle.com> References: <528E290A.5060508@berlin.de> <76D21C20-307D-49C8-91DF-9E085A7EA17A@oracle.com> Message-ID: <52974CCE.5020207@berlin.de> On 11/22/2013 12:55 AM, Dan Smith wrote: > [..] > Lets try this instead: > > "(While, as a final step in 18.5.1, it was necessary to demonstrate that the inference variables in B1 could be resolved in order to establish applicability, an instantiation produced by this resolution step is not considered part of B1.)" > > The instantiation for T#0 sticks around because we already knew it when B1 was defined, before the resolution step. > > Put another way, the resolution step described as the final step of 18.5.1 is tentative, and its results are immediately discarded. Thanks, now I got the meaning and this helped fix a significant bunch of regressions. cheers, Stephan