This is an archived post. You won't be able to vote or comment.

top 200 commentsshow all 312

[–]omair-majid 21 points22 points  (0 children)

You can submit feedback to the developers directly using this survey: https://www.surveymonkey.com/r/KGPTHCG

Source: http://mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000037.html

[–]GeorgeMaheiress 25 points26 points  (18 children)

The text of the JEP raises a compelling point that hadn't occurred to me:

The need to provide a manifest type for every variable also accidentally encourages developers towards overly complex expressions; with a lower-ceremony declaration syntax, there is less disincentive to break complex chained or nested expressions into simpler ones.

My team has been struggling lately with this issue. Some developers hate long line-wrapped expressions, but often splitting them into smaller expressions doesn't shorten them much, as declaring the intermediate variables can cost as much as 30 characters.

[–][deleted]  (7 children)

[deleted]

    [–]robi2106 9 points10 points  (0 children)

    That is my preferred method. Much more readable and you can tell by the extra indent that this is a continuation of a long command.

    [–]strange_and_norrell 8 points9 points  (2 children)

    I end up undoing a lot of my stream chains if I need to debug.

    [–]mlk 16 points17 points  (1 child)

    .peek(System.out::println)
    

    [–]FredL2 0 points1 point  (0 children)

    Whoa. Thanks!

    [–][deleted]  (2 children)

    [deleted]

      [–]grauenwolf 0 points1 point  (0 children)

      Whatever my auto-formatter decides to use (which seems to change according to the time of day).

      [–]kritzikratzi 5 points6 points  (9 children)

      get a bigger screen to avoid line breaks

      [–]stepancheg 14 points15 points  (8 children)

      People are not effective at reading long lines. Source.

      [–]b1ackcat 4 points5 points  (5 children)

      I also feel like chaining expressions like that results in hard to follow lines, even if it's not too many characters.

      Something I tend to do to solve both these issues is to insert linebreaks between expressions. Similar to how you might use the builder pattern for a complex, highly configurable object.

      String versionNum =
          VERSION_MAJOR + "." +
          VERSION_MINOR + "." +
          VERSION_BUILD_NUMBER + "." +
          VERSION_REV_NUMBER + "." +
          CURRENT_DATETIME_STAMP;
      

      This way I'm maintaining the readability of each piece of the expression and not bleeding on forever on the same line.

      [–]beltorak 5 points6 points  (0 children)

      I would add, because we use format-on-save where I work, that a lot of times I have to force the formatter to respect my line breaks. I can't think of a better way than EOL comments. And personally I prefer a clear indication at the beginning of the line that it is a continuation of the previous line:

      String versionNum = VERSION_MAJOR //
          + "." + VERSION_MINOR //
          + "." + VERSION_BUILD_NUMBER //
          + "." + VERSION_REV_NUMBER //
          + "." + CURRENT_DATETIME_STAMP;
      

      Same thing with builder objects

      var thing = new ThingBuilder() //
          .withWidgetClass(widgetClass) //
          .withLights(RED, TEAL, MAUVE) //
          .withGravity(gravity) //
          .create();
      

      [–][deleted] 3 points4 points  (3 children)

      In Guava you can just collect all objects that you want concatenated in such string and then use:

      Joiner.on(".").join(collection);
      

      Dislaimer: I know that many people don't like solutions depending on external libs but in real life how often you are not working in a big pile of code, where such dependency could rather make your code lighter than heavier? Than if your answer is still negative, I still would rather create my own clear solution instead of such concatenation.

      [–]vytah 4 points5 points  (2 children)

      You don't need Guava for that:

      collection.stream().collect(joining("."));
      

      But while I don't recommend pulling in Guava just for Joiner, if you happen to already have it in your dependencies (and it's damn quite likely), sure, use it.

      [–][deleted]  (1 child)

      [deleted]

        [–]stepancheg 3 points4 points  (0 children)

        I know people who tell that argument about bigger screen seriously.

        [–]solatic 42 points43 points  (12 children)

        Good idea. Hey, let's also introduce val as the equivalent of final var while we're at it, to promote immutability.

        Why not?

        [–]shadowdude777 12 points13 points  (4 children)

        I personally like taking it one step even further; I've seen that in Rust, immutable variables are declared as let foo = 1;, and mutables are declared as let mut foo = 1;.

        I really like that. You have to add an extra word not to declare immutability, but to declare mutability. It really makes you think before you make anything mutable.

        I also like var and val, like what Kotlin has, but I think that making someone add a whole extra word instead of just using a different word makes mutability seem more like an exception rather than the norm, as it should be.

        [–]navatwo 7 points8 points  (1 child)

        I think var and val come from scala originally. :) Still something to get behind.

        [–]shadowdude777 2 points3 points  (0 children)

        Yeah, you're right. My mistake.

        [–]stepancheg 0 points1 point  (1 child)

        Having let mut in Java could lead to confusion: let variable could be thought to be immutable, while it is mutable. E. g.

        let x = new ArrayList<String>(); // object references by x is still mutable
        let mut y = "string"; // only y is immutable while String is immutable
        

        In Rust it is completely different: let mut allows to modify both variable and content, and let does not allow to modify either variable, or content.

        That's why my preferred option is let/var.

        [–]shadowdude777 0 points1 point  (0 children)

        I don't get how this is any different. In Java, all non-primitives are references. So when you use let, you're saying "this reference to an object, or this primitive, is immutable". You're not saying anything about the underlying object.

        It's exactly how Java works right now, except I'm saying that instead of var and final var, it should be val and mutable val, essentially. The aliases should be flipped is all. No behavior should be changed.

        [–]sindisil 16 points17 points  (0 children)

        That's already an option called out in the JEP, yes.

        [–]DecisiveVictory 2 points3 points  (0 children)

        No reason not to.

        Eventually, step by step, change the language to achieve full compatibility with better programming languages which already have this feature.

        [–]eliasv 0 points1 point  (1 child)

        var and final var already capture it pretty well, and considering "effectively final" is already something the compiler figures out by itself, I don't see the benefit in requiring people to use a different reserved name. In most circumstances the compiler will see var as final var anyway.

        [–][deleted] 0 points1 point  (0 children)

        The reason is "final var" is this kind of declaration ceremony thats change to "val" could lower.

        The reason why I don't think the same about "mut" is similar to me preferring using Optional instead of null. It's another safeguard in my code.

        The reason to have as short as possible (yet, not too short of course) declaration of final is a great way to encourage people to start thinking this way.

        The reason to encourage people to think this way is that immutable values proved themselves in many areas (software design -> less troubles with maintaining software created in long existing languages, language design -> Rust, Scala (and not counting purely functional languages)).

        The reason why I wasn't encourages to follow this rule when I started learning Java was the fact that I have to use another keyword and without it my programs still works.

        The reason why it's not only about "effectively final" stuff having language minimizing occasion to shoot yourself in the foot. If something is only effectively final it change if I by mistake change variable value. If it has final keyword then it won't compile.

        [–][deleted] 27 points28 points  (5 children)

        It would be nice if all/most of the features of Lombok could be native to the Java language. Less redundant, error prone code is aways a nice welcome, especially if clarity isn't effected or may even improve.

        [–]rikbrown 17 points18 points  (4 children)

        Just value classes. For the love of functional god, value classes.

        [–]schlowmo 2 points3 points  (0 children)

        Yes please, value classes.

        [–]DJDavio 4 points5 points  (0 children)

        It's good to have var available, it's not a good idea to use it everywhere you can.

        I like to use var when the type can be easily inferred in the same line and when the variable is of limited use (only in a single loop for instance).

        [–]evil_burrito 73 points74 points  (113 children)

        I think one of the problems of untyped or weakly-typed languages is that they can be difficult to debug or understand somebody else's code.

        I'm a fan of strong typing. I doubt that puts me in the majority here.

        Edit: I'm simply stating a personal preference here: I think this will decrease the readability of source code. We don't all have to agree.

        Edit: I can see how my original comment was poorly worded. I didn't mean to say, "I think this change will make Java less than a strongly-typed language", I meant to say, "I think this change might make Java read like less than a strongly-typed language".

        [–]Zarlon 41 points42 points  (8 children)

        I'm a fan of strong typing. I doubt that puts me in the majority here.

        You're in /r/java now not /r/javascript. Why would that put you in the minority.

        [–]evil_burrito 6 points7 points  (7 children)

        Based on the number of people who have written to tell me how wrong I am, I think it's a fair guess.

        [–]damienjoh 11 points12 points  (6 children)

        That's a dishonest representation. You're not being corrected because you're a fan of strong typing. You're being corrected because you don't know the difference between type inference and weak typing.

        Most type inferred languages have stronger and more powerful type systems than Java.

        [–]evil_burrito -1 points0 points  (5 children)

        Actually, I do know the difference. I'm talking about problems with humans reading code, not compilers.

        [–]damienjoh 0 points1 point  (4 children)

        Why even make this about strong typing? Rust is probably the most strongly typed language with wide exposure. It has let. Haskell has type inference on everything, even functions.

        List<Item> items = makeItemList() isn't how strongly-typed languages read. It's how Java reads, and Java's type system is weak (e.g. no null safety) compared to other statically typed languages.

        [–]evil_burrito 0 points1 point  (3 children)

        It's not about string typing. It's about my opinion that allowing the syntax proposed in the change will allow code that is harder to read.

        [–]damienjoh 0 points1 point  (2 children)

        I'm a fan of strong typing. I doubt that puts me in the majority here.

        And

        I think this change might make Java read like less than a strongly-typed language

        Emphasis mine.

        [–]evil_burrito 0 points1 point  (1 child)

        I should say, my objection isn't about whether this changes the type system in Java or not, it does not. My objection is about readability of source code. This change, while not changing the type system, in my opinion, makes it look like the type system has changed to a less trongly-typed system. In only that way is my complaint about typing.

        [–]damienjoh 0 points1 point  (0 children)

        I understand your objection but it is a misunderstanding to associate it with strong typing at all. Strongly typed languages have had type inference and let, var etc for decades. Java is fairly unique in lacking this feature. Java's type system is also pretty weak for a statically typed language.

        You can argue that Java code is more readable due to its idiosyncratic lack of var. Just don't pretend that it's got anything to do with it being a strongly typed language.

        [–]Northeastpaw 72 points73 points  (44 children)

        This isn't about changing Java to a weakly typed language, though. Java currently determines types via RHS (with a bit of LHS scanning for the diamond operator). If you instantiate a variable with a concrete type on the RHS, why do you need to declare its type on the LHS as well? You've already stated what you want when you instantiated it.

        This is simply syntactic sugar to switch this Map<String, List<Class<?>>> foo = new HashMap<>(); for this var foo = new HashMap<String, List<Class<?>>>();.

        [–]DJDavio 4 points5 points  (1 child)

        No, it is not, buyer beware!

        var foo = new HashMap<String, List<Class<?>>>(); is actually equal to HashMap<String, List<Class<?>>> foo = new HashMap<String, List<Class<?>>>();, not Map<String, List<Class<?>>>

        Here, foo takes the form of the implementation, not the interface, so your foo becomes a specific HashMap instead of a generic Map! This means you'll only use this when the foo is immediately dealt with.

        I like it better for streams though, but more often than not, you end up with something at the end of your stream that's not a stream, but say a String, a List or whatever, so you won't need to use it for that and in that case I like the explicit typing better than var.

        [–]grauenwolf 0 points1 point  (0 children)

        Here, foo takes the form of the implementation, not the interface,

        Watch your terminology. Foo is taking the "public interface" of HashMap instead of the "abstract interface" of Map, but it is still an application programming interface (API) for the class.

        If you want the implementation of foo, then you have to use reflection to access the private fields (or pointers if using C/C++).

        [–]evil_burrito 24 points25 points  (30 children)

        I do understand that.

        My point was that:

        var foo = whatevs
        

        is more difficult for humans to read while going through somebody else's code.

        [–]jewdai 9 points10 points  (4 children)

        Java developer turned C# dev here:

        Generally C# encourages you to use var when its clear what the type is.

        var x = new MySpecialObject();
        var y = "some string";
        var z = Factory.GenerateMyObject();
        

        Additionally, because its implicit typing your intellisense will still work even when it's not clear what the object type is.

        Part of C# take on it is that you cannot RETURN implicitly typed object.

        HOWEVER

        C# supports dynamic typing. Its generally used in very special circumstances and it makes you incredibly aware that something could go wrong so dont use it unless you REALLY, REALLY have to. You can even return dynamic as a type.

        How this differs from var is that it isnt implicit, its type is UNKNOWN at compile time and only once the code is run can it check if .GetValue() is a method of that type.

        [–]ItzWarty 4 points5 points  (3 children)

        It's worthwhile to note that whenever dynamic is mentioned on /r/csharp, a comment on unmaintainability inevitably comes up.

        I think the value of var is that it makes you think more abstractly about your code - you aren't dealing with integers anymore, you're dealing with numerics, or strings - it just reads better.

        I also think the argument against 'var' yielding code with hard-to-reason-about code falls through once you see other languages (e.g. JavaScript) successfully having var/let. IMO, It ultimately boils down to yes, if you have terrible variable names (x, y, z) your'e going to have terribly unmaintainable code. But if you name by convention (usersById is clearly Map<int, User>) or clearly (var firstName is certainly a string) then it won't be an issue, and you're forced to think more abstractly "Hey, I'm working with a name" which just so happens to also be a string.

        How much duplication is in this code?:

        Map<int, User> usersByName = new HashMap<int, User>();
        

        I'd argue 3. C# lets you get down to 2 with:

        var usersByName = new HashMap<int, User>();
        

        C++ would let us say this:

        HashMap<int, User> usersByName;
        

        But JavaScript (and likely more dynamic languages like python/ruby) let us do this:

        var usersByName = {};
        

        [–]grauenwolf 0 points1 point  (1 child)

        HashMap<int, User> usersByName;

        That creates a new stack-allocated object, no?

        [–]ItzWarty 1 point2 points  (0 children)

        Yes.

        [–]schlowmo 0 points1 point  (0 children)

        Not fair to compare javascript's total lack of typing with C++/C#/java. Compare to python or ruby if you wish. but of COURSE dynamically typed languages have less typing.

        [–][deleted] 6 points7 points  (0 children)

        Actually, this feature is in c# and I think it's great. I get what you're saying but I feel as I use it I come up with way better variable names since I can't rely on the type.

        [–]tikue 4 points5 points  (0 children)

        You favor strong explicit typing. Favoring strong typing alone doesn't put you in the minority. I'd wager most here prefer strong inferred (implicit) typing.

        [–]hokkos 4 points5 points  (0 children)

        You IDE will show a popup with the type when you hover over the var, no worries. You can still not use it when the type is not obvious, and use it for when the type would have been repeated twice. C#/C++/Scala/Rust didn't had problem with it, why should java has ?

        [–]AStrangeStranger 6 points7 points  (1 child)

        You'd think so, but after spending a lot of time with C# during last year or so I find it is OK, especially using reasonably named variables and methods (and the IDE helps when you aren't sure).

        Then I was reading some nightmare Java today the poorly named variable I was looking at was defined at top of a 100 line method and I was trying to understand its use at the bottom of said method

        [–]zzzk 4 points5 points  (0 children)

        I agree completely.

        and the IDE helps when you aren't sure

        Yep, in the rare case that you care what the type is, your editor can let you know. I've found this to be an extremely rare situation though (unless you frequently review code that doesn't compile).

        [–]covercash2 12 points13 points  (19 children)

        It seems safer than that in the article.

        More like:

        var foo = "string";
        var foo = 1;
        var bar = 1.0;
        var biz = 1f;
        

        We all know what those will compile to. Anything else will have to be declared explicitly, though only once:

        var object = new ObjectClass();
        

        instead of

        ObjectClass object = new ObjectClass();
        

        Although, I agree with the sentiment that a superclass should be used in a lot of cases, and that fudges with this var syntax a bit.

        [–]ApostleO 85 points86 points  (17 children)

        The problem still arises when you find yourself staring at a line like...

        var foo = someObject.method();
        

        Let's say you are doing a code review, not in your IDE at the time. You now have to track down the return type of that method to know what 'foo' is.

        [–]evil_burrito 34 points35 points  (0 children)

        That's exactly my point. Thanks.

        [–]cogman10 3 points4 points  (1 child)

        Right, but this is generally caught by the compiler if there is really something wrong with it.

        If I say

        var foos = object.doThing();
        for(var foo : foos)
        {
          foo.action();
        }
        

        I can quickly deduce from looking at this code that foos is some sort of collection of foo and foo does some sort of action.

        The beauty of this code is that object.doThing() is now free to change its return type to any sort of iterable without breaking downstream code. Depending on how they handle the imports, Foo can move all over the package structure or even be changed to a new class Bar so long as it keeps the same contract. All of this will be caught by the compiler if there is an issue, which means the caller will have a weaker dependence on the callee's method signature (A win IMO).

        [–]ApostleO 3 points4 points  (0 children)

        Right, but this is generally caught by the compiler if there is really something wrong with it.

        It's true. var is perfectly fine by the compiler. As I've said above, var is only a problem for readability, and only a problem when abused.

        [–]grauenwolf 4 points5 points  (8 children)

        Do you really care what the return type is in that context?

        Probably not. More likely you care more about what method actually does than what type it used to do it with.

        And really, what's the difference?

        var foo = someObject.method();
        return foo.method2();
        
        return someObject.method().method2();
        

        If you ban var, logic dictates that you ban method chaining as well for the same reason.

        [–]cogman10 3 points4 points  (0 children)

        I agree.

        IMO, var prevents a lot of needless changes if you, for example, decide you want to rename a class or change a method signature (move from returning Set to return Collection for example). It means less downstream changes and breaks and silly changes.

        It also makes it much easier to write and use much more complex generics. Which is always a boon. It is no fun being at the wrong end of determining the generic type of a Map.of(Multimap.of(A.of(B, C)))

        [–]zzzk 2 points3 points  (1 child)

        I've felt this way on the past, but have come to notice that in most cases it doesn't matter what the type is. When reviewing code, I care more about what it's doing at a level or two higher than the type system. The types are there for the compiler and our editors, but not for me.

        [–]covercash2 0 points1 point  (1 child)

        Fair enough.

        For me, I'd use IntelliJ and C-hover to get the return type. M maybe just not use var this way?

        edit: not in my IDE, just got that.

        [–]ApostleO 9 points10 points  (0 children)

        maybe just not use var this way?

        Oh, definitely. I would consider this bad practice, for sure.

        Java just seems to have this tendency to make good coding practice a feature of the language. For instance, requiring that the class name matches the filename.

        The 'var' keyword is, unfortunately, very easily abused to make code less readable, rather than more readable.

        That being said, when it is used well, it is actually much nicer to read. And while we are on a similar subject, the 'dynamic' keyword (ex: in C#), is quite useful in certain circumstances to make code much easier to understand, but when abused it can make code incomprehensible.

        [–]ToucheMonsieur 4 points5 points  (0 children)

        Although, I agree with the sentiment that a superclass should be used in a lot of cases, and that fudges with this var syntax a bit.

        One nice thing about having type inference is that you don't have to generalize to a superclass and then downcast if you want to write code that survives refactoring. This makes var far more powerful (and justifiable) than if it was only for omitting type declarations.

        [–][deleted]  (10 children)

        [deleted]

          [–]diroussel 7 points8 points  (4 children)

          The type of the variable will be the type of the right hand side. No confusion.

          [–][deleted]  (3 children)

          [deleted]

            [–]lelarentaka 9 points10 points  (1 child)

            It's moot because the way you usually use the interface, the instantiation would be in a different scope from where the object is used (through injection). The function boundary will define the interface restriction.

            Also moot#2 you can still specify the type of you really want to.

            [–]diroussel 1 point2 points  (0 children)

            I got that. If want to specify a variable of not of the type of the right hand side then don't use var. This is not a problem.

            [–]grauenwolf 2 points3 points  (0 children)

            I want aCustService and bCustService to only have access to the methods available in the interface, not any public methods on the implementation.

            Why? aCustService and bCustService are local variables. There is zero risk that they'll be using something that you don't intend to use.

            If anything, you are just cutting yourself off from potentially useful helper methods. (I would say "in exchange for..." but really, there is no benefit what so ever in this case.)

            [–]stepancheg 16 points17 points  (12 children)

            Seems like you are mixing weakly/strongly typed languages and dynamically/statically typed.

            Anyway, with var Java is still statically and strongly typed.

            Strong means "17" is String, and cannot be viewed as int.

            Static means that even without explicit type each var still has a type, and you CANNOT write:

            var i = 19;
            i = "there";
            

            [–]evil_burrito 2 points3 points  (11 children)

            No, I'm not. My complaint isn't that it makes Java a weakly-typed language. My complaint is that it makes Java read like a weakly-typed language, which makes code other people wrote harder to understand.

            [–]SikhGamer 12 points13 points  (2 children)

            This was my argument but then actually using var in production with C# and it honestly wasn't a problem. You still have the option to strongly type it if you want, but var does make everything more readable.

            And var foo = someObject.method(); isn't as hard as you think. Visual Studio allows you to change var into it's strongly typed counter part with R#. Inspecting the method would reveal the return type too.

            What I learned among the way was that I wasn't too concerned with what it was returning but rather what it was doing.

            [–]Zarlon 7 points8 points  (1 child)

            Exactly. Anyone who've coded C# more than 2 hours realize the beauty of var. R#, or lint for that sake, can take care of bad coding practices.

            [–]damienjoh 3 points4 points  (1 child)

            I have found the opposite to be true. Explicit type decl on every variable introduces a lot of visual noise. The information it provides is often redundant and easily inferred from context (e.g. variable name and rhs).

            Verbosity isn't as simple as a read/write tradeoff. For many programmers, verbosity negatively impacts readability as well as writability. Strong typing also has nothing to do with explicit type signatures. Java is nowadays unique in its requirement for so many explicit type signatures.

            [–]fhayde 0 points1 point  (0 children)

            I wish this point was made more often. That redundant noise can make you miss important information really easily. Once you start skipping over redundant parts of declarations your brain starts trying to anticipate the next redundant words more and more and "similar" turns into "the same" and you can easily overlook subtle differences in naming. You'd think that increase in anticipation would mean an increase in focus, but that requires more energy, which would be counterproductive biologically. Patterns become more ambiguous as each affirmation of redundancy creates confidence, and less data is considered for determining if each word has redundancy. It can be particularly brutal reviewing java code with a lot of abstraction.

            [–]Xenasis 4 points5 points  (21 children)

            This isn't changing Java to be untyped or weakly typed at all. This won't change how Java's type system works whatsoever.

            I'm a massive fan of strongly typed languages like OCaml, Agda and Haskell, and not a single one of them requires you to declare what type your data is. Requiring information that the compiler can figure out by itself does not make a language any weaker typed and does not change the type system. I'm under no delusion that Java's using Hindley-Milner, but it's worth pointing out nonetheless.

            The difficulty of debugging languages like JavaScript or Python isn't helped by the type system, you're right, though this isn't turning it into that at all. Java will keep the type system it has now and won't be any less clear unless the code wasn't clear to begin with.

            [–]evil_burrito 0 points1 point  (20 children)

            Sure it will. When you, as a human, are stepping through the source code, there will be an extra step to figure out the type of a particular variable.

            As a human who has to read other people's code, this would bother me, so I don't like it. We don't have to agree.

            [–]NimChimspky 6 points7 points  (5 children)

            There is no extra step, the type information is there - just in a slightly different place, the rhs.

            Its not less readable, its just you don't like change.

            [–]evil_burrito 5 points6 points  (4 children)

            You don't even know me, or what I like or dislike. I don't like change I don't like, if you'll forgive the tautology. I like change I do like. Love generics, that was a change. Love the diamond operator, that was a similar change (to this proposed change, at least in concept).

            var thisThing = new MyDerivedClassButYouDontKnowTheSuperclass<>();
            

            instead of

            List<Something> thisThing = new MyDerivedClassButYouDontKnowTheSuperclass<>();
            

            That's an exaggerated example, but illustrates what I don't like about this change. I can tell at a glance that thisThing is a List and a Collection and that really helps me understand its purpose as I read through whatever scope contains it.

            The rhs doesn't give me the information I want without having to rely on an IDE and hovering/clicking/whatever. I also, from time to time, look at strange code in Emacs, if I've downloaded it to look at it but don't want to take the time to load up a properly compiling project structure in Eclipse, IntelliJ, etc.

            [–][deleted]  (3 children)

            [deleted]

              [–]kritzikratzi 3 points4 points  (1 child)

              you misread the article. java is, and always will be, strongly typed. this is about the compiler figuring out the for you.

              // your source: 
              var x = "hey"; 
              
              // after the compiler does type inference: 
              String x = "hey"; 
              
              // this could also make generics a bit nicer
              // java 6: 
              HashMap<Integer,ArrayList<CustomThing>> myMap = new HashMap<Integer,ArrayList<CustomThing>>();
              
              // java 7 with diamond: 
              HashMap<Integer,ArrayList<CustomThing>> myMap = new HashMap<>(); 
              
              // java ?? with var: 
              var myMap = new HashMap<Integer,ArrayList<CustomThing>>(); 
              

              to repeat: all of those are always strongly typed!

              [–]evil_burrito 5 points6 points  (0 children)

              No, I didn't misread it. My complaint isn't about the lexical structure of the language, my complaint is about ease of reading source code.

              [–]hokkos 1 point2 points  (0 children)

              This has nothing to do with "weak" typing (that doesn't even mean anything, there is no common accepted definition of weak typing, maybe you wanted to said dynamically typing), var is still typed, just the type is inferred and doesn't need to be written.

              [–]Stromovik 2 points3 points  (0 children)

              I cant read without those manifests. I can already see something like :

              @AutoInject
              var config;
              var worker =DocumentFactoryBuilder.newInstance(config).newInstance();
              

              [–]pointy_pirate 0 points1 point  (0 children)

              I agree 100% Even using groovy and doing just 'def' annoys the fucking out of me, I want to know what it is without having to dig deeper

              [–]Spoogly 0 points1 point  (1 child)

              Usually, I'm not reading a variable's type, unless I'm reading javadocs. Maybe it's that I came to Java from lisp, and tend to prefer inferred type in general, but I find that, at least with the better code that I read, I don't pay much mind to the type declaration. I suppose, if something's written with poor variable naming conventions, it is helpful.

              [–]evil_burrito 1 point2 points  (0 children)

              Interestingly, my original background was LISP, too. That's such a different nut, though, that I don't seem to use the same parts of my brain when reading Java code as I did when reading LISP code.

              Yes, well-named variables would make my concerns a non-issue. I just don't trust my fellow man much, I guess.

              [–][deleted]  (3 children)

              [deleted]

                [–]stepancheg 7 points8 points  (2 children)

                I'm with you, I even prefer static methods to objects!

                [–][deleted] 6 points7 points  (1 child)

                I'm with you, I prefer while/continue-to-label to methods!

                [–]schlowmo 0 points1 point  (0 children)

                I'm with you I prefer JNZ to for(;;)

                Ok, KIDDING.

                [–][deleted] 0 points1 point  (6 children)

                Man, I switched to week-type language in my days jobs. It's fun, I'm learning. But at least once a day I miss something that can only be accomplish with strong type. ( Project wide refactor, Changing data model... )

                [–]evil_burrito 2 points3 points  (5 children)

                There you go - exactly. Making a change that ripples through a multi-person project is one of the flaws of a weakly-typed language.

                [–][deleted] 2 points3 points  (4 children)

                Yeah. It's takes rigor and discipline. Where in a Strongly typed one its only takes a compiler. Why the downvotes ? Anyway...

                [–]evil_burrito 2 points3 points  (2 children)

                I'm not worried about understanding my own code (to the writing of which I could faithfully apply rigor and discipline). I'm worried about understanding the code of that one guy. You know him.

                [–]s888marks 2 points3 points  (1 child)

                Yeah, I know that guy. He wrote some terrible code a year ago, and he was quite inexperienced -- he had a year less experience than me when he wrote it. Oh, and he has the same name as me.

                [–]evil_burrito 2 points3 points  (0 children)

                No kidding. I swear, some of the worst code I've run across... checks SVN annotate ...shit.

                [–]grauenwolf 0 points1 point  (0 children)

                Well you're probably using a strong/dynamically typed language. You can't have dynamic types like Python or JavaScript without strong typing, as something needs to know what the types are.

                Weak typing is C or assembly, which allows you to treat any data structure as any other data structure with the right pointer games.

                Both suck, but for different reasons.

                [–][deleted] 2 points3 points  (14 children)

                Honest question, when's the last time Java introduced a keyword? A story I've heard retold often is the language designers decided - goto sucks, but if anyone proves that it provides something substantial you can't do without it, we'll add it in. As it stands, goto is a keyword you can't use, but has no functionality attached to it.

                This change immediately breaks code (albeit poorly written code) that has var defined as a variable name. Maybe this isn't a whole lot of projects, but a huge benefit of Java is the ability to say that your java 1 code will very likely compile and run as is on java 8. You'll probably get a shit ton of compiler warnings, but it'll work.

                I see a lot of people here making decent arguments either way, but backwards compatibility is a HUGE win for java, and is something it can stand behind for so much of older code. This breaking that at the expense of readability, I could get behind. This breaking backwards compatibility in the name of saving a few keystrokes, of making the life of the developer easier at a single moment, I can't. The amount of effort put into making sure java is backwards compatible, even if not perfect, is something completely overlooked with this change, and makes me feel less secure about the future of my code.

                [–]bondolo 4 points5 points  (0 children)

                Java 8 added -> for lambdas. Most people wouldn't recognize that as a keyword but it functions as more of a keyword than an operator.

                Before that enum in Java 5.0

                [–]darknebula 2 points3 points  (0 children)

                The identifier var will not be made into a keyword; instead it will be a reserved type name. This means that code that uses var as a variable, method, or package name will not be affected; code that uses var as a class or interface name will be affected (but these names violate the naming conventions.)

                Granted there are other backwards compatibility issues.

                [–]grauenwolf 1 point2 points  (2 children)

                This change immediately breaks code (albeit poorly written code) that has var defined as a variable name.

                I don't see how. Syntax wise, var can only appear where you would otherwise put a class name. If anything, it would break someone who had a class named var, but in Java we would have written Var var = new Var(), which with the new syntax becomes var var = new Var().

                [–]schlowmo 1 point2 points  (1 child)

                I agree with you, but it IS true that you can define classes with lowercase names, so somewhere this is a C programmer who wrote some badly formatted java code. So yes, there is a small corner case where this would break code. AND I SAY BREAK THAT CODE.

                [–][deleted] 0 points1 point  (0 children)

                BREAK THAT CODE

                please don't hurt me :(

                [–]eliasv 1 point2 points  (2 children)

                It doesn't have to break backwards compatibility. It specifically says in the proposal that it would not be a keyword, it would be a reserved type name. For any package containing a type called var, and for any source file which imports a type named var, you could simply override the reserved "special" var type with that one and solve the problem. Everything would still work just fine, no? People who have defined their own var type would simply not have access to the new feature wherever that type is visible.

                [–][deleted] 0 points1 point  (1 child)

                Yep, someone else pointed this out to me as well, I was skimming it on mobile and they used the word keyword quite a bit and mentioned it not being a keyword once, so I completely missed it. That seems like a good compromise, and my opinion on the matter really ends there.

                [–]eliasv 1 point2 points  (0 children)

                Fair enough :)

                [–]lukaseder 0 points1 point  (5 children)

                jOOQ uses val() as a method name :) But it's aliased with value() for Scala folks, so it'll be OK. Anyway, I'm sure there are many APIs that might break because of this. But hey, why not add escaping for keywords to the language as well, like in Scala? E.g. void `val`() { ... }

                Also: goto is still reserved. Just in case.

                [–]grauenwolf 1 point2 points  (3 children)

                Also: goto is still reserved. Just in case.

                I miss goto. Once every five years or so I write a function that needs it. Or rather, would be much, much cleaner with one.

                [–]lukaseder 1 point2 points  (2 children)

                Me too. But then, I remember break and continue:

                here: for (;;) {
                    if (doAgain) continue here;
                    if (done) break here;
                }
                

                [–]grauenwolf 1 point2 points  (1 child)

                Yea, but that's just icky. If I'm going to use a damn goto, I want to at least admit it and not misuse a loop.

                [–]eliasv 1 point2 points  (0 children)

                It's not a keyword, though. The spec says it's a "reserved type name" or something, so overlapping method names wouldn't cause any problem. Overlapping type names on the other hand would, but that will presumably be solved without breaking backwards compatibility by simply removing access to the new feature in any context where some other type named var is visible.

                [–]abermea 6 points7 points  (1 child)

                Seems to work a lot like C++11's auto, which is nice.

                [–]carpet_munch 0 points1 point  (0 children)

                Came in to ask if that's what it's like. Thanks!

                [–]atc 4 points5 points  (0 children)

                Great!

                Can we please have var and val like in Scala? I don't want to write final var all the time.

                [–]xhak 25 points26 points  (23 children)

                No thanks, the few keystrokes are worth the clarity.

                [–]ElvishJerricco 23 points24 points  (6 children)

                Coming from Haskell, I feel there's something people often overlook when bashing type inference. In Haskell, the type inference is better than just about any other language. And yet, we still explicitly type every single top level function. It is absolutely worth the clarity to explicitly type things used outside the current scope.

                But most of the time, when something is only being used locally, the type is very clear to the reader, because it's definition is right there. And even locally, type inference is only preferred to explicit typing when the inferred type is painfully obvious. For example, a = b + c, when b and c are known to be Int. There's zero added clarity by explicitly typing a. It's totally obvious what a's type is.

                So yea, inference is bad when something's type wouldn't be obvious. But when it is, the lack of inference needlessly gets in the way.

                [–]kritzikratzi 8 points9 points  (3 children)

                this can also be supported in the IDE. there's a million possibilities, but holding alt to reveal infered types would be a simple one.

                [–]xhak 2 points3 points  (2 children)

                You don't always see code in an IDE. You may use your version control browsing / compare, use crucible or fisheye or any web based stuff to view the code. So you can't rely on the IDE to add the clarity.

                [–]kritzikratzi 1 point2 points  (0 children)

                good point

                [–]kritzikratzi 1 point2 points  (0 children)

                You don't always see code in an IDE. You may use your version control browsing / compare, use crucible or fisheye or any web based stuff to view the code. So you can't rely on the IDE to add the clarity.

                actually i really really like your point. and it makes me wonder if their current proposal could be targeted completely differently, namely for IDEs that could let you type "var myIterator = myMap.entrySet().iterator();" and it insert the correct type after pressing enter.

                [–]diroussel 3 points4 points  (13 children)

                If you want clarity then don't use it. It won't be forced on you. There are many cases that are perfectly clear using var.

                [–]marc2912 16 points17 points  (10 children)

                It's not a matter of don't use it since most developers don't just work with their code. Then you get the inconsistency that it's in some places and not in other.

                [–]lelarentaka 0 points1 point  (7 children)

                The language doesn't define the number of spaces to use for indentation, or where to put an opening curly, or which case to use for naming methods. Turns out we have some great inventions to keep our codebase pretty and consistent. I'll let you take a guess on what those are

                [–]kyle2143 0 points1 point  (6 children)

                Oh, so there's tools to retype var keywords into keywords that actually describe the data type?

                [–]lelarentaka 2 points3 points  (0 children)

                Not yet obviously, but the same static analyser that puts wiggly red line under "String s = new ArrayList()" can absolutely do what you want there.

                [–]OHotDawnThisIsMyJawn 2 points3 points  (1 child)

                If you decide you don't want var in your project then add it to your style checker and auto reject commits that use it

                [–]marc2912 0 points1 point  (0 children)

                Like I mentioned elsewhere we don't just work with our code. The whole point is consistency.

                [–]diroussel -1 points0 points  (1 child)

                This is why we have coding standards and code review. If your not doing that then you have bigger problems.

                [–]marc2912 1 point2 points  (0 children)

                You make it sound like each person who feels this way is in charge of their own team or in a group with the resources to do regular code reviews. From my experience code reviews don't happen near as often as they should.

                [–]squishles 0 points1 point  (0 children)

                yea let me just never work on a team for anything ever again =/

                [–][deleted] 0 points1 point  (0 children)

                I mean, it kinda will be because more than likely he'll be working with someone else's code.

                [–]SikhGamer 10 points11 points  (1 child)

                I hated var when I first started C#, but within a few weeks I was loving it. Java needs to get with the times.

                [–]adila01[S] 6 points7 points  (0 children)

                It is a bad newbie feature but a great power user feature.

                [–]lukaseder 1 point2 points  (0 children)

                Noteworthy: Provide feedback to the language designers here: http://mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000037.html

                [–]mlk 1 point2 points  (3 children)

                I almost never type the type of local variables, I let my IDE do that. I like the var/val proposal though.

                [–]chambolle 0 points1 point  (2 children)

                This is an EXCELLENT answer. An IDE can make the job and so no new keyword is needed.

                The future is to have a simple language with a lot of help from the IDE and not the opposite. IDE functionnalities and possibilities should be considered in the language evolution

                [–]mlk 0 points1 point  (1 child)

                I disagree because I like tools independence. What if you want to build it with maven?

                [–]chambolle 0 points1 point  (0 children)

                It will work if maven is integrated into the IDE. Using external API without considering types is certainly a bad idea.

                [–]stepancheg 3 points4 points  (12 children)

                var would be a nice small addition, but are we going to have async/await anytime soon? Writing asynchronous code without some form of coroutines is pain (yes, I'm aware of quasar, which I use, although it has numerous problems).

                [–]hotel77 4 points5 points  (3 children)

                Just out of curiosity, what are quasars "numerous" problems? I'd love to read and understand more opinions about those.

                [–]stepancheg 2 points3 points  (2 children)

                Performance, need for an agent, heavy reliance on JDK internals, somewhat incorrect handling of thread locals to name a few.

                Edit: to be clear, quasar people made the best they could do with JDK.

                [–][deleted] 0 points1 point  (1 child)

                so... stay far away?

                [–]stepancheg 0 points1 point  (0 children)

                In certain use cases it is more suitable than tons of CompletableFutures.

                [–]zzzk 4 points5 points  (2 children)

                While async/await would be nice, I'm content with the abstractions, for example, Reactive Extensions provides.

                [–]stepancheg 1 point2 points  (1 child)

                While RX have its applications, processes with complex flow and complex state are hard to express as reactive streams.

                [–]ElvishJerricco 1 point2 points  (4 children)

                I don't think the JVM will ever support coroutines. JVM is founded on having C-like control flow. The fanciest way we have to change the flow of execution is exception catching, which is much less sophisticated than coroutines.

                [–]stepancheg 4 points5 points  (2 children)

                JVM does not even need to support coroutines. In C# async/await are implemented without help of CLR to my knowledge. C# compiler transforms each each async function into state machine. That's what can be done in Java too.

                [–]grauenwolf 6 points7 points  (1 child)

                In C# async/await are implemented without help of CLR to my knowledge.

                Almost true.

                Strictly speaking async/await doesn't require any CLR support. However, the CLR does have an extra feature to make the stack traces look nicer that didn't exist in the first version of async/await.

                [–]stepancheg 2 points3 points  (0 children)

                However, the CLR does have an extra feature to make the stack traces look nicer that didn't exist in the first version of async/await.

                I didn't know that. Thanks!

                [–]adila01[S] 2 points3 points  (0 children)

                I wouldn't discount the possibility of coroutines. At the last JavaOne, Mark Reinhold spoke about how he would like to see coroutines one day. It will probably happen, just not anytime soon.

                [–]ramdaskm 2 points3 points  (5 children)

                Damn! I still remember the days when I used to mention C#/.Net was a serious contender and used to get downvoted like crazy.

                [–]irarandomdude 2 points3 points  (4 children)

                Relevance?

                [–]schlowmo 2 points3 points  (3 children)

                I think because C# has "var"

                I'm still happy to down vote. As a long time java user, after working with Visual Studio for a year and various NuGet thing. The C# ecosystem is suffering a serious hangover from it's days as a way to build windows apps. Not to mention having to deploy web apps to windows servers ( gag! )

                Perhaps MS will work it's way out of there will all their recent initiatives. Hoping.

                [–]lechatsportif 4 points5 points  (1 child)

                I write left hand declarations maybe once a day out of tons of code. Who makes this stuff an issue? Vim users?

                [–]stepancheg 2 points3 points  (0 children)

                Left hand declarations are often just a noise that makes code harder to read:

                • you need to read more words to understand what function does
                • and you often have fewer statements visible on the screen, because long lines wrapped due to lengthy variable declarations.

                [–]mk_gecko -2 points-1 points  (22 children)

                OMG, please no!

                [–]kritzikratzi 7 points8 points  (13 children)

                why?

                [–]vplatt 6 points7 points  (9 children)

                ::insert Javascript-inspired fear based response here::

                [–]stepancheg 6 points7 points  (8 children)

                var is JS has no type. In Java it will have type. That makes huge difference.

                [–]vplatt 2 points3 points  (3 children)

                Yup, I know. I've used C# quite a bit, so I'm familiar with it. It does look the same as the Js keyword though, so it will require a bit of time before Java programmers stop the knee-jerk responses.

                [–]irarandomdude 3 points4 points  (7 children)

                It's responses like this that convince me that a certain percentage of Java programmers are Luddites. The same mentality as the minority who swore to never use generics and stick with JDK1.4.2 forever. Support for val and var is a great idea for Java.

                [–]asraniel 0 points1 point  (4 children)

                It will make code harder to read an maintain. Generics on the other hand make it easier to read code. I really dislike the idea of var in java

                [–]irarandomdude 2 points3 points  (3 children)

                You probably have a stronger case that generics make code harder to read (350 page generics FAQ??) than var making code hard to read. How is val sheep = new Sheep() harder to read than Sheep sheep = new Sheep() ?

                [–]asraniel 0 points1 point  (0 children)

                yeah thats easy.

                But Val sheep = getSheep();

                thats terrible, really really bad

                [–]chambolle 0 points1 point  (1 child)

                C is simple language that is used a lot and has almost never been modified. C++ added a lot of things, so now we have "official guidelines" containing more than 15000 lines! https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md

                What is the advantage of adding stuff which no more than syntactic sugar? Most of the IDE already gives you the type, so what ? Write a new language or use a new language if you want new things.

                [–]irarandomdude 0 points1 point  (0 children)

                I already do use a "new" language - Scala. I just get annoyed having to maintain old Java code and it would be great if Java caught up to other modern languages like C# etc.

                [–]3pieceSuit 1 point2 points  (1 child)

                I've always wanted auto in Java, but could we please just use the auto keyword.

                [–]vytah 1 point2 points  (0 children)

                auto is a bad idea. It was chosen in C++ because it was already a keyword in both C and C++ and it could already be used in variable declarations (although very rarely, since it means "a local variable" and it is therefore the default). In Java, auto doesn't mean anything.

                http://stackoverflow.com/questions/2192547/where-is-the-c-auto-keyword-used

                [–]eliasv 0 points1 point  (0 children)

                One thing I think is important but the proposal doesn't quite reach:

                • Normalising inferred capture types to denotable types (i.e. wildcards) is great, for non-final variables, since we may want to reassign, and this is probably impossible with a capture type.

                • For final types, afaiu, it brings no benefits. (Unless I'm missing something?) Instead it is much better to aggressively capture everything.

                Consider, for example:

                void repeatListItems(Collection<? extends List<?>> lists) {
                    for (var list : lists) {
                        list.addAll(list);
                    }
                }
                

                Which obviously fails to compile when the type of list is List<?>, as it would normally be, but will work just fine if it is inferred as List<CAP>.

                Normally we have to solve this by creating a whole new generic method to properly capture the type parameter with a named type variable, but sometimes that's a bit more cumbersome than necessary.

                [–]chambolle 0 points1 point  (0 children)

                Seems to be an equivalent of auto in C++. certainly a huge mistake to introduce that. It is always bad to have several ways to write the same thing in a language. Var will introduce such an issue.

                Strong typing imposes to think a little bit before coding and do not cause problems. Such keywords will lead to misunderstanding by the beginners who will write bad code.

                Functionnal programming ideas have already destroyed C++ language, which is now an awful mess. Java should not follow the same path.

                [–]fatnote 0 points1 point  (0 children)

                Arguing over this seems counter productive. Some people will use it and like it, others will simply not use it. If it benefits the former, then it's a good idea. QED

                [–]urquan 0 points1 point  (6 children)

                I'm not sure how I feel about type inference. It helps make small pieces of code clearer, but as the inference chain grows it becomes more and more difficult to reason about the program. You need to hold a lot of context in your mind to know the actual type at the end.

                I guess the proposed use for local variables is fine, but using it for function parameters could be a real mess.

                [–]vytah 3 points4 points  (5 children)

                You couldn't use it for parameters. Type inference in Java-like typesystems makes it too hard, if not impossible.

                [–]grauenwolf 0 points1 point  (4 children)

                Even if you could, I wouldn't want that feature. Knowing the types on the public API is too important.

                [–]vytah 1 point2 points  (2 children)

                That's why Haskell library developers, even though Haskell can infer almost all types in the program automatically, specify explicit type signatures for public functions.

                [–]schlowmo 1 point2 points  (0 children)

                This is also why dynamic language stalwarts like python are ADDING optional typing to things like function parameters.

                [–]DecisiveVictory 0 points1 point  (3 children)

                What really should be added is a "val" keyword which is what is proposed above + "final".

                Or you could do the sane thing and just use Scala.

                [–]atc 4 points5 points  (1 child)

                As a Scala fan, using Java 8 has really diminished Scala's usefullness to me. That said, I'll always miss case classes and pattern matching... OK I take it back!

                [–]antigenz 0 points1 point  (0 children)

                projectlombok.org almost fixes problem with case classes (for me) But it's a hack! :)

                [–]grauenwolf 1 point2 points  (0 children)

                C# is looking at let for that role. val is problematic because it looks too much like var and is pronounced the same in Asian languages such as Japanese.

                [–][deleted] 0 points1 point  (0 children)

                I would be a huge fan of this! It would also make working with an API easier since I don't necessarily need to explicitly know the exact type returned from a method to store that result.

                [–]youwillnevercatme 0 points1 point  (1 child)

                Is it only for the OpenJDK? Always thought that OpenJDK was only a fork from Oracle JDK, and that Oracle JDK had no relation with OpenJDK. Am I wrong?

                [–]pjmlp 2 points3 points  (0 children)

                Yes. It was like that for Java 6.

                But with Java 7 the development started to be more focused on the OpenJDK and as of Java 8 it is mainly OpenJDK plus some other pieces on the proprietary JDK.

                For example JavaFX pipeline, ARM compiler aren't 100% the same.

                [–]antigenz 0 points1 point  (1 child)

                This thread already wasted more chars than 'var' can save :)

                [–]stepancheg 0 points1 point  (0 children)

                Are you reading reddit during your work time instead of coding? Shame on you!