>This is not unique to Java and this difference is present even in a modern language like Rust. Primitives are copied by value, objects are copied by reference. If you want copy by value use Java records:
You're confusing my copy-by-value-copy-vs-by-reference criticism with my type system criticism. The point you're replying to is a point about the type system. Rust has no notion of a unified type system, so it can do whatever it wants. (It's still better to not have too many exceptions and special cases in your type system, I don't know enough about Rust to know if this is the case there.)
Java announces at the start that all types share a common ancestor, an idea it got out of objective-C which got it out of smalltalk. If you're going to do that, you better go all-in and make sure that ALL types really do in fact share a common ancestor. Objective-C couldn't do it because it was wrapping C, but in a new language there is no excuse to make a rule then immediately listing several exceptions to it right off the bat. Scala and Kotlin are proof it can work, your primitives are compile-time objects that you can call methods on and do all the things you can do to objects, the compiler decides if your code can compile to JVM primitives (and therefore the method calls are static function calls) or if you had done something that requires boxing like Generics.
>Because the JVM does escape analysis and performs automatic stack allocation
There is no reason it can't do all those things and give the developer the ability to explicitly specify that they want this data on the stack, for all the data that can be allocated on the stack (e.g. not dynamically sized arrays). The object representation is a low level yet very important question that shouldn't be monopolized by the language.
There is also no reason to bake what I'm saying into the JVM, the compiler is there. It can "unwrap" the objects that you stack-allocate into primitives (recursively) and translate all the code that manipulates the objects into equivalent code that manipulates the underlying primitives. The JVM would be none the wiser, all it would see is primitives.
This is what I mean when I say that Java is an assembly language, it tries too hard to reflect the underlying VM, developer ergonomics and productivity be damned.
>Deliberate design decision.
I never said it's accidental, I said it's bad and ugly and horrible for developer productivity.
>This is just done once at class declaration
And is this a rare thing in java ?
>easy and no-nonsense grepping of sources from the CLI
Regex is far from a no-nonsense solution to anything, for one thing it's sensitive to spaces and newlines. You can't match "class foo <newline and several tabs later> implements Iinterface" for example unless your regex explicitly and verbosely account for it. Kotlin's regex won't be anymore difficult than the equivalent java one that handles the same edge cases, syntax easy for humans is syntax not too difficult for machines.
Here is an example :
"class [^:]+:(\s|.)*Iinterface"
This matches all classes implementing Iinterface, accounting for any whitespace and the fact that Iinterface might not be the only interface implemented. This is pretty mild by regex standards.
>Satisfied by records now which are meant as the placement for POJO's.
Being late matters. Generating things automatically isn't rocket surgery, it has been done by languages since forever. It isn't enough to wake up, you have to do it at morning.
>Classes should now be used for services
Keyword is "should". Good luck forcing it on a community after being late for 20 years.
>which you _don't_ want generated constructors.
So override them. If you already know that you don't want constructors and you're going to override them anyway, why should the language force everybody to conform to your choices. Generating obvious things should be the default, it's up to you, as a person who wants to override the defaults, to know that you should override the defaults and go override them.
>Looks like you are ~10 years out of date on Java tech and community
I'm right here in this day and age, and no the horrible excesses and design pattern fetishism never went anywhere in the vast majority of non-performance-critical code.
>Perhaps look at some of the modern java libraries
Does Android count ? because I have seen things there you wouldn't believe, 7-class deep stacktraces full of "abstract" and "Impl".
> GraalVM
It's hardly fair to claim that a compiler\VM codebase is typical code.
>Kotlin readability is poor.
This is what I call the "COBOL view" on programming language readbility. The language should be as verbose as possible and full of natural language words to imitate an informal document.
Needless to say, I'm not very keen on this view. It's misguided. Readability is precisely when the language gets out of your way. For this to happen, it's crucial that it's not verbose, if you want verbosity later you can add it with vebosely-named language abstractions. In a language that allows macros (which isn't kotlin), you can make "implements" a keyword, if you want.
The keypoint is that verbosity and extreme detail is not readability, not always. Even in natural language. Readability is what happens when the problem is described at the exact level of verbosity that makes its solution fit in one human brain. The language shouldn't claim to know this level in advance for all possible problems, it should be as austere and as minimal as superhumanely possible, it should get out of the way and let those describing the problem decide how it should be described, because they know better (about the problem) than any language designer.
In other words, you can make Kotlin verbose for problems that benefit from it, but you can't make Java not verbose for problems that benefit from it.