From forax at univ-mlv.fr Tue Feb 5 13:46:42 2013 From: forax at univ-mlv.fr (Remi Forax) Date: Tue, 05 Feb 2013 22:46:42 +0100 Subject: Lambda weird scoping rule Message-ID: <51117DC2.9080108@univ-mlv.fr> Hi guys, we said a long time ago that we may re-visit the very specific rule that doesn't allow to use a variable which is already in the outer scope. I've been bitten by this rule too often to consider that this rule worth the trouble. We should keep things simple. Here is the latest example. public class LambdaChainTest { interface Completer extends CompletionHandler { public void completed(V result, Throwable exception, A attachment); @Override public default void completed(V result, A attachment) { completed(result, null, attachment); } @Override public default void failed(Throwable exc, A attachment) { completed(null, exc, attachment); } public default Completer onError(Consumer consumer) { return (result, exception, attachment) -> { if (exception != null) { consumer.accept(exception); return; } completed(result, exception, attachment); }; } } public static void main(String[] args) throws IOException { ByteBuffer buffer = ByteBuffer.allocate(8192); AsynchronousFileChannel channel = AsynchronousFileChannel.open(Paths.get("foo.txt")); channel.read(buffer, 0, buffer, ((Completer) (result, exception, buffer) -> { buffer.flip(); System.out.println(new String(buffer.array(), Charset.defaultCharset())); }).onError(e -> e.printStackTrace())); } } R?mi From srikanth_sankaran at in.ibm.com Tue Feb 5 20:36:16 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Tue, 5 Feb 2013 23:36:16 -0500 Subject: Exceptions and lambda. In-Reply-To: <51117DC2.9080108@univ-mlv.fr> References: <51117DC2.9080108@univ-mlv.fr> Message-ID: The following lambda expression does not compile with 8b74, while the implementation of the method in a class does compile: // ------------ interface G1 { Object m(E p) throws E; } interface G2 { String m(F q) throws Exception; } interface G extends G1, G2 {} // G has descriptor ()->String throws F public class X { G g = (x) -> { // Elided type is inferred from descriptor to be F throw x; // ~== throw new F() }; } class Y implements G { public String m(T t) throws T { throw t; } } // ----------------------- Is this a bug in the implementation or the specification ? Since the lambda cannot refer to the type variables of the descriptor by name nor declare its own, if 8b74 behavior is correct, that would mean that, no checked exceptions could be thrown from a lambda if the descriptor of the target interface method mentions a type variable in throws clause. My analysis is that the lambda should be accepted as it does not manufacture any fresh exceptions and simply throws an exception that is known to have satisfied the constraints at the invocation site, i.e no additional/unexpected surprises are there due the lambda throwing the object it was handed. Thanks in advance for your clarification. Srikanth. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130205/39b47aab/attachment.html From daniel.smith at oracle.com Tue Feb 5 22:29:43 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Tue, 5 Feb 2013 23:29:43 -0700 Subject: Exceptions and lambda. In-Reply-To: References: <51117DC2.9080108@univ-mlv.fr> Message-ID: <702F711B-D89E-4F94-9111-5EA9411BD42B@oracle.com> If you're getting an error from the lambda expression, that's the expected behavior. Perhaps the error message could be improved, though... This is not actually an exception problem: we simply don't allow lambda expressions to have type parameters. There's no syntax to introduce them, and if we inferred the declaration (something we thought about), it would be impossible or very confusing to talk about the type variable (e.g., give the lambda parameter an explicit type). The implication is that the only way to instantiate a functional interface that has a generic method (well, excluding the boring approach of declaring a class) is to use a method reference. If you haven't already done so, you'll probably be interested in testing the equivalent examples with the type parameters lifted to the interface level ("interface G1"). That should have less surprising behavior. ?Dan On Feb 5, 2013, at 9:36 PM, Srikanth S Adayapalam wrote: > The following lambda expression does not compile with 8b74, while the > implementation of the method in a class does compile: > > // ------------ > interface G1 { > Object m(E p) throws E; > } > interface G2 { > String m(F q) throws Exception; > } > interface G extends G1, G2 {} > > // G has descriptor ()->String throws F > > public class X { > > G g = (x) -> { // Elided type is inferred from descriptor to be F > throw x; // ~== throw new F() > }; > } > > class Y implements G { > public String m(T t) throws T { > throw t; > } > } > // ----------------------- > > Is this a bug in the implementation or the specification ? > Since the lambda cannot refer to the type variables of the > descriptor by name nor declare its own, if 8b74 behavior is > correct, that would mean that, no checked exceptions could > be thrown from a lambda if the descriptor of the target > interface method mentions a type variable in throws clause. > > My analysis is that the lambda should be accepted as it does > not manufacture any fresh exceptions and simply throws an > exception that is known to have satisfied the constraints at > the invocation site, i.e no additional/unexpected surprises > are there due the lambda throwing the object it was handed. > > Thanks in advance for your clarification. > Srikanth. From srikanth_sankaran at in.ibm.com Tue Feb 5 22:41:03 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Wed, 6 Feb 2013 01:41:03 -0500 Subject: Exceptions and lambda. In-Reply-To: <702F711B-D89E-4F94-9111-5EA9411BD42B@oracle.com> References: <51117DC2.9080108@univ-mlv.fr> <702F711B-D89E-4F94-9111-5EA9411BD42B@oracle.com> Message-ID: > From: Dan Smith > Subject: Re: Exceptions and lambda. > > If you're getting an error from the lambda expression, that's the > expected behavior. Perhaps the error message could be improved, though... > > This is not actually an exception problem: we simply don't allow > lambda expressions to have type parameters. There's no syntax to > introduce them, and if we inferred the declaration (something we > thought about), it would be impossible or very confusing to talk > about the type variable (e.g., give the lambda parameter an explicit type). I understand the part about there being no syntax to introduce type variables, but with types elided and inferred, the snippet I posted constitutes a well formed program as far I can see - we are working with a particular instance of type that meets the bounds criteria specified by the interface method and it is surprising that I cannot simply throw that object - I apologize if this was discussed earlier and I missed the discussion. > The implication is that the only way to instantiate a functional > interface that has a generic method (well, excluding the boring > approach of declaring a class) is to use a method reference. So, should I expect the following to fail to compile ? It compiles fine with b74: // ---- interface G1 { Object m(E p) throws E; } interface G2 { String m(F q) throws Exception; } interface G extends G1, G2 {} // G has descriptor ()->String throws F public class X { G g = (x) -> { return "OK"; }; } // --- -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130206/b7cf04db/attachment.html From srikanth_sankaran at in.ibm.com Wed Feb 6 01:28:57 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Wed, 6 Feb 2013 04:28:57 -0500 Subject: Exceptions and lambda. In-Reply-To: References: <51117DC2.9080108@univ-mlv.fr> <702F711B-D89E-4F94-9111-5EA9411BD42B@oracle.com> Message-ID: > From: Srikanth S Adayapalam/India/IBM at IBMIN > So, should I expect the following to fail to compile ? It compiles > fine with b74: > > // ---- > interface G1 { > Object m(E p) throws E; > } > interface G2 { > String m(F q) throws Exception; > } > interface G extends G1, G2 {} > > // G has descriptor ()->String throws F > > public class X { > > G g = (x) -> { > return "OK"; > }; > } > // --- Playing around with it a bit more I see that javac does reject a program that tries to target a generic method, but not consistently: import java.util.List; interface A { T foo(List p); } interface B { S foo(List p); } interface C extends A, B {} class Z { A a = (p) -> { return null;}; // rejected B d = (p) -> { return null;}; // rejected C c = (p) -> { return null;}; // accepted } I get a "method (List)T in interface A is generic" diagnostic. So shouldn't C c = (p) -> { return null;}; // accepted also be rejected for the same reason ? Thanks! Srikanth. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130206/c17f30f9/attachment-0001.html From maurizio.cimadamore at oracle.com Wed Feb 6 02:32:58 2013 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 06 Feb 2013 10:32:58 +0000 Subject: Exceptions and lambda. In-Reply-To: References: <51117DC2.9080108@univ-mlv.fr> <702F711B-D89E-4F94-9111-5EA9411BD42B@oracle.com> Message-ID: <5112315A.5000201@oracle.com> On 06/02/13 09:28, Srikanth S Adayapalam wrote: > import java.util.List; > interface A { T foo(List p); } > interface B { S foo(List p); } > interface C extends A, B {} > > class Z { > A a = (p) -> { return null;}; // rejected > B d = (p) -> { return null;}; // rejected > C c = (p) -> { return null;}; // accepted > } This is a bug in the logic that merges descriptors from supertypes. Type parameters should be carried over. Maurizio From srikanth_sankaran at in.ibm.com Wed Feb 6 04:51:44 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Wed, 6 Feb 2013 07:51:44 -0500 Subject: Exceptions and lambda. In-Reply-To: <5112315A.5000201@oracle.com> References: <51117DC2.9080108@univ-mlv.fr> <702F711B-D89E-4F94-9111-5EA9411BD42B@oracle.com> <5112315A.5000201@oracle.com> Message-ID: > From: Maurizio Cimadamore > Subject: Re: Exceptions and lambda. > This is a bug in the logic that merges descriptors from supertypes. Type > parameters should be carried over. Thanks for the clarification. I did a quick scan of the spec (0.6.1) and while the part about how a lambda cannot declare type variables is clearly called out, I couldn't find some text that explicitly forbids the scenario we are talking about (where types are elided and inferred and there is no further need to refer to any type variables) - That plus the fact that I could actually get javac to compile some invalid code resulted in my confusion. Srikanth. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130206/505a05cd/attachment.html From maurizio.cimadamore at oracle.com Wed Feb 6 05:03:05 2013 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 06 Feb 2013 13:03:05 +0000 Subject: Exceptions and lambda. In-Reply-To: References: <51117DC2.9080108@univ-mlv.fr> <702F711B-D89E-4F94-9111-5EA9411BD42B@oracle.com> <5112315A.5000201@oracle.com> Message-ID: <51125489.1040402@oracle.com> On 06/02/13 12:51, Srikanth S Adayapalam wrote: > I couldn't find some text that explicitly > forbids the scenario we are talking about (where types are elided and > inferred and > there is no further need to refer to any type variables) I think I cannot find it either - I think it should be in 15.27.3 Type of a Lambda Expression' - Dan? Maurizio -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130206/3f660312/attachment.html From maurizio.cimadamore at oracle.com Wed Feb 6 05:33:58 2013 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 06 Feb 2013 13:33:58 +0000 Subject: Exceptions and lambda. In-Reply-To: <51125489.1040402@oracle.com> References: <51117DC2.9080108@univ-mlv.fr> <702F711B-D89E-4F94-9111-5EA9411BD42B@oracle.com> <5112315A.5000201@oracle.com> <51125489.1040402@oracle.com> Message-ID: <51125BC6.4010900@oracle.com> On 06/02/13 13:03, Maurizio Cimadamore wrote: > On 06/02/13 12:51, Srikanth S Adayapalam wrote: >> I couldn't find some text that explicitly >> forbids the scenario we are talking about (where types are elided and >> inferred and >> there is no further need to refer to any type variables) > I think I cannot find it either - I think it should be in 15.27.3 Type > of a Lambda Expression' - Dan? > > Maurizio The only bit about this that I could find is the discussion section in 9.8 (bullet 4). It would seem that the text is implying that the restriction comes from the fact that a lambda has no syntax for declaring type-parameters. On the other hand I'm not sure that's enough, as the compiler could simply generate a signature that matches the one in the functional descriptor so that overriding is preserved (esp. when lambda formals are omitted). If parameters are explcit, it's a different story, as the check that enforces that lambda parameter types should match types in the functional descriptor is mostly enough to guarantee that a lambda will not be compatible with a generic functional descriptor. I said mostly because if the descriptor doesn't mention type-variables in the argument part, then the check doesn't help and we're back to square one. Maurizio -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130206/116bb6ba/attachment.html From srikanth_sankaran at in.ibm.com Wed Feb 6 05:50:07 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Wed, 6 Feb 2013 08:50:07 -0500 Subject: Exceptions and lambda. In-Reply-To: <51125489.1040402@oracle.com> References: <51117DC2.9080108@univ-mlv.fr> <702F711B-D89E-4F94-9111-5EA9411BD42B@oracle.com> <5112315A.5000201@oracle.com> <51125489.1040402@oracle.com> Message-ID: I understand the parsing complexities around introducing type variables (" generic lambdas involves invasive, messy changes to the grammar. ") in lambda expressions. It is also reasonable to stipulate that a lambda expression cannot refer to type variables from the descriptor by name - that would be too fragile and unreadable. But where the formal parameter types are elided and derived from the descriptor, it would seem it makes sense to allow a lambda expression to implement the interface method if the implementation has no need to refer to the type variables. It gets passed certain objects that are guaranteed to have satisfied the constrains and it can do what it wants with it. Banning it outright seems way more restrictive than saying you can't introduce type variables and you can't "inherit" type variables - Perhaps I am missing some nuances here. Personally speaking, I am still on 1.4 and don't expect to use lambda expressions in the next decade or so :-) I have no problem banning lambdas when the descriptor is generic - I just did that in the eclipse compiler :) Srikanth Maurizio Cimadamore wrote on 02/06/2013 08:03:05 AM: > From: Maurizio Cimadamore > To: Srikanth S Adayapalam/India/IBM at IBMIN, > Cc: Dan Smith , lambda-spec- > experts at openjdk.java.net, lambda-spec-experts- > bounces at openjdk.java.net, lambda-spec-observers at openjdk.java.net > Date: 02/06/2013 08:02 AM > Subject: Re: Exceptions and lambda. > > On 06/02/13 12:51, Srikanth S Adayapalam wrote: > I couldn't find some text that explicitly > forbids the scenario we are talking about (where types are elided > and inferred and > there is no further need to refer to any type variables) > I think I cannot find it either - I think it should be in 15.27.3 > Type of a Lambda Expression' - Dan? > > Maurizio -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130206/7a0bc7e7/attachment.html From srikanth_sankaran at in.ibm.com Wed Feb 6 05:57:42 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Wed, 6 Feb 2013 08:57:42 -0500 Subject: Exceptions and lambda. In-Reply-To: <51125BC6.4010900@oracle.com> References: <51117DC2.9080108@univ-mlv.fr> <702F711B-D89E-4F94-9111-5EA9411BD42B@oracle.com> <5112315A.5000201@oracle.com> <51125489.1040402@oracle.com> <51125BC6.4010900@oracle.com> Message-ID: > From: Maurizio Cimadamore > Subject: Re: Exceptions and lambda. > It would seem that the text is implying that the restriction comes > from the fact that a lambda has no syntax for declaring type- > parameters. On the other hand I'm not sure that's enough, as the > compiler could simply generate a signature that matches the one in > the functional descriptor so that overriding is preserved (esp. when > lambda formals are omitted). As a matter of fact, I had (incorrectly) assumed that the primary reason we support elided types was to accommodate this scenario, where due to lack of own type variables, the lambda won't be able to spell out a signature that is equivalent and only secondarily to minimize noise in complex expressions/invocations etc. > I said > mostly because if the descriptor doesn't mention type-variables in > the argument part, then the check doesn't help and we're back to square one. Then don't we just have concrete types that could be type checked against each other ? Srikanth. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130206/4f6f1bb5/attachment-0001.html From daniel.smith at oracle.com Wed Feb 6 13:24:41 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Wed, 6 Feb 2013 14:24:41 -0700 Subject: Exceptions and lambda. In-Reply-To: <51125BC6.4010900@oracle.com> References: <51117DC2.9080108@univ-mlv.fr> <702F711B-D89E-4F94-9111-5EA9411BD42B@oracle.com> <5112315A.5000201@oracle.com> <51125489.1040402@oracle.com> <51125BC6.4010900@oracle.com> Message-ID: On Feb 6, 2013, at 6:33 AM, Maurizio Cimadamore wrote: > On 06/02/13 13:03, Maurizio Cimadamore wrote: >> On 06/02/13 12:51, Srikanth S Adayapalam wrote: >>> I couldn't find some text that explicitly >>> forbids the scenario we are talking about (where types are elided and inferred and >>> there is no further need to refer to any type variables) >> I think I cannot find it either - I think it should be in 15.27.3 Type of a Lambda Expression' - Dan? >> >> Maurizio > The only bit about this that I could find is the discussion section in 9.8 (bullet 4). > > It would seem that the text is implying that the restriction comes from the fact that a lambda has no syntax for declaring type-parameters. On the other hand I'm not sure that's enough, as the compiler could simply generate a signature that matches the one in the functional descriptor so that overriding is preserved (esp. when lambda formals are omitted). You're right. I expect a rule in 15.27.3 that says the type parameters of the lambda (constrained to be none by the syntax) are the same as the type parameters of the function descriptor. But it seems I left out that rule. I think the EG agreed on the behavior I describe back in April. But by "agreed," I mostly mean a silent consensus, and it's possible subtleties like this weren't fully considered. I'll write up the alternative behavior (the lambda's type params being derived from the descriptor and unmentionable) and see if it piques anyone's interest. ?Dan From daniel.smith at oracle.com Wed Feb 6 13:44:18 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Wed, 6 Feb 2013 14:44:18 -0700 Subject: Lambdas with implicit type parameters Message-ID: Our status quo for handling of generic function descriptors (derived from functional interfaces with generic methods) was described by Brian back in April [1]: method references can target these functional interfaces, but lambdas, because they can declare no type parameters, cannot. I remember discussions about an alternative approach, but I don't know whether it really got proper treatment from the EG, so I'll describe it here. If anyone thinks this is a good enhancement to make, or if anybody remembers a previous, more in-depth discussion, please say so. (Background: Remember that a lambda is treated like an override of the functional interface's method; generally speaking, the rules for a legal lambda correspond to the rules for a legal overriding declaration -- this means the lambda must declare the "same" (allowing for renaming) type parameters as the descriptor. Also recall that we tried to find a syntax for generic lambdas, and failed to find anything acceptable.) The idea: a lambda that targets a generic function descriptor may have an implicit type parameter declaration. Unlike most other forms of inference (using the term broadly), this is inference of a _declaration_ of a new name. Sort of like wildcard capture. The new names would be unmentionable, but if the lambda can be defined without needing to refer explicitly to a type parameter name (probably fairly common, especially when the lambda parameter types are inferred), that's fine. Error messages would have to find a way to talk about these nameless tparams, of course (if, say, there's a type error in the lambda body). Typically the functional interface declaration provides a reasonable name, although, in general, there can be multiple methods that describe the same descriptor with different type parameter names. Example: interface ListFactory { List make(); } ListFactory f1 = ArrayList::new; // currently legal ListFactory f2 = () -> new ArrayList<>(); // illegal currently, the enhancement would allow it ListFactory f3 = () -> new ArrayList(); // definitely illegal: T is not in scope ?Dan [1] "Generic functional interfaces, generic method refs, and generic lambdas", 12 Apr 2012, from jsr-335-eg at jcp.org From maurizio.cimadamore at oracle.com Thu Feb 7 07:11:14 2013 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 07 Feb 2013 15:11:14 +0000 Subject: Exceptions and lambda. In-Reply-To: References: <51117DC2.9080108@univ-mlv.fr> <702F711B-D89E-4F94-9111-5EA9411BD42B@oracle.com> <5112315A.5000201@oracle.com> Message-ID: <5113C412.4020202@oracle.com> On 06/02/13 12:51, Srikanth S Adayapalam wrote: > > From: Maurizio Cimadamore > > Subject: Re: Exceptions and lambda. > > > This is a bug in the logic that merges descriptors from supertypes. > Type > > parameters should be carried over. > > Thanks for the clarification. Fixed now. Maurizio > > I did a quick scan of the spec (0.6.1) and while the part about how a > lambda cannot > declare type variables is clearly called out, I couldn't find some > text that explicitly > forbids the scenario we are talking about (where types are elided and > inferred and > there is no further need to refer to any type variables) - > > That plus the fact that I could actually get javac to compile some > invalid code > resulted in my confusion. > > Srikanth. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130207/513687cc/attachment.html From brian.goetz at oracle.com Thu Feb 7 11:34:58 2013 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 07 Feb 2013 14:34:58 -0500 Subject: Fwd: hg: lambda/lambda/langtools: Enhancement: more stable serialized lambda names In-Reply-To: <20130207193045.C0DCC478E7@hg.openjdk.java.net> References: <20130207193045.C0DCC478E7@hg.openjdk.java.net> Message-ID: <511401E2.6070802@oracle.com> This is now implemented. The more complex convention is only used for serializable lambdas. -------- Original Message -------- Subject: hg: lambda/lambda/langtools: Enhancement: more stable serialized lambda names Date: Thu, 07 Feb 2013 19:30:41 +0000 From: maurizio.cimadamore at oracle.com To: lambda-dev at openjdk.java.net Changeset: 7bffb45844fb Author: mcimadamore Date: 2013-02-07 19:30 +0000 URL: http://hg.openjdk.java.net/lambda/lambda/langtools/rev/7bffb45844fb Enhancement: more stable serialized lambda names Serializable lambdas are desugared to methods where name follows following pattern: lambda$mmm$kkkk$nnn where mmm is the method name and kkk is the hashcode of the method signature, and nnn is a sequentially assigned number. That way, dependencies on lambdas from other methods will be minimized. ! src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java ! src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java From srikanth_sankaran at in.ibm.com Sat Feb 9 20:10:39 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Sat, 9 Feb 2013 23:10:39 -0500 Subject: Broken example in spec ? In-Reply-To: References: <51117DC2.9080108@univ-mlv.fr> <702F711B-D89E-4F94-9111-5EA9411BD42B@oracle.com> Message-ID: 0.6.1 - 9.8, Discussion & motivation box, second bullet says: // --------8< ----------------- Under the current definition, a functional interface may be parameterized in a way that produces distinct abstract methods?that is, multiple methods that cannot be legally overridden with a single declaration. For example: interface I { Object m(); } interface J { S m(); } interface K { T m(); } interface Functional extends I, J, K {} Interface Functional is functional?I.m is return-type-substitutable for the other two?but Functional clearly cannot be implemented with a single method. This situation is acceptable, however: when functional interfaces are implicitly implemented, the overriding effectively occurs generically; instantiation of type parameters only occurs at the use site. In other words, if a lambda expression represents a Functional, its treatment is similar to that of the following: class FunctionalImpl implements Functional { ... } Functional f = new FunctionalImpl(); // --------8< ----------------- I think this part needs a careful relook - Both javac 8b74 and eclipse refuse to compile this snippet *precisely* for the reason that certain parameterization could run into unrelated return types. Ergo, `Functional' is not even a legal interface - let alone a functional interface. Let me know if I have missed some nuance here. Thanks! Srikanth. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130209/a55e4c61/attachment.html From maurizio.cimadamore at oracle.com Mon Feb 11 03:50:11 2013 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Mon, 11 Feb 2013 11:50:11 +0000 Subject: Broken example in spec ? In-Reply-To: References: <51117DC2.9080108@univ-mlv.fr> <702F711B-D89E-4F94-9111-5EA9411BD42B@oracle.com> Message-ID: <5118DAF3.4000302@oracle.com> On 10/02/13 04:10, Srikanth S Adayapalam wrote: > I think this part needs a careful relook - Both javac 8b74 and eclipse > refuse to compile this snippet*precisely* for the reason that certain > parameterization could run into unrelated return types. > Ergo, `Functional' is not even a legal interface - let alone a functional > interface. I agree that Functional is ill formed, as it inherits two methods that are override-equivalent signatures, but where neither overrides the other. I think the point here is - should the functional interface definition be allowed in contexts where an error can occur? One could imagine an instantiation like this: Functional, or Function which would lead to a well-formed interface. And functional, too (as all methods can be implemented at once). On the other hand, I believe that some time ago we pushed back on the notion of making functional interface definition a property of types, which, as you example demonstrates, often leads to obscure semantics; and we aimed at an approach where functional interface is a a property of class declarations (hence the possibility of using an annotation). This is probably a case in which the definition needs to be dumbed down a little in order to take into account some form of class/interface well-formedness. Maurizio -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130211/39ab5b9d/attachment.html From srikanth_sankaran at in.ibm.com Mon Feb 11 06:00:39 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Mon, 11 Feb 2013 09:00:39 -0500 Subject: Minor wording issue around effectively final definition Message-ID: Hello ! 0.6.1 (4.12.4) reads: A local variable or a method, constructor, lambda, or exception parameter is effectively final if it is not final but it never occurs as the left hand operand of an assignment operator (15.26) or as the operand of an increment or decrement operator (15.14, 15.15). [jsr335-4.12.4-10] In addition, a local variable whose declaration lacks an initializer is effectively final if all of the following are true: [jsr335-4.12.4-20] It is not final. [jsr335-4.12.4-20-A] Whenever it occurs as the left-hand operand of an assignment operator, it is definitely unassigned and not definitely assigned before the assignment (that is, it is definitely unassigned and not definitely assigned after the right-hand operand of the assignment) (16). I think the first sentence meant to say, never occurs as the left hand operand of a *compound* assignment operator. Srikanth -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130211/3b0bf636/attachment.html From daniel.smith at oracle.com Mon Feb 11 10:47:05 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Mon, 11 Feb 2013 11:47:05 -0700 Subject: Broken example in spec ? In-Reply-To: References: <51117DC2.9080108@univ-mlv.fr> <702F711B-D89E-4F94-9111-5EA9411BD42B@oracle.com> Message-ID: <0B3A2563-14C8-4B63-BED4-14DBFFD049F8@oracle.com> Looks to me like the JLS and javac/Eclipse are out of sync on the definition of "return-type-substitutability" (JLS 8.4.5). If this is longstanding, accepted implementation behavior, we could probably adjust the JLS text to accommodate. I'll investigate further. ?Dan On Feb 9, 2013, at 9:10 PM, Srikanth S Adayapalam wrote: > 0.6.1 - 9.8, Discussion & motivation box, second bullet says: > > // --------8< ----------------- > > > Under the current definition, a functional interface may be parameterized in a way that produces distinct abstract methods?that is, multiple methods that cannot be legally overridden with a single declaration. For example: > interface I { Object m(); } > interface J { S m(); } > interface K { T m(); } > interface Functional extends I, J, K {} > > Interface Functional is functional?I.m is return-type-substitutable for the other two?but Functional clearly cannot be implemented with a single method. This situation is acceptable, however: when functional interfaces are implicitly implemented, the overriding effectively occurs generically; instantiation of type parameters only occurs at the use site. In other words, if a lambda expression represents a Functional, its treatment is similar to that of the following: > > class FunctionalImpl implements Functional { ... } > Functional f = new FunctionalImpl(); > > // --------8< ----------------- > > I think this part needs a careful relook - Both javac 8b74 and eclipse refuse to compile this snippet *precisely* for the reason that certain parameterization could run into unrelated return types. > Ergo, `Functional' is not even a legal interface - let alone a functional interface. > > Let me know if I have missed some nuance here. > > Thanks! > Srikanth. From daniel.smith at oracle.com Mon Feb 11 10:53:14 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Mon, 11 Feb 2013 11:53:14 -0700 Subject: Minor wording issue around effectively final definition In-Reply-To: References: Message-ID: <2E2859BC-2882-4540-90F3-DE5B9E4695C6@oracle.com> On Feb 11, 2013, at 7:00 AM, Srikanth S Adayapalam wrote: > Hello ! > > 0.6.1 (4.12.4) reads: > > A local variable or a method, constructor, lambda, or exception parameter is effectively final if it is not final but it never occurs as the left hand operand of an assignment operator (15.26) or as the operand of an increment or decrement operator (15.14, 15.15). [jsr335-4.12.4-10] > In addition, a local variable whose declaration lacks an initializer is effectively final if all of the following are true: [jsr335-4.12.4-20] > > ? It is not final. [jsr335-4.12.4-20-A] > ? Whenever it occurs as the left-hand operand of an assignment operator, it is definitely unassigned and not definitely assigned before the assignment (that is, it is definitely unassigned and not definitely assigned after the right-hand operand of the assignment) (16). > > I think the first sentence meant to say, never occurs as the left hand operand of a *compound* assignment operator. The intent is to cover both compound and simple assignments. The first sentence says that if you never assign to a variable, it's effectively final. The second sentence says that if you _do_ assign to a variable, it may still be effectively final if the assignment is the _first_ assignment. Note that there's a restriction, separate from "effectively final," that a variable must be definitely assigned wherever it is referenced, including in a compound assignment. I think the complexities you're worried about are bundled up inside the definitions of "definitely unassigned" and "definitely assigned". But if you're unsure, feel free to share a concrete example of something you don't think will work right. ?Dan From srikanth_sankaran at in.ibm.com Tue Feb 12 06:22:21 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Tue, 12 Feb 2013 09:22:21 -0500 Subject: Minor wording issue around effectively final definition In-Reply-To: <2E2859BC-2882-4540-90F3-DE5B9E4695C6@oracle.com> References: <2E2859BC-2882-4540-90F3-DE5B9E4695C6@oracle.com> Message-ID: > From: Dan Smith > Subject: Re: Minor wording issue around effectively final definition > The intent is to cover both compound and simple assignments. > > The first sentence says that if you never assign to a variable, it's > effectively final. > > The second sentence says that if you _do_ assign to a variable, it > may still be effectively final if the assignment is the _first_ assignment. Thanks, it looks fine. The apparent contradiction was due to my having missed out the phrase "in addition". Sorry for the SIGINT. Srikanth. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130212/65be82fb/attachment.html From srikanth_sankaran at in.ibm.com Tue Feb 12 06:36:47 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Tue, 12 Feb 2013 09:36:47 -0500 Subject: ReferenceType in CastExpression productions In-Reply-To: <0B3A2563-14C8-4B63-BED4-14DBFFD049F8@oracle.com> References: <51117DC2.9080108@univ-mlv.fr> <702F711B-D89E-4F94-9111-5EA9411BD42B@oracle.com> <0B3A2563-14C8-4B63-BED4-14DBFFD049F8@oracle.com> Message-ID: A while ago, in the context of the method/constructor reference expression grammar changes, it was pointed out that JLS7 has two definitions of ReferenceType in different chapters: one that includes arrays and one that doesn't. We said that the one that includes arrays is the right one to use for parsers. It appears that this split-personality could be influencing 8b74's behavior in rejecting the snippet below: // ---- import java.io.serializeable; public class X { X [] x = (X[] & Serializable & Cloneable) new X[0]; // error: unexpected type, required class, found X[] } I cannot think of a non-pedantic case where this should matter, calling it out just the same in case I missed some subtleties. Srikanth. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130212/34654780/attachment.html From daniel.smith at oracle.com Tue Feb 12 14:41:09 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Tue, 12 Feb 2013 15:41:09 -0700 Subject: Minor wording issue around effectively final definition In-Reply-To: References: <2E2859BC-2882-4540-90F3-DE5B9E4695C6@oracle.com> Message-ID: <0F4995BE-8898-4027-970C-4E22BBB4493B@oracle.com> Thanks for the feedback, Neal. Note that the constraint about DA/DU is about the point of assignment, not the point of capture. Here, the only assignment to 'i' occurs when it is (!DA)&&DU; and at the only use of 'i', it is DA: int i; i = 2; if (false) { Runnable r = () -> { int j = i; }; } So everything's okay. The (!DA)&&DU restriction was introduced to handle situations like this: int i; i = 2; if (false) { i = 3; Runnable r = () -> { int j = i; }; } Here, 'i' is DU wherever it is assigned to; but if we were to declare 'i' 'final', there would be an error at the point of the second assignment, per JLS 7 6.5.6.1, precisely because it is also DA. That's bad, because we want "effectively final" to mean "could have been declared final". (The treatment of final variables in situations like this was unclear previously, so this is a spec change (bug #4721499). I don't think it has made its way into the javac code yet. Ultimately, the goal will be to make the spec for "final", the spec for "effectively final", and the implementation all be in sync.) Now, back to your original example: if (false) { int i; i = 2; // i is both definitely assigned and definitely unassigned here Runnable r = () -> { int j = i; }; // error: i not effectively final } Here, again, 'i' is both DA&&DU at the assignment, so if it were to be declared 'final', there would be an error -- you can't assign to a DA final variable. So 'i' shouldn't be effectively final. But maybe that just pushes the criticism back to the rules about final variables. It is somewhat surprising that this would be illegal: if (false) { int i; i = 2; // i is DA, represents a "value", can't be assigned to (per 6.5.6.1) } I'll investigate that further. ?Dan On Feb 12, 2013, at 9:46 AM, Neal Gafter wrote: > Sorry, the example should have been > > int i; > i = 2; > if (false) { > // i is both definitely assigned and definitely unassigned here > Runnable r = () => { int j = i; }; // error: i not effectively final > } > > Cheers, > Neal > > On Mon, Feb 11, 2013 at 4:36 PM, Neal Gafter wrote: > Here is one example that does not work right according to the spec: > > if (false) { > int i; > i = 2; // i is both definitely assigned and definitely unassigned here > Runnable r = () => { int j = i; }; // error: i not effectively final > } > > One way to fix this section of the spec is to remove the words "and not definitely assigned" twice where they appear in the definition of effectively final. > > On Mon, Feb 11, 2013 at 10:53 AM, Dan Smith wrote: > On Feb 11, 2013, at 7:00 AM, Srikanth S Adayapalam wrote: > > > Hello ! > > > > 0.6.1 (4.12.4) reads: > > > > A local variable or a method, constructor, lambda, or exception parameter is effectively final if it is not final but it never occurs as the left hand operand of an assignment operator (15.26) or as the operand of an increment or decrement operator (15.14, 15.15). [jsr335-4.12.4-10] > > > In addition, a local variable whose declaration lacks an initializer is effectively final if all of the following are true: [jsr335-4.12.4-20] > > > > ? It is not final. [jsr335-4.12.4-20-A] > > ? Whenever it occurs as the left-hand operand of an assignment operator, it is definitely unassigned and not definitely assigned before the assignment (that is, it is definitely unassigned and not definitely assigned after the right-hand operand of the assignment) (16). > > > > I think the first sentence meant to say, never occurs as the left hand operand of a *compound* assignment operator. > > The intent is to cover both compound and simple assignments. > > The first sentence says that if you never assign to a variable, it's effectively final. > > The second sentence says that if you _do_ assign to a variable, it may still be effectively final if the assignment is the _first_ assignment. > > Note that there's a restriction, separate from "effectively final," that a variable must be definitely assigned wherever it is referenced, including in a compound assignment. > > I think the complexities you're worried about are bundled up inside the definitions of "definitely unassigned" and "definitely assigned". But if you're unsure, feel free to share a concrete example of something you don't think will work right. > > ?Dan > > From srikanth_sankaran at in.ibm.com Wed Feb 13 20:41:18 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Wed, 13 Feb 2013 23:41:18 -0500 Subject: Effective finality requirements for method reference receiver ? In-Reply-To: References: <2E2859BC-2882-4540-90F3-DE5B9E4695C6@oracle.com> <0F4995BE-8898-4027-970C-4E22BBB4493B@oracle.com> Message-ID: Are there any ? 0.6.1 - Part C is silent. The words final and capture don't occur there. But SOTL 4th edition talks about the implicit lambda capturing a variable and using that as the receiver. Spec should override all other prose - right ? I also see that the mention of implicit lambda is from a pedagogical pov. BTW, 0.6.1 Part B links to SOTL edition 3 - which is very outdated with respect to the present state of affairs. I see that javac 8b74 compiles this code fine: // -- interface I { void foo(); } public class X { private void foo() { X x = new X(); x = new X(); I i = x::foo; } } Thanks in advance for any clarifications. Srikanth. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130213/8b11a33f/attachment.html From brian.goetz at oracle.com Thu Feb 14 08:01:01 2013 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 14 Feb 2013 11:01:01 -0500 Subject: Effective finality requirements for method reference receiver ? In-Reply-To: References: <2E2859BC-2882-4540-90F3-DE5B9E4695C6@oracle.com> <0F4995BE-8898-4027-970C-4E22BBB4493B@oracle.com> Message-ID: <511D0A3D.2000308@oracle.com> > Are there any ? No. As part of evaluating a method reference, the receiver is evaluated. So it is fine to have a mutable receiver; the value is bound at the time the MR is evaluated. Then the receiver is treated as the first captured argument and placed in the dynamic argument list of the metafactory (pushed on the stack for the indy call.) > 0.6.1 - Part C is silent. The words final and capture don't occur there. > But SOTL 4th edition talks about the implicit lambda capturing a variable > and using that as the receiver. Spec should override all other prose - > right ? > I also see that the mention of implicit lambda is from a pedagogical pov. > > BTW, 0.6.1 Part B links to SOTL edition 3 - which is very outdated with > respect > to the present state of affairs. > > I see that javac 8b74 compiles this code fine: > > // -- > interface I { > void foo(); > } > > public class X { > private void foo() { > X x = new X(); > x = new X(); > I i = x::foo; > } > } > > Thanks in advance for any clarifications. > Srikanth. From daniel.smith at oracle.com Thu Feb 14 09:12:43 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Thu, 14 Feb 2013 10:12:43 -0700 Subject: Effective finality requirements for method reference receiver ? In-Reply-To: References: <2E2859BC-2882-4540-90F3-DE5B9E4695C6@oracle.com> <0F4995BE-8898-4027-970C-4E22BBB4493B@oracle.com> Message-ID: <6A79DD38-A855-4A69-A03D-6FE9C89C7F0E@oracle.com> On Feb 13, 2013, at 9:41 PM, Srikanth S Adayapalam wrote: > Are there any ? > > 0.6.1 - Part C is silent. The words final and capture don't occur there. > But SOTL 4th edition talks about the implicit lambda capturing a variable > and using that as the receiver. Spec should override all other prose - right ? > I also see that the mention of implicit lambda is from a pedagogical pov. Here's the relevant spec, from Part E, 15.28.2: "If the method reference begins with an ExpressionName or a Primary, the target reference of the invocation is the value of this expression, as determined _at the time_ the method reference was evaluated, and the parameters of the invocation are the parameters of the synthetic method." The intuition is that "Func f = expr::foo;" is translated into something like this: final Foo receiver = expr; Func f = (x, y) -> receiver.foo(x, y); (Hard to actually do such a translation in general, though, since you can't put variable declarations in the middle of an expression.) > BTW, 0.6.1 Part B links to SOTL edition 3 - which is very outdated with respect > to the present state of affairs. Thanks. I'll fix that. ?Dan > I see that javac 8b74 compiles this code fine: > > // -- > interface I { > void foo(); > } > > public class X { > private void foo() { > X x = new X(); > x = new X(); > I i = x::foo; > } > } > > Thanks in advance for any clarifications. > Srikanth. From forax at univ-mlv.fr Thu Feb 14 11:55:19 2013 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 14 Feb 2013 20:55:19 +0100 Subject: Effective finality requirements for method reference receiver ? In-Reply-To: <511D0A3D.2000308@oracle.com> References: <2E2859BC-2882-4540-90F3-DE5B9E4695C6@oracle.com> <0F4995BE-8898-4027-970C-4E22BBB4493B@oracle.com> <511D0A3D.2000308@oracle.com> Message-ID: <511D4127.4070308@univ-mlv.fr> On 02/14/2013 05:01 PM, Brian Goetz wrote: >> Are there any ? > > No. As part of evaluating a method reference, the receiver is > evaluated. So it is fine to have a mutable receiver; the value is > bound at the time the MR is evaluated. Then the receiver is treated > as the first captured argument and placed in the dynamic argument list > of the metafactory (pushed on the stack for the indy call.) You can use the very same argument for captured local variable of lambda/inner class if there are not mutated inside the lambda/inner-class. R?mi > >> 0.6.1 - Part C is silent. The words final and capture don't occur there. >> But SOTL 4th edition talks about the implicit lambda capturing a >> variable >> and using that as the receiver. Spec should override all other prose - >> right ? >> I also see that the mention of implicit lambda is from a pedagogical >> pov. >> >> BTW, 0.6.1 Part B links to SOTL edition 3 - which is very outdated with >> respect >> to the present state of affairs. >> >> I see that javac 8b74 compiles this code fine: >> >> // -- >> interface I { >> void foo(); >> } >> >> public class X { >> private void foo() { >> X x = new X(); >> x = new X(); >> I i = x::foo; >> } >> } >> >> Thanks in advance for any clarifications. >> Srikanth. From forax at univ-mlv.fr Thu Feb 14 12:16:15 2013 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 14 Feb 2013 21:16:15 +0100 Subject: Effective finality requirements for method reference receiver ? In-Reply-To: <6A79DD38-A855-4A69-A03D-6FE9C89C7F0E@oracle.com> References: <2E2859BC-2882-4540-90F3-DE5B9E4695C6@oracle.com> <0F4995BE-8898-4027-970C-4E22BBB4493B@oracle.com> <6A79DD38-A855-4A69-A03D-6FE9C89C7F0E@oracle.com> Message-ID: <511D460F.8070900@univ-mlv.fr> On 02/14/2013 06:12 PM, Dan Smith wrote: > On Feb 13, 2013, at 9:41 PM, Srikanth S Adayapalam wrote: > >> Are there any ? >> >> 0.6.1 - Part C is silent. The words final and capture don't occur there. >> But SOTL 4th edition talks about the implicit lambda capturing a variable >> and using that as the receiver. Spec should override all other prose - right ? >> I also see that the mention of implicit lambda is from a pedagogical pov. > Here's the relevant spec, from Part E, 15.28.2: > > "If the method reference begins with an ExpressionName or a Primary, the target reference of the invocation is the value of this expression, as determined _at the time_ the method reference was evaluated, and the parameters of the invocation are the parameters of the synthetic method." > > The intuition is that "Func f = expr::foo;" is translated into something like this: > > final Foo receiver = expr; > Func f = (x, y) -> receiver.foo(x, y); > > (Hard to actually do such a translation in general, though, since you can't put variable declarations in the middle of an expression.) FYI, javac has a special node for doing this exact translation internally (line 2374 of [1]) but it doesn't use it in that case. >> BTW, 0.6.1 Part B links to SOTL edition 3 - which is very outdated with respect >> to the present state of affairs. > Thanks. I'll fix that. > > ?Dan R?mi [1] http://hg.openjdk.java.net/lambda/lambda/langtools/file/dae2aede7f35/src/share/classes/com/sun/tools/javac/tree/JCTree.java > >> I see that javac 8b74 compiles this code fine: >> >> // -- >> interface I { >> void foo(); >> } >> >> public class X { >> private void foo() { >> X x = new X(); >> x = new X(); >> I i = x::foo; >> } >> } >> >> Thanks in advance for any clarifications. >> Srikanth. From srikanth_sankaran at in.ibm.com Thu Feb 14 19:24:23 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Thu, 14 Feb 2013 22:24:23 -0500 Subject: Descriptor computation in the presence of raw types ? In-Reply-To: <511D460F.8070900@univ-mlv.fr> References: <2E2859BC-2882-4540-90F3-DE5B9E4695C6@oracle.com> <0F4995BE-8898-4027-970C-4E22BBB4493B@oracle.com> <6A79DD38-A855-4A69-A03D-6FE9C89C7F0E@oracle.com> <511D460F.8070900@univ-mlv.fr> Message-ID: 0.6.1 9.8 is silent about descriptor computation in the presence of raw types. Is this specified somewhere else ? Discouraged though this scenario may be, we can expect to run into this sooner or later, intentionally coded or otherwise. The reference compiler at 8b74 seems to erase the descriptor as seen by the following program: This seems reasonable from one pov. From another, this is somewhat at odds with the ban on lambdas implementing generic methods in that, in both cases we have (or are likely to have) unadaptable type variable usage in various constituents of the descriptor. And the target type is raw in one case and the lambda is "raw" in the other case (by virtue of there being no grammar support for type parameter encoding) I am happy erasing the descriptor, but (a) should this stay unspecified if it indeed is and (b) does the inconsistency in treatment with generic lambdas OK ? Thanks in advance for clarifications. // --- import java.util.List; interface I { void foo(List f); } class Y { void goo(I f) { } } class Z { void zoo(I f) { } } public class X { public static void main(String [] args) { new Y().goo((List ls) -> {}); // Compiles OK with 8b74 new Z().zoo((List ls) -> {}); // OK } } -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130214/e264d490/attachment.html From srikanth_sankaran at in.ibm.com Thu Feb 14 20:04:14 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Thu, 14 Feb 2013 23:04:14 -0500 Subject: Descriptor computation in the presence of raw types ? In-Reply-To: References: <2E2859BC-2882-4540-90F3-DE5B9E4695C6@oracle.com> <0F4995BE-8898-4027-970C-4E22BBB4493B@oracle.com> <6A79DD38-A855-4A69-A03D-6FE9C89C7F0E@oracle.com> <511D460F.8070900@univ-mlv.fr> Message-ID: > From: Srikanth S Adayapalam/India/IBM at IBMIN > Sent by: lambda-spec-experts-bounces at openjdk.java.net > I am happy erasing the descriptor, but (a) should this stay > unspecified if it indeed > is and (b) does the inconsistency in treatment with generic lambdas OK ? To see the correlation between generic lambdas and raw types in target type study this program in which 8b74 is inadvertently allowing a generic lambda since it does not see the descriptor as being generic due to erasure: // ----- import java.util.List; interface I {

P foo(List f); } class Y { void goo(I f) { } } class Z { void zoo(I f) { } } public class X { public static void main(String [] args) { new Y().goo((List ls) -> { return null; }); // Fails: descriptor is generic new Z().zoo((List ls) -> { return null; }); // compiles fine, we are overriding a generic method with another that has no type variables!! } } Srikanth. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130214/f647827f/attachment.html From daniel.smith at oracle.com Fri Feb 15 09:08:04 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Fri, 15 Feb 2013 10:08:04 -0700 Subject: Descriptor computation in the presence of raw types ? In-Reply-To: References: <2E2859BC-2882-4540-90F3-DE5B9E4695C6@oracle.com> <0F4995BE-8898-4027-970C-4E22BBB4493B@oracle.com> <6A79DD38-A855-4A69-A03D-6FE9C89C7F0E@oracle.com> <511D460F.8070900@univ-mlv.fr> Message-ID: <7FAF2A9A-5A74-4F49-98E4-19C1527054FA@oracle.com> Good catch. Yes, this needs to be specified, and the right thing to do is erase the descriptor. I'll put it on my list. ?Dan On Feb 14, 2013, at 8:24 PM, Srikanth S Adayapalam wrote: > 0.6.1 9.8 is silent about descriptor computation in the presence of raw types. > Is this specified somewhere else ? Discouraged though this scenario may be, > we can expect to run into this sooner or later, intentionally coded or otherwise. > > The reference compiler at 8b74 seems to erase the descriptor as seen by the > following program: This seems reasonable from one pov. From another, this is > somewhat at odds with the ban on lambdas implementing generic methods in that, > in both cases we have (or are likely to have) unadaptable type variable usage in > various constituents of the descriptor. And the target type is raw in one case > and the lambda is "raw" in the other case (by virtue of there being no grammar > support for type parameter encoding) > > I am happy erasing the descriptor, but (a) should this stay unspecified if it indeed > is and (b) does the inconsistency in treatment with generic lambdas OK ? > > Thanks in advance for clarifications. > > // --- > import java.util.List; > interface I { > void foo(List f); > } > > class Y { > void goo(I f) { > } > } > > class Z { > void zoo(I f) { > } > } > public class X { > public static void main(String [] args) { > new Y().goo((List ls) -> {}); // Compiles OK with 8b74 > new Z().zoo((List ls) -> {}); // OK > } > } From daniel.smith at oracle.com Fri Feb 15 09:09:32 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Fri, 15 Feb 2013 10:09:32 -0700 Subject: Descriptor computation in the presence of raw types ? In-Reply-To: References: <2E2859BC-2882-4540-90F3-DE5B9E4695C6@oracle.com> <0F4995BE-8898-4027-970C-4E22BBB4493B@oracle.com> <6A79DD38-A855-4A69-A03D-6FE9C89C7F0E@oracle.com> <511D460F.8070900@univ-mlv.fr> Message-ID: <97084350-1964-4019-981C-BBB64BC736E7@oracle.com> On Feb 14, 2013, at 9:04 PM, Srikanth S Adayapalam wrote: > import java.util.List; > interface I { >

P foo(List f); > } > > class Y { > void goo(I f) { > } > } > > class Z { > void zoo(I f) { > } > } > public class X { > public static void main(String [] args) { > new Y().goo((List ls) -> { return null; }); // Fails: descriptor is generic > new Z().zoo((List ls) -> { return null; }); // compiles fine, we are overriding a generic method with another that has no type variables!! > } > } This doesn't bother me. The raw type I does not have a generic method, even if the parameterized type I does. It's also somewhat analogous to the situation in which we allow an erased-signature method to override a generic one. ?Dan From srikanth_sankaran at in.ibm.com Sat Feb 16 10:55:51 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Sat, 16 Feb 2013 13:55:51 -0500 Subject: Method/Constructor references. In-Reply-To: References: <51117DC2.9080108@univ-mlv.fr> <702F711B-D89E-4F94-9111-5EA9411BD42B@oracle.com> <0B3A2563-14C8-4B63-BED4-14DBFFD049F8@oracle.com> Message-ID: (1) 0.6.1, 15.28 says: "It is a compile-time error if the ClassType of a constructor reference denotes a class that is an enum type or that is abstract. " While JLS7 15.9 in addition says: "It is a compile-time error if any of the type arguments used in a class instance creation expression are wildcard type arguments (?4.5.1)." So is the less restrictive version with constructor references intentional ? I don't see anything in the design/motivation section regarding this to determine if it is. I would like to use one definition of what can be instantiated unless the relaxation is deliberate. So, should the following program compile ? // --- interface I { X zoo(int x, String p); } public class X { X(int x, String p) {} I i = X::new; // will compile X x = new X(); // will not compile. } I don't see a type safety issue here since the parameterization would have pass bounds check, only a consistency issue. (2) And since the production for ClassType (despite the name) cannot prune type variables and annotation types, should these also be called out as error scenarios ? (3) Should the (obvious) point about primary evaluating to base type being a forbidden scenario be mentioned ? (4) "The immediately enclosing instance of an inner class instance (15.9.2 ) must be provided for a constructor reference by a lexically enclosing instance of this (8.1.3). " Is this restrictive ? Can this be supplied at method invocation time or even via a primary from ? Implementable != useful and I don't have an assessment as to how useful practically it would be though. Again this is a consistency issue: the call to new Inner() can occur outside of the enclosing class in an entirely unrelated class as long as there an enclosing instance is available and the types are visible. Srikanth -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130216/9a3d59e2/attachment.html From srikanth_sankaran at in.ibm.com Sun Feb 17 04:06:38 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Sun, 17 Feb 2013 07:06:38 -0500 Subject: 15.28.1 needs some polish ? Message-ID: Hello ! (1) 0.6.1, 15.28.1 reads: ----------------------- Given a function descriptor with parameter types P1..Pn, the compile-time declaration for a method reference is determined as follows. If the method reference is qualified by a ReferenceType, two searches for a most-specific applicable method are performed, following the process outlined in 15.12.2. Each search may produce a method or, in the case of an error as specified in 15.12.2, no result. First, the reference is treated as if it were an invocation of a method named by Identifier with argument expressions of types P1..Pn; the type to search is the ReferenceType; the type arguments, if any, are given by the method reference. Second, if P1..Pn is not empty and P1 is a subtype of ReferenceType, the reference is treated as if it were an invocation of a method named by Identifier with argument expressions of types P2..Pn. If the ReferenceType is a raw type, and there exists a parameterization of this type, G, that is a supertype of P1, the type to search is G; otherwise, the type to search is the ReferenceType. Again, the type arguments, if any, are given by the method reference. If both of these searches match a method, the reference is considered ambiguous. Otherwise, if the first search matches an instance method or the second search matches a static method, no method is chosen. Otherwise, if one of the searches matches a method, that is the compile-time declaration. ---------------------------- The first mention of static occurs in the penultimate sentence of the quoted text: Does that mean the following program should be declared ambiguous ? (8b74 compiles this fine, but at run time there is an NPE) - There is no real ambiguity here. // ---- interface I { void zoo(Y y, String s); } class Y { void zoo(String s) { System.out.println("Y.zoo(String)"); } void zoo(Y y, String s) { System.out.println("Y.zoo(Y, String)"); } } public class X { public static void main(String[] args) { I i = Y::zoo; i.zoo(null, null); } } // ----------- I think this calls for a reordering of clauses and perhaps some rewording ? The sentence "Otherwise, if the first search matches an instance method or the second search matches a static method, no method is chosen." is a bit vague ? i.e does this mean "No method is chosen as the compile declaration of the method reference" or that "these matches are eliminated from further reckoning ?" Also the sentence "If both of these searches match a method, the reference is considered ambiguous." preceding the first utterance of 'static' would render the program above illegal. Or reword the passage "First, the reference is treated as if it were an invocation of a method" to "First, the reference is treated as if it were an invocation of a _static_ method" and likewise massage the second part too ? (2) Should the passage "Also note that static method invocations have the form TypeName.method(), while here we're using the more general ReferenceType; an error occurs if the reference ends up being a static method reference and the qualifier is a parameterized type." be relegated to the motivation box ? Thanks! Srikanth. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130217/468317ad/attachment.html From srikanth_sankaran at in.ibm.com Sun Feb 17 04:52:10 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Sun, 17 Feb 2013 07:52:10 -0500 Subject: 15.28.1 needs some polish ? In-Reply-To: References: Message-ID: I unsuccessfully searched through my old mails for the surveys we did a while ago and to see what we concluded on that - no luck there. I recall that we banned a bound reference targetting a static method, but not sure what was agreed to be done when a ReferenceType form "selects" an instance method. Ban on the former case had the point going for that with hindsight it is a known bad form. But in the latter case, the method is simply not applicable due to absence of receiver and is arguably best eliminated from reckoning rather than declare error. Perhaps the spec is consistent with the survey conclusions, but the reference compiler is not consistent with the spec ? TIA for any insights/clarifications. Srikanth. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130217/d03f687f/attachment.html From srikanth_sankaran at in.ibm.com Mon Feb 18 11:12:46 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Mon, 18 Feb 2013 14:12:46 -0500 Subject: 15.28.1 needs some polish ? In-Reply-To: References: Message-ID: > (2) Should the passage "Also note that static method invocations > have the form TypeName.method(), > while here we're using the more general ReferenceType; an error > occurs if the reference ends up being a > static method reference and the qualifier is a parameterized type." > be relegated to the motivation box ? This is an incorrect observation on my part - sorry. This is very much covered in the main body. I actually meant to ask if this section should expressly ban parameterized array creation and ended up asking the wrong question. The spec is silent on generic array creation and 8b74 allows: //--- import java.util.ArrayList; import java.util.List; interface I { List [] doit(int x); } public class X { I i1 = ArrayList[]::new; // Compiles OK I i2 = List[]::new; // Compiles OK List [] ls = new ArrayList[10]; // Error. } // ------- Srikanth. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130218/3f7c43ec/attachment.html From maurizio.cimadamore at oracle.com Tue Feb 19 02:44:11 2013 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Tue, 19 Feb 2013 10:44:11 +0000 Subject: 15.28.1 needs some polish ? In-Reply-To: References: Message-ID: <5123577B.9020608@oracle.com> On 18/02/13 19:12, Srikanth S Adayapalam wrote: >> (2) Should the passage "Also note that static method invocations >> have the form TypeName.method(), >> while here we're using the more general ReferenceType; an error >> occurs if the reference ends up being a >> static method reference and the qualifier is a parameterized type." >> be relegated to the motivation box ? > This is an incorrect observation on my part - sorry. This is very much > covered > in the main body. I actually meant to ask if this section should expressly > > ban parameterized array creation and ended up asking the wrong question. > > The spec is silent on generic array creation and 8b74 allows: Whoops - I believe the language should be consistent here - array creation is not any safer if it happens through method reference, so the code deserves an unchecked warning. Maurizio > > //--- > import java.util.ArrayList; > import java.util.List; > interface I { > List [] doit(int x); > } > public class X { > I i1 = ArrayList[]::new; // Compiles OK > I i2 = List[]::new; // Compiles OK > List [] ls = new ArrayList[10]; // Error. > } > // ------- > > Srikanth. From maurizio.cimadamore at oracle.com Tue Feb 19 03:40:03 2013 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Tue, 19 Feb 2013 11:40:03 +0000 Subject: 15.28.1 needs some polish ? In-Reply-To: References: <5123577B.9020608@oracle.com> Message-ID: <51236493.9080104@oracle.com> On 19/02/13 11:33, Srikanth S Adayapalam wrote: > > From: Maurizio Cimadamore > > Subject: Re: 15.28.1 needs some polish ? > > > > The spec is silent on generic array creation and 8b74 allows: > > Whoops - I believe the language should be consistent here - array > > creation is not any safer if it happens through method reference, so > the > > code deserves an unchecked warning. > > Note that direct array creation is an error, not a warning. > > Srikanth. Right - but we also have cases (in varargs) where indirect array creation is treated as warning. I guess in my mind this looked closer to the latter (as no array is created if the mref is never called) but I could see this going either way. Maurizio -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130219/e4d0f552/attachment.html From srikanth_sankaran at in.ibm.com Tue Feb 19 03:33:17 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Tue, 19 Feb 2013 06:33:17 -0500 Subject: 15.28.1 needs some polish ? In-Reply-To: <5123577B.9020608@oracle.com> References: <5123577B.9020608@oracle.com> Message-ID: > From: Maurizio Cimadamore > Subject: Re: 15.28.1 needs some polish ? > > The spec is silent on generic array creation and 8b74 allows: > Whoops - I believe the language should be consistent here - array > creation is not any safer if it happens through method reference, so the > code deserves an unchecked warning. Note that direct array creation is an error, not a warning. Srikanth. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130219/a2d6190e/attachment.html From daniel.smith at oracle.com Tue Feb 19 15:47:27 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Tue, 19 Feb 2013 16:47:27 -0700 Subject: Method/Constructor references. In-Reply-To: References: <51117DC2.9080108@univ-mlv.fr> <702F711B-D89E-4F94-9111-5EA9411BD42B@oracle.com> <0B3A2563-14C8-4B63-BED4-14DBFFD049F8@oracle.com> Message-ID: <9D360112-4A58-4D4F-8878-B1F670D07743@oracle.com> Thanks for the comments. They have helped to significantly improve 15.28. On Feb 16, 2013, at 11:55 AM, Srikanth S Adayapalam wrote: > (1) 0.6.1, 15.28 says: > > "It is a compile-time error if the ClassType of a constructor reference denotes a class that is an enum type or that is abstract. " > > While JLS7 15.9 in addition says: > > "It is a compile-time error if any of the type arguments used in a class instance > creation expression are wildcard type arguments (?4.5.1)." > > So is the less restrictive version with constructor references intentional ? I don't see anything in > the design/motivation section regarding this to determine if it is. > > I would like to use one definition of what can be instantiated unless the relaxation is deliberate. > > So, should the following program compile ? > > // --- > interface I { > X zoo(int x, String p); > } > public class X { > X(int x, String p) {} > I i = X::new; // will compile > X x = new X(); // will not compile. > } > > I don't see a type safety issue here since the parameterization would have pass bounds check, only a consistency issue. Good catch. This is just something I missed when scanning through 15.9 for errors. I've added a restriction on type arguments to Part C, 15.28. Wildcards are now prohibited from constructor references. > (2) And since the production for ClassType (despite the name) cannot prune type variables and > annotation types, should these also be called out as error scenarios ? My intent is for the ClassType production to have a semantic meaning along with the syntax: it only applies to names of actual classes. Looking at other usages of "ClassType" and "InterfaceType", though, as in 8.1.4 and 8.1.5, it seems to typically be accompanied by a restriction like "The ClassType must name an accessible (?6.6) class type, or a compile-time error occurs." I'll follow suit here. > (3) Should the (obvious) point about primary evaluating to base type being a forbidden scenario > be mentioned ? I think you mean something like "1::m". That's covered in a roundabout way by Part E -- 15.28.1 says if 15.12.1 defines an error, then a candidate method is not applicable (and so no applicable methods would be found, and that would be an error). But I think it's a lot more clear to state the restriction explicitly, so I will do so. I also see some restrictions from 15.12.1 on 'super' invocations (as modified by Part H) that deserve stating explicitly here, too. > (4) "The immediately enclosing instance of an inner class instance (15.9.2) must be provided for a constructor reference by a lexically enclosing instance of this (8.1.3). " > Is this restrictive ? Can this be supplied at method invocation time or even via a primary from ? Implementable != useful and > I don't have an assessment as to how useful practically it would be though. Again this is a consistency issue: the call to > new Inner() can occur outside of the enclosing class in an entirely unrelated class as long as there an enclosing instance is > available and the types are visible. I can think of three plausible ways to get an enclosing instance for an inner class constructor reference. Do you have one of these in mind?: - There's a compatible enclosing 'this' from point of the constructor reference. Such a scenario is supported, and is what the above sentence is meant to describe. - The constructor reference syntax provides the value, analogous to 'OuterObject.new Foo()'. We have no syntax for this scenario, and decided it wasn't worth adding syntactic complexity in order to support. - The function descriptor has an extra parameter so that the _invoker_ of the reference can provide an enclosing instance. This scenario was discussed in one of the surveys from this summer and ultimately dismissed. (Again, too much complexity for a marginal benefit.) ?Dan From daniel.smith at oracle.com Tue Feb 19 15:54:31 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Tue, 19 Feb 2013 16:54:31 -0700 Subject: 15.28.1 needs some polish ? In-Reply-To: References: <5123577B.9020608@oracle.com> Message-ID: <32860FFA-31E2-439E-8404-620CF4F1AAF5@oracle.com> On Feb 19, 2013, at 4:33 AM, Srikanth S Adayapalam wrote: > > From: Maurizio Cimadamore > > Subject: Re: 15.28.1 needs some polish ? > > > > The spec is silent on generic array creation and 8b74 allows: > > Whoops - I believe the language should be consistent here - array > > creation is not any safer if it happens through method reference, so the > > code deserves an unchecked warning. > > Note that direct array creation is an error, not a warning. > > Srikanth. I've mimicked the error from 15.10 in 15.28. The new rule is that the ArrayType must be reifiable, or an error occurs. ?Dan From daniel.smith at oracle.com Tue Feb 19 16:13:59 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Tue, 19 Feb 2013 17:13:59 -0700 Subject: 15.28.1 needs some polish ? In-Reply-To: References: Message-ID: <17AB896B-A271-475E-BF09-83D30E0A97D4@oracle.com> On Feb 17, 2013, at 5:06 AM, Srikanth S Adayapalam wrote: > Hello ! > > (1) 0.6.1, 15.28.1 reads: > > ----------------------- > Given a function descriptor with parameter types P1..Pn, the compile-time declaration for a method reference is determined as follows. > > If the method reference is qualified by a ReferenceType, two searches for a most-specific applicable method are performed, following the process outlined in 15.12.2. Each search may produce a method or, in the case of an error as specified in 15.12.2, no result. > First, the reference is treated as if it were an invocation of a method named by Identifier with argument expressions of types P1..Pn; the type to search is the ReferenceType; the type arguments, if any, are given by the method reference. > > Second, if P1..Pn is not empty and P1 is a subtype of ReferenceType, the reference is treated as if it were an invocation of a method named by Identifier with argument expressions of types P2..Pn. If the ReferenceType is a raw type, and there exists a parameterization of this type, G, that is a supertype of P1, the type to search is G; otherwise, the type to search is the ReferenceType. Again, the type arguments, if any, are given by the method reference. > > If both of these searches match a method, the reference is considered ambiguous. > > Otherwise, if the first search matches an instance method or the second search matches a static method, no method is chosen. > > Otherwise, if one of the searches matches a method, that is the compile-time declaration. > ---------------------------- > > The first mention of static occurs in the penultimate sentence of the quoted text: Does that mean the following program > should be declared ambiguous ? (8b74 compiles this fine, but at run time there is an NPE) - There is no real ambiguity here. > > // ---- > interface I { > void zoo(Y y, String s); > } > > class Y { > void zoo(String s) { > System.out.println("Y.zoo(String)"); > } > void zoo(Y y, String s) { > System.out.println("Y.zoo(Y, String)"); > } > } > > > public class X { > public static void main(String[] args) { > I i = Y::zoo; > i.zoo(null, null); > } > } > // ----------- > > I think this calls for a reordering of clauses and perhaps some rewording ? > The sentence "Otherwise, if the first search matches an instance method or > the second search matches a static method, no method is chosen." is a bit > vague ? i.e does this mean "No method is chosen as the compile declaration > of the method reference" or that "these matches are eliminated from further > reckoning ?" > > Also the sentence "If both of these searches match a method, the reference > is considered ambiguous." preceding the first utterance of 'static' would > render the program above illegal. > > Or reword the passage "First, the reference is treated as if it were an > invocation of a method" to "First, the reference is treated as if it were an > invocation of a _static_ method" and likewise massage the second part too ? This is an intentional design choice, although I think it's not quite right. The goal is to mimic the behavior of 15.12: a "static" method invocation can match an instance method, and it's only after a most-specific applicable method is chosen that an error occurs (per 15.12.3). Generalizing, the search for a method is not supposed to take 'static'-ness into account. (If anybody feels like this hasn't been sufficiently discussed, though, I acknowledge that this is a bit of a leap and we can debate it more...) So your example should be an error. In addition, 'static'-ness shouldn't affect resolution of an enclosing method invocation (e.g., 'overloadedMethod(Foo::m)'), any more than type arguments do (e.g., 'overloadedMethod(Foo::m)'), so the check should wait to happen until after compatibility has been established. So I've removed the sentence in question entirely, and added a similar restriction to the bulleted list that starts with "A method or constructor reference may be illegal even if it is compatible with its expected type". ?Dan From srikanth_sankaran at in.ibm.com Tue Feb 19 22:40:34 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Wed, 20 Feb 2013 01:40:34 -0500 Subject: Method/Constructor references. In-Reply-To: <9D360112-4A58-4D4F-8878-B1F670D07743@oracle.com> References: <51117DC2.9080108@univ-mlv.fr> <702F711B-D89E-4F94-9111-5EA9411BD42B@oracle.com> <0B3A2563-14C8-4B63-BED4-14DBFFD049F8@oracle.com> <9D360112-4A58-4D4F-8878-B1F670D07743@oracle.com> Message-ID: > I can think of three plausible ways to get an enclosing instance for > an inner class constructor reference. Do you have one of these in mind?: Yes, > ultimately dismissed. (Again, too much complexity for a marginal benefit.) I am comfortable with this assessment, so this question can be considered closed. Thanks! Srikanth. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130220/5749f483/attachment.html From srikanth_sankaran at in.ibm.com Tue Feb 19 23:01:15 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Wed, 20 Feb 2013 02:01:15 -0500 Subject: Part G - Concerns. In-Reply-To: <9D360112-4A58-4D4F-8878-B1F670D07743@oracle.com> References: <51117DC2.9080108@univ-mlv.fr> <702F711B-D89E-4F94-9111-5EA9411BD42B@oracle.com> <0B3A2563-14C8-4B63-BED4-14DBFFD049F8@oracle.com> <9D360112-4A58-4D4F-8878-B1F670D07743@oracle.com> Message-ID: Good morning, With the eclipse compiler implementation [excluding code generation] of Parts A-E essentially complete and part H nearly so, we are working on parts F & G. The intrepid gladiators who have (despite not being armed with a double PhD in Math and Comp.Sc :)) chosen to enter the colosseum to tame these two lions are respectively, yours truly (F) and Stephan Herrmann (G). Please find below a high level assessment from Stephan, the Eclipse JDT implementation lead for the 335 type inference project on the state of the specification of Part-G. I have requested Stephan to raise (where the state of part G would permit) specific point issues with example code to ask pointed questions about specified behavior or to call out lack of clarity and we will try and do that in the coming days and weeks. I am also studying this part in detail to formulate my own opinion, but given the gravity of his assessment, I wanted to share it as is already. Thanks! Srikanth. ---------------------------------------- I appreciate the effort to put the specification of type inference on more solid grounds, as this should help to reduce the deviations between different compilers which all adhere to the same specification. However, as of the 0.6.1 early draft of JSR 335 the section "18 Type Inference" is not in a state that can be used for any downstream activities. It is not possible to implement a type checker based on this draft nor is it possible to validate whether the given rules actually produce the desired results. The main problem is that sections 18.3 and 18.4 are completely missing (except for "To do" place holders). These sections should contribute to the back bone of the algorithm of type inference and without these not a single example program can be type checked. Many more sections contain similar "To do" placeholders, 18.2.3 ff. might be critical, too, whereas some others may be regarded as details that can be filled in last minute. As an example consider the fact that the algorithm terminates when inference variables are "resolved" as represented by an equality type constraint. However, not a single rule in the specification will ever *create* such a constraint. IMHO, the specification needs a significant period of validation between the day when it is considered complete and the point where agreement can be achieved that this will indeed be the foundation of Java 8 as a standard. Looking at the milestone schedule for Java 8 I am very worried that JSR 335 will ship an underspecified type system that puts users at the mercy of the intuition of compiler engineers. Stephan. ------------- -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130220/57d05ef7/attachment-0001.html From maurizio.cimadamore at oracle.com Wed Feb 20 02:07:24 2013 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 20 Feb 2013 10:07:24 +0000 Subject: Part G - Concerns. In-Reply-To: References: <51117DC2.9080108@univ-mlv.fr> <702F711B-D89E-4F94-9111-5EA9411BD42B@oracle.com> <0B3A2563-14C8-4B63-BED4-14DBFFD049F8@oracle.com> <9D360112-4A58-4D4F-8878-B1F670D07743@oracle.com> Message-ID: <5124A05C.8060105@oracle.com> Good luck with F & G ;-) To address your concern, I know that a new draft with all inference sections is in the works and will be made available. The goal of the current draft is to define the high-level framework in which inference operates. In terms of the implementation, I believe the current status of the inference engine in javac [1] captures the design fairly closely, and it can be used as a valid starting point. [1] - http://hg.openjdk.java.net/jdk8/jdk8/langtools/file/tip/src/share/classes/com/sun/tools/javac/comp/Infer.java Maurizio On 20/02/13 07:01, Srikanth S Adayapalam wrote: > Good morning, > > With the eclipse compiler implementation [excluding code > generation] of > Parts A-E essentially complete and part H nearly so, we are working on > parts > F & G. The intrepid gladiators who have (despite not being armed with a > double > PhD in Math and Comp.Sc :)) chosen to enter the colosseum to tame these > two lions > are respectively, yours truly (F) and Stephan Herrmann (G). > > Please find below a high level assessment from Stephan, the Eclipse JDT > implementation > lead for the 335 type inference project on the state of the specification > of Part-G. > I have requested Stephan to raise (where the state of part G would permit) > specific > point issues with example code to ask pointed questions about specified > behavior or > to call out lack of clarity and we will try and do that in the coming days > and weeks. > I am also studying this part in detail to formulate my own opinion, but > given the > gravity of his assessment, I wanted to share it as is already. > > Thanks! > Srikanth. > > ---------------------------------------- > I appreciate the effort to put the specification of type inference > on more solid grounds, as this should help to reduce the deviations > between different compilers which all adhere to the same specification. > However, as of the 0.6.1 early draft of JSR 335 the section "18 Type > Inference" is not in a state that can be used for any downstream > activities. It is not possible to implement a type checker based on > this draft nor is it possible to validate whether the given rules > actually produce the desired results. > The main problem is that sections 18.3 and 18.4 are completely missing > (except for "To do" place holders). These sections should contribute > to the back bone of the algorithm of type inference and without these > not a single example program can be type checked. > Many more sections contain similar "To do" placeholders, 18.2.3 ff. > might be critical, too, whereas some others may be regarded as details > that can be filled in last minute. > As an example consider the fact that the algorithm terminates when > inference variables are "resolved" as represented by an equality type > constraint. However, not a single rule in the specification will ever > *create* such a constraint. > IMHO, the specification needs a significant period of validation between > the day when it is considered complete and the point where agreement > can be achieved that this will indeed be the foundation of Java 8 as > a standard. Looking at the milestone schedule for Java 8 I am very > worried that JSR 335 will ship an underspecified type system that puts > users at the mercy of the intuition of compiler engineers. > > Stephan. > ------------- -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130220/54cd5191/attachment.html From srikanth_sankaran at in.ibm.com Wed Feb 20 02:55:24 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Wed, 20 Feb 2013 05:55:24 -0500 Subject: Part G - Concerns. In-Reply-To: <5124A05C.8060105@oracle.com> References: <51117DC2.9080108@univ-mlv.fr> <702F711B-D89E-4F94-9111-5EA9411BD42B@oracle.com> <0B3A2563-14C8-4B63-BED4-14DBFFD049F8@oracle.com> <9D360112-4A58-4D4F-8878-B1F670D07743@oracle.com> <5124A05C.8060105@oracle.com> Message-ID: > From: Maurizio Cimadamore > Subject: Re: Part G - Concerns. > > Good luck with F & G ;-) Thanks! > To address your concern, I know that a new draft with all inference > sections is in the works and will be made available. Thanks, we look forward to it. > In terms of the implementation, I believe the current status of the > inference engine in javac [1] captures the design fairly closely, > and it can be used as a valid starting point. > > [1] - http://hg.openjdk.java.net/jdk8/jdk8/langtools/file/tip/src/ > share/classes/com/sun/tools/javac/comp/Infer.java Per my understanding, Eclipse committers are not allowed to even visit open jdk blogs, let alone look at the source code :) Srikanth. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130220/d314f1b7/attachment.html From forax at univ-mlv.fr Wed Feb 20 07:15:45 2013 From: forax at univ-mlv.fr (Remi Forax) Date: Wed, 20 Feb 2013 16:15:45 +0100 Subject: Exceptions and lambda. In-Reply-To: References: <51117DC2.9080108@univ-mlv.fr> <702F711B-D89E-4F94-9111-5EA9411BD42B@oracle.com> <5112315A.5000201@oracle.com> <51125489.1040402@oracle.com> <51125BC6.4010900@oracle.com> Message-ID: <5124E8A1.6060706@univ-mlv.fr> On 02/06/2013 02:57 PM, Srikanth S Adayapalam wrote: > > From: Maurizio Cimadamore > > Subject: Re: Exceptions and lambda. > > > It would seem that the text is implying that the restriction comes > > from the fact that a lambda has no syntax for declaring type- > > parameters. On the other hand I'm not sure that's enough, as the > > compiler could simply generate a signature that matches the one in > > the functional descriptor so that overriding is preserved (esp. when > > lambda formals are omitted). > > As a matter of fact, I had (incorrectly) assumed that the primary reason > we support elided types was to accommodate this scenario, where due to > lack of own type variables, the lambda won't be able to spell out a > signature that is equivalent and only secondarily to minimize noise in > complex expressions/invocations etc. No, the main reason is more practical, if you doesn't allow to elide types, you end up with lambda where the parameter declaration part is far bigger than the expression part. This goes back to the lambda/closure syntax war in 2009, it was part of the CICE proposal. > > > I said > > mostly because if the descriptor doesn't mention type-variables in > > the argument part, then the check doesn't help and we're back to > square one. > > Then don't we just have concrete types that could be type checked against > each other ? > > Srikanth. R?mi From forax at univ-mlv.fr Wed Feb 20 07:15:54 2013 From: forax at univ-mlv.fr (Remi Forax) Date: Wed, 20 Feb 2013 16:15:54 +0100 Subject: Exceptions and lambda. In-Reply-To: References: <51117DC2.9080108@univ-mlv.fr> <702F711B-D89E-4F94-9111-5EA9411BD42B@oracle.com> <5112315A.5000201@oracle.com> <51125489.1040402@oracle.com> <51125BC6.4010900@oracle.com> Message-ID: <5124E8AA.80100@univ-mlv.fr> On 02/06/2013 10:24 PM, Dan Smith wrote: > On Feb 6, 2013, at 6:33 AM, Maurizio Cimadamore wrote: > >> On 06/02/13 13:03, Maurizio Cimadamore wrote: >>> On 06/02/13 12:51, Srikanth S Adayapalam wrote: >>>> I couldn't find some text that explicitly >>>> forbids the scenario we are talking about (where types are elided and inferred and >>>> there is no further need to refer to any type variables) >>> I think I cannot find it either - I think it should be in 15.27.3 Type of a Lambda Expression' - Dan? >>> >>> Maurizio >> The only bit about this that I could find is the discussion section in 9.8 (bullet 4). >> >> It would seem that the text is implying that the restriction comes from the fact that a lambda has no syntax for declaring type-parameters. On the other hand I'm not sure that's enough, as the compiler could simply generate a signature that matches the one in the functional descriptor so that overriding is preserved (esp. when lambda formals are omitted). > You're right. I expect a rule in 15.27.3 that says the type parameters of the lambda (constrained to be none by the syntax) are the same as the type parameters of the function descriptor. But it seems I left out that rule. > > I think the EG agreed on the behavior I describe back in April. But by "agreed," I mostly mean a silent consensus, and it's possible subtleties like this weren't fully considered. I'll write up the alternative behavior (the lambda's type params being derived from the descriptor and unmentionable) and see if it piques anyone's interest. > > ?Dan Hi Dan, I'm interested :) Yes, the compiler should try to infer the type variables and that these variables should not be accessible in Java. R?mi From brian.goetz at oracle.com Wed Feb 20 07:57:04 2013 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 20 Feb 2013 10:57:04 -0500 Subject: Part G - Concerns. In-Reply-To: References: <51117DC2.9080108@univ-mlv.fr> <702F711B-D89E-4F94-9111-5EA9411BD42B@oracle.com> <0B3A2563-14C8-4B63-BED4-14DBFFD049F8@oracle.com> <9D360112-4A58-4D4F-8878-B1F670D07743@oracle.com> Message-ID: <5124F250.9050305@oracle.com> I salute the intrepid gladiators who have taken on this task, which I know is not small. I am not entirely surprised by Stephan's initial reaction on first entering the colosseum. Were I him, I too would be intimidated by what is ahead of me! My advice: breathe. There is a lot here, but it was not pulled out of a hat this morning. It may take some time to take it all in. And, we're friendly. No hungry lions here. He is correct that there are pieces missing in the Type Inference section; that was known (and we welcome questions). and we're working on filling them in. However, I don't think the "OMG this is a disaster" response is quite warranted. Is it finished? No. But is it so incomplete that there is no place to begin? Again, no. In fact, a third party -- IntelliJ -- has a prototype that has nearly achieved feature parity with javac already. So clearly it is not the case that "there's no place to start" or "it can't be done." So, concerns have their place, but let's not be paralyzed by them. I'm sure that after Stephan takes a few deep breaths, he'll have some concrete questions and concerns, and we look forward to them. Welcome, Stephan. We look forward to your participation. On 2/20/2013 2:01 AM, Srikanth S Adayapalam wrote: > Good morning, > > With the eclipse compiler implementation [excluding code generation] > of Parts A-E essentially complete and part H nearly so, we are > working on parts F & G. The intrepid gladiators who have (despite not > being armed with a double PhD in Math and Comp.Sc :)) chosen to enter > the colosseum to tame these two lions are respectively, yours truly > (F) and Stephan Herrmann (G). > > Please find below a high level assessment from Stephan, the Eclipse > JDT implementation lead for the 335 type inference project on the > state of the specification of Part-G. I have requested Stephan to > raise (where the state of part G would permit) specific point issues > with example code to ask pointed questions about specified behavior > or to call out lack of clarity and we will try and do that in the > coming days and weeks. I am also studying this part in detail to > formulate my own opinion, but given the gravity of his assessment, I > wanted to share it as is already. > > Thanks! Srikanth. > > ---------------------------------------- I appreciate the effort to > put the specification of type inference on more solid grounds, as > this should help to reduce the deviations between different compilers > which all adhere to the same specification. However, as of the 0.6.1 > early draft of JSR 335 the section "18 Type Inference" is not in a > state that can be used for any downstream activities. It is not > possible to implement a type checker based on this draft nor is it > possible to validate whether the given rules actually produce the > desired results. The main problem is that sections 18.3 and 18.4 are > completely missing (except for "To do" place holders). These sections > should contribute to the back bone of the algorithm of type inference > and without these not a single example program can be type checked. > Many more sections contain similar "To do" placeholders, 18.2.3 ff. > might be critical, too, whereas some others may be regarded as > details that can be filled in last minute. As an example consider the > fact that the algorithm terminates when inference variables are > "resolved" as represented by an equality type constraint. However, > not a single rule in the specification will ever *create* such a > constraint. IMHO, the specification needs a significant period of > validation between the day when it is considered complete and the > point where agreement can be achieved that this will indeed be the > foundation of Java 8 as a standard. Looking at the milestone schedule > for Java 8 I am very worried that JSR 335 will ship an underspecified > type system that puts users at the mercy of the intuition of compiler > engineers. > > Stephan. ------------- From daniel.smith at oracle.com Wed Feb 20 10:35:05 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Wed, 20 Feb 2013 11:35:05 -0700 Subject: Lambdas with implicit type parameters In-Reply-To: References: Message-ID: <452ED23A-4228-4A2C-A1AA-0C323CE3485E@oracle.com> On Feb 6, 2013, at 2:44 PM, Dan Smith wrote: > Our status quo for handling of generic function descriptors (derived from functional interfaces with generic methods) was described by Brian back in April [1]: method references can target these functional interfaces, but lambdas, because they can declare no type parameters, cannot. > > I remember discussions about an alternative approach, but I don't know whether it really got proper treatment from the EG, so I'll describe it here. If anyone thinks this is a good enhancement to make, or if anybody remembers a previous, more in-depth discussion, please say so. > > (Background: Remember that a lambda is treated like an override of the functional interface's method; generally speaking, the rules for a legal lambda correspond to the rules for a legal overriding declaration -- this means the lambda must declare the "same" (allowing for renaming) type parameters as the descriptor. Also recall that we tried to find a syntax for generic lambdas, and failed to find anything acceptable.) > > The idea: a lambda that targets a generic function descriptor may have an implicit type parameter declaration. Unlike most other forms of inference (using the term broadly), this is inference of a _declaration_ of a new name. Sort of like wildcard capture. The new names would be unmentionable, but if the lambda can be defined without needing to refer explicitly to a type parameter name (probably fairly common, especially when the lambda parameter types are inferred), that's fine. > > Error messages would have to find a way to talk about these nameless tparams, of course (if, say, there's a type error in the lambda body). Typically the functional interface declaration provides a reasonable name, although, in general, there can be multiple methods that describe the same descriptor with different type parameter names. > > Example: > > interface ListFactory { > List make(); > } > > ListFactory f1 = ArrayList::new; // currently legal > ListFactory f2 = () -> new ArrayList<>(); // illegal currently, the enhancement would allow it > ListFactory f3 = () -> new ArrayList(); // definitely illegal: T is not in scope > > ?Dan > > [1] "Generic functional interfaces, generic method refs, and generic lambdas", 12 Apr 2012, from jsr-335-eg at jcp.org Remi says "yes, please": On Feb 20, 2013, at 8:15 AM, Remi Forax wrote: > Hi Dan, > I'm interested :) > Yes, the compiler should try to infer the type variables and that these variables should not be accessible in Java. > > R?mi Anybody else have an opinion? ?Dan From sam at sampullara.com Wed Feb 20 10:46:37 2013 From: sam at sampullara.com (Sam Pullara) Date: Wed, 20 Feb 2013 10:46:37 -0800 Subject: Lambdas with implicit type parameters In-Reply-To: <452ED23A-4228-4A2C-A1AA-0C323CE3485E@oracle.com> References: <452ED23A-4228-4A2C-A1AA-0C323CE3485E@oracle.com> Message-ID: I think we should allow it as well. Is there some downside? Sam On Wed, Feb 20, 2013 at 10:35 AM, Dan Smith wrote: > On Feb 6, 2013, at 2:44 PM, Dan Smith wrote: > >> Our status quo for handling of generic function descriptors (derived from functional interfaces with generic methods) was described by Brian back in April [1]: method references can target these functional interfaces, but lambdas, because they can declare no type parameters, cannot. >> >> I remember discussions about an alternative approach, but I don't know whether it really got proper treatment from the EG, so I'll describe it here. If anyone thinks this is a good enhancement to make, or if anybody remembers a previous, more in-depth discussion, please say so. >> >> (Background: Remember that a lambda is treated like an override of the functional interface's method; generally speaking, the rules for a legal lambda correspond to the rules for a legal overriding declaration -- this means the lambda must declare the "same" (allowing for renaming) type parameters as the descriptor. Also recall that we tried to find a syntax for generic lambdas, and failed to find anything acceptable.) >> >> The idea: a lambda that targets a generic function descriptor may have an implicit type parameter declaration. Unlike most other forms of inference (using the term broadly), this is inference of a _declaration_ of a new name. Sort of like wildcard capture. The new names would be unmentionable, but if the lambda can be defined without needing to refer explicitly to a type parameter name (probably fairly common, especially when the lambda parameter types are inferred), that's fine. >> >> Error messages would have to find a way to talk about these nameless tparams, of course (if, say, there's a type error in the lambda body). Typically the functional interface declaration provides a reasonable name, although, in general, there can be multiple methods that describe the same descriptor with different type parameter names. >> >> Example: >> >> interface ListFactory { >> List make(); >> } >> >> ListFactory f1 = ArrayList::new; // currently legal >> ListFactory f2 = () -> new ArrayList<>(); // illegal currently, the enhancement would allow it >> ListFactory f3 = () -> new ArrayList(); // definitely illegal: T is not in scope >> >> ?Dan >> >> [1] "Generic functional interfaces, generic method refs, and generic lambdas", 12 Apr 2012, from jsr-335-eg at jcp.org > > Remi says "yes, please": > > On Feb 20, 2013, at 8:15 AM, Remi Forax wrote: > >> Hi Dan, >> I'm interested :) >> Yes, the compiler should try to infer the type variables and that these variables should not be accessible in Java. >> >> R?mi > > Anybody else have an opinion? > > ?Dan From maurizio.cimadamore at oracle.com Wed Feb 20 10:54:18 2013 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 20 Feb 2013 18:54:18 +0000 Subject: Lambdas with implicit type parameters In-Reply-To: References: <452ED23A-4228-4A2C-A1AA-0C323CE3485E@oracle.com> Message-ID: <51251BDA.8050305@oracle.com> On 20/02/13 18:46, Sam Pullara wrote: > I think we should allow it as well. Is there some downside? Implementation-wise seems reasonably straightforward - not much more than just allowing generic functional descriptors on lambdas, I think. Actually, is there any reason why we should recreate new type-variables _at all_ as opposed as to reusing those from the functional interface declaration? Maurizio > > Sam > > On Wed, Feb 20, 2013 at 10:35 AM, Dan Smith wrote: >> On Feb 6, 2013, at 2:44 PM, Dan Smith wrote: >> >>> Our status quo for handling of generic function descriptors (derived from functional interfaces with generic methods) was described by Brian back in April [1]: method references can target these functional interfaces, but lambdas, because they can declare no type parameters, cannot. >>> >>> I remember discussions about an alternative approach, but I don't know whether it really got proper treatment from the EG, so I'll describe it here. If anyone thinks this is a good enhancement to make, or if anybody remembers a previous, more in-depth discussion, please say so. >>> >>> (Background: Remember that a lambda is treated like an override of the functional interface's method; generally speaking, the rules for a legal lambda correspond to the rules for a legal overriding declaration -- this means the lambda must declare the "same" (allowing for renaming) type parameters as the descriptor. Also recall that we tried to find a syntax for generic lambdas, and failed to find anything acceptable.) >>> >>> The idea: a lambda that targets a generic function descriptor may have an implicit type parameter declaration. Unlike most other forms of inference (using the term broadly), this is inference of a _declaration_ of a new name. Sort of like wildcard capture. The new names would be unmentionable, but if the lambda can be defined without needing to refer explicitly to a type parameter name (probably fairly common, especially when the lambda parameter types are inferred), that's fine. >>> >>> Error messages would have to find a way to talk about these nameless tparams, of course (if, say, there's a type error in the lambda body). Typically the functional interface declaration provides a reasonable name, although, in general, there can be multiple methods that describe the same descriptor with different type parameter names. >>> >>> Example: >>> >>> interface ListFactory { >>> List make(); >>> } >>> >>> ListFactory f1 = ArrayList::new; // currently legal >>> ListFactory f2 = () -> new ArrayList<>(); // illegal currently, the enhancement would allow it >>> ListFactory f3 = () -> new ArrayList(); // definitely illegal: T is not in scope >>> >>> ?Dan >>> >>> [1] "Generic functional interfaces, generic method refs, and generic lambdas", 12 Apr 2012, from jsr-335-eg at jcp.org >> Remi says "yes, please": >> >> On Feb 20, 2013, at 8:15 AM, Remi Forax wrote: >> >>> Hi Dan, >>> I'm interested :) >>> Yes, the compiler should try to infer the type variables and that these variables should not be accessible in Java. >>> >>> R?mi >> Anybody else have an opinion? >> >> ?Dan From daniel.smith at oracle.com Wed Feb 20 11:44:42 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Wed, 20 Feb 2013 12:44:42 -0700 Subject: Lambdas with implicit type parameters In-Reply-To: <51251BDA.8050305@oracle.com> References: <452ED23A-4228-4A2C-A1AA-0C323CE3485E@oracle.com> <51251BDA.8050305@oracle.com> Message-ID: On Feb 20, 2013, at 11:54 AM, Maurizio Cimadamore wrote: > On 20/02/13 18:46, Sam Pullara wrote: >> I think we should allow it as well. Is there some downside? > Implementation-wise seems reasonably straightforward - not much more than just allowing generic functional descriptors on lambdas, I think. Maurizio, thanks, that's useful. At this stage, I don't think we'd want to consider it at all if the implementation were nontrivial. Sam, even so, we do still need to keep in mind that our budget is quite small at this point, and there are costs (e.g., testing overhead) associated with every "new feature," no matter how easy it is to implement. Worth considering whether _this_ is the feature we want to spend our budget on. (Perhaps at some point soon I should collect all practical outstanding feature ideas and we can pick our favorites, limited by our remaining budget...) Beyond that, I think the main question is how we feel about the instability it creates in the language design -- the most stable point would be either to prohibit generic descriptors altogether, or provide syntax for generic lambdas. But those alternatives are unattractive. Our compromise point was to say method references can be generic, but lambdas cannot -- a little more awkward, but still a pretty clear line. Making this change would mean lambdas can be generic *as long as you don't need to talk about the type parameters*. That's a lot harder to explain, and increases the likelihood that somebody's going to be really annoyed when they need to tweak their program and find that the syntax arbitrarily prohibits what they want to say. Intertwined with this is the problem that non-denotable types are generally a pain, and this would introduce them in yet another place. So that's the argument against. I'm also sympathetic to the argument for, which is that [big number]% of uses cases don't need to mention the type variables, and this would sure be convenient for them. > Actually, is there any reason why we should recreate new type-variables _at all_ as opposed as to reusing those from the functional interface declaration? It's essentially a theoretical concern for specification. Types have to be interpreted in a particular scope, and we can't have the descriptor's type variables polluting the scope with names that shadow enclosing things. But, depending on the details of an implementation, it might be able to ignore this (e.g., maybe the implementation's types don't need to be interpreted in a scope). ?Dan From daniel.smith at oracle.com Wed Feb 20 13:24:15 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Wed, 20 Feb 2013 14:24:15 -0700 Subject: Lambdas with implicit type parameters In-Reply-To: <51253C96.4030109@oracle.com> References: <452ED23A-4228-4A2C-A1AA-0C323CE3485E@oracle.com> <51251BDA.8050305@oracle.com> <51253C96.4030109@oracle.com> Message-ID: <2E447BAC-0344-4579-AA3F-27BC62FBB049@oracle.com> On Feb 20, 2013, at 2:13 PM, Robert Field wrote: > Dan, > You are right to keep the feature budget in mind. So, the question we always asked ourselves when we were doing FX is, and so the question I'm asking you: if we left things as they are, would we be constrained against doing things the way we (may) want in a future release? That is, are we painting ourselves in a corner by leaving it? If not, keeping it simple is a win. Good question. In this case, no, there is no pressure to get this "right" now. We can always take the small step of inferring type parameters later*, or the big step of adding syntax for type parameters -- given that we wouldn't want to change the current lambda syntax in any case. (*Statements like this ignore the fact that speculative checking of lambdas relies, in certain corner cases, on errors that occur in the body. Strictly speaking, from 8 onward, a typing-related language change that eliminates an error from a program will usually be source-incompatible. But I think we've decided the corner-case source incompatibilities there will always be something we're willing to tolerate.) ?Dan From brian.goetz at oracle.com Wed Feb 20 14:29:00 2013 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 20 Feb 2013 17:29:00 -0500 Subject: Lambdas with implicit type parameters In-Reply-To: References: <452ED23A-4228-4A2C-A1AA-0C323CE3485E@oracle.com> <51251BDA.8050305@oracle.com> Message-ID: <51254E2C.7070904@oracle.com> > Beyond that, I think the main question is how we feel about the > instability it creates in the language design -- the most stable > point would be either to prohibit generic descriptors altogether, or > provide syntax for generic lambdas. But those alternatives are > unattractive. Our compromise point was to say method references can > be generic, but lambdas cannot -- a little more awkward, but still a > pretty clear line. Making this change would mean lambdas can be > generic *as long as you don't need to talk about the type > parameters*. That's a lot harder to explain, and increases the > likelihood that somebody's going to be really annoyed when they need > to tweak their program and find that the syntax arbitrarily prohibits > what they want to say. I agreed that the current tradeoff is a simpler middle ground between the less desirable "prohibited" and "just go all the way" than the proposed enhancement. I think the incremental complexity is not justified by the incremental expressiveness. I think we've found a good compromise here and should stick to it. From srikanth_sankaran at in.ibm.com Fri Feb 22 02:18:37 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Fri, 22 Feb 2013 05:18:37 -0500 Subject: Assignment context defined ? In-Reply-To: <51254E2C.7070904@oracle.com> References: <452ED23A-4228-4A2C-A1AA-0C323CE3485E@oracle.com> <51251BDA.8050305@oracle.com> <51254E2C.7070904@oracle.com> Message-ID: It came up during local discussion that the term assignment context appears not be defined precisely: The introduction of section 5 has an informal discussion where item 2 bullet 1 starts: "Assignment contexts (including return statements, etc.) are supported" which implies that the term "assignment context" is used loosely, to include many more syntactic constructs. Shouldn't there be a clear enumeration ? (Assignment, return statements, local declarations with initialization, field declarations with initializations, array creation expressions with initializations ...) Thanks! Srikanth -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130222/f8d61230/attachment.html From daniel.smith at oracle.com Fri Feb 22 10:25:47 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Fri, 22 Feb 2013 11:25:47 -0700 Subject: Assignment context defined ? In-Reply-To: References: <452ED23A-4228-4A2C-A1AA-0C323CE3485E@oracle.com> <51251BDA.8050305@oracle.com> <51254E2C.7070904@oracle.com> Message-ID: <87FB151A-4C01-47FB-9A22-B92335979451@oracle.com> It could be convenient to have a forward-reference to all the places assignment contexts are used. I'll keep that in mind... For normative rules, where you should be looking is the specification for the corresponding construct -- i.e., 15.26, 14.17, 10.6, 8.3.2. Here, the text generally talks about being "assignable", where it should probably be more explicit about defining the context. I'll make a note to fix that. ?Dan On Feb 22, 2013, at 3:18 AM, Srikanth S Adayapalam wrote: > It came up during local discussion that the term assignment context appears not > be defined precisely: The introduction of section 5 has an informal discussion > where item 2 bullet 1 starts: > > "Assignment contexts (including return statements, etc.) are supported" > > which implies that the term "assignment context" is used loosely, to include > many more syntactic constructs. > > Shouldn't there be a clear enumeration ? (Assignment, return statements, > local declarations with initialization, field declarations with initializations, > array creation expressions with initializations ...) > > Thanks! > Srikanth > > From srikanth_sankaran at in.ibm.com Sun Feb 24 10:24:05 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Sun, 24 Feb 2013 23:54:05 +0530 Subject: Broken link and missing section ? In-Reply-To: <2E447BAC-0344-4579-AA3F-27BC62FBB049@oracle.com> References: <452ED23A-4228-4A2C-A1AA-0C323CE3485E@oracle.com> <51251BDA.8050305@oracle.com> <51253C96.4030109@oracle.com> <2E447BAC-0344-4579-AA3F-27BC62FBB049@oracle.com> Message-ID: Part D: 5. Conversions and contexts: "Similarly, the rules determining when a target type allows an implicit conversion vary depending on the kind of context, the type of the expression, and, in one special case, the value of a constant expression ( 15.30). " The section numbered 15.30 does not appear in JLS7, nor does it seem to occur in 0.6.1 as a search for 15.30 in the one page html form shows only the reference, not the section itself. Can I get the contents of this section if it is available ? Thanks in advance, Srikanth. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130224/d3e1fdf6/attachment.html From sam at sampullara.com Sun Feb 24 10:36:26 2013 From: sam at sampullara.com (Sam Pullara) Date: Sun, 24 Feb 2013 10:36:26 -0800 Subject: Broken link and missing section ? In-Reply-To: References: <452ED23A-4228-4A2C-A1AA-0C323CE3485E@oracle.com> <51251BDA.8050305@oracle.com> <51253C96.4030109@oracle.com> <2E447BAC-0344-4579-AA3F-27BC62FBB049@oracle.com> Message-ID: It looks like it meant to reference 15.28 as it does later in the text: http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.28 Sam On Sun, Feb 24, 2013 at 10:24 AM, Srikanth S Adayapalam wrote: > Part D: 5. Conversions and contexts: > > "Similarly, the rules determining when a target type allows an implicit > conversion vary depending on the kind of context, the type of the > expression, and, in one special case, the value of a constant expression > (15.30). " > > The section numbered 15.30 does not appear in JLS7, nor does it seem to > occur in 0.6.1 as a search for 15.30 in the one page > html form shows only the reference, not the section itself. > > Can I get the contents of this section if it is available ? > > Thanks in advance, > Srikanth. From daniel.smith at oracle.com Mon Feb 25 11:48:48 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Mon, 25 Feb 2013 12:48:48 -0700 Subject: Broken link and missing section ? In-Reply-To: References: <452ED23A-4228-4A2C-A1AA-0C323CE3485E@oracle.com> <51251BDA.8050305@oracle.com> <51253C96.4030109@oracle.com> <2E447BAC-0344-4579-AA3F-27BC62FBB049@oracle.com> Message-ID: <6A6F23A3-1BE5-41EC-B378-B688047E57EC@oracle.com> Pretty much, yes. I needed to make room for extra sections (for lambdas, method references), and was initially planning to move JLS 7 15.28 to JLS 8 15.30. Now the plan is to use 15.29. I added a note explaining the 15.28->15.29 renumbering and fixed the broken link. Thanks, Srikanth. ?Dan On Feb 24, 2013, at 11:36 AM, Sam Pullara wrote: > It looks like it meant to reference 15.28 as it does later in the text: > > http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.28 > > Sam > > On Sun, Feb 24, 2013 at 10:24 AM, Srikanth S Adayapalam > wrote: >> Part D: 5. Conversions and contexts: >> >> "Similarly, the rules determining when a target type allows an implicit >> conversion vary depending on the kind of context, the type of the >> expression, and, in one special case, the value of a constant expression >> (15.30). " >> >> The section numbered 15.30 does not appear in JLS7, nor does it seem to >> occur in 0.6.1 as a search for 15.30 in the one page >> html form shows only the reference, not the section itself. >> >> Can I get the contents of this section if it is available ? >> >> Thanks in advance, >> Srikanth. From srikanth_sankaran at in.ibm.com Wed Feb 27 09:41:42 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Wed, 27 Feb 2013 23:11:42 +0530 Subject: What is the motivation behind the descriptor visibility rules ? In-Reply-To: References: <452ED23A-4228-4A2C-A1AA-0C323CE3485E@oracle.com> <51251BDA.8050305@oracle.com> <51253C96.4030109@oracle.com> <2E447BAC-0344-4579-AA3F-27BC62FBB049@oracle.com> Message-ID: Hello ! 15.27.3 and 15.28.1 state: It is a compile-time error if any class or interface mentioned by either T' or the descriptor of T' is not accessible from the class in which the lambda expression appears. I would like to understand the motivation behind these rules. These are more restrictive than a normal method overriding (lambda case) scenario: (under covariance return could be a visible subtype of an inaccessible declared return type in super method, thrown exceptions don't have be visible as long as the subtype implementation does not want to throw them) This rule is also more restrictive than a method invocation scenario (method/constructor reference case) where even the parameter types need not be visible. I don't have a real case where this is hurting, but with jigsaw knocking at the doors, I wonder if contours could emerge in different ways and there could be strange bed fellows. Srikanth. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130227/1919b41a/attachment.html From srikanth_sankaran at in.ibm.com Wed Feb 27 09:41:41 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Wed, 27 Feb 2013 23:11:41 +0530 Subject: Java 7 -> Java8 code breakage scenarios In-Reply-To: References: <452ED23A-4228-4A2C-A1AA-0C323CE3485E@oracle.com> <51251BDA.8050305@oracle.com> <51253C96.4030109@oracle.com> <2E447BAC-0344-4579-AA3F-27BC62FBB049@oracle.com> Message-ID: Is there a list of scenarios documented somewhere that enumerates the situations under which a valid Java 7 program will either (a) cease to be a valid Java 8 program (b) or will exhibit a different behavior ? Looks like default methods clash can cause (a) and the (unlikely) usage of diamond inference usage in method arguments can cause (b). I would be curious to see what other cases exist. TIA, Srikanth. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/lambda-spec-experts/attachments/20130227/81562400/attachment.html From daniel.smith at oracle.com Wed Feb 27 10:41:02 2013 From: daniel.smith at oracle.com (Dan Smith) Date: Wed, 27 Feb 2013 11:41:02 -0700 Subject: What is the motivation behind the descriptor visibility rules ? In-Reply-To: References: <452ED23A-4228-4A2C-A1AA-0C323CE3485E@oracle.com> <51251BDA.8050305@oracle.com> <51253C96.4030109@oracle.com> <2E447BAC-0344-4579-AA3F-27BC62FBB049@oracle.com> Message-ID: <6646D354-7253-4FC1-AA7F-E34BD0CB5140@oracle.com> On Feb 27, 2013, at 10:41 AM, Srikanth S Adayapalam wrote: > Hello ! > > 15.27.3 and 15.28.1 state: > > It is a compile-time error if any class or interface mentioned by either T' > or the descriptor of T' is not accessible from the class in which the lambda > expression appears. > > I would like to understand the motivation behind these rules. These > are more restrictive than a normal method overriding (lambda case) scenario: > (under covariance return could be a visible subtype of an inaccessible declared > return type in super method, thrown exceptions don't have be visible as long > as the subtype implementation does not want to throw them) > > This rule is also more restrictive than a method invocation scenario (method/constructor > reference case) where even the parameter types need not be visible. > > I don't have a real case where this is hurting, but with jigsaw knocking at the doors, > I wonder if contours could emerge in different ways and there could be strange bed > fellows. Lambas and method references _both_ implicitly override the descriptor, and always match it exactly. It's morally equivalent to: class FuncImpl implements Func { public Return method(Param1 x, Param2 y) throws Throws { lambda body or referenced method invocation } } new FuncImpl(); If this were in the source, all the types mentioned above would need to be accessible. Now, it's possible that some implementations won't actually need to mention all of those types, but we don't want to require them to have to find clever workarounds (like introducing a covariant override). ?Dan From forax at univ-mlv.fr Wed Feb 27 12:02:45 2013 From: forax at univ-mlv.fr (Remi Forax) Date: Wed, 27 Feb 2013 21:02:45 +0100 Subject: What is the motivation behind the descriptor visibility rules ? In-Reply-To: References: <452ED23A-4228-4A2C-A1AA-0C323CE3485E@oracle.com> <51251BDA.8050305@oracle.com> <51253C96.4030109@oracle.com> <2E447BAC-0344-4579-AA3F-27BC62FBB049@oracle.com> Message-ID: <512E6665.4050403@univ-mlv.fr> On 02/27/2013 06:41 PM, Srikanth S Adayapalam wrote: > Hello ! > > 15.27.3 and 15.28.1 state: > > It is a compile-time error if any class or interface mentioned by > either /T'/ > or the descriptor of /T'/ is not accessible from the class in which > the lambda > expression appears. > > I would like to understand the motivation behind these rules. > These > are more restrictive than a normal method overriding (lambda case) > scenario: > (under covariance return could be a visible subtype of an inaccessible > declared > return type in super method, thrown exceptions don't have be visible > as long > as the subtype implementation does not want to throw them) > > This rule is also more restrictive than a method invocation scenario > (method/constructor > reference case) where even the parameter types need not be visible. > > I don't have a real case where this is hurting, but with jigsaw > knocking at the doors, > I wonder if contours could emerge in different ways and there could be > strange bed > fellows. > > Srikanth. I believe the problem is that for classical covariant override the compiler can generate a bridge, I always find that dubious but you can. Lambda proxies are generated at runtime, and at runtime you can easily trigger a runtime error because a class is not visible when by example you use reflection in order to generate the bytecode of the proxy. BTW, this code doesn't work with Eclipse but compiles with javac: package fizz; class X { } package fizz; public interface A { public X m(); } package fizz; public class Y extends X { } package buzz; import fizz.A; import fizz.Y; public class Main { static class B implements A { public Y m() { System.out.println("B::m"); return null; } } public static void main(String[] args) { A a = new B(); a.m(); } } cheers, R?mi