From brian.goetz at oracle.com Wed Mar 9 19:06:22 2016 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 9 Mar 2016 14:06:22 -0500 Subject: Local Variable Type Inference Message-ID: <56E0742E.90506@oracle.com> PLEASE DO NOT RESPOND DIRECTLY TO THIS MAIL -- SEE BELOW FOR HOW TO PROVIDE FEEDBACK. The Java Language Team has been working on a proposal for Local Variable Type Inference (sometimes called "var") for Java. There is a JEP draft here: http://openjdk.java.net/jeps/286 A draft specification is attached to the following issue: https://bugs.openjdk.java.net/browse/JDK-8151553 Please review the proposal, and consider providing feedback through the survey form below. PROVIDING FEEDBACK ------------------ Because we expect this topic to generate a large volume of (primarily opinion-based) feedback, rather than following the usual "replies to replies" approach on the mailing lists, we are following a more formal mechanism for gathering input. We believe this will encourage people to respond directly to the proposal, and will give everyone a chance to be heard equally. Accordingly, rather than posting your feedback here, please provide feedback through the following survey form: https://www.surveymonkey.com/r/KGPTHCG It has general survey questions, as well as an opportunity to provide long-form questions and comments. The survey will be open for one week, at which point we will make all the responses public, and then there will be another round in which you can respond to any feedback raised through this survey. There is also a section for "Questions for the Java Language Team"; we will attempt to address these publicly after the survey closes. From maurizio.cimadamore at oracle.com Thu Mar 10 14:48:25 2016 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 10 Mar 2016 14:48:25 +0000 Subject: Local Variable Type Inference - prototype Message-ID: <56E18939.2090006@oracle.com> Hi, I've pushed the first iteration of the local variable type inference prototype in the sandbox repository[1]. For those willing and brave enough to experiment, the branch name is "JEP-286-branch". We are also working to get some ready-made binary snapshots out of the door and hope to have an update on that soon. This first iteration supports the 'var-only' syntax style: var s = "Hello!"; That is, the type of 's' is inferred from the initializer, and no special assumption is made about mutability. Please share your experience with the prototype. For comments on this feature please refer to the survey[2] that Brian posted few days ago. Maurizio [1] - http://cr.openjdk.java.net/~chegar/docs/sandbox.html [2] - http://mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000037.html From brian.goetz at oracle.com Thu Mar 10 15:07:54 2016 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 10 Mar 2016 10:07:54 -0500 Subject: Reader Mail Bag for Thursday In-Reply-To: <56E0742E.90506@oracle.com> References: <56E0742E.90506@oracle.com> Message-ID: <56E18DCA.3010507@oracle.com> PLEASE DO NOT RESPOND DIRECTLY TO THIS MAIL -- SEE BELOW FOR HOW TO PROVIDE FEEDBACK. The first ~1000 survey responses are in. We'll publish the full results when the survey closes, but I'll take this opportunity to answer some of the questions from the "Questions for the Java Language Team" section. (I've paraphrased / generalized a lot of the questions.) I'll answer more as they come in. *** If you want to respond, please do it through the survey! If you've already taken the survey, don't worry, there'll be a follow-up survey where you can provide additional feedback. The survey link is: https://www.surveymonkey.com/r/KGPTHCG *** We'll also be posting a prototype soon, which will answer a lot of the "what would happen in this case..." questions. 1. What about multiple assignments? If we have var x = new Foo(); ... x = new Bar(); we compute the type of x based solely on the type of the initializer. So the above code is equivalent to: Foo x = new Foo(); ... x = new Bar(); If Bar is a subtype of Foo, then this code is fine, otherwise it is a type error -- just like before. Local variable type inference is purely local; we compute the type of x from its initializer, and thereafter, it is as if it were manifestly typed. 2. If the type of the initializer is ArrayList, can you infer List instead, as we probably would have written by hand? This would be confusing type inference with mind reading. 3. Can I say "final var", even if we have "val"? Almost certainly yes. 4. Can I say "final val"? Silly, but probably yes as well. 5. Will this interfere with existing uses of "var" and "val" as identifiers, package names, or method names? No. 6. Will this interfere with existing uses of "var" and "val" as a class name? Yes. We consider this to be an acceptable source-compatibility violation, because these are likely to be quite rare as class names (the naming conventions for Java code, which are almost universally accepted, say that class names should start with an uppercase letter.) 7. Why is it not possible to use var when the initializer is an array initializer, as in: var ints = { 1, 2, 3 } The rule is: we derive the type of the variable by treating the initializer as a standalone expression, and deriving its type. However, array initializers, like lambdas and method refs, are *poly expressions* -- they need a target type in order to compute their type. So they are rejected. Could we *make* this work? We probably could. But it would add a lot of complexity to the feature, for the benefit of a mostly corner case. We'd like for this to be a simple feature. 8. How do we debug programs with inferred types? We expect tooling will evolve to help here. In languages that have this feature, IDEs will show you the type as you hover over the variable name (most Java IDEs already do this). We are also considering providing a javac option to produce a source file that shows all inferred types (lambda formals, generic method type parameters, diamond constructor args, inferred locals.) 9. Won't bad developers misuse this feature to write terrible code? Yes. 10. What do you mean by "action at a distance"? Type inference is constraint solving. The main choices a language designer gets to make in designing a type inference algorithm are where to get the constraints, and when (over what scope) to solve. We could, if we chose, let all assignments to a variable contribute constraints, and solve globally; while this produces nice sharp types (though sometimes surprising types) when it works, it produces extremely confusing error messages when it doesn't, and means that a change anywhere in a program could affect things far away in the program. For example, if we followed the approach of using all assignments to constrain the type of an implicitly typed variable, if we had: var x = ""; ... x = anInteger; the compiler might compute the type of x by taking the least upper bound of String and Integer. (You might think this would be Object, but really is something more like Object&Serializable&Comparable, if not more complicated.) Action-at-a-distance refers to the fact that a use of x several hundred lines away could change the type of x, and cause confusing errors nowhere near where the change occurred. 11. What is the reasoning behind not inferring types for variables that use the C-style "int x[]" convention? In part, this would be asking for half-inference; "I want x to be an array with a given rank, but infer the component type please." Valid, but that's basically a different feature. Besides, this convention is, at this point, mostly vestigial. 12. You ran the prototype over the JDK as a corpus, and gathered statistics. Can you run it over a larger source base? The JDK is pretty large, but yes, we already did this over a corpus of ~100 popular OSS projects including Eclipse, NetBeans, and many Apache projects. We got essentially the same numbers. 13. Will this work for the index variable of a for loop or foreach loop? Yes. 14. What happens if we ask for inference on both sides, as in: var x = new ArrayList<>() In most cases, you'll get an informative compiler error telling you that you're asking for your mind to be read. In some cases, we'll fall back to inferring Object, as we currently do with: Object o = new ArrayList<>() // always inferred ArrayList here 15. Isn't this opposed to static typing? No. Variables are still statically typed, as they have always been (and the inference algorithm used here ensures that we always produce a denotable type, meaning that there is an equivalent manifestly typed program.) What's happening here is that you have the opportunity to let the compiler figure out the type. 16. Why exclude field declarations? Field and method declarations are part of a classes interface contract, and may be referenced from other classes (meaning their type descriptors will be copied into other classfiles, and dynamically linked by exact descriptor match at runtime.) This means that small changes to the program implementation could silently turn into binary compatibility issues, if the type changes subtle and the client is not recompiled. The operating theory here is that local variables are *implementation details* -- they are part of the method implementation, not part of the classes interface contract. They cannot be referenced from other compilation units or other methods. Therefore, a lower degree of ceremony is needed than when specifying interface contracts across compilation units. 17. When do we get this? When it's ready. 18. Can I have feature X too? Let's do one thing at a time, OK? From forax at univ-mlv.fr Thu Mar 10 16:35:36 2016 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 10 Mar 2016 17:35:36 +0100 (CET) Subject: Local Variable Type Inference - prototype In-Reply-To: <56E18939.2090006@oracle.com> References: <56E18939.2090006@oracle.com> Message-ID: <866620739.3600841.1457627736888.JavaMail.zimbra@u-pem.fr> For those that find that the message of Maurizio was mysterious :) here is a more detailed instructions 1. you need to download a binary version of jdk9 from here https://jdk9.java.net/download/ 2. you need a recent version of ant (that includes support of jdk9 perhaps ?, ant 1.9.5 works for me) https://www.apache.org/dist/ant/binaries/ 3. clone the repository hg clone http://hg.openjdk.java.net/jdk9/sandbox/langtools 4. switch to the branch "JEP-286-branch" hg update JEP-286-branch 5. use ant to compile javac cd langtools/make export ANT_HOME=my_path_to_ant export JAVA_HOME=my_path_to_jkd9 ant -Dboot.java.home=my_path_to_jdk9 6. ant has generated a jar in langtools/dist name jdk.compiler.jar, to run javac path_to_jdk9/bin/java -Xbootclasspath/p:langtools/dist/lib/jdk.compiler.jar com.sun.tools.javac.Main VarTest.java 6.bis. you can also ask javac which local variables can be declared using var with no compatibility issue path_to_jdk9/bin/java -Xbootclasspath/p:langtools/dist/lib/jdk.compiler.jar com.sun.tools.javac.Main -XDfind=local VarTest.java happy testing, R?mi ----- Mail original ----- > De: "Maurizio Cimadamore" > ?: platform-jep-discuss at openjdk.java.net > Envoy?: Jeudi 10 Mars 2016 15:48:25 > Objet: Local Variable Type Inference - prototype > > Hi, > I've pushed the first iteration of the local variable type inference > prototype in the sandbox repository[1]. For those willing and brave > enough to experiment, the branch name is "JEP-286-branch". We are also > working to get some ready-made binary snapshots out of the door and hope > to have an update on that soon. > > This first iteration supports the 'var-only' syntax style: > > var s = "Hello!"; > > That is, the type of 's' is inferred from the initializer, and no > special assumption is made about mutability. > > Please share your experience with the prototype. For comments on this > feature please refer to the survey[2] that Brian posted few days ago. > > Maurizio > > [1] - http://cr.openjdk.java.net/~chegar/docs/sandbox.html > [2] - > http://mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000037.html > From stuart.marks at oracle.com Thu Mar 10 21:56:43 2016 From: stuart.marks at oracle.com (Stuart Marks) Date: Thu, 10 Mar 2016 13:56:43 -0800 Subject: Local Variable Type Inference - prototype In-Reply-To: <56E18939.2090006@oracle.com> References: <56E18939.2090006@oracle.com> Message-ID: <56E1ED9B.9070708@oracle.com> Hi Maurizio, Nice work! I gave this a spin using the new JEP 269 Convenience Collection Factories. [3] The following examples transliterated from the old "collection literals" proposal [4] worked quite nicely: // List var piDigits = List.of(3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 9); // Set var primes = Set.of(2, 7, 31, 127, 8191, 131071, 524287); // Map static var platonicSolids = Map.of( 4, "tetrahedron", 6, "cube", 8, "octahedron", 12, "dodecahedron", 20, "icosahedron"); // List> var pascalsTriangle = List.of(List.of(1), List.of(1, 1), List.of(1, 2, 1), List.of(1, 3, 3, 1), List.of(1, 4, 6, 4, 1)); The following example, however, failed: // List var numbers = List.of(2, 2.718281828); error: cannot infer type for local variable numbers var numbers = List.of(2, 2.718281828); (inferred type is non denotable) The old Coin proposal suggested that this was an edge case that would require a type witness. Rephrasing that example in terms of the collections factories, it would be List numbers = List.of(2, 2.718281828); However, type inference had improved enough already by JDK 8 that this works: List numbers = List.of(2, 2.718281828); But trying to push this to var numbers = List.of(2, 2.718281828); doesn't work. This is a rather special case. The "obvious" choice is List, but as Brian mentioned in his "Reader Mailbag" message [5, Q#10], that the inferred type is actually likely to be much more complicated, hence the "non denotable" message. In this case requiring an explicit type is probably warranted anyway. So... ship it! :-) s'marks [3] http://openjdk.java.net/jeps/269 [4] http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001193.html [5] http://mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000039.html On 3/10/16 6:48 AM, Maurizio Cimadamore wrote: > Hi, > I've pushed the first iteration of the local variable type inference prototype > in the sandbox repository[1]. For those willing and brave enough to experiment, > the branch name is "JEP-286-branch". We are also working to get some ready-made > binary snapshots out of the door and hope to have an update on that soon. > > This first iteration supports the 'var-only' syntax style: > > var s = "Hello!"; > > That is, the type of 's' is inferred from the initializer, and no special > assumption is made about mutability. > > Please share your experience with the prototype. For comments on this feature > please refer to the survey[2] that Brian posted few days ago. > > Maurizio > > [1] - http://cr.openjdk.java.net/~chegar/docs/sandbox.html > [2] - > http://mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000037.html From forax at univ-mlv.fr Thu Mar 10 22:13:19 2016 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 10 Mar 2016 23:13:19 +0100 (CET) Subject: Local Variable Type Inference - prototype In-Reply-To: <56E1ED9B.9070708@oracle.com> References: <56E18939.2090006@oracle.com> <56E1ED9B.9070708@oracle.com> Message-ID: <1134987460.3730602.1457647999487.JavaMail.zimbra@u-pem.fr> Hi Stuart, ----- Mail original ----- > De: "Stuart Marks" > ?: "Maurizio Cimadamore" , platform-jep-discuss at openjdk.java.net > Envoy?: Jeudi 10 Mars 2016 22:56:43 > Objet: Re: Local Variable Type Inference - prototype > > Hi Maurizio, > > Nice work! I gave this a spin using the new JEP 269 Convenience Collection > Factories. [3] The following examples transliterated from the old "collection > literals" proposal [4] worked quite nicely: > > // List > var piDigits = List.of(3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 9); > > // Set > var primes = Set.of(2, 7, 31, 127, 8191, 131071, 524287); > > // Map > static var platonicSolids = Map.of( > 4, "tetrahedron", > 6, "cube", > 8, "octahedron", > 12, "dodecahedron", > 20, "icosahedron"); > > // List> > var pascalsTriangle = > List.of(List.of(1), > List.of(1, 1), > List.of(1, 2, 1), > List.of(1, 3, 3, 1), > List.of(1, 4, 6, 4, 1)); > > The following example, however, failed: > > // List > var numbers = List.of(2, 2.718281828); > > error: cannot infer type for local variable numbers > var numbers = List.of(2, 2.718281828); > (inferred type is non denotable) > > The old Coin proposal suggested that this was an edge case that would require > a > type witness. Rephrasing that example in terms of the collections factories, > it > would be > > List numbers = List.of(2, 2.718281828); > > However, type inference had improved enough already by JDK 8 that this works: > > List numbers = List.of(2, 2.718281828); > > But trying to push this to > > var numbers = List.of(2, 2.718281828); > > doesn't work. This is a rather special case. The "obvious" choice is > List, but as Brian mentioned in his "Reader Mailbag" message [5, > Q#10], > that the inferred type is actually likely to be much more complicated, hence > the > "non denotable" message. In this case requiring an explicit type is probably > warranted anyway. The issue is that the inferred type is something like: Number & Comparable & Serailizable> & Serializable because Integer implements Comparable and Double implements Comparable so types like Number or Comparable are valid substitute of T with no obvious most specific types, here. An interesting question for the future is to see if inference can be improved by making union types denotable like in Ceylon [1] (or in TypeScript, or the next version of Scala), something like: List numbers = ... > > So... ship it! :-) > > s'marks R?mi [1] http://ceylon-lang.org/documentation/1.0/spec/html/typesystem.html#uniontypes > > [3] http://openjdk.java.net/jeps/269 > > [4] http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001193.html > > [5] > http://mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000039.html > > > On 3/10/16 6:48 AM, Maurizio Cimadamore wrote: > > Hi, > > I've pushed the first iteration of the local variable type inference > > prototype > > in the sandbox repository[1]. For those willing and brave enough to > > experiment, > > the branch name is "JEP-286-branch". We are also working to get some > > ready-made > > binary snapshots out of the door and hope to have an update on that soon. > > > > This first iteration supports the 'var-only' syntax style: > > > > var s = "Hello!"; > > > > That is, the type of 's' is inferred from the initializer, and no special > > assumption is made about mutability. > > > > Please share your experience with the prototype. For comments on this > > feature > > please refer to the survey[2] that Brian posted few days ago. > > > > Maurizio > > > > [1] - http://cr.openjdk.java.net/~chegar/docs/sandbox.html > > [2] - > > http://mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000037.html > From forax at univ-mlv.fr Thu Mar 10 22:21:49 2016 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 10 Mar 2016 23:21:49 +0100 (CET) Subject: Local Variable Type Inference - prototype In-Reply-To: <56E18939.2090006@oracle.com> References: <56E18939.2090006@oracle.com> Message-ID: <1664237129.3734349.1457648509636.JavaMail.zimbra@u-pem.fr> At least, jshell need some tweaks :) $ /usr/jdk/jdk-9/bin/java -Xbootclasspath/p:langtools/dist/lib/jdk.compiler.jar:langtools/dist/lib/jdk.jshell.jar:langtools/dist/lib/jdk.internal.le.jar:langtools/dist/lib/jdk.jdi.jar jdk.internal.jshell.tool.JShellTool | Welcome to JShell -- Version 9-internal | Type /help for help -> void m() { >> var a = 3; >> } | Added method m() -> m() -> var a = 3; Exception in thread "main" java.lang.StringIndexOutOfBoundsException: begin -1, end -1, length 10 at java.lang.String.checkBoundsBeginEnd(String.java:3122) at java.lang.String.substring(String.java:1910) at jdk.jshell.Wrap$Range.part(Wrap.java:168) at jdk.jshell.Wrap$RangeWrap.(Wrap.java:350) at jdk.jshell.Wrap.varWrap(Wrap.java:97) at jdk.jshell.Eval.processVariables(Eval.java:227) at jdk.jshell.Eval.eval(Eval.java:116) at jdk.jshell.JShell.eval(JShell.java:355) at jdk.internal.jshell.tool.JShellTool.processCompleteSource(JShellTool.java:1923) at jdk.internal.jshell.tool.JShellTool.processSource(JShellTool.java:1911) at jdk.internal.jshell.tool.JShellTool.processSourceCatchingReset(JShellTool.java:652) at jdk.internal.jshell.tool.JShellTool.run(JShellTool.java:632) at jdk.internal.jshell.tool.JShellTool.start(JShellTool.java:427) at jdk.internal.jshell.tool.JShellTool.start(JShellTool.java:400) at jdk.internal.jshell.tool.JShellTool.main(JShellTool.java:390) R?mi ----- Mail original ----- > De: "Maurizio Cimadamore" > ?: platform-jep-discuss at openjdk.java.net > Envoy?: Jeudi 10 Mars 2016 15:48:25 > Objet: Local Variable Type Inference - prototype > > Hi, > I've pushed the first iteration of the local variable type inference > prototype in the sandbox repository[1]. For those willing and brave > enough to experiment, the branch name is "JEP-286-branch". We are also > working to get some ready-made binary snapshots out of the door and hope > to have an update on that soon. > > This first iteration supports the 'var-only' syntax style: > > var s = "Hello!"; > > That is, the type of 's' is inferred from the initializer, and no > special assumption is made about mutability. > > Please share your experience with the prototype. For comments on this > feature please refer to the survey[2] that Brian posted few days ago. > > Maurizio > > [1] - http://cr.openjdk.java.net/~chegar/docs/sandbox.html > [2] - > http://mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000037.html > From robert.field at oracle.com Thu Mar 10 22:55:39 2016 From: robert.field at oracle.com (Robert Field) Date: Thu, 10 Mar 2016 14:55:39 -0800 Subject: Local Variable Type Inference - prototype In-Reply-To: <1664237129.3734349.1457648509636.JavaMail.zimbra@u-pem.fr> References: <56E18939.2090006@oracle.com> <1664237129.3734349.1457648509636.JavaMail.zimbra@u-pem.fr> Message-ID: <56E1FB6B.5090504@oracle.com> On 03/10/16 14:21, Remi Forax wrote: > At least, jshell need some tweaks :) Yes, it will. Thanks Remi! It will need the analysis pass of the compiler run so that the type can be determined. Variables are implemented as fields. Is this something I should work on now? -Robert > > $ /usr/jdk/jdk-9/bin/java -Xbootclasspath/p:langtools/dist/lib/jdk.compiler.jar:langtools/dist/lib/jdk.jshell.jar:langtools/dist/lib/jdk.internal.le.jar:langtools/dist/lib/jdk.jdi.jar jdk.internal.jshell.tool.JShellTool > | Welcome to JShell -- Version 9-internal > | Type /help for help > > -> void m() { >>> var a = 3; >>> } > | Added method m() > > -> m() > > -> var a = 3; > Exception in thread "main" java.lang.StringIndexOutOfBoundsException: begin -1, end -1, length 10 > at java.lang.String.checkBoundsBeginEnd(String.java:3122) > at java.lang.String.substring(String.java:1910) > at jdk.jshell.Wrap$Range.part(Wrap.java:168) > at jdk.jshell.Wrap$RangeWrap.(Wrap.java:350) > at jdk.jshell.Wrap.varWrap(Wrap.java:97) > at jdk.jshell.Eval.processVariables(Eval.java:227) > at jdk.jshell.Eval.eval(Eval.java:116) > at jdk.jshell.JShell.eval(JShell.java:355) > at jdk.internal.jshell.tool.JShellTool.processCompleteSource(JShellTool.java:1923) > at jdk.internal.jshell.tool.JShellTool.processSource(JShellTool.java:1911) > at jdk.internal.jshell.tool.JShellTool.processSourceCatchingReset(JShellTool.java:652) > at jdk.internal.jshell.tool.JShellTool.run(JShellTool.java:632) > at jdk.internal.jshell.tool.JShellTool.start(JShellTool.java:427) > at jdk.internal.jshell.tool.JShellTool.start(JShellTool.java:400) > at jdk.internal.jshell.tool.JShellTool.main(JShellTool.java:390) > > R?mi > > ----- Mail original ----- >> De: "Maurizio Cimadamore" >> ?: platform-jep-discuss at openjdk.java.net >> Envoy?: Jeudi 10 Mars 2016 15:48:25 >> Objet: Local Variable Type Inference - prototype >> >> Hi, >> I've pushed the first iteration of the local variable type inference >> prototype in the sandbox repository[1]. For those willing and brave >> enough to experiment, the branch name is "JEP-286-branch". We are also >> working to get some ready-made binary snapshots out of the door and hope >> to have an update on that soon. >> >> This first iteration supports the 'var-only' syntax style: >> >> var s = "Hello!"; >> >> That is, the type of 's' is inferred from the initializer, and no >> special assumption is made about mutability. >> >> Please share your experience with the prototype. For comments on this >> feature please refer to the survey[2] that Brian posted few days ago. >> >> Maurizio >> >> [1] - http://cr.openjdk.java.net/~chegar/docs/sandbox.html >> [2] - >> http://mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000037.html >> From maurizio.cimadamore at oracle.com Thu Mar 10 23:39:16 2016 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 10 Mar 2016 23:39:16 +0000 Subject: Local Variable Type Inference - prototype In-Reply-To: <1134987460.3730602.1457647999487.JavaMail.zimbra@u-pem.fr> References: <56E18939.2090006@oracle.com> <56E1ED9B.9070708@oracle.com> <1134987460.3730602.1457647999487.JavaMail.zimbra@u-pem.fr> Message-ID: <56E205A4.4050100@oracle.com> On 10/03/16 22:13, Remi Forax wrote: > The issue is that the inferred type is something like: > Number & Comparable & Serailizable> & Serializable > because > Integer implements Comparable and > Double implements Comparable > > so types like Number or Comparable are valid substitute of T with no obvious most specific types, here Right - and intersection types are the only kind (together with union types - which are kind of treated as intersections by Java language) which are not supported by LVTI. The problem with intersection types is that in the general case, when you have a type like C & I1 & I2 ... & In, how do you pick the 'best' type? Maurizio From maurizio.cimadamore at oracle.com Thu Mar 10 23:41:05 2016 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 10 Mar 2016 23:41:05 +0000 Subject: Local Variable Type Inference - prototype In-Reply-To: <56E1FB6B.5090504@oracle.com> References: <56E18939.2090006@oracle.com> <1664237129.3734349.1457648509636.JavaMail.zimbra@u-pem.fr> <56E1FB6B.5090504@oracle.com> Message-ID: <56E20611.5080908@oracle.com> On 10/03/16 22:55, Robert Field wrote: > > On 03/10/16 14:21, Remi Forax wrote: >> At least, jshell need some tweaks :) > > Yes, it will. Thanks Remi! > > It will need the analysis pass of the compiler run so that the type > can be determined. Variables are implemented as fields. > > Is this something I should work on now? One question for you Robert: currently javac does not parse 'var' as a special Token - as doing that requires even more jshell changes; I'm happy to leave the code as is, but if, when hacking on the jshell side, you discover that a VAR token would be useful please let me know. Maurizio > > -Robert > >> >> $ /usr/jdk/jdk-9/bin/java >> -Xbootclasspath/p:langtools/dist/lib/jdk.compiler.jar:langtools/dist/lib/jdk.jshell.jar:langtools/dist/lib/jdk.internal.le.jar:langtools/dist/lib/jdk.jdi.jar >> jdk.internal.jshell.tool.JShellTool >> | Welcome to JShell -- Version 9-internal >> | Type /help for help >> >> -> void m() { >>>> var a = 3; >>>> } >> | Added method m() >> >> -> m() >> >> -> var a = 3; >> Exception in thread "main" java.lang.StringIndexOutOfBoundsException: >> begin -1, end -1, length 10 >> at java.lang.String.checkBoundsBeginEnd(String.java:3122) >> at java.lang.String.substring(String.java:1910) >> at jdk.jshell.Wrap$Range.part(Wrap.java:168) >> at jdk.jshell.Wrap$RangeWrap.(Wrap.java:350) >> at jdk.jshell.Wrap.varWrap(Wrap.java:97) >> at jdk.jshell.Eval.processVariables(Eval.java:227) >> at jdk.jshell.Eval.eval(Eval.java:116) >> at jdk.jshell.JShell.eval(JShell.java:355) >> at >> jdk.internal.jshell.tool.JShellTool.processCompleteSource(JShellTool.java:1923) >> at >> jdk.internal.jshell.tool.JShellTool.processSource(JShellTool.java:1911) >> at >> jdk.internal.jshell.tool.JShellTool.processSourceCatchingReset(JShellTool.java:652) >> at jdk.internal.jshell.tool.JShellTool.run(JShellTool.java:632) >> at jdk.internal.jshell.tool.JShellTool.start(JShellTool.java:427) >> at jdk.internal.jshell.tool.JShellTool.start(JShellTool.java:400) >> at jdk.internal.jshell.tool.JShellTool.main(JShellTool.java:390) >> >> R?mi >> >> ----- Mail original ----- >>> De: "Maurizio Cimadamore" >>> ?: platform-jep-discuss at openjdk.java.net >>> Envoy?: Jeudi 10 Mars 2016 15:48:25 >>> Objet: Local Variable Type Inference - prototype >>> >>> Hi, >>> I've pushed the first iteration of the local variable type inference >>> prototype in the sandbox repository[1]. For those willing and brave >>> enough to experiment, the branch name is "JEP-286-branch". We are also >>> working to get some ready-made binary snapshots out of the door and >>> hope >>> to have an update on that soon. >>> >>> This first iteration supports the 'var-only' syntax style: >>> >>> var s = "Hello!"; >>> >>> That is, the type of 's' is inferred from the initializer, and no >>> special assumption is made about mutability. >>> >>> Please share your experience with the prototype. For comments on this >>> feature please refer to the survey[2] that Brian posted few days ago. >>> >>> Maurizio >>> >>> [1] - http://cr.openjdk.java.net/~chegar/docs/sandbox.html >>> [2] - >>> http://mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000037.html >>> >>> > From maurizio.cimadamore at oracle.com Thu Mar 10 23:42:01 2016 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 10 Mar 2016 23:42:01 +0000 Subject: Local Variable Type Inference - prototype In-Reply-To: <866620739.3600841.1457627736888.JavaMail.zimbra@u-pem.fr> References: <56E18939.2090006@oracle.com> <866620739.3600841.1457627736888.JavaMail.zimbra@u-pem.fr> Message-ID: <56E20649.4080206@oracle.com> Thanks for the detailed instructions. Another way to get there is to do steps 3 and 4 and just build the entire repo - that will give you a perfectly functioning JDK with LVTI enabled. Maurizio On 10/03/16 16:35, Remi Forax wrote: > For those that find that the message of Maurizio was mysterious :) > here is a more detailed instructions > 1. you need to download a binary version of jdk9 from here > https://jdk9.java.net/download/ > > 2. you need a recent version of ant (that includes support of jdk9 perhaps ?, ant 1.9.5 works for me) > https://www.apache.org/dist/ant/binaries/ > > 3. clone the repository > hg clone http://hg.openjdk.java.net/jdk9/sandbox/langtools > > 4. switch to the branch "JEP-286-branch" > hg update JEP-286-branch > > 5. use ant to compile javac > cd langtools/make > export ANT_HOME=my_path_to_ant > export JAVA_HOME=my_path_to_jkd9 > ant -Dboot.java.home=my_path_to_jdk9 > > 6. ant has generated a jar in langtools/dist name jdk.compiler.jar, > to run javac > path_to_jdk9/bin/java -Xbootclasspath/p:langtools/dist/lib/jdk.compiler.jar com.sun.tools.javac.Main VarTest.java > > 6.bis. you can also ask javac which local variables can be declared using var with no compatibility issue > path_to_jdk9/bin/java -Xbootclasspath/p:langtools/dist/lib/jdk.compiler.jar com.sun.tools.javac.Main -XDfind=local VarTest.java > > happy testing, > R?mi > > ----- Mail original ----- >> De: "Maurizio Cimadamore" >> ?: platform-jep-discuss at openjdk.java.net >> Envoy?: Jeudi 10 Mars 2016 15:48:25 >> Objet: Local Variable Type Inference - prototype >> >> Hi, >> I've pushed the first iteration of the local variable type inference >> prototype in the sandbox repository[1]. For those willing and brave >> enough to experiment, the branch name is "JEP-286-branch". We are also >> working to get some ready-made binary snapshots out of the door and hope >> to have an update on that soon. >> >> This first iteration supports the 'var-only' syntax style: >> >> var s = "Hello!"; >> >> That is, the type of 's' is inferred from the initializer, and no >> special assumption is made about mutability. >> >> Please share your experience with the prototype. For comments on this >> feature please refer to the survey[2] that Brian posted few days ago. >> >> Maurizio >> >> [1] - http://cr.openjdk.java.net/~chegar/docs/sandbox.html >> [2] - >> http://mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000037.html >> From forax at univ-mlv.fr Fri Mar 11 07:59:35 2016 From: forax at univ-mlv.fr (Remi Forax) Date: Fri, 11 Mar 2016 08:59:35 +0100 (CET) Subject: Local Variable Type Inference - prototype In-Reply-To: <56E18939.2090006@oracle.com> References: <56E18939.2090006@oracle.com> Message-ID: <190452603.3999991.1457683175554.JavaMail.zimbra@u-pem.fr> Hi Maurizio, hi all, currently, this compiles public class VarTest { var x = 3; static final var FOO = 3; } while i don't care too much about being able to declare final static field with var, being able to declare instance field with var is plainly wrong for me (and out of the scope of this JEP). R?mi ----- Mail original ----- > De: "Maurizio Cimadamore" > ?: platform-jep-discuss at openjdk.java.net > Envoy?: Jeudi 10 Mars 2016 15:48:25 > Objet: Local Variable Type Inference - prototype > > Hi, > I've pushed the first iteration of the local variable type inference > prototype in the sandbox repository[1]. For those willing and brave > enough to experiment, the branch name is "JEP-286-branch". We are also > working to get some ready-made binary snapshots out of the door and hope > to have an update on that soon. > > This first iteration supports the 'var-only' syntax style: > > var s = "Hello!"; > > That is, the type of 's' is inferred from the initializer, and no > special assumption is made about mutability. > > Please share your experience with the prototype. For comments on this > feature please refer to the survey[2] that Brian posted few days ago. > > Maurizio > > [1] - http://cr.openjdk.java.net/~chegar/docs/sandbox.html > [2] - > http://mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000037.html > From robert.field at oracle.com Fri Mar 11 08:01:03 2016 From: robert.field at oracle.com (Robert Field) Date: Fri, 11 Mar 2016 00:01:03 -0800 Subject: Local Variable Type Inference - prototype In-Reply-To: <56E20611.5080908@oracle.com> References: <56E18939.2090006@oracle.com> <1664237129.3734349.1457648509636.JavaMail.zimbra@u-pem.fr> <56E1FB6B.5090504@oracle.com> <56E20611.5080908@oracle.com> Message-ID: <56E27B3F.6060108@oracle.com> Patch to fix this attached. Apply as desired. -Robert On 03/10/16 15:41, Maurizio Cimadamore wrote: > > > On 10/03/16 22:55, Robert Field wrote: >> >> On 03/10/16 14:21, Remi Forax wrote: >>> At least, jshell need some tweaks :) >> >> Yes, it will. Thanks Remi! >> >> It will need the analysis pass of the compiler run so that the type >> can be determined. Variables are implemented as fields. >> >> Is this something I should work on now? > One question for you Robert: currently javac does not parse 'var' as a > special Token - as doing that requires even more jshell changes; I'm > happy to leave the code as is, but if, when hacking on the jshell > side, you discover that a VAR token would be useful please let me know. > > Maurizio >> >> -Robert >> >>> >>> $ /usr/jdk/jdk-9/bin/java >>> -Xbootclasspath/p:langtools/dist/lib/jdk.compiler.jar:langtools/dist/lib/jdk.jshell.jar:langtools/dist/lib/jdk.internal.le.jar:langtools/dist/lib/jdk.jdi.jar >>> jdk.internal.jshell.tool.JShellTool >>> | Welcome to JShell -- Version 9-internal >>> | Type /help for help >>> >>> -> void m() { >>>>> var a = 3; >>>>> } >>> | Added method m() >>> >>> -> m() >>> >>> -> var a = 3; >>> Exception in thread "main" >>> java.lang.StringIndexOutOfBoundsException: begin -1, end -1, length 10 >>> at java.lang.String.checkBoundsBeginEnd(String.java:3122) >>> at java.lang.String.substring(String.java:1910) >>> at jdk.jshell.Wrap$Range.part(Wrap.java:168) >>> at jdk.jshell.Wrap$RangeWrap.(Wrap.java:350) >>> at jdk.jshell.Wrap.varWrap(Wrap.java:97) >>> at jdk.jshell.Eval.processVariables(Eval.java:227) >>> at jdk.jshell.Eval.eval(Eval.java:116) >>> at jdk.jshell.JShell.eval(JShell.java:355) >>> at >>> jdk.internal.jshell.tool.JShellTool.processCompleteSource(JShellTool.java:1923) >>> at >>> jdk.internal.jshell.tool.JShellTool.processSource(JShellTool.java:1911) >>> at >>> jdk.internal.jshell.tool.JShellTool.processSourceCatchingReset(JShellTool.java:652) >>> at jdk.internal.jshell.tool.JShellTool.run(JShellTool.java:632) >>> at jdk.internal.jshell.tool.JShellTool.start(JShellTool.java:427) >>> at jdk.internal.jshell.tool.JShellTool.start(JShellTool.java:400) >>> at jdk.internal.jshell.tool.JShellTool.main(JShellTool.java:390) >>> >>> R?mi >>> >>> ----- Mail original ----- >>>> De: "Maurizio Cimadamore" >>>> ?: platform-jep-discuss at openjdk.java.net >>>> Envoy?: Jeudi 10 Mars 2016 15:48:25 >>>> Objet: Local Variable Type Inference - prototype >>>> >>>> Hi, >>>> I've pushed the first iteration of the local variable type inference >>>> prototype in the sandbox repository[1]. For those willing and brave >>>> enough to experiment, the branch name is "JEP-286-branch". We are also >>>> working to get some ready-made binary snapshots out of the door and >>>> hope >>>> to have an update on that soon. >>>> >>>> This first iteration supports the 'var-only' syntax style: >>>> >>>> var s = "Hello!"; >>>> >>>> That is, the type of 's' is inferred from the initializer, and no >>>> special assumption is made about mutability. >>>> >>>> Please share your experience with the prototype. For comments on this >>>> feature please refer to the survey[2] that Brian posted few days ago. >>>> >>>> Maurizio >>>> >>>> [1] - http://cr.openjdk.java.net/~chegar/docs/sandbox.html >>>> [2] - >>>> http://mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000037.html >>>> >>>> >> > -------------- next part -------------- A non-text attachment was scrubbed... Name: varJShell.diff Type: text/x-patch Size: 7793 bytes Desc: not available URL: From forax at univ-mlv.fr Fri Mar 11 08:08:43 2016 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Fri, 11 Mar 2016 09:08:43 +0100 (CET) Subject: Local Variable Type Inference - prototype In-Reply-To: <56E27B3F.6060108@oracle.com> References: <56E18939.2090006@oracle.com> <1664237129.3734349.1457648509636.JavaMail.zimbra@u-pem.fr> <56E1FB6B.5090504@oracle.com> <56E20611.5080908@oracle.com> <56E27B3F.6060108@oracle.com> Message-ID: <2122879997.4007851.1457683723285.JavaMail.zimbra@u-pem.fr> Works for me :) many thanks ! R?mi ----- Mail original ----- > De: "Robert Field" > ?: "Maurizio Cimadamore" , "Remi Forax" > Cc: platform-jep-discuss at openjdk.java.net, "Jan Lahoda" > Envoy?: Vendredi 11 Mars 2016 09:01:03 > Objet: Re: Local Variable Type Inference - prototype > > Patch to fix this attached. > > Apply as desired. > > -Robert > > > On 03/10/16 15:41, Maurizio Cimadamore wrote: > > > > > > On 10/03/16 22:55, Robert Field wrote: > >> > >> On 03/10/16 14:21, Remi Forax wrote: > >>> At least, jshell need some tweaks :) > >> > >> Yes, it will. Thanks Remi! > >> > >> It will need the analysis pass of the compiler run so that the type > >> can be determined. Variables are implemented as fields. > >> > >> Is this something I should work on now? > > One question for you Robert: currently javac does not parse 'var' as a > > special Token - as doing that requires even more jshell changes; I'm > > happy to leave the code as is, but if, when hacking on the jshell > > side, you discover that a VAR token would be useful please let me know. > > > > Maurizio > >> > >> -Robert > >> > >>> > >>> $ /usr/jdk/jdk-9/bin/java > >>> -Xbootclasspath/p:langtools/dist/lib/jdk.compiler.jar:langtools/dist/lib/jdk.jshell.jar:langtools/dist/lib/jdk.internal.le.jar:langtools/dist/lib/jdk.jdi.jar > >>> jdk.internal.jshell.tool.JShellTool > >>> | Welcome to JShell -- Version 9-internal > >>> | Type /help for help > >>> > >>> -> void m() { > >>>>> var a = 3; > >>>>> } > >>> | Added method m() > >>> > >>> -> m() > >>> > >>> -> var a = 3; > >>> Exception in thread "main" > >>> java.lang.StringIndexOutOfBoundsException: begin -1, end -1, length 10 > >>> at java.lang.String.checkBoundsBeginEnd(String.java:3122) > >>> at java.lang.String.substring(String.java:1910) > >>> at jdk.jshell.Wrap$Range.part(Wrap.java:168) > >>> at jdk.jshell.Wrap$RangeWrap.(Wrap.java:350) > >>> at jdk.jshell.Wrap.varWrap(Wrap.java:97) > >>> at jdk.jshell.Eval.processVariables(Eval.java:227) > >>> at jdk.jshell.Eval.eval(Eval.java:116) > >>> at jdk.jshell.JShell.eval(JShell.java:355) > >>> at > >>> jdk.internal.jshell.tool.JShellTool.processCompleteSource(JShellTool.java:1923) > >>> at > >>> jdk.internal.jshell.tool.JShellTool.processSource(JShellTool.java:1911) > >>> at > >>> jdk.internal.jshell.tool.JShellTool.processSourceCatchingReset(JShellTool.java:652) > >>> at jdk.internal.jshell.tool.JShellTool.run(JShellTool.java:632) > >>> at jdk.internal.jshell.tool.JShellTool.start(JShellTool.java:427) > >>> at jdk.internal.jshell.tool.JShellTool.start(JShellTool.java:400) > >>> at jdk.internal.jshell.tool.JShellTool.main(JShellTool.java:390) > >>> > >>> R?mi > >>> > >>> ----- Mail original ----- > >>>> De: "Maurizio Cimadamore" > >>>> ?: platform-jep-discuss at openjdk.java.net > >>>> Envoy?: Jeudi 10 Mars 2016 15:48:25 > >>>> Objet: Local Variable Type Inference - prototype > >>>> > >>>> Hi, > >>>> I've pushed the first iteration of the local variable type inference > >>>> prototype in the sandbox repository[1]. For those willing and brave > >>>> enough to experiment, the branch name is "JEP-286-branch". We are also > >>>> working to get some ready-made binary snapshots out of the door and > >>>> hope > >>>> to have an update on that soon. > >>>> > >>>> This first iteration supports the 'var-only' syntax style: > >>>> > >>>> var s = "Hello!"; > >>>> > >>>> That is, the type of 's' is inferred from the initializer, and no > >>>> special assumption is made about mutability. > >>>> > >>>> Please share your experience with the prototype. For comments on this > >>>> feature please refer to the survey[2] that Brian posted few days ago. > >>>> > >>>> Maurizio > >>>> > >>>> [1] - http://cr.openjdk.java.net/~chegar/docs/sandbox.html > >>>> [2] - > >>>> http://mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000037.html > >>>> > >>>> > >> > > > > From maurizio.cimadamore at oracle.com Fri Mar 11 10:57:49 2016 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Fri, 11 Mar 2016 10:57:49 +0000 Subject: Local Variable Type Inference - prototype In-Reply-To: <190452603.3999991.1457683175554.JavaMail.zimbra@u-pem.fr> References: <56E18939.2090006@oracle.com> <190452603.3999991.1457683175554.JavaMail.zimbra@u-pem.fr> Message-ID: <56E2A4AD.1040403@oracle.com> On 11/03/16 07:59, Remi Forax wrote: > Hi Maurizio, hi all, > currently, this compiles > > public class VarTest { > var x = 3; > static final var FOO = 3; > } > > while i don't care too much about being able to declare final static field with var, > being able to declare instance field with var is plainly wrong for me > (and out of the scope of this JEP). That's outside the scope, and it's a bug in the implementation. I will fix this. Maurizio > > R?mi > > ----- Mail original ----- >> De: "Maurizio Cimadamore" >> ?: platform-jep-discuss at openjdk.java.net >> Envoy?: Jeudi 10 Mars 2016 15:48:25 >> Objet: Local Variable Type Inference - prototype >> >> Hi, >> I've pushed the first iteration of the local variable type inference >> prototype in the sandbox repository[1]. For those willing and brave >> enough to experiment, the branch name is "JEP-286-branch". We are also >> working to get some ready-made binary snapshots out of the door and hope >> to have an update on that soon. >> >> This first iteration supports the 'var-only' syntax style: >> >> var s = "Hello!"; >> >> That is, the type of 's' is inferred from the initializer, and no >> special assumption is made about mutability. >> >> Please share your experience with the prototype. For comments on this >> feature please refer to the survey[2] that Brian posted few days ago. >> >> Maurizio >> >> [1] - http://cr.openjdk.java.net/~chegar/docs/sandbox.html >> [2] - >> http://mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000037.html >> From maurizio.cimadamore at oracle.com Fri Mar 11 13:15:07 2016 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Fri, 11 Mar 2016 13:15:07 +0000 Subject: Local Variable Type Inference - prototype In-Reply-To: <56E27B3F.6060108@oracle.com> References: <56E18939.2090006@oracle.com> <1664237129.3734349.1457648509636.JavaMail.zimbra@u-pem.fr> <56E1FB6B.5090504@oracle.com> <56E20611.5080908@oracle.com> <56E27B3F.6060108@oracle.com> Message-ID: <56E2C4DB.60500@oracle.com> Thanks - pushed Maurizio On 11/03/16 08:01, Robert Field wrote: > Patch to fix this attached. > > Apply as desired. > > -Robert > > > On 03/10/16 15:41, Maurizio Cimadamore wrote: >> >> >> On 10/03/16 22:55, Robert Field wrote: >>> >>> On 03/10/16 14:21, Remi Forax wrote: >>>> At least, jshell need some tweaks :) >>> >>> Yes, it will. Thanks Remi! >>> >>> It will need the analysis pass of the compiler run so that the type >>> can be determined. Variables are implemented as fields. >>> >>> Is this something I should work on now? >> One question for you Robert: currently javac does not parse 'var' as >> a special Token - as doing that requires even more jshell changes; >> I'm happy to leave the code as is, but if, when hacking on the jshell >> side, you discover that a VAR token would be useful please let me know. >> >> Maurizio >>> >>> -Robert >>> >>>> >>>> $ /usr/jdk/jdk-9/bin/java >>>> -Xbootclasspath/p:langtools/dist/lib/jdk.compiler.jar:langtools/dist/lib/jdk.jshell.jar:langtools/dist/lib/jdk.internal.le.jar:langtools/dist/lib/jdk.jdi.jar >>>> jdk.internal.jshell.tool.JShellTool >>>> | Welcome to JShell -- Version 9-internal >>>> | Type /help for help >>>> >>>> -> void m() { >>>>>> var a = 3; >>>>>> } >>>> | Added method m() >>>> >>>> -> m() >>>> >>>> -> var a = 3; >>>> Exception in thread "main" >>>> java.lang.StringIndexOutOfBoundsException: begin -1, end -1, length 10 >>>> at java.lang.String.checkBoundsBeginEnd(String.java:3122) >>>> at java.lang.String.substring(String.java:1910) >>>> at jdk.jshell.Wrap$Range.part(Wrap.java:168) >>>> at jdk.jshell.Wrap$RangeWrap.(Wrap.java:350) >>>> at jdk.jshell.Wrap.varWrap(Wrap.java:97) >>>> at jdk.jshell.Eval.processVariables(Eval.java:227) >>>> at jdk.jshell.Eval.eval(Eval.java:116) >>>> at jdk.jshell.JShell.eval(JShell.java:355) >>>> at >>>> jdk.internal.jshell.tool.JShellTool.processCompleteSource(JShellTool.java:1923) >>>> at >>>> jdk.internal.jshell.tool.JShellTool.processSource(JShellTool.java:1911) >>>> >>>> at >>>> jdk.internal.jshell.tool.JShellTool.processSourceCatchingReset(JShellTool.java:652) >>>> at jdk.internal.jshell.tool.JShellTool.run(JShellTool.java:632) >>>> at jdk.internal.jshell.tool.JShellTool.start(JShellTool.java:427) >>>> at jdk.internal.jshell.tool.JShellTool.start(JShellTool.java:400) >>>> at jdk.internal.jshell.tool.JShellTool.main(JShellTool.java:390) >>>> >>>> R?mi >>>> >>>> ----- Mail original ----- >>>>> De: "Maurizio Cimadamore" >>>>> ?: platform-jep-discuss at openjdk.java.net >>>>> Envoy?: Jeudi 10 Mars 2016 15:48:25 >>>>> Objet: Local Variable Type Inference - prototype >>>>> >>>>> Hi, >>>>> I've pushed the first iteration of the local variable type inference >>>>> prototype in the sandbox repository[1]. For those willing and brave >>>>> enough to experiment, the branch name is "JEP-286-branch". We are >>>>> also >>>>> working to get some ready-made binary snapshots out of the door >>>>> and hope >>>>> to have an update on that soon. >>>>> >>>>> This first iteration supports the 'var-only' syntax style: >>>>> >>>>> var s = "Hello!"; >>>>> >>>>> That is, the type of 's' is inferred from the initializer, and no >>>>> special assumption is made about mutability. >>>>> >>>>> Please share your experience with the prototype. For comments on this >>>>> feature please refer to the survey[2] that Brian posted few days ago. >>>>> >>>>> Maurizio >>>>> >>>>> [1] - http://cr.openjdk.java.net/~chegar/docs/sandbox.html >>>>> [2] - >>>>> http://mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000037.html >>>>> >>>>> >>> >> > From maurizio.cimadamore at oracle.com Fri Mar 11 13:19:44 2016 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Fri, 11 Mar 2016 13:19:44 +0000 Subject: Local Variable Type Inference - prototype In-Reply-To: <56E2A4AD.1040403@oracle.com> References: <56E18939.2090006@oracle.com> <190452603.3999991.1457683175554.JavaMail.zimbra@u-pem.fr> <56E2A4AD.1040403@oracle.com> Message-ID: <56E2C5F0.6020101@oracle.com> Fix pushed - thanks Maurizio On 11/03/16 10:57, Maurizio Cimadamore wrote: > > > On 11/03/16 07:59, Remi Forax wrote: >> Hi Maurizio, hi all, >> currently, this compiles >> >> public class VarTest { >> var x = 3; >> static final var FOO = 3; >> } >> >> while i don't care too much about being able to declare final static >> field with var, >> being able to declare instance field with var is plainly wrong for me >> (and out of the scope of this JEP). > That's outside the scope, and it's a bug in the implementation. I will > fix this. > > Maurizio >> >> R?mi >> >> ----- Mail original ----- >>> De: "Maurizio Cimadamore" >>> ?: platform-jep-discuss at openjdk.java.net >>> Envoy?: Jeudi 10 Mars 2016 15:48:25 >>> Objet: Local Variable Type Inference - prototype >>> >>> Hi, >>> I've pushed the first iteration of the local variable type inference >>> prototype in the sandbox repository[1]. For those willing and brave >>> enough to experiment, the branch name is "JEP-286-branch". We are also >>> working to get some ready-made binary snapshots out of the door and >>> hope >>> to have an update on that soon. >>> >>> This first iteration supports the 'var-only' syntax style: >>> >>> var s = "Hello!"; >>> >>> That is, the type of 's' is inferred from the initializer, and no >>> special assumption is made about mutability. >>> >>> Please share your experience with the prototype. For comments on this >>> feature please refer to the survey[2] that Brian posted few days ago. >>> >>> Maurizio >>> >>> [1] - http://cr.openjdk.java.net/~chegar/docs/sandbox.html >>> [2] - >>> http://mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000037.html >>> >>> > From forax at univ-mlv.fr Fri Mar 11 13:43:58 2016 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Fri, 11 Mar 2016 14:43:58 +0100 (CET) Subject: Local Variable Type Inference - prototype In-Reply-To: <56E2C5F0.6020101@oracle.com> References: <56E18939.2090006@oracle.com> <190452603.3999991.1457683175554.JavaMail.zimbra@u-pem.fr> <56E2A4AD.1040403@oracle.com> <56E2C5F0.6020101@oracle.com> Message-ID: <484546799.4418256.1457703838986.JavaMail.zimbra@u-pem.fr> yes, verified ! R?mi ----- Mail original ----- > De: "Maurizio Cimadamore" > ?: "Remi Forax" > Cc: platform-jep-discuss at openjdk.java.net > Envoy?: Vendredi 11 Mars 2016 14:19:44 > Objet: Re: Local Variable Type Inference - prototype > > Fix pushed - thanks > > Maurizio > > On 11/03/16 10:57, Maurizio Cimadamore wrote: > > > > > > On 11/03/16 07:59, Remi Forax wrote: > >> Hi Maurizio, hi all, > >> currently, this compiles > >> > >> public class VarTest { > >> var x = 3; > >> static final var FOO = 3; > >> } > >> > >> while i don't care too much about being able to declare final static > >> field with var, > >> being able to declare instance field with var is plainly wrong for me > >> (and out of the scope of this JEP). > > That's outside the scope, and it's a bug in the implementation. I will > > fix this. > > > > Maurizio > >> > >> R?mi > >> > >> ----- Mail original ----- > >>> De: "Maurizio Cimadamore" > >>> ?: platform-jep-discuss at openjdk.java.net > >>> Envoy?: Jeudi 10 Mars 2016 15:48:25 > >>> Objet: Local Variable Type Inference - prototype > >>> > >>> Hi, > >>> I've pushed the first iteration of the local variable type inference > >>> prototype in the sandbox repository[1]. For those willing and brave > >>> enough to experiment, the branch name is "JEP-286-branch". We are also > >>> working to get some ready-made binary snapshots out of the door and > >>> hope > >>> to have an update on that soon. > >>> > >>> This first iteration supports the 'var-only' syntax style: > >>> > >>> var s = "Hello!"; > >>> > >>> That is, the type of 's' is inferred from the initializer, and no > >>> special assumption is made about mutability. > >>> > >>> Please share your experience with the prototype. For comments on this > >>> feature please refer to the survey[2] that Brian posted few days ago. > >>> > >>> Maurizio > >>> > >>> [1] - http://cr.openjdk.java.net/~chegar/docs/sandbox.html > >>> [2] - > >>> http://mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000037.html > >>> > >>> > > > > From forax at univ-mlv.fr Fri Mar 11 14:11:40 2016 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Fri, 11 Mar 2016 15:11:40 +0100 (CET) Subject: Local Variable Type Inference - prototype In-Reply-To: <56E2C5F0.6020101@oracle.com> References: <56E18939.2090006@oracle.com> <190452603.3999991.1457683175554.JavaMail.zimbra@u-pem.fr> <56E2A4AD.1040403@oracle.com> <56E2C5F0.6020101@oracle.com> Message-ID: <1540076533.4470380.1457705500305.JavaMail.zimbra@u-pem.fr> Another bug, public static void main(String[] args) throws Throwable { for(var i = 0; i < 3; i++) { // ok } System.out.println("foo"); // statement unreachable ?? } cheers, R?mi ----- Mail original ----- > De: "Maurizio Cimadamore" > ?: "Remi Forax" > Cc: platform-jep-discuss at openjdk.java.net > Envoy?: Vendredi 11 Mars 2016 14:19:44 > Objet: Re: Local Variable Type Inference - prototype > > Fix pushed - thanks > > Maurizio > > On 11/03/16 10:57, Maurizio Cimadamore wrote: > > > > > > On 11/03/16 07:59, Remi Forax wrote: > >> Hi Maurizio, hi all, > >> currently, this compiles > >> > >> public class VarTest { > >> var x = 3; > >> static final var FOO = 3; > >> } > >> > >> while i don't care too much about being able to declare final static > >> field with var, > >> being able to declare instance field with var is plainly wrong for me > >> (and out of the scope of this JEP). > > That's outside the scope, and it's a bug in the implementation. I will > > fix this. > > > > Maurizio > >> > >> R?mi > >> > >> ----- Mail original ----- > >>> De: "Maurizio Cimadamore" > >>> ?: platform-jep-discuss at openjdk.java.net > >>> Envoy?: Jeudi 10 Mars 2016 15:48:25 > >>> Objet: Local Variable Type Inference - prototype > >>> > >>> Hi, > >>> I've pushed the first iteration of the local variable type inference > >>> prototype in the sandbox repository[1]. For those willing and brave > >>> enough to experiment, the branch name is "JEP-286-branch". We are also > >>> working to get some ready-made binary snapshots out of the door and > >>> hope > >>> to have an update on that soon. > >>> > >>> This first iteration supports the 'var-only' syntax style: > >>> > >>> var s = "Hello!"; > >>> > >>> That is, the type of 's' is inferred from the initializer, and no > >>> special assumption is made about mutability. > >>> > >>> Please share your experience with the prototype. For comments on this > >>> feature please refer to the survey[2] that Brian posted few days ago. > >>> > >>> Maurizio > >>> > >>> [1] - http://cr.openjdk.java.net/~chegar/docs/sandbox.html > >>> [2] - > >>> http://mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000037.html > >>> > >>> > > > > From maurizio.cimadamore at oracle.com Fri Mar 11 16:30:05 2016 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Fri, 11 Mar 2016 16:30:05 +0000 Subject: Local Variable Type Inference - prototype In-Reply-To: <1540076533.4470380.1457705500305.JavaMail.zimbra@u-pem.fr> References: <56E18939.2090006@oracle.com> <190452603.3999991.1457683175554.JavaMail.zimbra@u-pem.fr> <56E2A4AD.1040403@oracle.com> <56E2C5F0.6020101@oracle.com> <1540076533.4470380.1457705500305.JavaMail.zimbra@u-pem.fr> Message-ID: <56E2F28D.3090206@oracle.com> Fixed - thanks Maurizio On 11/03/16 14:11, forax at univ-mlv.fr wrote: > Another bug, > > public static void main(String[] args) throws Throwable { > for(var i = 0; i < 3; i++) { > // ok > } > System.out.println("foo"); // statement unreachable ?? > } > > cheers, > R?mi > > ----- Mail original ----- >> De: "Maurizio Cimadamore" >> ?: "Remi Forax" >> Cc: platform-jep-discuss at openjdk.java.net >> Envoy?: Vendredi 11 Mars 2016 14:19:44 >> Objet: Re: Local Variable Type Inference - prototype >> >> Fix pushed - thanks >> >> Maurizio >> >> On 11/03/16 10:57, Maurizio Cimadamore wrote: >>> >>> On 11/03/16 07:59, Remi Forax wrote: >>>> Hi Maurizio, hi all, >>>> currently, this compiles >>>> >>>> public class VarTest { >>>> var x = 3; >>>> static final var FOO = 3; >>>> } >>>> >>>> while i don't care too much about being able to declare final static >>>> field with var, >>>> being able to declare instance field with var is plainly wrong for me >>>> (and out of the scope of this JEP). >>> That's outside the scope, and it's a bug in the implementation. I will >>> fix this. >>> >>> Maurizio >>>> R?mi >>>> >>>> ----- Mail original ----- >>>>> De: "Maurizio Cimadamore" >>>>> ?: platform-jep-discuss at openjdk.java.net >>>>> Envoy?: Jeudi 10 Mars 2016 15:48:25 >>>>> Objet: Local Variable Type Inference - prototype >>>>> >>>>> Hi, >>>>> I've pushed the first iteration of the local variable type inference >>>>> prototype in the sandbox repository[1]. For those willing and brave >>>>> enough to experiment, the branch name is "JEP-286-branch". We are also >>>>> working to get some ready-made binary snapshots out of the door and >>>>> hope >>>>> to have an update on that soon. >>>>> >>>>> This first iteration supports the 'var-only' syntax style: >>>>> >>>>> var s = "Hello!"; >>>>> >>>>> That is, the type of 's' is inferred from the initializer, and no >>>>> special assumption is made about mutability. >>>>> >>>>> Please share your experience with the prototype. For comments on this >>>>> feature please refer to the survey[2] that Brian posted few days ago. >>>>> >>>>> Maurizio >>>>> >>>>> [1] - http://cr.openjdk.java.net/~chegar/docs/sandbox.html >>>>> [2] - >>>>> http://mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000037.html >>>>> >>>>> >> From maurizio.cimadamore at oracle.com Fri Mar 11 17:15:02 2016 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Fri, 11 Mar 2016 17:15:02 +0000 Subject: Local Variable Type Inference - compiler messages Message-ID: <56E2FD16.9060806@oracle.com> Hi, We've collected some snippets of problematic uses of the 'var' feature and stack them together in a single browsable page[1], to make it easy to see what the generated compiler message looks like. Please let us know what you think i.e. if you see error messages which needs to be improved - and should you run into corner cases which are not covered in this doc, please let us know! I will be updating this page as we discover new 'interesting' error messages. Maurizio [1] - http://cr.openjdk.java.net/~mcimadamore/var-diags.html From forax at univ-mlv.fr Fri Mar 11 17:23:57 2016 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Fri, 11 Mar 2016 18:23:57 +0100 (CET) Subject: Local Variable Type Inference - prototype In-Reply-To: <56E2F28D.3090206@oracle.com> References: <56E18939.2090006@oracle.com> <190452603.3999991.1457683175554.JavaMail.zimbra@u-pem.fr> <56E2A4AD.1040403@oracle.com> <56E2C5F0.6020101@oracle.com> <1540076533.4470380.1457705500305.JavaMail.zimbra@u-pem.fr> <56E2F28D.3090206@oracle.com> Message-ID: <847158269.4692225.1457717037568.JavaMail.zimbra@u-pem.fr> yes, thanks. R?mi ----- Mail original ----- > De: "Maurizio Cimadamore" > ?: forax at univ-mlv.fr > Cc: platform-jep-discuss at openjdk.java.net > Envoy?: Vendredi 11 Mars 2016 17:30:05 > Objet: Re: Local Variable Type Inference - prototype > > Fixed - thanks > > Maurizio > > On 11/03/16 14:11, forax at univ-mlv.fr wrote: > > Another bug, > > > > public static void main(String[] args) throws Throwable { > > for(var i = 0; i < 3; i++) { > > // ok > > } > > System.out.println("foo"); // statement unreachable ?? > > } > > > > cheers, > > R?mi > > > > ----- Mail original ----- > >> De: "Maurizio Cimadamore" > >> ?: "Remi Forax" > >> Cc: platform-jep-discuss at openjdk.java.net > >> Envoy?: Vendredi 11 Mars 2016 14:19:44 > >> Objet: Re: Local Variable Type Inference - prototype > >> > >> Fix pushed - thanks > >> > >> Maurizio > >> > >> On 11/03/16 10:57, Maurizio Cimadamore wrote: > >>> > >>> On 11/03/16 07:59, Remi Forax wrote: > >>>> Hi Maurizio, hi all, > >>>> currently, this compiles > >>>> > >>>> public class VarTest { > >>>> var x = 3; > >>>> static final var FOO = 3; > >>>> } > >>>> > >>>> while i don't care too much about being able to declare final static > >>>> field with var, > >>>> being able to declare instance field with var is plainly wrong for me > >>>> (and out of the scope of this JEP). > >>> That's outside the scope, and it's a bug in the implementation. I will > >>> fix this. > >>> > >>> Maurizio > >>>> R?mi > >>>> > >>>> ----- Mail original ----- > >>>>> De: "Maurizio Cimadamore" > >>>>> ?: platform-jep-discuss at openjdk.java.net > >>>>> Envoy?: Jeudi 10 Mars 2016 15:48:25 > >>>>> Objet: Local Variable Type Inference - prototype > >>>>> > >>>>> Hi, > >>>>> I've pushed the first iteration of the local variable type inference > >>>>> prototype in the sandbox repository[1]. For those willing and brave > >>>>> enough to experiment, the branch name is "JEP-286-branch". We are also > >>>>> working to get some ready-made binary snapshots out of the door and > >>>>> hope > >>>>> to have an update on that soon. > >>>>> > >>>>> This first iteration supports the 'var-only' syntax style: > >>>>> > >>>>> var s = "Hello!"; > >>>>> > >>>>> That is, the type of 's' is inferred from the initializer, and no > >>>>> special assumption is made about mutability. > >>>>> > >>>>> Please share your experience with the prototype. For comments on this > >>>>> feature please refer to the survey[2] that Brian posted few days ago. > >>>>> > >>>>> Maurizio > >>>>> > >>>>> [1] - http://cr.openjdk.java.net/~chegar/docs/sandbox.html > >>>>> [2] - > >>>>> http://mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000037.html > >>>>> > >>>>> > >> > > From richard.warburton at gmail.com Sun Mar 13 09:01:54 2016 From: richard.warburton at gmail.com (Richard Warburton) Date: Sun, 13 Mar 2016 09:01:54 +0000 Subject: JEP 286 Builds Message-ID: Hi, If anyone wants to try out JEP 286 we've put some builds online for you to download and try out. http://iteratrlearning.com/jep286.html regards, Richard Warburton http://insightfullogic.com @RichardWarburto From glen at organicdesign.org Mon Mar 14 14:09:33 2016 From: glen at organicdesign.org (Glen Peterson) Date: Mon, 14 Mar 2016 10:09:33 -0400 Subject: platform-jep to this point Message-ID: I just completed the survey, then read the entire message archive for this list. I put most of my ideas in the survey, but I have a few responses that I thought of after the survey (or weren't asked there). Re: Local Variable Type Inference http://mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000039.html > 10. What do you mean by "action at a distance"? > > var x = "Some String"; > ... > x = 42; Great example. Why not just add type inference for `final` variables? It: - Uses an existing language term without changing its meaning (doesn't break old code) - Prevents the above re-assignment issue entirely - Encourages lazy programmers to prefer immutability because the syntax is shorter (they don't have to specify any types). Question: "The problem with intersection types is that in the general case, when you have a type like C & I1 & I2 ... & In, how do you pick the 'best' type?" - Maurizio Answer: The compiler can't read the user's mind. The user has to specify the type they want the old fashioned way, or accept a potentially complicated intersection type. Please be as slow as possible to infer Object as that's just not useful type inference in any situation except `var x = new Object()`. Scala infers Any (it's ultimate super-type) too often and it's incredibly frustrating. -- Glen K. Peterson (828) 393-0081 11110 000 10 011111 10 011001 10 000010 From brian.goetz at oracle.com Mon Mar 14 14:33:48 2016 From: brian.goetz at oracle.com (Brian Goetz) Date: Mon, 14 Mar 2016 07:33:48 -0700 Subject: platform-jep to this point In-Reply-To: References: Message-ID: Don?t worry, there?ll be another round of survey input for this sort of stuff before we?re done. As the over 2000 survey responses show, doing this on the mailing list is not going to scale, and it doesn?t take much before a hundred-message thread breaks out. So please, respect the request to not use the list for this. Thanks! > On Mar 14, 2016, at 7:09 AM, Glen Peterson wrote: > > I just completed the survey, then read the entire message archive for > this list. I put most of my ideas in the survey, but I have a few > responses that I thought of after the survey (or weren't asked there). > > Re: Local Variable Type Inference > http://mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000039.html > >> 10. What do you mean by "action at a distance"? >> >> var x = "Some String"; >> ... >> x = 42; > > Great example. Why not just add type inference for `final` variables? It: > - Uses an existing language term without changing its meaning > (doesn't break old code) > - Prevents the above re-assignment issue entirely > - Encourages lazy programmers to prefer immutability because the > syntax is shorter (they don't have to specify any types). > > > Question: > "The problem with intersection types is that in the general case, when > you have a type like C & I1 & I2 ... & In, how do you pick the 'best' > type?" - Maurizio > > Answer: > The compiler can't read the user's mind. The user has to specify the > type they want the old fashioned way, or accept a potentially > complicated intersection type. Please be as slow as possible to infer > Object as that's just not useful type inference in any situation > except `var x = new Object()`. Scala infers Any (it's ultimate > super-type) too often and it's incredibly frustrating. > > -- > Glen K. Peterson > (828) 393-0081 > > 11110 000 > 10 011111 > 10 011001 > 10 000010 From brian.goetz at oracle.com Tue Mar 22 02:18:33 2016 From: brian.goetz at oracle.com (Brian Goetz) Date: Mon, 21 Mar 2016 19:18:33 -0700 Subject: Local variable type inference survey -- round 1 results, and round 2 survey Message-ID: <7D904DAA-8357-4A4B-9178-B666C7F35CDB@oracle.com> PLEASE DO NOT RESPOND DIRECTLY TO THIS MAIL -- SEE BELOW FOR HOW TO PROVIDE FEEDBACK. Thank you to everyone who responded to the survey! We received nearly 2500 responses. The next steps are: - Publish the results of the first survey, so everyone can see all the comments; - Start the next round of survey, which allows everyone to respond to comments posted in the first round, and post additional comments. The results of the first round can be found at: https://www.surveymonkey.com/results/SM-FLWGS5PW/ The next round of survey can be found at: https://www.surveymonkey.com/r/JYHNQ72 In the next few days, I?ll also post an update to the ?Reader Mail Bag?, addressing suitable questions raised in the first round of survey. From brian.goetz at oracle.com Thu Mar 24 19:44:13 2016 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 24 Mar 2016 15:44:13 -0400 Subject: Reader Mail Bag -- Local Type Inference Message-ID: <56F4438D.9090604@oracle.com> (Please do not respond directly to this mail; if you want to respond, please use the follow-up survey.) The first survey is closed, and we received ~2500 entries, with over 400 providing long-form comments and questions. I'll try to answer some of the the constructive questions here, which I've divided into groups by topic. I've answered the mostly non-subjective questions here; I'll cover the more subjective ones in a separate mail. (Also see the earlier "Reader Mail Bag" response, which answers some of the early-arriving questions.) "How does it work" ================== Q: How does mutability/finality work in "var only"? In all of the alternatives, effective-finality analysis applies to local variables declared with 'var'. In the alternatives that also include val/let, these are treated as explicitly final, but the existence of val/let doesn't mean that we don't do effectively-final analysis on variables declared with 'var'. Q: Are 'val' and 'final var' equivalent? Yes, val/let would be equivalent to 'final var'. Q: Will this break existing programs that use 'var' or 'val' as field or method names? No. Q: Will this break existing programs that use 'var' or 'val' as a class or interface name? Yes. We've explored how to provide a means to save these classes, at the cost of additional complexity, but the return-on-complexity didn't seem to be there. Q: Does 'let' mean 'immutable'? It means 'final'. Q: Are these dynamically typed? No! This is not dynamic typing; it is allowing the compiler to determine the static type for you, rather than making you provide it explicitly. Once the compiler chooses a type (which is based entirely on the type of the initializer expression), it is as if you had provided that type explicitly. Q: How does this interact with existing type inference, such as for diamond constructors, generic methods, or lambda formals in the initializer expression? For inference variables in the initializer expression, if they can be inferred from type information in the initializer expression itself, then the expression is compatible with using 'var' on the declaration. On the other hand, if they cannot be inferred without a target type, and no target type is provided, then inference will fail, and the compiler will issue an error message. Q: What is the type of an anonymous class creation expression? For an anonymous class creation expression, we infer the base type. So for example, in: var foo = new Foo() { ... } we would infer 'Foo' for the type of 'foo'. Q: How does it work with variables that don't have initializers. It doesn't; this is an error. Q: Can I mix explicit and implicit types? Yes. Tooling Impact ============== Q: Does this affect the runtime or classfile? No. Q: Will this affect runtime performance? No. Q: Will this affect compiler performance? In any realistic case, no. (Even with a manifest type, the compiler still has to synthesize the type of the initializer, and perform a subtyping check against the manifest type.) Q: Does this affect Javadoc? No; local variables do not appear in Javadoc. Q: Can we have Javac modify the code and insert the type? IDEs will certainly do this for you. Javac doesn't modify code in-place, but we are considering enhancing features of javac like -printSource to expand inferred types (and not just for locals, but also for generic methods, diamond constructors, and lambda formals), as a debugging aid. Q: Can we have a compiler warning that detects the use of 'var'? This seems better handled by style-checking tools like CheckStyle. Q: Will it require targeting the latest class file? There are no classfile changes mandated by this feature. Feature Scope ============= Q: Why not allow it on fields or method returns? Because these are part of the *interface* of your class, and these appear in classfiles (which could then cause silent compatibility issues if implementation changes cause the inferred type to change.) Locals cannot be accessed outside of the declaring scope; their types are pure implementation details. Q: OK, what about private fields or method returns? They aren't accessible from other classes. We could choose to include these; this would be a tradeoff of greater complexity (more complex set of rules for when 'var' is allowed, would mean broadening the accessibility of a member becomes potentially not a source-compatible change) for greater applicability. We're inclined to keep it simple. Q: Why not allow diamond on the LHS? This is a viable feature, and has pros and cons. This helps for generic types, but doesn't help at all for long type names (AbstractBeanProviderFactory). Q: How does it interact with subsequent uses? As proposed, we infer the type of the local purely from the initializer type; thereafter, the type is fixed as if it were explicitly provided. Alternately, we could instead have chosen to infer it from all assignments; this might well result in inferring weaker types (like Object). The choice to use the initializer only is a tradeoff; we gain greater simplicity and stability, at the cost of being able to infer types for more locals. (Because other assignments might be far away from the declaration, using all assignments could easily generate confusing action-at-a-distance errors.) From brian.goetz at oracle.com Fri Mar 25 19:24:56 2016 From: brian.goetz at oracle.com (Brian Goetz) Date: Fri, 25 Mar 2016 15:24:56 -0400 Subject: Reader Mail Bag -- Local Type Inference (JEP 286) Message-ID: <56F59088.2080704@oracle.com> (Please do not respond directly to this mail; if you want to respond, please use the follow-up survey.) As promised yesterday, I'm back to cover some of the more subjective responses and questions to the survey. Overall, the responses were strongly in favor of the feature; given a choice of great/ok/bad idea, 74% chose "great idea", 12% chose "OK", and 10% chose "bad idea". The written comments had more of a negative bias, but this shouldn't be surprising -- people are generally more inclined to speak up in disagreement than in agreement. The positive comments were very positive; the negative comments were very negative. So no matter what we do here, some people are going to be very disappointed. (One interesting observation here is that, while developers frequently complain about Java's verbosity, there is at least a silent minority that *likes* that verbosity, and complains only when we threaten to take some of it away.) Readability =========== The biggest category of negative comments regarded concerns for readability. We have always held out "Reading code is more important than writing code" as a core value of the language; plenty of folks threw this in our face, assuming that this feature would inevitably lead to less readable code. For example, code like the following strawman was offered by several commenters: var x = y.getFoo() and offered as evidence of "see, its unreadable, you have no idea what 'x' is." The readability problem here, though, stems primarily from the fact that 'x' is a silly variable name. While every situation may be different, we believe that, with judicious use of this feature in well-written code, readability can actually be *enhanced*. Consider a block of locals: UserModelHandle userDB = broker.findUserDB(); List users = db.getUsers(); Map addressesByUser = db.getAddresses(); What is the most important thing on each line? IMO, in a block like the above, the variable *names* are more important than the *types* or their initializing expressions -- they describe the role of the variable in the current program. And note that the variables names are not so easy to visually pick out from the above code -- they're stuck in the middle of each line, and at a different place on each line. Ideally, we'd like for the most important thing to be front-and-center in the reader's view. (Some languages have us declare variables with the syntax "name : type", which also furthers this goal, but that ship sailed in 1995.) If we rewrite the above block with inferred types: var userDB = broker.findUserDB(); var users = db.getUsers(); var addressesByUser = db.getAddresses(); the true intent of this code pops out much more readily. The types are not needed, because we've chosen good variable names. Another aspect in which this feature could improve readability (as suggested in the JEP) is that users frequently construct complex nested and chained expressions not because this is the most readable way to write the code, but because the overhead of declaring additional temporary variable seems burdensome. (We all do this.) By reducing this overhead, implementation patterns will likely reequilibrate to a less artificially-condensed form, enhancing readability. A second version of this complaint could be summarized as "bad programmers will use this as an excuse to write bad code." (This is sometimes phrased as some form of "I like this feature for me, but am not sure other developers can handle the responsibility.") This may be true, but I think we all know that bad programmers don't need excuses to write bad code. There is always a balance to be found between "preventing bad things" and "enabling good things", and reasonable people will reasonably differ on which is more important in any given situation or timeframe. Ultimately, this comes down to the usual question of "Here's a feature that can be used for both good and bad; should we trust developers to use it responsibility, or take that choice away from them?" (And of course, proponents on both sides can find precedent in past decisions to claim "the spirit of Java" is on their side.) Recall too that we heard all the same arguments about lambdas -- that they were too advanced, that Java programmers couldn't handle them, that they'd destroy readability (and Java with it) -- in the not-so-distant past. Further, just because the feature exists, doesn't mean that we can't have stylistic guidelines regarding its use -- just like any other feature. (Users can write 1000-line long methods, or pick terrible variable names, or store all their state in public static variables, but they shouldn't.) Goals ===== Many people made assumptions about the goals, such as "this is about concision", or "this is about making writing code easier." But these assumptions are incorrect. The goal here is about *reducing ceremony* -- allowing irrelevant details to be elided where appropriate. In many cases, manifest types are not only inconvenient to write, but they get in the way of easily seeing what is going on when reading code. Note that this feature is, quite deliberately, restricted to *pure implementation details*. We don't use inference to determine the types of fields or methods; we are willing to accept a higher degree of ceremonial overhead for interface contracts than for implementation details. And the body of a method is an implementation detail. Several users simply expressed the notion that "Java is just fine as it is". Others simply asked "Why?" Proponents on both sides claimed "simplicity" was on their side :) First-hand experiences ====================== It's not surprising that many people were quicker to see the bad things that such a feature might enable than the good things; this is human nature. But we are inclined to take the comments from those who have used this before in other languages most seriously, as they are the most informed about the tradeoffs. Of the respondents who cited first-hand experience, several listed this as a major friction point of polyglot projects, or of moving to Java from C#, C++, or Groovy (though several did point out that blanket use of inferred types everywhere was inadvisable, and that it required some judgment to use it correctly.)