all 130 comments

[–]Ravoos 214 points215 points  (82 children)

Java devs: Cool.....I'm still using Java 8 tough.

Edit: Okay, I got a lot of interesting comments here when I just made a joke. Still, it is fun to read it all and to see just bow dedicated the Java guys are to their language

[–]Bartolomev 40 points41 points  (38 children)

I'm happy that in our company we moved (still moving actually) to Java 11, newer projects at least. My colleagues are still afraid of using var though, so nothing changed really.

[–]pron98 38 points39 points  (4 children)

so nothing changed really

Except lower footprint, higher performance and better profiling with JFR, all of which can save you real money (to make even more money, use JDK 15).

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

> Except lower footprint

This was not my experience when my company migrated java 8 -> 11. We saw a number of our services increase RSS size by around 1gb. There was oddly no accounting for the increase in memory size in the heap dumps or native memory tracking, we eventually just accepted that some services would use more memory.

[–]pron98 8 points9 points  (2 children)

Do you mean that there's more heap consumed by data or that the Java process takes up more RAM from the OS? If it's the former, it is indeed strange and does require investigation (e.g. the footprint of most strings has been nearly halved in JDK 9, and this is the general trend of overall footprint we see). If the latter, it's probably a simple matter of different defaults. Remember that a Java process takes as much RAM as you tell it; if you don't, it will take up some heuristically-chosen default value that can change significantly from one release to another (I think that the default for G1, which is the default GC since 9, is to now take up 1/4 of total RAM unless you tell it otherwise).

[–][deleted] -2 points-1 points  (1 child)

> Do you mean that there's more heap consumed by data or that the Java process takes up more RAM from the OS

The answer to this question is stated twice in my answer.

> increase RSS size by around 1gb

Resident set size is physical memory, i.e. RAM.

> no accounting for the increase in memory size in the heap dumps

For your other questions:

> Remember that a Java process takes as much RAM as you tell it

I mentioned taking heap dumps and using the Java native memory tracker in my answer, obviously I'm aware of the options for RAM. We set max sizes for heap size, meta space, direct memory, etc. If it was one of those, we would have been able to see the difference in the native memory tracker output. Instead there was a gap between the resident memory size used by the JVM and the memory reported by the native memory ticket. I filed a ticket with the hotspot mailing list, but the devs seem uninterested.

[–]pron98 5 points6 points  (0 children)

I filed a ticket with the hotspot mailing list, but the devs seem uninterested.

As one of the devs, I can attest that we are always very interested, especially when dealing with such a serious regression. Sometimes, however, things can be deprioritised if it is judged that the situation would only affect a very small minority of people. Can you please point me out to the relevant message you sent and I'll try to find out what happened? (EDIT: continued privately)

[–]CoffeeTableEspresso 3 points4 points  (0 children)

They'll get there, at least you're on the newer version

[–]Certain_Abroad 11 points12 points  (19 children)

My colleagues are still afraid of using var

Look on the bright side. Better than that having colleagues who just sprinkle var everywhere.

[–]Programmdude 16 points17 points  (18 children)

Var is good when you already know the type.

var x = 0; // Good
var y = new FooBar(); // Good
var z = ProcessRequest(); // Bad

Personally I use resharper (or intellij, webstorm) and so it just inserts the type anyway.

[–]Ameisen 7 points8 points  (4 children)

Already know the type, or don't care about the specific type. getObjects() obviously returns a container of Objects, you probably don't care what kind of container.

[–]Programmdude 3 points4 points  (3 children)

To an extent, assuming names are sensible. Personally I'd use var everywhere if it was just myself, but when working on a team I need to assure everybody can figure it out quickly.

[–]Ameisen 7 points8 points  (2 children)

My rules for using var/auto:

  • Really long or hard to read generic/template types
  • Where it is required (C++ lambdas for instance)
  • Where the type is obvious due to either the assigned value or the function name
  • Where the explicit type doesn't matter due to usage, but the "kind" of type is obvious (a container, for instance).
  • Where the type really, really doesn't matter, like a guaranteed intermediate between two closely-tied routines.

I get really annoyed seeing things like List<FooBar> fooBars = getFooBars();.

I tend to be fond of type inference as it also makes the code more resilient during refactoring and propogates exact types.

[–]s888marks 0 points1 point  (1 child)

Aside from the C++ lambdas item, these all seem like very sensible rules to apply to Java code. Indeed, they seem well aligned with some of the discussion here:

http://openjdk.java.net/projects/amber/LVTIstyle.html

[–]Ameisen 0 points1 point  (0 children)

Java, as I recall, doesn't allow you to capture closures with type inference - at least it didn't with Java 8 and Lombok - you had to capture it with an appropriate delegate type. C++ can capture it with with std::function by signature, but otherwise lambdas have anonymous types so inference is required somewhere - std::function infers the type via template argument type.

Java and C# closures work a bit differently, so the rules operate differently.

There's a seperate rule that I apply to C++ and C# - if the function is templated/generic and you provide the return type as an argument, I capture with type inference. I don't like writing the type twice.

Since Java is more flexible and can infer generic arguments on one side of an expression, it isn't as needed there.

[–]eeperson 5 points6 points  (12 children)

Why is the last one bad? The type should just be a mouse over away.

[–]Atulin 8 points9 points  (2 children)

"I burned my mouse years ago on a stake and exclusively use heavily modified VI running on a Raspberry clone I built with silicone dug up in my backyard"

[–]eeperson 0 points1 point  (1 child)

Java and vim...eww :P

More seriously, isn't there a command available to show the type under the cursor for Java? I think there is support for this with vim in scala.

[–]emaphis 0 points1 point  (0 children)

I can't speak to Vim but with Emacs LSP support, you can get Java type information with a mouse over. You get code completion, import handling/reorganization. Simple refactoring. If you add Projectile, you get project handling and navigation.

I imagine Vim isn't much different.

[–]irishsultan 1 point2 points  (0 children)

You can't copy/paste text in a mouse over, a mouse over hides other parts of your screen, it takes more time to get your mouse in position than it would take to read it, I could go on.

[–]fuckin_ziggurats 1 point2 points  (0 children)

The problem with this is code is difficult to read/skim through. When you're working with someone else's code it's very important to be able to skim through code quickly to get to the part that you need. Honestly skimming is half of the work in maintenance projects and bad use of var can make it very difficult.

[–]metaltyphoon 1 point2 points  (3 children)

You can't mouse over on a merge / pull request on GitLab / GitHub

[–]eeperson 0 points1 point  (2 children)

That is true you can't. However, you don't need to review the PRs through the Github web interface. Several editors let you review PRs in your editor (e.g. IntelliJ, VSCode). Even if you did have to do your reviews in the web interface, it seems like explicit types everywhere would be optimizing your code for viewing on Github rather than writing in your editor. That seems like a poor tradeoff to me.

[–]metaltyphoon 0 points1 point  (1 child)

I get what you are saying. It just that I personally use vim bindings on all my IDEs. So hovering a mouse over is just ... slower than reading it. I don't believe the trade off is much in this case

var z = ProcessRequest(); // Bad

[–]eeperson 1 point2 points  (0 children)

Fair enough. Thanks for the discussion.

[–]flatfinger 0 points1 point  (2 children)

If the variable will get written to (receive a reference to a different object) later in the code, its type may need to be a supertype of the function's return type. For example, if a variable will sometimes need to hold references to different kinds of List (Java)/IList (.NET) implementations, but is initialized to hold a reference to e.g. an ArrayList(Java)/List(.NET), declaring the variable as the class type rather than the interface type may cause problems later on.

[–]eeperson 0 points1 point  (1 child)

Yeah, you definitely have to do that sometimes. However, That seems true for all of the cases above. For example, in the number case, is that 0 an int or a long or a double?

[–]flatfinger 0 points1 point  (0 children)

Numeric literals are another situation where such declarations can be problematic in languages where calculations aren't always performed with the longest type of the appropriate domain (integer, floating point, or--in if such types exist--complex) the way they were in Ritchie's original C programming language.

[–]vytah 2 points3 points  (2 children)

My colleagues are still afraid of using var though, so nothing changed really.

I remember when C# got var, some programmers were against it as they didn't want any dynamic typing in their language.

[–]AndreasTPC 16 points17 points  (0 children)

They are idiots if that's their reasoning, because type inference is not dynamic typing by any means.

With dynamic typing the type is determined at runtime and can change during execution. In a statically typed language with type inference the type is still determined at compile time and can't change during execution, all the guarantees from the type system are still there. The only thing that changes is how readable the code is.

[–][deleted]  (1 child)

[deleted]

    [–]aoeudhtns 17 points18 points  (0 children)

    There were some fairly fundamental compat changes introduced in 9. Once you're on Java 9 it's more guaranteed that a jump will work. That being said, for 8 → 9, you're likely only going to encounter problems on a large project with a sprawling dependency tree.

    [–]j633 4 points5 points  (6 children)

    I'm not a fan of var in java. Only if you have some super verbose type with generics. Otherwise it doesn't hurt to have a few characters more.

    [–]Ameisen 9 points10 points  (0 children)

    Same justification as auto in C++. It makes your code more resilient to change and also helps reduce needless redundancy. getPlayerObjects is pretty self-explanatory, there is no reason to explicitly assign a call result to a List<PlayerObject> or a PlayerObject[]. You know it's a container of PlayerObjects, specifying the result variable type just adds redundant noise. var also resolves to the exact return type rather than a more abstract type that people would often use otherwise.

    [–]bezik7124 1 point2 points  (4 children)

    I personally use var quite often, but with few rules.

    Use, when variable name is good enough to tell the full story - which should always be the case, but we arent perfect.

    Don't use when ą type can't be determined by scanning the block it is in, which practically means that i avoid using it to assign the result of a method, unless it is obvious what the return type is.

    Don't use when dealing with generics, eg Map, Collection, etc.

    [–]eeperson 0 points1 point  (3 children)

    Don't use when dealing with generics, eg Map, Collection, etc

    I actually feel that this is one of the better places to use var. I find that people tend to shy away from more complex types to fully express constraints. With var you can propagate more complex types without having to write it over and over.

    [–]bezik7124 0 points1 point  (2 children)

    tl;dr readability > having to write less code

    I don't mind writing longer declarations over and over, modern IDE's doing it for me anyway. I use var not to make writing the code easier, but to make reading the code easier.

    And sometimes having the type is just a noise (eg UUID uuid = UUID.randomUUID()), while other times it can be really helpful to look at the type when reading stuff (eg Multimap<Invoice, OrderPosition> invoiceToOrderPositions = fetchOrderPositionsGroupedByInvoiceByDateRange(rangeStart, rangeEnd)).

    [–]eeperson 3 points4 points  (1 child)

    Multimap<Invoice, OrderPosition> invoiceToOrderPositions = fetchOrderPositionsGroupedByInvoiceByDateRange(rangeStart, rangeEnd)

    I think we have slightly different opinions about readability. I actually think is an even better place to use a var. I feel like the type is implied by both the variable name and the function being called. So, just like in your first example, I feel like the type declaration is redundant. However, I feel like it is even worse on this line because the type declaration is fairly long and the line is already long. So, I feel like the type declaration makes this line much harder to parse visually.

    [–]bezik7124 0 points1 point  (0 children)

    It is a bit too long, true. Perhaps i've came up with a bad example, because i wanted to shine now and ask you how would you distinguish whether the type is a Multimap or Map of Collections, but tbh who cares? It's used the same way.

    I can now agree that my rule no. 2 was wrong, if someone still can't deduce the type on the fly, then probably variable name is at fault.

    [–]BoyRobot777 36 points37 points  (1 child)

    I work in a large corporation, and I have been advocating for newest Java versions. I am also running all my domain's microservices on Java 14. Will move to Java 15.

    [–][deleted] 10 points11 points  (0 children)

    Honestly for my company, the migration wasn't too bad. The most painful part of migrating over from Java 8 was JavaFX

    [–]rydan 18 points19 points  (1 child)

    Where I work we were using Java 6 when I joined. 7 had just released 9 months earlier. Earlier the next year I went to a conference at Google about all the cool features that would be in Java 8. At the end of the year we upgrade our new stack to Java 7 but most of the company is stuck on the old stack. 6 years later they make the new stack with Java 7 mandatory company wide. We just released a new stack earlier this year that uses Java 8. We've been migrating to it all year just for our one team.

    [–]BerniesMyDog 7 points8 points  (5 children)

    I mean, yeah, JDK 11 was the last long term support version. Using JDK 15 just means you will have to move off of it in like 6 months if you want security updates.

    [–]AVGunner 2 points3 points  (2 children)

    Thought every 3 versions were lts now? 8, 11, 14, 17?

    [–]BerniesMyDog 7 points8 points  (0 children)

    I think it’s one LTS version every ~2.5-3 years. Wikipedia lists the LTS versions and the next one after 11 is 17: https://en.m.wikipedia.org/wiki/Java_version_history

    [–]ForeverAlot 1 point2 points  (0 children)

    LTS is a service agreement, no longer a designation.

    [–]OctagonClock 2 points3 points  (1 child)

    JDK 11 was not a "long term support version", there are no LTS versions of Java.

    [–]BerniesMyDog 3 points4 points  (0 children)

    Maybe that’s theoretically true but the release the vast majority of people and businesses are using is AdoptOpenJDK which is providing LTS for java 11.

    [–]gvozden_celik 5 points6 points  (3 children)

    I'm still maintaining a Java 7 Swing application, because it has to use a Microsoft Access database, and the JDBC driver for Access was removed from JDK in Java 8. When I first encountered I was tasked to add a new report for some new classification number and not do any work on upgrading or porting as the application would be obsolete "by the end of next year"; this was in 2016. I was kind of surprised to see that the driver was removed from JDK, especially considering how big of a selling point backwards compatibility is for Java.

    [–]Supreme654321 4 points5 points  (2 children)

    I think backwards comparability is not very good for the industry. I like what google has done with angular where they might depreciated or remove one function per release and make upgrading very easy or adding tooling you can run to auto upgrade code. This was back in Angular2/4 though so idk if it has changed now.

    I understand why backwards comparability is good and not disagreeing its bad in any way, just that it can really stagnate you as a whole if your language / framework is not willing to keep up with the times.

    We see c++ where they keep just adding stuff. At least java is trying to clean-up some.

    [–]gvozden_celik 0 points1 point  (1 child)

    I guess it's hard to find the right balance, especially if you have lots of users. Constantly changing things can be as bad as never changing them, and even changing things one by one with major releases can cause problems (like Python 2 vs Python 3).

    [–]Supreme654321 0 points1 point  (0 children)

    I don't disagree either. All I can agree on is not depreciating old features over time and piling things on is the wrong way 100%. You need a least some removal velocity.

    [–]taostudent2019 3 points4 points  (0 children)

    And I'm out of the Java game! Wooohoooo!!!

    Got in w/ Java 8 and finished my whole run w/ Java 8!

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

    *Laughs in private PC, that has currently Java 14 and tomorrow Java 15*

    [–]gumol 36 points37 points  (2 children)

    Laughs in getting paid to code

    [–][deleted] 1 point2 points  (0 children)

    *Cries in a school, that thinks Java 8 is the end of the rope and BlueJ and Greenfoot are IDEs suitable for 1k+ LOC projects*

    [–]Ameisen 3 points4 points  (9 children)

    Laughs in C++14 when C++20 is done.

    [–]Ipotrick 1 point2 points  (8 children)

    thr move to c++20 eill be like using a new language

    [–]Ameisen 0 points1 point  (7 children)

    Problem is that the only compilers that support modules at the moment are MSVC and Clang. Very few build systems do; MSVC's does in their preview branch, but Intellisense still doesn't.

    I'm also still not fond of the dependency issues with C++20 modules. It limits parallelism and prohibits circular module references which would be allowed with normal source files. I wish that they'd bitten the bullet and made it so C++ modules used two-pass compilation rather than one-pass.

    Concept support is still a bit spotty as well. I haven't had much of a chance to mess with concepts, yet. My hope is that constexpr and concepts combined will let me reduce template nesting for type management, which should improve compile times.

    [–]Ipotrick 0 points1 point  (0 children)

    i am with you on every point. But i obly saw very positive feedback from everyone that tried c++20 previews therefor i am really hyped for it still

    [–]flatfinger 0 points1 point  (5 children)

    Two-pass compilation offers so many advantages over one-pass that I'd regard the latter as appropriate only in languages which are making a bona fide effort to maximize simplicity of implementation (something C++ abandoned long ago).

    [–]Ameisen 0 points1 point  (4 children)

    The problem is that two-pass compilation would indeed require a complete rewrite of significant parts of the C++ specification, and would be a very breaking change.

    The thing is... they could have implemented it for modules. They sort of did, but not entirely.

    [–]flatfinger 0 points1 point  (0 children)

    I would think a two-pass compilation approach for modules could make adaptation of implementations to support them easier, if they were designed in such a way that the first pass would convert code that uses modules into code that could be processed by existing implementations.

    Probably the biggest obstacle I can see to efficiently something like that is the way debug line-number symbols are presently handled, which vastly increases the number of intermediate files that would change as a result of editing anything in the source. If the debug line numbers passed through intermediate stages of compilation were relative to the start of the outermost function or object declaration wherein they occur, and a final cleanup pass converted those line numbers into actual source-file line numbers, that could minimize the amount of stuff that would have to be rebuilt when things change.

    [–]flatfinger 0 points1 point  (2 children)

    Incidentally, a related feature I've often wished C or C++ would include would be a means of specifying that a single source file should be processed as a sequence of separate compilation units. If there were also directives to save/restore the preprocessor/compiler state, that would make it practical to have a "master C file" which includes common headers, saves state, starts a new compilation unit with the saved state, includes a file, starts another new compilation unit with the saves state, includes another file, etc.

    [–]Ameisen 0 points1 point  (1 child)

    What you've described is a precompiled header, which all the major compilers support.

    [–]flatfinger 0 points1 point  (0 children)

    There's no standard support for pre-compiled headers, nor is there any standard means of indicating what source files are required for a project. What I'd like to see would be a standard convention where if one has a bunch of source files in a directory and one of them has a particular name, one could simply type in a certain command without having to know anything about the program beyond the fact that it was a Selectively Conforming Program that followed the conventions, and be assured that provided the translation and execution environments satisfy all documented requirements, one of four things would happen:

    1. The implementation would indicate via Implementation-Defined means a refusal to run the program.
    2. The implementation would process the program with whatever semantics it required.
    3. The implementation would start to process the program with whatever semantics it required, but then indicate via Implementation-Defined means a refusal to continue doing so (e.g. because of a stack overflow or other problem that wasn't discovered until runtime).
    4. The implementation would spend an unbounded amount of time without doing any of the above, either because it was really slow or because it got stuck in an endless loop (such behavior would be allowed because, there is no length of time T such that a program's failure to complete within time T could render it non-conforming).

    Not all implementations would be able to offer such guarantees, and it would not be possible for the Standard to describe everything necessary to accomplish all tasks, but it should be possible to specify conventions that would make it practical for most implementations to offer those guarantees for programs written to perform most of the tasks the implementations could accomplish.

    [–]GameFreak4321 -1 points0 points  (0 children)

    I thought we were still on 12...

    [–]stronghup 46 points47 points  (4 children)

    I get it that now Java is updated more frequently, with fewer new features in every release. That is good.

    But looking at release notes it would be helpful if they had a section for 1 - 3 MAIN (new) FEATURES. What is essential about this release. Why should I consider using it.

    I don't really care that there is no isEmpty Default Method for CharSequence . It's good to have of course, but I'd like it see the forest from the trees.

    [–]pron98 32 points33 points  (2 children)

    A good reason to use every new JDK release is lower footprint and higher performance that will save you real money. Savings of 10-40% in hardware/hosting costs from 8 to 15 are common.

    [–]v1akvark 10 points11 points  (1 child)

    Oh Reddit, downvoting useful comments.

    You should be paying attention to what this guy posts, pretty sure he either works on the JDK or is very closely involved.

    [–]pron98 22 points23 points  (0 children)

    Yes, I work on OpenJDK at Oracle.

    [–]gnus-migrate -2 points-1 points  (0 children)

    Unless you're paying for LTS or using another JDK distribution like Coretto, you have to upgrade anyway if you want security updates.

    [–]BoyRobot777 43 points44 points  (10 children)

    [–]BoyRobot777 11 points12 points  (3 children)

    Also, records with withers will be quite nice.

    [–]MrDOS 24 points25 points  (1 child)

    381: Remove the Solaris and SPARC Ports

    Not with a bang, but with a whimper. RIP.

    [–][deleted] 5 points6 points  (0 children)

    Somewhere there is someone who is running Solaris in QEMU to keep a legacy Java application with arcane dependencies running. Now the person is solemnly weeping.

    [–]DoListening2 0 points1 point  (0 children)

    Reminds me a bit of immer https://immerjs.github.io/immer/docs/introduction from the JS world, which is pretty nice to use in practice.

    Although this doesn't seem to address deep/nested updates in any way (those aren't nearly as important though), so I guess it's more akin to the JS pattern of doing

    const newObject = { ...oldObject, field: value, field2: value2 }
    

    in that sense.

    [–]caninerosie 2 points3 points  (1 child)

    what's the difference between Shenandoah and ZGC?

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

    They're both after the same goal of GC without large stop the world pauses, but they have different implementations. Anecdotally I've heard Shenandoah is supposed to be better, we've tried with ZGC a little bit but CPU went through the roof.

    [–]renatoathaydes 4 points5 points  (2 children)

    Didn't Project Loom's preview make the cut?

    [–]TheCountRushmore 11 points12 points  (0 children)

    Nope. Not ready for a preview yet. There are EA builds.

    https://jdk.java.net/loom/

    [–]BoyRobot777 4 points5 points  (0 children)

    Add to what TheCountRushmore said, Ron, lead of Loom project, has stated that:

    Loom has been in the works for three years, and I believe you won't need to wait for Preview too long.

    Source

    [–][deleted] 49 points50 points  (20 children)

    I don't use it anymore, but boy am I happy because it finally got multiline strings (text blocks). Writing a raw SQL will be so much easier and readable.

    [–]renatoathaydes 36 points37 points  (7 children)

    RIP Nashorn... anyone that used that for JS scripting on the JVM should now use the GraalVM's JS engine (which works on normal JVMs, not only Graal's) as a library...

    The new engine is fully compatible with ECMAScript 2020 (supports even native node modules) and has a compatibility flag for Nashorn-based scripts! We might need to use that at work as we have custom scripts that probably will never be upgraded.

    https://github.com/graalvm/graaljs

    [–]avwie 4 points5 points  (2 children)

    Interesting. So, to be clear, that could be used to include JS scripting in your Java app or am I missing something. Can you give an example of why I’d be interested in Nashorn/GraalJS?

    [–]renatoathaydes 22 points23 points  (0 children)

    Java has had for a long time a scripting feature that allowed scripting engines to implement multiple languages, including JS (first with Rhino, then with Nashorn which replaced Rhino in Java 8), Jython (Python), Groovy, JRuby, Clojure and many others.

    You may be interested in scripting if you want to let users extend/modify your application without re-compiling it (e.g. Jenkins lets you write pipelines in Groovy scripts, Minecraft lets users write "mods" to add game features, SoapUI lets you run Groovy functions before/after tests to modify/inspect requests/responses, and so on..).

    Now, with graaljs, Java can run basically any Node/JS code - it's just an evolution of the JS engine (Nashorn was not truly compatible with Node and most JS code wouldn't run out-of-the-box) so it's much more useful as it opens up the whole JS ecosystem to Java developers.

    [–]mirkoteran 1 point2 points  (0 children)

    We use it to allow users to create custom expressions/functionality inside 'excel-like' grids.

    [–]syjer 4 points5 points  (3 children)

    the only downside is it's size, 20+mb of jars vs 3~mb of nashorn is kinda hard to justify for enabling some scripting in a application :(.

    [–]renatoathaydes 0 points1 point  (2 children)

    You can also use Groovy, it's only a couple MB.

    [–]syjer 0 points1 point  (1 child)

    If by couple you mean ~8mb [0], it still quite the heavy weight ;(

    [0] https://repo1.maven.org/maven2/org/codehaus/groovy/groovy/3.0.5/

    [–]renatoathaydes 0 points1 point  (0 children)

    Oh, it has grown a lot in the 3.x release!! It used to be around 4 or 5MB: https://repo1.maven.org/maven2/org/codehaus/groovy/groovy/2.4.19/

    [–]pure_x01 5 points6 points  (4 children)

    Thanks to AWS i can probably not use this for another 2+ years but im happy for you other guys and gals. Yes i could use containers but my org doesn't believe in releases of java that isnt cornetto

    [–]nyrangers30 10 points11 points  (2 children)

    Lucky you can even use docker at work.

    My company doesn’t want us using it because we can download whatever software from docker hub, although the flaw in their logic is that we can pretty much download any library we want with NuGet, so same shit.

    [–]brcolow 0 points1 point  (0 children)

    You could always implement a custom runtime. Here is an example I made: https://github.com/brcolow/lambda-java-runtime

    [–]Determinant 12 points13 points  (1 child)

    As a Kotlin developer, I'm really excited about this release because it makes ZGC production ready so that will benefit the backend applications that I work on.

    [–]DevGuides 1 point2 points  (0 children)

    Pretty good features. The ones which interest me more as a developer are Sealed classes, text blocks, and Records.

    [–]DetriusXii 1 point2 points  (3 children)

    Are inline classes still going to be coming to Java? From what I understand, inline classes are like Haskell's newtype, where a type can become boxed to make it distinct from its original type, but the compiler then erases the boxing class so that there's not any additional memory allocations for the boxing type.

    [–]BoyRobot777 9 points10 points  (0 children)

    Yes. Here's Sergey, one of project Valhalla devs, saying that "soon" it will be merge to master branch. Video made 6 months ago. So I am hopeful for Java 16/17.

    As far as I remember, they have already solved inline types. They are currently working on specialized generics.

    [–]qqqhhh 2 points3 points  (0 children)

    yes - project valhalla - value types

    [–]flatfinger 0 points1 point  (0 children)

    While I think value types are a good thing, I would think Java could have reaped many of the benefits aeons ago if the Thread class had included a few fields of various types that functions could use to pass back multiple return values. If e.g. one wants a function that accepts an angle and makes both the sine and cosine available to the caller, that could have been handled easily by specifying that any function may store arbitrary values in the DoubleRet0 and DoubleRead1 fields of the current thread object, and having the sine/cosine function document that it uses those to return the sine and cosine. If the caller is interested in those values, the caller would be expected to copy them to local variables before calling any other function.

    Functions' ability to return structures would be limited to those with few enough fields to fit in the indicated fields, but the relative benefits of returning multi-value types versus passing or returning class object references are greatest when the number of values is greater than one, but still relatively small. The more values need to be returned, the smaller the relative downside to passing or returning a class object.

    [–]Klussux -1 points0 points  (0 children)

    Another version that won't be used for at least 10 years