I am very excited for this feature and has been a long time coming. This will make immutable transformation code much easier to write and reason about.
That said, I'm a little uneasy with the idea that we don't even have the option to write out our deconstruction pattern. That feels like a foot gun. I know that records come pre-baked with a deconstructor, I'm not asking to be able to choose. I am more asking for the ability to see the variable that I am overwriting. And I am not asking that every Java developer should have to shoulder that burden -- keep it implicit for those who want it. But I feel uneasy that I don't even have the option to write out the variables in my deconstructor.
I will try it out before taking issue with it, but these are my initial, uninformed feelings from looking at it. Regardless, even if my fears become true, this feature is well worth it, and I'm very happy to have it!
That does raise a good point -- If this concept might one day go over to the every day class, it sounds like they might be forced to list the deconstruction pattern used to do "reconstruction".
Either way, my main point is that -- the implicitness of this feature is appreciated, but I don't know if I want to be forced between implicit or just not using this feature, since my uninformed gut feels like I would appreciate the explicit clarity of seeing the variables I am working with. It might feel like a step back, but again, this is my opinion before having a chance to try this thing.
Why wasn't this included in the initial records implementation? I tried records and quickly gave up after realizing there was no copy method. There's plenty of prior art. Scala has had this for twenty years. Java needs to stop shipping features that don't work as well as in other languages.
Oh yes, 18 years. Guess that's not enough time. And yes, Scala's relevance is waining but not sure what that has to do with this topic. Kotlin also has a copy method if you need an example of a language doing well.
Kotlin is only doing well on Android, because mama Google tells so to all the kids targeting Android that they have to eat Kotlin no matter what.
Java is doing quite well on the Java Virtual Machine, it isn't going anywhere for not adopting every feature from Beanshell, Groovy, jTcl, jython, Frege, Ruby, Scala, Kotlin, and whatever else comes that needs to implement on top of Java to exist in first place.
No need to get defensive about Java. I developed with it for over 20 years. But personally, I left it because I find it too painful to code in. Every once in a while I try the latest version and it continues to disappoint, records are a good example.
I've also been working in fintech for the past 7 years and the companies I worked for, don't want to use Java. Its either been Kotlin/Spring because the syntax is much nicer, or Go because it doesn't have all the JVM baggage. Maybe Java is still really popular but fortunately, its also easy to avoid now.
The problem with this approach is that in the mean time the people will have to adopt crutches like https://github.com/Randgalt/record-builder and by the time Java adds missing features all the codebases will be forever polluted with legacy workarounds that nobody will dare to remove because of backwards compatibility.
It also hinders adoption of new features as people will prefer to maintain consistency in their codebases.
I think you have correctly identified the cost of aiming for long term, evergreen success -- you must sacrifice short term gain to get it.
Yes, because records are still slowly being improved, it means that people will put together workarounds and temporary solutions so that they can get their desired feature as soon as possible. It also means that some will just throw up their hands in frustration and say "It's half-baked!", then disregard the feature entirely. It's a tradeoff that the Java team considers on a regular basis.
It was a similar tradeoff that led to them releasing Virtual Threads before they had a solution implemented for the pinning problem. That one wasn't so much that they needed feedback before they could fix the problem, but moreso that they didn't want to miss out on potential feedback while they were fixing the pinning problem. So, they released VT with this (temporary) deficiency, and they are working on it now while gathering as much insight as possible into how VT's are being used across the ecosystem.
Tradeoffs like this are painful, but they make for a better language. Not to mention, for faster long term progress. A well designed feature becomes easy to extend. A poorly designed one is easy to extend initially, but becomes far more difficult in the long run.
> Tradeoffs like this are painful, but they make for a better language. Not to mention, for faster long term progress.
Don't think like Java is a good example of that, more like the anti-example. Plenty of more sophisticated languages move way faster without negative effects on long term progress (C#, Kotlin, to some extent Scala)
> A well designed feature becomes easy to extend. A poorly designed one is easy to extend initially, but becomes far more difficult in the long run.
Most of Java problems come down to unfortunate design choices in the past.
E.g. checked exceptions vs lambdas
I dearly miss checked exceptions in C#, it is like tracking land mines, when fixing code from others that happily decided to ignore exceptions that then blow up in production.
Also moving fast and breaking things newly adopted .NET culture is the reason I am mostly stuck on .NET Framework for corporate production apps, unless we're doing newly written microservices, and some big names like Sitecore decided it was easier to buy products written in other languages than rewrite their stuff into .NET Core.
In theory exceptions can be easily found with static analysis. I suppose lack of such tools (and failure of code contracts which I think could've verified it statically) means that vast majority of people are happy with status quo.
Just an idea - maybe you can use CodeQL?
The transition to .NET core is indeed rather painful but it's just Microsoft's choice. Things were dropped/backwards compatibility broken mostly to simplify runtime but I saw nothing that couldn't have been emulated with some modest effort.
Also they could've easily softened the transition by continuing development of .NET Standard a bit longer and allowing side by side hosting of 4.x and Core in same process as that seemed to be the plan in the beginning. I guess they don't care.
Both this and parent comments are so...strange. If you had any significant experience working with post-"Framework" .NET, you would know that the features that got deprecated were unsound, carried significant performance and complexity cost hindering the efforts towards further platform evolution. And most actually important use cases saw appropriate dev work to provide polyfills and shim packages to provide the path for migration.
.NET Standard existed and still exists as a bridge for .NET Framework and "odd" platforms like UWP (effectively dead), Unity and maybe a couple of others - you never know! Fortunately it slowly but surely fades into obscurity as all the actively developed platforms are converging around pure 'net6+'-based TFMs.
Special note regarding "being stuck with .NET Framework" - this may be true for some enterprise scenarios but I have grown to adopt a mental model of considering opinions like these as nonsensical or deeply out of touch with reality as much more useful way of dealing with audience that still lives in this camp. It is not worth entertaining, nor it is reasonable to respond to "move fast and break things" criticism after all these years - some people just have a bone to pick, for the pace is "moderate" and there are no changes made like in the early days of .NET Core 1.x and 2.x when the platform's fate was uncertain.
Do you consider in-box PowerShell and MS Office to be rare enterprise/nonsensical scenarios?
Or how about C# Source Generators that were introduced just few years ago and are stuck on .NET Standard 2.0 because of Visual Studio using .NET framework?
There is a lot of actively developed software out there either built in .NET or using it to provide extensibility that is now stuck as you can't add support for .NET Core without breaking all existing plugins.
The only alternative is complete redesign with out-of-process architecture which is not going to be compatible and might be inappropriate in some scenarios.
This is still just a proposal, so nothing is hammered out. And we can talk about the merits of this solution. But my point is, by focusing on designing features the way they have, you can minimize intrusion while maximizing the value provided. I think this proposal demonstrates that extremely well.
This proposal allows the developer to maintain all the good parts about checked exceptions and lambdas, while being able to side-step the major downside.
> Don't think like Java is a good example of that, more like the anti-example. Plenty of more sophisticated languages move way faster without negative effects on long term progress (C#, Kotlin, to some extent Scala)
To be clear, when I say long term, I am measuring on the scale of decades. In that respect, I actually don't think your statement is correct.
To give an example with Kotlin, someone (I think Brian) talked about Kotlin's release strategy for features being great for short term, but costly in the long term. Kotlin had record-esque classes long before Java ever got theirs, but now that Java finally has theirs, Kotlin is using an annotation to disambiguate between Java style records and Kotlin style records -- https://kotlinlang.org/docs/jvm-records.html#declare-records.... While this isn't some critical problem on its own, this type of rift growing wider means that Kotlin is going to have to wrestle with how much they want to allow Java representation of concepts to exist in Kotlin. For example, how will Kotlin handle Java's version of pattern-matching vs their own? The 2 are not the same, so you cannot just call them aliases of each other - they have different semantics.
To give another example with C#, there has been a lot of recent discussion about finding potential alternatives to their async-await concurrency model. They cite the level of effort it takes to maintain the async await style code and the costs that come from this. Rust had a similar conversation not too long ago too.
The point I am trying to say is that, I think Java's strategy of play it slow and conservative is actually paying off for them, but on the scale of decades. Some of the languages it gets compared too aren't even that old yet.
This is fine but removes only about 10% of the pain of mandatory exception handling inside typical lambda.
Nothing short of making exceptions transparent to lambda receivers will cut it for me.
> Kotlin is using an annotation to disambiguate between Java style records and Kotlin style records
This is inherent risk of building on top of something you don't control.
Don't really see this as fair comparison. It's a known design constraint.
The only way to avoid it is to not build on top of Java or not adding any features on top of Java.
> To give another example with C#, there has been a lot of recent discussion about finding potential alternatives to their async-await concurrency model. They cite the level of effort it takes to maintain the async await style code and the costs that come from this.
I had a very different take-away. They did PoC with virtual threads and decided it's not worth the switch now and async-await that they have is good enough.
> Nothing short of making exceptions transparent to lambda receivers will cut it for me.
If your wish is to have Checked Exceptions be throwable from the lambda, then I understand your point. Still, I stand by argument, which is that they are actively addressing these pain points, but doing so slowly in ways that minimize intrusion.
> Kotlin
If it's not a fair comparison in your eyes, I'll leave it.
> async await in C#
I'd be more willing to accept your point of view if there wasn't so much discussion online about how painful async await is via color-my-function. And that's ignoring the fact that languages such as Go and Erlang have been garnering a big following, in large part due to their concurrency model and how simple it is.
I have had my share of async await too. I think it's no coincidence that many language designers are looking more and more into moving away from async await, thus prompting these PoC's and experiments.
As for the C# link specifically, I interpreted that to be that they felt the pain of async await strongly, and did the PoC in response. However, the PoC did not play well with their async await world, and trying to change the world to make room for it would be too much of a lift. Therefore, they stick with async. I did not interpret it to be that async await was good enough for them, but rather, that improving async await is the best option available to them for now.
> Age of languages
Sure, there are some languages that are a similar age to Java. But those are the languages where I believe the costs for the decisions they made are becoming more apparent. I already gave 1 example with C#. And I think we can both agree that Scala's design philosophy served as a great learning experience for other languages, but was a poor survivability tactic as a language. It feels like the language is buckling under its own weight.
Either way, I am not trying to say that these other languages are bad. Merely that their design philosophies benefit them in the short term, but show cracks in the long term. Java's philosophy, meanwhile, minimizes intrusion, and thus, allows it to sidestep alot of the problems that these other languages are trying to get out of.
> They just released a proposal that effectively side-steps the problem of checked-exceptions-in-lambdas.
The main problem of checked exception in lambdas is that Java's type system does not allow expressing statements like "`forEach` throws whatever the lambda throws". Here are two links:
The biggest reason why is because the Java team works as hard as possible to get as much user feedback before putting a feature out there.
Part of that means that they will release minimal versions of a feature (records), and then observe how people use them before they start adding the "obvious" Quality-of-Life changes.
It's painful for those of us who are here when these features are just now releasing. But the end result is a feature that has less chance of screwing over other potential features.
It's best to think of it as a short term cost for a much longer term gain. Moving slow like this means that they will release a feature that is more cohesive than it otherwise could be.
This looks like it could be a good change. Personally I think new point with { x = 1, y = 2, z = 3 } is much cleaner looking than say point.withX(1).withY(2).withZ(3). names params is generally something I like it languages though, so I might be biased here.
Point newLoc = oldLoc with {
x *= 2;
y *= 2;
z *= 2;
};
It feels more like a mutable "Builder" class than a copy constructor. I guess the benefit is that you can do things like the above, instead of the following in Kotlin:
val newLoc = oldLoc.copy(
x = oldLoc.x * 2,
y = oldLoc.y * 2,
z = oldLoc.z * 2
)
But in Kotlin it's more clear that oldLoc is immutable.
The syntax is definitely strange and not Java like, it doesn’t match any Java syntax I recall. Not a lambda, not a method call, not a keyword or even a static method
It should be 1 of the above. They also made the same weird new syntax choice with string template.
One of the most important things about a language is coherence and consistency. That’s why a language designer is a role/talent
The C# with seems bit more restricted though because it uses object initializer syntax while Java has full-blown code block, so in Java you can put arbitrary statements in. Also in Java you get the original values in the with statement, which I don't see in C#.
It is a bit clunky, but it makes things really traceable.
The Java team even backported their old, historical bugs/requests-for-enhancement into JIRA. You can see feature requests from the late 90's in there. Plus, you can write little SQL-esque queries to filter down submissions to just what you want.
So, true to Java form -- it's clunky, but the value is real.
I know we don't have the ability to follow/get notifications about a ticket, but we do have the ability to submit issues and comments by proxy!
If you lack an account, go to the Java Bug Database -- https://bugs.java.com/bugdatabase/, and about halfway down, you will find options for submitting a bug or a Request-for-Enhancement (RFE). You check some boxes, fill out a form, and press submit. Then, a member from the Java team or Java's bug reporting team (usually ANUPAM) will get your ticket submitted to the JIRA. They will also email you, notifying you that your ticket was approved to be added.
When they notify you, they also provide you a point of contact email. You can can send comments on your ticket by emailing this point of contact email.
And finally, if you want to comment on tickets that do not belong to you, you can reach out to ANUPAM and request them to forward your comment. But they might be hesitant if it is not your ticket.
I will certainly concede that it is a lot of friction.
The mailing list is also very clunky, I will further concede that.
And no matter how you slice it, this is all still community-hostile behaviour, I will also concede that too.
I think part of the reason for all of this friction is precisely because they don't want to keep the barrier of entry that low. It's no secret that the Java community is *ENORMOUS*. Having a little bit of friction goes a long way in quelling the influx of repetitive discussion topics. I'm not saying that's a good excuse -- more so saying that there probably isn't enough incentive to take the effort to fix these friction points.
And leaning into that further -- I'm not sure how much they are missing out on by keeping these friction points *on official Java discussion platforms, like the mailing lists*.
The fact is, there are an influx of Java opinions being given on the internet with no help from the Java Team, and if they want to get the public opinion, these social media sites will have it within hours. So if they already have that, why take on the massive burden of opening the flood gates on their official community discussion platforms?
Still, that's no excuse for things like no search function or the lack of moderator activity. It's probably something they have just de-prioritized in the name of getting features out faster.
Going extra mile to ensure Google can't index doesn't sound like mere deprioritization.
I will admit the system works if its goal is to prevent wasting OpenJDK devs time on repetitive topics.
I was going to ask one such potentially repetitive question (can't tell without search) but waiting for non-existent moderator to approve my message successfully drained any energy I had for this :)
Yeah, the mailing lists are built with subscription in mind. You can't really interact with them easily otherwise.
But to be fair, you can subscribe, but change the settings to decide what gets sent to you.
For example, you can turn off mail delivery so that you will only get included in conversations that you start yourself. People do that when they are in a mailing list just to ask a few questions, and don't want to opt-in to the flood of other discussions. Sounds like that might be for you.
And fair point on the indexing. I am actually working on a workaround myself. I'll let you know when it's finished up, in case you rediscover the motivation to try your comment again.
Alternatively, if you want, let me know your email address and send me your question. I would be happy to forward your message along, and then CC you in the thread. Get you past the door, so to speak.
Good to know you can disable delivery completely once signed up, I haven't used mailman in ages! I will sign up in this case. The signup page only lets you switch to digest, which can mislead new users.
BTW mailing lists can work great for guest visitors who don't want to subscribe.
They can also work great for teams who don't want guests.
The problem is openjdk mailman allows guest posting and lies about guests posts awaiting moderation.
Had they simply disabled guest posting and said up-front that you must subscribe and send rejection notice to guests I would be perfectly fine with that.
Mailman sucks worse than even Google Groups and in this case it's also poorly configured.
PS. To add to frustration, LastPass (I know it's shit but don't have time to migrate) somehow can't deal with Mailman signups - it will generate but won't save passwords.
Very fair. I know there's at least a couple of mailing lists that actually keep up with the mod queue, but it is as you say -- you can be stuck there for a long time, if not indefinitely. It does not feel like it is actively monitored. I've had messages approved/rejected after weeks of waiting.
But happy to have you join the discussion! I look forward to see your email!
The proposed syntax is not intuitive... How can I know to which records x, y and z are refering to in: Point newLoc = oldLoc with { x = 2; y = 2; z *= 2; } ? And in this case "return this with { im = -im; };" - which "im" goes to which record? Please make more intuitive syntax for this!
The general idea behind JEP Drafts such as these is that they first focus on the semantics -- what can/should this feature do?
They save things like syntax until the very end, right before they decide to submit this as an actual JEP instead of a JEP Draft. This JEP entered the Draft stage only a few hours ago.
All that is to say -- your comment makes sense, but you are criticizing the part of this JEP Draft that is not only the least relevant to the discussion, but the thing that is most likely to change before it exits the Draft stage. Oftentimes, they even put in placeholder syntax to highlight this fact.
I'd limit criticisms of syntax until they submit this JEP for actual review.
Well, records are immutable so assignment must go to newly constructed instance, meanwhile new instance does not exist yet so any read must be from old instance.
Therefore, everything you already know is intuitive. Oh wait, does that mean that intuitive is not a property of this proposal but of the reader and the proposal? Ergo, it is almost useless to ask whether some programming language feature is intuitive or not.
Could a moderator change the title back to at least include the phrase JEP Draft?
That is important because it communicates that this feature is actually not yet in Preview, but is on its way to being that.
Being in the JEP Draft state sets expectations about what part of this proposal is up for debate and criticism, and what parts are merely placeholder until the "heavier topics" have been hammered out.
Because you changed the title to this, it is actually not communicating the true intent, and thus, might invite discussion (read - criticisms) that this JEP Draft was never meant to contest.
55 comments
[ 3.5 ms ] story [ 114 ms ] threadI am very excited for this feature and has been a long time coming. This will make immutable transformation code much easier to write and reason about.
That said, I'm a little uneasy with the idea that we don't even have the option to write out our deconstruction pattern. That feels like a foot gun. I know that records come pre-baked with a deconstructor, I'm not asking to be able to choose. I am more asking for the ability to see the variable that I am overwriting. And I am not asking that every Java developer should have to shoulder that burden -- keep it implicit for those who want it. But I feel uneasy that I don't even have the option to write out the variables in my deconstructor.
I will try it out before taking issue with it, but these are my initial, uninformed feelings from looking at it. Regardless, even if my fears become true, this feature is well worth it, and I'm very happy to have it!
That does raise a good point -- If this concept might one day go over to the every day class, it sounds like they might be forced to list the deconstruction pattern used to do "reconstruction".
Either way, my main point is that -- the implicitness of this feature is appreciated, but I don't know if I want to be forced between implicit or just not using this feature, since my uninformed gut feels like I would appreciate the explicit clarity of seeing the variables I am working with. It might feel like a step back, but again, this is my opinion before having a chance to try this thing.
Scala is also on the edge of turning into Coffee Script, its relevance wanning.
20 years is pushing it, by the way.
Java is doing quite well on the Java Virtual Machine, it isn't going anywhere for not adopting every feature from Beanshell, Groovy, jTcl, jython, Frege, Ruby, Scala, Kotlin, and whatever else comes that needs to implement on top of Java to exist in first place.
It is like using Web and avoiding JavaScript, or UNIX and avoiding C/C++.
Sure it is possible to pretend it isn't there, until one needs to do serious stuff that requires understanding the platform and its ecosystem.
By the way, once upon a time Spring was also all hot on Groovy, then it was Scala, now it is Kotlin.
There is a certain irony complaining about Java programming language features and them going into Go, the epitome of programming language design.
It also hinders adoption of new features as people will prefer to maintain consistency in their codebases.
Stuff like Lombok are persona non grata when coding in Java, other than when imposed on us via 3rd parties without alternatives.
The alternative is to write this code by hand which isn't any better.
Yes, because records are still slowly being improved, it means that people will put together workarounds and temporary solutions so that they can get their desired feature as soon as possible. It also means that some will just throw up their hands in frustration and say "It's half-baked!", then disregard the feature entirely. It's a tradeoff that the Java team considers on a regular basis.
It was a similar tradeoff that led to them releasing Virtual Threads before they had a solution implemented for the pinning problem. That one wasn't so much that they needed feedback before they could fix the problem, but moreso that they didn't want to miss out on potential feedback while they were fixing the pinning problem. So, they released VT with this (temporary) deficiency, and they are working on it now while gathering as much insight as possible into how VT's are being used across the ecosystem.
Tradeoffs like this are painful, but they make for a better language. Not to mention, for faster long term progress. A well designed feature becomes easy to extend. A poorly designed one is easy to extend initially, but becomes far more difficult in the long run.
Don't think like Java is a good example of that, more like the anti-example. Plenty of more sophisticated languages move way faster without negative effects on long term progress (C#, Kotlin, to some extent Scala)
> A well designed feature becomes easy to extend. A poorly designed one is easy to extend initially, but becomes far more difficult in the long run.
Most of Java problems come down to unfortunate design choices in the past. E.g. checked exceptions vs lambdas
Also moving fast and breaking things newly adopted .NET culture is the reason I am mostly stuck on .NET Framework for corporate production apps, unless we're doing newly written microservices, and some big names like Sitecore decided it was easier to buy products written in other languages than rewrite their stuff into .NET Core.
Just an idea - maybe you can use CodeQL?
The transition to .NET core is indeed rather painful but it's just Microsoft's choice. Things were dropped/backwards compatibility broken mostly to simplify runtime but I saw nothing that couldn't have been emulated with some modest effort.
Also they could've easily softened the transition by continuing development of .NET Standard a bit longer and allowing side by side hosting of 4.x and Core in same process as that seemed to be the plan in the beginning. I guess they don't care.
.NET Standard existed and still exists as a bridge for .NET Framework and "odd" platforms like UWP (effectively dead), Unity and maybe a couple of others - you never know! Fortunately it slowly but surely fades into obscurity as all the actively developed platforms are converging around pure 'net6+'-based TFMs.
Special note regarding "being stuck with .NET Framework" - this may be true for some enterprise scenarios but I have grown to adopt a mental model of considering opinions like these as nonsensical or deeply out of touch with reality as much more useful way of dealing with audience that still lives in this camp. It is not worth entertaining, nor it is reasonable to respond to "move fast and break things" criticism after all these years - some people just have a bone to pick, for the pace is "moderate" and there are no changes made like in the early days of .NET Core 1.x and 2.x when the platform's fate was uncertain.
Or how about C# Source Generators that were introduced just few years ago and are stuck on .NET Standard 2.0 because of Visual Studio using .NET framework?
There is a lot of actively developed software out there either built in .NET or using it to provide extensibility that is now stuck as you can't add support for .NET Core without breaking all existing plugins.
The only alternative is complete redesign with out-of-process architecture which is not going to be compatible and might be inappropriate in some scenarios.
Funnily enough, your example has actually supported my point.
They just released a proposal that effectively side-steps the problem of checked-exceptions-in-lambdas. Here is a link -- https://inside.java/2023/12/15/switch-case-effect/
This is still just a proposal, so nothing is hammered out. And we can talk about the merits of this solution. But my point is, by focusing on designing features the way they have, you can minimize intrusion while maximizing the value provided. I think this proposal demonstrates that extremely well.
This proposal allows the developer to maintain all the good parts about checked exceptions and lambdas, while being able to side-step the major downside.
> Don't think like Java is a good example of that, more like the anti-example. Plenty of more sophisticated languages move way faster without negative effects on long term progress (C#, Kotlin, to some extent Scala)
To be clear, when I say long term, I am measuring on the scale of decades. In that respect, I actually don't think your statement is correct.
To give an example with Kotlin, someone (I think Brian) talked about Kotlin's release strategy for features being great for short term, but costly in the long term. Kotlin had record-esque classes long before Java ever got theirs, but now that Java finally has theirs, Kotlin is using an annotation to disambiguate between Java style records and Kotlin style records -- https://kotlinlang.org/docs/jvm-records.html#declare-records.... While this isn't some critical problem on its own, this type of rift growing wider means that Kotlin is going to have to wrestle with how much they want to allow Java representation of concepts to exist in Kotlin. For example, how will Kotlin handle Java's version of pattern-matching vs their own? The 2 are not the same, so you cannot just call them aliases of each other - they have different semantics.
To give another example with C#, there has been a lot of recent discussion about finding potential alternatives to their async-await concurrency model. They cite the level of effort it takes to maintain the async await style code and the costs that come from this. Rust had a similar conversation not too long ago too.
The point I am trying to say is that, I think Java's strategy of play it slow and conservative is actually paying off for them, but on the scale of decades. Some of the languages it gets compared too aren't even that old yet.
This is fine but removes only about 10% of the pain of mandatory exception handling inside typical lambda.
Nothing short of making exceptions transparent to lambda receivers will cut it for me.
> Kotlin is using an annotation to disambiguate between Java style records and Kotlin style records
This is inherent risk of building on top of something you don't control. Don't really see this as fair comparison. It's a known design constraint. The only way to avoid it is to not build on top of Java or not adding any features on top of Java.
> To give another example with C#, there has been a lot of recent discussion about finding potential alternatives to their async-await concurrency model. They cite the level of effort it takes to maintain the async await style code and the costs that come from this.
I had a very different take-away. They did PoC with virtual threads and decided it's not worth the switch now and async-await that they have is good enough.
https://github.com/dotnet/runtimelab/issues/2398
> Some of the languages it gets compared too aren't even that old yet.
C# is more than old enough to drink and Scala just had its 20th birthday this weekend :) Java is only 4 years older than C#.
If your wish is to have Checked Exceptions be throwable from the lambda, then I understand your point. Still, I stand by argument, which is that they are actively addressing these pain points, but doing so slowly in ways that minimize intrusion.
> Kotlin
If it's not a fair comparison in your eyes, I'll leave it.
> async await in C#
I'd be more willing to accept your point of view if there wasn't so much discussion online about how painful async await is via color-my-function. And that's ignoring the fact that languages such as Go and Erlang have been garnering a big following, in large part due to their concurrency model and how simple it is.
I have had my share of async await too. I think it's no coincidence that many language designers are looking more and more into moving away from async await, thus prompting these PoC's and experiments.
As for the C# link specifically, I interpreted that to be that they felt the pain of async await strongly, and did the PoC in response. However, the PoC did not play well with their async await world, and trying to change the world to make room for it would be too much of a lift. Therefore, they stick with async. I did not interpret it to be that async await was good enough for them, but rather, that improving async await is the best option available to them for now.
> Age of languages
Sure, there are some languages that are a similar age to Java. But those are the languages where I believe the costs for the decisions they made are becoming more apparent. I already gave 1 example with C#. And I think we can both agree that Scala's design philosophy served as a great learning experience for other languages, but was a poor survivability tactic as a language. It feels like the language is buckling under its own weight.
Either way, I am not trying to say that these other languages are bad. Merely that their design philosophies benefit them in the short term, but show cracks in the long term. Java's philosophy, meanwhile, minimizes intrusion, and thus, allows it to sidestep alot of the problems that these other languages are trying to get out of.
The main problem of checked exception in lambdas is that Java's type system does not allow expressing statements like "`forEach` throws whatever the lambda throws". Here are two links:
http://james-iry.blogspot.com/2012/02/checked-exceptions-mig...
https://blog.jooq.org/javas-checked-exceptions-are-just-weir...
The proposed syntax puts the exceptions on equal footing with the happy path. Not a bad idea, but irrelevant to the main problem.
Part of that means that they will release minimal versions of a feature (records), and then observe how people use them before they start adding the "obvious" Quality-of-Life changes.
It's painful for those of us who are here when these features are just now releasing. But the end result is a feature that has less chance of screwing over other potential features.
It's best to think of it as a short term cost for a much longer term gain. Moving slow like this means that they will release a feature that is more cohesive than it otherwise could be.
It should be 1 of the above. They also made the same weird new syntax choice with string template.
One of the most important things about a language is coherence and consistency. That’s why a language designer is a role/talent
https://learn.microsoft.com/en-us/dotnet/fsharp/language-ref...
The Java team even backported their old, historical bugs/requests-for-enhancement into JIRA. You can see feature requests from the late 90's in there. Plus, you can write little SQL-esque queries to filter down submissions to just what you want.
So, true to Java form -- it's clunky, but the value is real.
If you lack an account, go to the Java Bug Database -- https://bugs.java.com/bugdatabase/, and about halfway down, you will find options for submitting a bug or a Request-for-Enhancement (RFE). You check some boxes, fill out a form, and press submit. Then, a member from the Java team or Java's bug reporting team (usually ANUPAM) will get your ticket submitted to the JIRA. They will also email you, notifying you that your ticket was approved to be added.
When they notify you, they also provide you a point of contact email. You can can send comments on your ticket by emailing this point of contact email.
And finally, if you want to comment on tickets that do not belong to you, you can reach out to ANUPAM and request them to forward your comment. But they might be hesitant if it is not your ticket.
I'm surprised there isn't an option to send your request via post mail.
Also other community-hostile behaviors of Java/OpenJDK project:
- mailing lists have no search function and block search engines/crawlers by returning 403 (apparently robots.txt is not enough!)
- can't post to mailing list without subscribing despite information that such messages will just need to be approved by moderator (they never are)
The mailing list is also very clunky, I will further concede that.
And no matter how you slice it, this is all still community-hostile behaviour, I will also concede that too.
I think part of the reason for all of this friction is precisely because they don't want to keep the barrier of entry that low. It's no secret that the Java community is *ENORMOUS*. Having a little bit of friction goes a long way in quelling the influx of repetitive discussion topics. I'm not saying that's a good excuse -- more so saying that there probably isn't enough incentive to take the effort to fix these friction points.
And leaning into that further -- I'm not sure how much they are missing out on by keeping these friction points *on official Java discussion platforms, like the mailing lists*.
The fact is, there are an influx of Java opinions being given on the internet with no help from the Java Team, and if they want to get the public opinion, these social media sites will have it within hours. So if they already have that, why take on the massive burden of opening the flood gates on their official community discussion platforms?
Still, that's no excuse for things like no search function or the lack of moderator activity. It's probably something they have just de-prioritized in the name of getting features out faster.
I will admit the system works if its goal is to prevent wasting OpenJDK devs time on repetitive topics.
I was going to ask one such potentially repetitive question (can't tell without search) but waiting for non-existent moderator to approve my message successfully drained any energy I had for this :)
But to be fair, you can subscribe, but change the settings to decide what gets sent to you.
For example, you can turn off mail delivery so that you will only get included in conversations that you start yourself. People do that when they are in a mailing list just to ask a few questions, and don't want to opt-in to the flood of other discussions. Sounds like that might be for you.
And fair point on the indexing. I am actually working on a workaround myself. I'll let you know when it's finished up, in case you rediscover the motivation to try your comment again.
Alternatively, if you want, let me know your email address and send me your question. I would be happy to forward your message along, and then CC you in the thread. Get you past the door, so to speak.
BTW mailing lists can work great for guest visitors who don't want to subscribe. They can also work great for teams who don't want guests.
The problem is openjdk mailman allows guest posting and lies about guests posts awaiting moderation. Had they simply disabled guest posting and said up-front that you must subscribe and send rejection notice to guests I would be perfectly fine with that.
Mailman sucks worse than even Google Groups and in this case it's also poorly configured.
PS. To add to frustration, LastPass (I know it's shit but don't have time to migrate) somehow can't deal with Mailman signups - it will generate but won't save passwords.
But happy to have you join the discussion! I look forward to see your email!
They save things like syntax until the very end, right before they decide to submit this as an actual JEP instead of a JEP Draft. This JEP entered the Draft stage only a few hours ago.
All that is to say -- your comment makes sense, but you are criticizing the part of this JEP Draft that is not only the least relevant to the discussion, but the thing that is most likely to change before it exits the Draft stage. Oftentimes, they even put in placeholder syntax to highlight this fact.
I'd limit criticisms of syntax until they submit this JEP for actual review.
Seems very intuitive to me (and same as C#).
That is important because it communicates that this feature is actually not yet in Preview, but is on its way to being that.
Being in the JEP Draft state sets expectations about what part of this proposal is up for debate and criticism, and what parts are merely placeholder until the "heavier topics" have been hammered out.
Because you changed the title to this, it is actually not communicating the true intent, and thus, might invite discussion (read - criticisms) that this JEP Draft was never meant to contest.
A shame that you can't ping them directly through this application (like you can in Reddit), but the response time was quick, so that is appreciated.