Also it is quite common on embedded Java for the vendors to have their own implementation with code translation.
What isn't normal is having stagnant compatibility.
So even if feature wise the 2 equalize (a good thing not a bad thing IMO) stylistic differences will remain. Many of Kotlins syntactic differences are unlikely to make it to Java for instance.
I'm ok with this. I use both for different things. Kotlin for most app level development, Kotlin for libraries that are only useful in the context of Kotlin, Java for everything else so it has minimal dependencies and can be used from Kotlin/Scala/Java/Clojure equally well.
The truth of it is that Kotlin is incredibly easy to learn, even for non-Java devs. It is definitely focused on a very low barrier to entry. I don't think this was an original goal but it's become a significant focus of the language especially after being selected to be the next platform language for Android.
This isn't true of Scala at all. Beyond things like SBT, comparatively poor IDE support (less of an issue these days) it is also just a very complex language, with many complicated semantics in it's standard library and even more complex/fancy 3rd party libraries piled on top of that.
Scala became an incredibly powerful language, not a simple or easy to use one however.
Kotlin is a very user friendly language that is easy to learn but still has enough power to keep most expressiveness focussed devs happy.
Beyond the learning curve Kotlin integrates with Java a lot better, calling in both directions.
These 2 factors alone probably account for why it was chosen over Scala for Android and in general why it has value over both Java and Scala.
I think with Gradle moving from Groovy -> Kotlin, Android obviously and big companies adopting Kotlin w/Spring on the backend the ship has indeed sailed for Scala, it doesn't really have a place outside of places that specifically want a more FP lang.
The point about tooling and developer experience I'll concede. It has been at times patchy in Scala in the past but it's pretty good these days.
As I say, I have no hate for Kotlin, and I'll possibly use it one day being a JVM developer familiar with Java as well, I just find it unfortunate that a language which is so similar to the languages it's influenced by was invented.
It can be used as a better Java but requires discipline. Things like implicits can easily cause an unnecessary amount of pain. Kotlin on the other hand implemented extension methods in a way that doesn't detract from the better Java paradigm. This is only one example though, there are many many reasons why Kotlin is more suited for the "better Java" role. Namely it's simply not that different to Java. It's effectively Java with a more modern syntax and polished extensions to the Java standard library.
That's not my truth.
I tried it, after not doing "real" programming for a while, and found it the most obfuscated, incomprehensible language I've ever run into. What new concepts are there in Kotlin that justify it?
"Expressiveness" sounds toxic to me - along the lines of "facilitates a personal idiom that makes your code impossible to understand and you irreplaceable".
After several days trying to do the simplest form of asynchronous processing in an "hello world" Android app, I switched back to Java, and everything made sense again.
I also wrote a small program in C# and that too was just as easy as I recall from ~10 years ago.
But then, I've seen some shit Java too.
I'm surprised you feel Kotlin is incomphrensible though, it definitely can be written that way because it has features that allow for extreme terseness.
I think there is a minimal set of things you need to learn over Java for Kotlin to make sense, nullability operators, block passing syntax and the differences in OOP (inheritance/interfaces are slightly different, classes are closed by default, companion objects replace static methods).
So yeah. Kotlin is strictly larger than Java so it takes longer to learn all of it.
That said because of the look and feel of Kotlin it's more accessible to developers of Ruby/Python/JS/Typescript. This tradeoff is personally worth it for me.
Not because I care that much, I can just as easily use Java. However it's -very- difficult in modern times to convince my team and company to use Java when there is hipster options like Typescript taking all the air out of the room. Kotlin competes in the same area but provides the same battle tested runtime and excelent libraries, it's almost like a compromise between the new age and the old age.
This is why it's such a great language for me in particular but I realize not everyone is in the same boat.
SBT is inexcusably awful (and so is ScalaTest, which is a lot of people's first exposure to the language), and you might be right about the zeitgeist having moved on, but it's a shame; it's honestly a significantly better language design.
New features in Java and the JVM (records, loom, valhalla, ...) are directly going to benefit Scala and make it even better.
On the contrary, Kotlin's essence has always been threatened by the fact it's nothing more than a better Java. I assume there's still a big demand for that on Android, but if you're running on a recent JVM, I would certainly consider Java over Kotlin.
That said you don't need to understand that much to use high-level libraries in the Typelevel ecosystem. And when I do need to reach for low-level constructs, I find nice that everything is built upon clean and composable abstractions.
You mention Akka, it's kind of its own beast. The inner workings go definitely way beyond "better Java", yet Lightbend needs to provide a surface API that plays nice with Java interop. It's not an ecosystem easy to navigate in my opinion.
Java has been catching up on language features but I'm not sure if I'm ready to switch back to Java for Spring projects yet. Mostly because of nullability, extension methods and coroutines in Kotlin.
I give you nullability, however extension methods without proper typeclasses is just syntactic sugar, and coroutines will be superseded by Loom.
Java hasn't only been catching up, it now supports pattern matching which Kotlin still lacks.
Especially with the heavy, under-the-hood developments of the JVM, like Loom and Valhalla.
Scala has been declining steadily for a decade now, and Scala 3 is going to precipitate this state of affairs by splitting the shrinking community even further.
Kotlin, on the other hand, has done nothing but grow for the past five years, no doubt helped by Google's formidable support for it. I just took a quick look at one of its Slack channels, "getting-started", and it has over 38,000 people on it. And that's just one channel among dozens more.
I don't think Java's latest additions are anywhere near threatening Kotlin's rise to dominance since Java is moving at a very slow pace, by design, while Kotlin supports some features and design directions that will never happen in Java.
Yeah right they had to reboot it.
Google is Kotlin's godfather, naturally they are using it, just like Amazon with their own Android flavour.
* null safe navigation operator
* properties
* mutable records
* a way to ignore checked exceptions (or at least having the stream API take functional interfaces that can throw exceptions)
* adding functional methods like .filter()/.map() directly to collections instead of having to .stream().map(..).collect(toList())
In my company we have f(list).map(…), which is a wrapper for the streams. But newcomers don’t like it because it’s not the standard.
Some features are low hanging fruit, some are proposed small changes that actually should be defined a bit differently to be better and they will take more effort.
But even small hanging fruits means that they need to chose which ones to do. Should they delay pattern matching by 6 months to get elvis operator? I wouldn't like it, pattern matching is more important.
Basically they have limited resources and have to chose what to work on.
So we're killing two birds with one stone: making it easier to work with "simple data" while also reducing reliance on getters and setters. On the other hand, C# finds itself needing to add more and more capabilities to this feature, while Java dodged that bullet.
I hope both Java and Kotlin can converge into a common coding style. As you said regarding C#, Kotlin's emphasis on properties makes it easier to use getters and setters and thus may hinder getting rid of them in the Java ecosystem. I'm not sure if I should support Kotlin's success at this point.
When?
> On the other hand, C# finds itself needing to add more and more capabilities to this feature, while Java dodged that bullet.
Java "dodged it" by never even having to fight. While C#'s "poor choices" are leading to a language with less and less boilerplate with almost each year, in Java we'll have to wait another 10 years before it delivers half of a half of the "withers" functionality that doesn't work with half of existing standard library code (the way arrays, lists and collections are three non-intersecting entities).
Like, I would prefer not having 10+ initializers from C++ in a language.
In Java you have one of these:
- a hope that someone provided a useful static `.of` method
- a hope that someone provided the 15000 setter methods that you have to tediously invoke one by one
- a hope that someone provided a generator that created a builder that has 15000 setter methods that you have to tediously invoke one by one
Meanwhile in C#:
new Object {
x = ...,
y = ...,
z = ...
}
for literally any object (provided properties are public of course).And don't get me started on array vs list vs collections none of which are compatible with each other. And hundreds of other QoL improvements that are begging to be implemented, and are not.
And yeah, C# feels to me to be on the way to being way too feature-packed, which can be a detriment in the extreme.
> And don't get me started on array vs list vs collections none of which are compatible with each other.
This is not true. Lists are collections, and while arrays are different, Arrays.asList() gives you a list view of arrays.
> And hundreds of other QoL improvements that are begging to be implemented, and are not.
First of all, just in the past five years we got local variable type inference (var), switch expressions, records (with much more to come), sealed classes, and basic pattern matching (with much more to come), and string templates are around the corner. All of those are significant QoL improvements.
Second, every feature comes at the expense of all others -- both because of opportunity cost and overall language complexity budget -- and the question is one of priorities. Not everyone has the same priorities.
Finally, because Java is expected to remain extremely popular for at least a couple more decades, we must be very careful about adding features. While other languages are trying desperately to gain many developers right away, we're looking ahead to ensure that we'll be attractive to developers in ten and twenty years from now, and so must spend the complexity budget carefully.
Once again: when?
And why only records? Why does everything in java require someone to manually create an .of method, or create 15000 setter methods or generate those 15000 setter methods?
> This is not true. Lists are collections, and while arrays are different,
I remember running into an issue with the difference, but can't remember now. Quite possible it was an artefact of an early implementation.
> Arrays.asList() gives you a list view of arrays.
Yup. One of the hundreds papercuts that litter Java.
C#:
var list = new List<string>()
{
"carrot",
"fox",
"explorer"
};
var array = new string[]{ "carrot", "fox", "explorer" };
... use whatever IEnumerable methods on both ...
Java:Ahahaha. No. For lists use a static .of method and be glad that someone manually wrote that in the library. And be thankful that there's some shortcut to create an array. But for Lists? eff off, no shortcuts for you.
Oh you want convenience methods on arrays? Ahahaha, no. Use a separate helper to convert into a list first. (This is so bad that IDEA suggests some version .toList as the first method on I swear 90% of array/collection/list/stream operations).
Because, as someone said, "our goal isn't to adopt the strategy of less successful products, but to forge our own".
I'm really surprised records made it into the language with this approach to things.
Edit: Note: Ii use Java and C# interchangeably at my day job. Man is C# a nicer language with literally hundreds of QoL improvements that make you scream "why didn't Java adopt these?" I still reach for Java as I'm more comfortable with it and it has an unparalleled breadth of libraries.
But every time I need to write or implement and write another X.builder().setX.setY.setZ.build() instead of `new X { x=.., y=.., z=.. }` I want to claw my eyes out.
When it's ready. Again, because of Java's position, we aim for features that will work well for decades rather than those that will grab some more users now. I know this is hard for some to understand, but the main complaint we're getting is that Java is getting too many features too quickly, not the other way around. The people who like lots of features are a minority; a large one, but still a minority. Whether we add a feature or don't add it, some people will be disappointed. It's impossible to please everyone, so we try to please the majority.
> Ahahaha.
var list = List.of(
"carrot",
"fox",
"explorer");
var array = new String[]{"carrot", "fox", "explorer"};
This is not where we think the language's complexity budget is best spent. When we do add a feature to the language, we want it to have much more bang than that. Those who like lots of features don't like that but, again, they're the minority. I cannot stress enough how much people hate language features. Language features don't have Javadoc, and people have to learn them. If they have to go and learn a new feature, they expect it to be worth it.> I'm really surprised records made it into the language with this approach to things.
You mean the approach that has consistently made Java so successful? We try to add as few features to the language as we can afford to, which means that we make the features we do add extra powerful. This gives us room to add some of the features people will be asking for in ten years, rather than waste all of the complexity budget now.
> "why didn't Java adopt these?"
Because Java's strategy is different, and it's working better.
> But every time I need to write or implement and write another X.builder().setX.setY.setZ.build() instead of `new X { x=.., y=.., z=.. }` I want to claw my eyes out.
With that I completely agree, which is why we'll address that.
So, I'm likely to be dead by then.
> You mean the approach that has consistently made Java so successful?
Why are you adding all these features from all these "non-successful languages" then?
Why is it that dealing with long chains of setter methods isn't "spending complexity budget" and is a "feature more bang than that" (whatever "that" is), but adding literally the same thing: better ways of working with collections is "no, we don't adopt features from less successful languages".
The issue isn't the features themselves but the evolution strategy. Sure, we've been adopting most of the features added to Java since 1995 from ML (1972-3) and we're nearly done, but what we don't adopt is the approach of adding lots of features that each help a little. We like few features that help a lot.
> Why is it that dealing with long chains of setter methods isn't "spending complexity budget" and is a "feature more bang than that" (whatever "that" is), but adding literally the same thing: better ways of working with collections is "no, we don't adopt features from less successful languages".
We don't adopt an evolution strategy -- not features -- from less successful languages just because they're doing it. Java's strategy has been to innovate quickly on the VM (and we're innovating there more than anyone else, I think), and keep the language relatively conservative and relatively slow-moving. And it seems that more people like it this way. For the others, we make sure that the platform supports a choice of more feature-rich languages with good interop.
But the answer to your question is that we're trying to add as few features as we can (to leave room for growth in the futures, as requirements and fashions change again) and we believe that the features we do add help more than the ones we don't. Still, at the end of the day, there's hardly ever consensus among developers on anything. Whatever we do or don't do, some people won't like it. What's important to remember is that even if in some cases you don't agree with the language team's decisions, they are among the most experienced and successful language design teams in the history of software (I can say that because I'm not on the language team). They might make mistakes from time to time, but overall, they know what they're doing. In any event, the argument that millions of people prefer Pepsi to Coke is not the one that will convince Coke to change its flavour to that of Pepsi, because even more people prefer Coke.
var list = List.of("carrot", "fox", "explorer")
You are right about the builder, but most projects I have worked with use Lombok and the @Builder annotation to generate the builder automatically. I agree that a native syntax for this would be better.Are they though? I agree mutable data classes and property _setters_ are bad, but what about the rest?
I personally like the idea of checked exceptions, but there is no doubt they failed to deliver on Java. Perhaps the good parts of this idea can be salvaged by having an easy way to explicitly wrap a checked exception, like with_context() in the anyhow Rust crate. Kotlin dumped checked exceptions in favor of Results, and I don't see how Java has anything right now that supersedes that.
Explicit nullability is unarguably a good feature. You could make a convincing argument that expressing it with an Option/Maybe is better than the road that Kotlin, Swift, C# and TypeScript took. But Java's Optional<T> is not that solution, since the T within the Optional can still be null. And I'm not even getting into how verbose and unnatural using it feels, or the small issue of having to rewrite all the existing Java APIs to make it work.
The same goes for having eager collection operators. The JIT compiler might be able to inline and optimize simple stream operators, but the ergonomics of doing simple things on a collection is just bad.
But even if Java does all of that, just lack of extension methods and top-level functions make using Java a nightmare for me. If Java had extensions methods (or an equivalent concept like Type classes or the Uniform Function Call Syntax that D has), the previous complaint about lacking collection operators directly defined on Collection<T> and Iterable<T> will be a non-issue. Just let anybody who wants it define their own.
Why is there no doubt? I agree that their interaction with lambdas leaves much to be desired, but those problems can be fixed.
> Explicit nullability is unarguably a good feature.
It is. It wasn't on the list, which asked for a "null safe navigation operator"; that is not a good feature, as it makes it even harder to see where the nulls are.
> But Java's Optional<T> is not that solution
I didn't say it was. Nullability types for Java are being studied.
> But even if Java does all of that, just lack of extension methods and top-level functions make using Java a nightmare for me.
Extension methods make a language a nightmare for me, though. Java doesn't try to appeal to all people, and no language ever will. It just tries to appeal to most. As for top-level functions -- stay tuned.
What is already possible with switch expressions is branching based on type, in a much more ML-like style like case Point p -> … which doesn’t require instanceof checks and castings, but it will soon become Point(x, y), where the x, y will automatically get the values of the corresponding fields.
those feature are either horrible
I speculate that most users of languages that have these features (Kotlin has all of them) would be unhappy if you took them away. algebraic data types and pattern-matching -- will lead to better development practices, rather than making it easier to work with inferior ones.
I am not arguing against those features, but the ones I asked for seem easier to implement by comparison as they are already in other successful JVM languages.
Furthermore, they are far more frequently useful for my use case of web services storing, transforming and moving data around, often without caring too much about their semantics.
I speculate that a large portion -probably a majority- of JEE/Spring devs are in the same position.I am disturbed by how universally true you seem to consider your positions - as if there were no cases in which mutability is preferable to immutability (even if that is sometimes just due to the way some ORM or serialization library works).
If these features are such bad ideas there should be plenty of stories of Kotlin/C# devs cursing the language for providing them with these footguns.
Having a JDK dev respond like this only strengthens my argument that cageface has no reason to fear that Kotlin will lose steam - Java has different priorities. There is nothing wrong with that, but more developers who want these features should be aware that they will not be getting them from future Java versions.
Mutable records, especially primitives are a pain in the ass for C#, so it is a bullet avoided. Immutable objects are much easier to optimize away, and are safer to use in concurrent code.
Kotlin has very little impact over the ecosystem due to its small market share (compared to Java). Plus, it has no influence over the platform, or any of the other platforms it targets for that matter, with the possible exception of Android, although I guess that's up to Google. The best it can do on the Java platform is make current practices a little easier. Java, on the other hand, has the option of changing the platform and the ecosystem and moving it toward better practices.
> in other successful JVM languages
Just so that we're clear, for over a decade now, the portion of Java platform developers using all other "successful JVM languages" combined has been pretty much steady at 10%. That's not to say they're not popular in absolute terms, but Java is so stupendously popular, that it's in a completely different league.
> If these features are such bad ideas there should be plenty of stories of Kotlin/C# devs cursing the language for providing them with these footguns.
Those languages appeal to different people, and, in the case of Kotlin, at least, they're the best they can do given their clout. If I don't like something, there will be those who do. The question is, how many? When I said that the features are bad or superseded by better ones, I didn't mean they're necessarily bad for all people or all languages, just that they're either bad for Java or that Java can do better.
> has no reason to fear that Kotlin will lose steam
The way this works is that the alternative languages on the Java platform fight for market share with each other. Kotlin will not disappear because of Java, but it will eventually lose its market to some other alternative language, just as Scala has lost to Kotlin. 10% of people just prefer other languages, and I am very happy that the platform can accommodate them. We'll continue working to make sure that the platform is a good target for different languages that appeal to different people. Other languages don't take away from the Java language, but make the platform more appealing to people who prefer less mainstream languages, and so we all win. Java's 9/1 ratio of Java language vs. others is a pretty good one, and we're trying to preserve it (we would be even happier with 85/15 or 8/2, as it probably means a larger market share for the platform overall rather than a smaller market share for the language. Remember that OpenJDK is funded by people buying support; they're not buying support for the language, but for the platform). If the non-Java-language market has shifted from Groovy and Scala to Kotlin, as that's what most of those in that group prefer -- so be it (although I do wish more people use Clojure; it is, IMO, the most interesting and best design alternative Java platform language out there, and one of the most interesting and best designed languages around in general).
The strategy that keeps the VM is innovative and the language is conservative has worked very well for Java, and because it's expected to remain very popular for a couple of more decades at least, we are very careful about adding features. The goal is to avoid new features as much as possible, and the way to do that is to add fewer, but more powerful features.
C# has these "inferior practices" and is a much better language overall. Why Java doesn't adopt the low and not-so-low hanging fruit from C# is really baffling.
Anything from yes, properties, to object initialization shortcuts and a sane IEnumerable/Collection interface that doesn't require stream/toList everywhere.
Because Java is doing a lot better than C#, and obviously we feel Java is a much better language overall.
Now the "doing a lot better" is dwindling. And dragging feet on QoL isn't helping.
wat
> our goal isn't to adopt the strategy of less successful products
This sounds like "we don't care if some other languages have great quality of life improvements, we pretend that success (for some unknown definition of success) is the only thing that matters, so we'll keep implementing one or two features every 10 years that don't work with half the language and standard lib, and still require hundreds of lines of boilerplate to work with."
In a sibling comment you're pretending that withers is a thing that will ever happen. It won't, not for another ten years. Meanwhile we're left with a language that has to resort things like Lombok to try and cut down on the ridiculous amounts of code one still has to write for even the simplest things. Or almost but not quite incompatible lists and collections (none of which have even a pretence of a DX for easy construction). Or value types that have been a proposal for 9 years, and generics with primitive types that has been a proposal for 7. And the list (or collection? or stream? or?...) just goes on and on and on.
Thank god we finally got multiline text blocks and some form of pattern matching. Wait. Those come from less successful languages. How could you?
Their focus seems to have shifted to TypeScript, and that's understandable as they have far better chances for success there. Their best hope for .NET was to make it the Pepsi to Java's Coke, but that hasn't materialised (in fact, it's getting further away). .NET has not been anywhere near the go-to alternative choice for people who just don't want Java for one reason or another in years.
> This sounds like "we don't care if some other languages have great quality of life improvements
I'm sorry it sounds that way to you. It means, "we understand that some portion of developers prefer more features, but we cater to the majority, and, given that Java has a very long future, we'd rather pace ourselves." For the quick-feature-loving minority -- which we also care about -- we make sure the platform can host more feature-rich languages that interop well.
> It won't, not for another ten years.
You're very wrong about that. Remember that only five years ago, Java didn't have var, didn't have switch expressions, didn't have text blocks, didn't have records, didn't have sealed classes, and didn't have pattern matching. More people complain that Java is getting new features too quickly than too slowly.
> Wait. Those come from less successful languages. How could you?
It's not that we don't adopt features from less successful language; it's that we don't copy their evolution strategy. Our goal isn't just to make sure Java is very popular now, but also that it's very popular ten and even twenty years from now. This means that we have to budget language complexity very carefully. We also have the new developers learning Java in 2035 to think of.
C# 9 has more features in the release (one year after the release of C# 8) than java had in the past five years.
Whatever "seems" to you, it clearly isn't true.
> > It won't, not for another ten years.
> You're very wrong about that. Remember that only five years ago, Java didn't have var, didn't have switch expressions, didn't have text blocks, didn't have records, didn't have sealed classes, and didn't have pattern matching.
Me: Java is moving too slowly
You: no-no. Some people even think we're moving too fast. Here, we have five features in five years. Some of those features should've been there 20 years ago.
> it's that we don't copy their evolution strategy.
It's a great delusion. Java's development is abysmally slow. It has nothing to do with "quick-feature-loving minority" as you so condescendingly put.
Java moves in fits and starts, taking 5-10 years to add some features that often don't fit with either the rest of the language, or with half of the standard library. Almost literally everything takes near a magnitude more boilerplate to write and develop than it should. And when it's not, it's only available to some parts of the lang, and not to the other.
But when you express concern about this? Oh, then you're a "quick-feature-loving minority", and not a developer earning their living with Java and hoping for any meaningful improvement to it.
Oh, I'm sorry. I'm not smart enough to understand why a possible solution to tolstoyesque method chaining calls that will maybe come to Java in 10 years is "evolution of the language", but literally the same solution to collections (and unifying lists and arrays) is "a quick feature from less successful languages, and we don't adopt evolution strategies from those".
As I don't understand a hundred other things that can elevate Java-the-language from mediocre to great.
Not even close. They're adding small features to the language, while Java adds huge features to the runtime. .NET is 10-15 years behind Java on the runtime. Roughly speaking, Java's philosophy (going back to Gosling) has been to innovate on the runtime and keep the language conservative, while .NET's has been to add a lot of features to the language and keep the runtime relatively crude. There is no indication that changing our strategy would be a wise move.
> Some people even think we're moving too fast. Here, we have five features in five years.
Not some; most. Most people prefer fewer than five features in five years, even though many prefer more. I really wish we could make both you and the others happy, but I don't see how we can do that other than what we're already doing: have Java be the popular mainstream language, and support other languages on the platform for those who prefer something else.
> Some of those features should've been there 20 years ago.
Should have been there so that what? Or at the expense of what? Our goal is to build a successful language used by millions, not to push the envelope in programming language design (although we are pushing the envelope in runtime design). We introduce features when we think mainstream programmers could use them in the best way, and we add them slowly enough so that we're not overtaken by fashion and we have room to grow for decades. You may not like it, it's okay, and it's even perfectly reasonable. But this has worked really, really well.
> It's a great delusion.
Fine. Maybe you have more access to market data than we do. Fact of the matter is, no other language is doing any better, and Java has fewer serious competitors today than it did in the last 15 years.
> But when you express concern about this?
I am not dismissing your concerns. I am merely explaining that we have about ten million other developers we cater to aside from you, and they don't all share your opinions. Your views are far from unique, and we are well aware that many people want the language to evolve faster -- and that's perfectly legitimate although I personally don't think it's a good idea for such a popular language -- but even more don't.
Ah yes. Using a single common way to initalize things and unifying arrays and lists (so that you don't need helper modules, and you don't have to rely on the kindness of libs to provide .of methods) is "fashion" (as are many other things).
But "yeah, we will maybe some day 10-20 years from now provide a way to build records, and only records, in a way that doesn't require hundreds of lines of boilerplate", that's long-term strategic planning and evolution.
Well, we're talking past each other. I'm well aware that any change in a language the scale of Java is a daunting task. But the condescending tone that dismisses something as "features for the quick-feature-mided fashion crowd" clearly shows that it's not these concerns that drive these decisions, but purely subjective outlook on things.
I think that being honest about our strategy that dates back to Java's inception -- an innovative runtime and a conservative, slow-changing language -- that has worked well for us and so we're sticking to is more respectful than giving you some non-committal marketing response. I think you should also be respectful and understand that the Java language team is one of the most successful and experienced language design teams in the world and know what they're doing, even when people might disagree with some decisions. Even experts disagree, and people have different tastes (I find C# and contemporary Kotlin positively garish, while I think Clojure and Zig are elegant and beautiful).
And the language features Java does intend to adopt will come quickly, just as the smallish-medium ones over the last few years have. I believe lambdas were the only language feature that took more than a couple of years to deliver. Once the language team decide they want a feature, they deliver quite quickly. The features that take a long time are usually changes to the runtime (what I mostly work on), not just the language.
As far as runtimes... CLR bytecode is expressive enough to compile C++ into it. Try that with JVM.
https://docs.oracle.com/en/java/javase/17/docs/api/java.base...()
Otherwise, you've got a high risk of developers inserting a ? to fix a bug, which only fixes the symptoms.
As of now, Optional#map seems to be the way to go.
Re: Streams API that allows checked exceptions. Brian Goetz has written about this issue. (Search StackOverflow.com) They did not allow because of the optionally parallel (threaded) nature of streams. If multiple parallel streams throw an exception, when/when/where/how are the exceptions re-thrown? Moving exceptions across thread boundaries is a tricky thing in any language. If you don't care about parallel streams, there are many open source projects that effective create a nearly identical Streams API but allow throws Exception everywhere. Are these open source solutions insufficient for your needs?
Re: adding functional methods like... Is there an advantage other than typing nine less characters?
Not really. C++ has std::exception_ptr for that exact reason, and C# has ExceptionDispatchInfo. Both are very straightforward - you catch the exception, get a handle for it, and then re-throw that handle in another context, with original stack trace preserved.
Multiple concurrent exceptions is also a solved problem. In C#, if you do something like Task.WhenAll(), and one or more task throws, you get back an AggregateException, which can be inspected to see which task threw what. The same can be applied to async streams.
What matters more in all honesty, and what's hard to change IMO is:
- The base of the language (is it verbose, how the base features interact with each other) vs being "tacked on". A language with these features initially. e.g. you mention F# and I know it uses HM type inference, immutability by null, makes null hard to express by default, etc.
- Anything that breaks backwards compatibility (e.g. Java's generic implementation) for example including existing API's. Adding Async afterwards takes time, and changing the underlying model of the language (e.g. Python's GIL, OcAML multithreading) takes time and needs a lot more consideration. Its code, anything can change, its just harder and maybe easier to take something that was designed for that case initially. Being a polygot isn't a bad thing per se I think if it can be justified tech wise.
Java improving borrowing ideas from other JVM languages had happened in the past, and that has made the ecosystem stronger. Nothing unfortunate about it.
- Explicit null
- Extension methods
- Getters/setters which use property syntax
- == instead of Object.equals confusion
Also Kotlin's this-scoping and delegated properties, while they take a while to get used to, can be incredibly useful. They make it possible for to write typesafe DSLs like kotlin-html.
Moreover, Kotlin is usually very easy to integrate with existing Java projects. Setting up Kotlin in Gradle is just adding a plugin, and Kotlin automatically imports and exports java code. And it runs on the JVM so it will support most platforms that also support Java. And one of the top Java IDEs and contributors (JetBrains) maintains and prioritizes Kotlin.
Long term this could lead to a loss of maintenance for tools and libraries for these languages which could kill them and leave those that migrated with a dead & decaying ecosystem.
Of course this is a bit of a stretch but it's not unheard of.
Silhouette is probably just because of one guy's schedule, but Play/Slick seems like after-effects of lightbend's layoffs many months ago, and while I don't know the cause of those it seems plausible it's because of the kind of thing you describe above.
I'm guessing Java hate, which is kind of fashionable. If Java evolves to stay relevant, it won't be usurped and fade away.
Personally, I think one of my favorite things about Java is that, all things considered, it's a small-ish language. So I'm glad that Java is both willing to evolve (slowly, letting other people try stuff out first) but also clearly focused on a curated feature set and resistant to letting new stuff in to bloat it. I am very happy to deal with minor things like no multiline string support if it means we get to avoid being a terrible mess of language features that ruby, scala, python, etc have accrued in a relatively quicker timescale.
I was fairly sad around the java 6-7 days where we went quite a long time with no visibly major new language features (diamond inference was 7's big thing, lol). So it is nice that we're moving a bit faster than that, now.
It will look something like this:
STR.”text with \\{variable}”, but anything implementing the TemplatedString interface can change the behavior of interpolation. There is not even a requirement to produce strings only!
A lisp-er would probably say that CL is so malleable that it hasn't needed to change, but I'm not so sure about that.