From daniel.smith at oracle.com Mon Feb 3 15:40:13 2014 From: daniel.smith at oracle.com (Dan Smith) Date: Mon, 3 Feb 2014 16:40:13 -0700 Subject: Bug fixes since PFD Message-ID: A few spec bugs have come up since PFD. They've been resolved, and will be included in the next spec iteration (0.9.3). They are listed here: https://bugs.openjdk.java.net/issues/?jql=labels%20%3D%20lambda-pfd ?Dan From daniel.smith at oracle.com Mon Feb 3 15:44:39 2014 From: daniel.smith at oracle.com (Dan Smith) Date: Mon, 3 Feb 2014 16:44:39 -0700 Subject: necessary information is never considered by inference? In-Reply-To: <777D04F7-4BCB-4479-9B06-132F02F1051B@oracle.com> References: <52E79589.9060306@berlin.de> <777D04F7-4BCB-4479-9B06-132F02F1051B@oracle.com> Message-ID: <409C8EBA-0214-4ADB-BF86-AA5B77076A56@oracle.com> On Jan 31, 2014, at 5:39 PM, Dan Smith wrote: > On Jan 28, 2014, at 4:33 AM, Stephan Herrmann wrote: > >> Consider this example: >> >> import java.util.stream.Stream; >> import java.util.*; >> import static java.util.stream.Collectors.collectingAndThen; >> import static java.util.stream.Collectors.toList; >> public class X { >> void test(Stream> stream) { >> stream.collect(collectingAndThen(toList(), Collections::unmodifiableList)) >> .remove(0); >> } >> } >> >> I fail to see anything in the spec that would let us determine the >> return type of the collect(..) invocation. Hence the remove() call >> would be unresolvable. >> >> Given that javac does accept the program, I'm wondering what's causing >> this discrepancy. >> >> We have two inference variables from the outer invocation, let's write it as: > > ... > >> However, I don't see where the spec would allow me to introduce >> such constraints: we're reducing this constraint: >> ?collectingAndThen(toList(), Collections::unmodifiableList) ? Collector,A#1,R#0>? >> for this reduction 18.2.1 instructs me to apply 18.5.2 for computing B3. >> The problem is: computation of B3 only comprise those parts of 18.5.2 that >> never touch the argument expressions, those come into the picture only after. > > Yes, this is the crux of the problem. The nested invocation's method reference is irrelevant to invocation typing in the spec, but javac is using it. I believe javac captures the intended behavior; I'm now revisiting the design discussions about this to figure out what's supposed to happen. See the bug tracker here: https://bugs.openjdk.java.net/browse/JDK-8033488 The solution is simply to collect nested nested invocation arguments that were not pertinent to applicability when the set of remaining constraints, C, is assembled. (We also need to collect 'throws' constraints from all nested arguments that are lambdas/method refs.) Then they participate in the dependency analysis, just like everything else. ?Dan From stephan.herrmann at berlin.de Thu Feb 6 08:44:54 2014 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Thu, 06 Feb 2014 17:44:54 +0100 Subject: non-wildcard parameterization Message-ID: <52F3BC06.3040508@berlin.de> I don't understand the javac behavior for the following example: interface I> { T foo(S p); } public class X { public void bar() { I> f = (p) -> p; } } javac accepts, but I don't see how the non-wildcard parameterization of I can be determined for this case. I believe compilation should fail during this sentence from 9.8: "If Ai is a wildcard, and the corresponding type parameter bound, Bi, mentions one of P1...Pn, then Ti is undefined and there is no function type." From the LHS of the assignment: F = I> A1 = Object A2 = ? extends X From the declaration of I: P1 = T P2 = S extends X B1 = n/a B2 = X A2 (? extends X) is a wildcard, and the corresponding bound, B2 (X), mentions P1 (T), hence Ti is undefined and there is no function type. is my interpretation of the spec correct? thanks, Stephan From daniel.smith at oracle.com Thu Feb 6 11:44:44 2014 From: daniel.smith at oracle.com (Dan Smith) Date: Thu, 6 Feb 2014 12:44:44 -0700 Subject: non-wildcard parameterization In-Reply-To: <52F3BC06.3040508@berlin.de> References: <52F3BC06.3040508@berlin.de> Message-ID: <2C91C9D6-0D22-474C-B7BE-A6936B6AE978@oracle.com> You're right, this is a javac bug. The motivation of the spec is to carve this space out for future improvement, if necessary: if it turns out some common patterns could use some better analysis (yours is a good example), we can come back and design something to address that. But the general problem doesn't have a good solution, so we have to draw a line somewhere. ?Dan On Feb 6, 2014, at 9:44 AM, Stephan Herrmann wrote: > I don't understand the javac behavior for the following example: > > > interface I> { > T foo(S p); > } > > public class X { > public void bar() { > I> f = (p) -> p; > } > } > > javac accepts, but I don't see how the non-wildcard parameterization of I > can be determined for this case. > > I believe compilation should fail during this sentence from 9.8: > "If Ai is a wildcard, and the corresponding type parameter bound, Bi, > mentions one of P1...Pn, then Ti is undefined and there is no function type." > > From the LHS of the assignment: > F = I> > A1 = Object > A2 = ? extends X > > From the declaration of I: > P1 = T > P2 = S extends X > B1 = n/a > B2 = X > > A2 (? extends X) is a wildcard, and the corresponding bound, B2 (X), > mentions P1 (T), hence Ti is undefined and there is no function type. > > is my interpretation of the spec correct? > > thanks, > Stephan From daniel.smith at oracle.com Thu Feb 6 13:32:58 2014 From: daniel.smith at oracle.com (Dan Smith) Date: Thu, 6 Feb 2014 14:32:58 -0700 Subject: JSR 335 Lambda Specification, 0.9.3 Message-ID: An updated specification can be found here: http://cr.openjdk.java.net/~dlsmith/jsr335-0.9.3/ This addresses a few bugs that were discovered since the Proposed Final Draft. To avoid confusion, it also aligns the section numbers for Method Reference Expressions (15.13) with the integrated JLS 8 section numbering. Other links Diff: http://cr.openjdk.java.net/~dlsmith/jsr335-0.9.3-diff.html One-page HTML: http://cr.openjdk.java.net/~dlsmith/jsr335-0.9.3.html Downloadable zip: http://cr.openjdk.java.net/~dlsmith/jsr335-0.9.3.zip This has been bundled up with the API docs, including a small API correction in Comparator (discussed on lambda-libs-spec-experts), to produce the final specification. Preview here: http://cr.openjdk.java.net/~dlsmith/jsr335-final zip: http://cr.openjdk.java.net/~dlsmith/jsr335-final.zip This will be submitted for publishing via the JCP page. Full change log, from the document: > Method References: Renumbered the Method Reference Expressions section 15.13 (to make room, the JLS 7 15.13 will be merged with a previous section). > > Typing and Evaluation: Added changes to 6.6.2 to clarify accessibility of references to protected methods. > > Type Inference: Bug fix for subtyping constraints involving the null type. Added rule to invocation typing for lifting constraints on nested invocation arguments that are lambdas/method references into the enclosing inference context. ?Dan From stephan.herrmann at berlin.de Tue Feb 11 08:18:11 2014 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Tue, 11 Feb 2014 17:18:11 +0100 Subject: Status for "most specific" varargs method? Message-ID: <52FA4D43.4040200@berlin.de> Hi, Looking at remaining differences in behavior between javac and ecj, I came across this bug from 2009: https://bugs.openjdk.java.net/browse/JDK-6886431 This made me wonder about the status of this bug. * Is JLS8 supposed to change the picture? - (I don't see it would) * Are there plans to fix this in javac? - (javac8 again shows the bug, after javac7 did not) We'd love to be consistent with JLS *and* javac :) thanks, Stephan PS: I made experiments as to what spec changes would allow us to accept the example. I figured extending the 3 phases of overload resolution into 4 might be the cleanest way: 1. applicable by strict invocation 2. applicable by loose invocation 3. applicable by variable-arity strict invocation 4. applicable by variable-arity loose invocation IFF the current javac behavior is desired, then this would be my proposal for JLS9 :) From daniel.smith at oracle.com Tue Feb 11 10:37:52 2014 From: daniel.smith at oracle.com (Dan Smith) Date: Tue, 11 Feb 2014 11:37:52 -0700 Subject: Status for "most specific" varargs method? In-Reply-To: <52FA4D43.4040200@berlin.de> References: <52FA4D43.4040200@berlin.de> Message-ID: <3711E5FF-9131-46D2-B1A9-A8364E7C23FB@oracle.com> This problem was fixed in JDK 7 and mentioned in the release notes, even though this particular bug was not closed. http://www.oracle.com/technetwork/java/javase/compatibility-417013.html#jdk7 "Changes in Most Specific Varargs Method Selection" So I've closed the bug. We toyed with some ideas for enhancing most-specific to allow things like this in 8, but there was a lot of redundancy with the staged approach to boxing currently used by JLS, and we weren't confident enough to dump the staged approach, so ultimately rolled most-specific back to only give special treatment to functional interfaces (this was spec version 0.6.3). I'm surprised to see some of this work apparently leaking through into javac; I'll report a new bug. ?Dan On Feb 11, 2014, at 9:18 AM, Stephan Herrmann wrote: > Hi, > > Looking at remaining differences in behavior between javac and ecj, > I came across this bug from 2009: > > https://bugs.openjdk.java.net/browse/JDK-6886431 > > This made me wonder about the status of this bug. > > * Is JLS8 supposed to change the picture? > - (I don't see it would) > > * Are there plans to fix this in javac? > - (javac8 again shows the bug, after javac7 did not) > > We'd love to be consistent with JLS *and* javac :) > > thanks, > Stephan > > PS: I made experiments as to what spec changes would allow us > to accept the example. I figured extending the 3 phases of > overload resolution into 4 might be the cleanest way: > 1. applicable by strict invocation > 2. applicable by loose invocation > 3. applicable by variable-arity strict invocation > 4. applicable by variable-arity loose invocation > IFF the current javac behavior is desired, then this would be > my proposal for JLS9 :) From stephan.herrmann at berlin.de Sat Feb 15 12:45:28 2014 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Sat, 15 Feb 2014 21:45:28 +0100 Subject: 18.5.2: =?UTF-8?B?4p+ofFJ8IOKGkiBU4p+pIHZzIOKfqFIgzrgg4oaSIFTin6k=?= Message-ID: <52FFD1E8.2090301@berlin.de> Is javac right to accept this program? (I couldn't find an existing bug for this) import java.util.*; interface A {} interface B extends A {} public class Z { static Collection test(B[] array) { Collection collection = Collections.unmodifiableCollection( array == null ? Collections.EMPTY_LIST : Arrays.asList((A[]) array)); return collection; } } While reducing the constraint regarding EMPTY_LIST: List ? Collection we need to apply unchecked conversion, which is remembered for later. Then during 18.5.2. we apply bullet 3.1: "If unchecked conversion was necessary for the method to be applicable in 18.5.1 ..." creating this constraint: ?Collection ? Collection? As all subsequent bullets at that level are skipped (due to the "Otherwise, ..." disjunction) the parameter A in the target type has no effect on inference. Hence parameterization of that method is inferred as: Collection unmodifiableCollection(Collection) This return type is not assignment compatible with the LHS Collection. Yet, javac does not report this error. It appears javac either doesn't respect the fact that unchecked conversion was needed, or it simply falls through to the last "Otherwise" bullet. Either bug would result in adding also this constraint: ?R ? ? T? which lets us infer Collection unmodifiableCollection(Collection) which *is* assignment compatible. Additional witness in the library: Class java.util.stream.FindOps contains a structure at line 58 (at b129), which in my strict interpretation of the spec should be illegal, but can be accepted if adding the ?R ? ? T? constraint. What's intended? Stephan