For some examples relating to business logic, see https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/...
Lots of compilers are written in functional languages and use pattern matching for traversing abstract syntax trees, dispatching on the node type. The OO way to do this is to put all logic relating to a particular class in the class itself. The functional approach is to put all logic for a given method/function in one place and handle all the different types. They are two different philosophies both with different tradeoffs, and which is best depends on the type of program you're writing. But it's nice for a language to support both, so you can pick and choose which approach is best for a given problem.
The pattern shows up a lot with result and option types but you can do it any other time where a tagged union makes sense. The classic way to do a tagged union in Java was just a personal taste amongst bad options: tagging interface and instanceof on implementations or an encapsulating class that will return null (or throw an exception) if the gets are called for the types which aren't encapsulated.
If in your career you never needed to enumerate cases that required different data in each case and you couldn't see how binding those requirements into an invariant via the type system was helpful then you probably won't use these new features either. Some people thought it was helpful but the boilerplate cost was too high so wouldn't do it in practice (I am in this category).
Edit: you could also make tagged unions more type safe with callbacks, but then implementing a closure to pull the value out of the callback was just annoying.
It's fair that you've found sensible ways to achieve your goals without ever needing pattern matching. Nobody should fault you for that. But can you grant that other developers might have other sensible ways to achieve other goals (or sometimes other ways to achieve the same goals!)?
I think most Java developers will be familiar with the visitor pattern. In almost all cases (there are exceptions!), I detest it; I find sum types with pattern matching to be a far superior way to say what I mean. Java added `sealed` interfaces recently, so you can actually model a closed family of types. Now pattern matching closes the loop, giving you a supremely ergonomic way of dispatching over that closed family without using a visitor.
Maybe it's not clear from other responses, but the part of the JEP about an "exhaustive switch" is critical here. Java statically guarantees that you've handled each member of your closed family, just like if you forgot to implement a method for a visitor.
It's ironic because you're throwing shade at Javascript when JS developers are doing the same thing against Typescript. Fearing what you don't know or understand under the guise that change is bad or things are "good enough".
I think messy fits.
Showing your opinion doesn't make it immune from critique.
If anything, this is _not_ something JS devs are asking for, but rather devs using functional languages.
And if you're strongly typing your system rather than relying on strings, extra so.
This feature aims at the conciseness of first model (instanceof) with the safety of the second approach (i.e. all types are handled).
I would love this feature for my project! ( https://www.adama-platform.com ) since I use Java to implement a programming language.
In applications yes, but instanceof is heavily used if you write frameworks.
And as someone else has mentioned, the more functional style java you write the more use you start to make of instanceof
This might be a casual dismissal of what is in fact a nuanced aspect of programming languages.
Multiple ways of doing the same thing can make the language less accessible because it becomes confusing to reason about what the "right" way is.
That said, this particular addition merely reduces repetitive toil, and it follows similar existing Java conventions, for example see the Java-7 equivalent of Python "with-statements".
Bjarne Stroustrup once noted in Design & Evolution of C++ that people want different things from the seemingly simple artifacts we call "Programming Languages". Some people want an algorithmic language to express procedures cleanly in, others want a design language to express large scale systems in. Some want a terse and uniform "executable mathematics" notation, others want a down-to-earth worse-is-better lets-make-some-goddamn-apps-and-put-some-fucking-bread-on-the-table working class language. Some want a language with an emphasis on the lone author, others an emphasis on the corporate business team. A language as a tool that you wield skillfully for the single purpose it was built for, a language as a toolbox full of gadgets, a language as a material to build the previous two from, a language as a community hub to organize around, etc etc etc. I have seen people argue that "Language" the wrong metaphor to understand computer notations entirely.
This is why you can't say anything general about programming languages.
You're welcome to switch your language of choice to go if that's really your bag.
Java has none.
In most standard IT applications it may be less common. I've seen it used fairly well in scientific applications. There are of course other ways of approaching working with and acting on wide taxonomies of objects that could exist but this is one of them.
I started programming in Java in 2002. I had some of your stated attitude learning Scala ten years ago. Probably because I grew up on Turbo Pascal and C++ , majored in EE, and didn't hear about PL theory. I cannot fathom anyone wishing to go back to Java after using Scala (as a better Java, without cats/scalaz&Co) or at least Kotlin. The way you describe new Java features I'd think you come from a golang background.
I have nothing against staying on the JVM for the rest of my career. For this to be feasible we need modern languages fully supported and popular. I personally want more concise syntax and more elegant abstractions in my daily life.
In terms of the classic 'patterns', it's the difference between standard dispatch and the 'Visitor' pattern. There are cases where you want to specify each case of data structure locally, and others where you want to specify each method of each variant locally. Welcome to the expression problem!
There are cases in Java where you do want a true POJO - just a bag of structured data. This is probably a very strong candidate for using along side that.
This is... just wrong.
Plenty of people are using JS without any sort of typing whatsoever. Other dynamic languages, like Clojure, Gradle, Elixir, Pharao (a smalltalk), just to mention a few, are still going strong.
> they have this webassembly, that runs in a schizophrenia-type VM wannabe
wasm is mostly being used as a target for C(++), Rust and even C# programs that want to run in the browser. It's there to expand the reach of the browser. Most JS projects don't touch the stuff.
because... JS isn't good enough?
Thinking you have an I-told-you-so moment with static typing and dynamic languages only shows you don't understand the details and tradeoffs in the design space. For example TypeScript's approach to static typing is very different to Java's and these differences reflect consideration of the problems being solved, JavaScript's specific use cases, its history and the path dependence of its design. Because these details are invisible to you the whole thing is simplified in your mind to "everyone is switching to static typing just like I said they should!" In fact this type of prognostication was never useful or meaningful. The hard part wasn't deciding to build static typing onto JavaScript. The hard part was determining specifically what that should look like, how it would fit nicely with the language and then doing the work of building it and driving adoption.
TypeScript is successful not because it is static typing but because it is a form of static typing that's exceptionally well suited to JavaScript and its use cases. If people like you had their way it would have been a failed attempt to bolt a Java style type system onto JavaScript, worsening the design debt in a language and ecosystem that is already loaded with it. This already happened on a smaller scale with classes in ES6 which were driven by Java devs writing JavaScript and wanting something familiar instead of trying to understand the language.
You might be right that adding pattern matching to Java isn't a great idea but at the moment your disagreement is based in ignorance. You've been given ample explanations of pattern matching in this thread. Put down the ego and take some time to learn on your own.
Now that functional stuff and instanceof fluff is something else. I don't like it either.
It much depends on the task of course. My biggest project in Java was a SAT solver years ago, and millions of little clauses did not sit well with it at all. I ended up changing the data organization internally. My first attempt, the natural AOS would have been also the best choice performance-wise in C, but in Java it choked the GC. I had to switch it around to SOA which was quite awkward but it reduced the number of objects from millions to a small constant.
Also thinking of the number of lines of code running for JIT, GC, whatever... in the background all the time...
In projects where you can’t get away from object allocation (due to it being less deterministic for example) with some clever trick like arenas and the like, chances are the GC will be actually much faster than malloc-ing them all — and while it may not sit well with you, GC running in the background just amortizes the cost of each deallocation to basically zero time overhead (of course at the cost of memory overhead).
But I’m not trying to dismiss your experience or anything, the JVM has its place and of course there are plenty of use cases where it is not the best fit at all.
And that statement was not about the allocation time. But my understanding is that deallocation (GC) is not amortizable to constant for long-lived objects.
We can probably agree that having to code a separate class (with object overhead) to represent each little tuple of 2 integers or so, is bulky - programming-wise but also concerning the memory overhead (and possibly GC overhead).
Programming in C does not imply using malloc() to allocate individual objects. This is a bad practice.