> Java has been gradually eating all the good parts of Scala. So far, it's eaten lambdas, map / reduce / fold functions, option types, raw string literals, the concept of a built-in REPL, type inference for local variables, and default methods in interfaces (which is kind of like mixins).
If you adopted Scala 5 years ago, you could have had all the good stuff Java has today, 5 years ago. If you adopt Scala today you can have all the good stuff Java will be getting in the next 5 years, today.
> Pattern matching and type classes are on the menu, but not yet formally merged into Java.
How many years or decades will those "formalities" take? Java language enhancements have a history of taking much longer than originally claimed.
> Operator overloading, which tends to lead to unclear code.
The problem with traditional operator overloading is that you have to memorize which symbol corresponds to which magic method name (I can never remember what method * calls in Python, for example). Scala avoids that because it doesn't actually have operator overloading; rather, operators are just normal methods that you call in the normal way.
> The ability to embed XML into code (why?).
Already moved into an optional library, being dropped entirely in the next version.
Replaced in the next version. (And the complex parts were only ever for doing things that are completely impossible in any other language).
> So what does Scala have left?
Higher-kinded types (which let you represent secondary effects in a uniform way - obvious things like validation or async, but also custom effects like database transactions or an audit trail). Uniform representation of structures/records (via Shapeless) that lets you traverse data structures in a normal, type-safe way.
Put that together and you get a language where you never need the magical frameworks that (real-world) Java needs. No reflection-based runtime serialization that you have to control via a type registry separate from the language type system. No reflection-based database mapping that you have to control via another, subtly different type registry. No AOP decorators where you rename a method and it magically stops having a database transaction applied. No magical annotations for your http routes that tell it which string class name to load at runtime for serialization, where if you want your web threads to do something before/after you use yet another magic method or registry. No magical autowiring framework instantiating all your classes for you.
Just plain old functions and values. Standard language features (plus one macro in shapeless that might as well be part of the language for it's used) for all of the above. One standard syntax (for/yield) for effect management that all the language tools understand. Libraries for things that would be language features in most other languages, but without having to resort to the free-for-all of custom macros.
That's what Scala has. If Java catches up to that one day, great! But without higher-kinded types, and without some kind of uniform representation of records/case classes/data classes/what-have-you, it will never get close.
> The problem with traditional operator overloading is that you have to
> memorize which symbol corresponds to which magic method name.
That's not even in the top 5 problems with operator overloading.
> How many years or decades will those "formalities" take? Java language
> enhancements have a history of taking much longer than originally claimed.
Almost certainly a shorter amount of time than it would take to migrate our
codebase away from Java. Oracle has actually been moving pretty fast with Java
recently, for better or worse.
> [XML is...] Already moved into an optional library, being dropped entirely in
> the next version.
And this illustrates another problem: Scala is constantly breaking backwards
compatibility. Which is a real-world problem, unlike "I want the latest
gee-whiz language feature."
> Put that together and you get a language where you never need the magical
> frameworks that (real-world) Java needs.
Scala has plenty of "magical frameworks": scalaz, akka, shapeless, the list
goes on.
Newer Java libraries like Jackson don't need a type registry (or at least, not
one that have to manually set up.)
I won't try to defend J2EE or Hibernate, but also, I don't use them.
> That's not even in the top 5 problems with operator overloading.
What other problem is there? Some libraries define functions with stupid names and that's a problem, but it's a problem you have without operator overloading too.
> Almost certainly a shorter amount of time than it would take to migrate our codebase away from Java.
I rather doubt that; a typical codebase has a half-life of what, 5 years? Which is less time than many of the Java features you listed have been delayed for.
> And this illustrates another problem: Scala is constantly breaking backwards compatibility.
Hardly. One major compatibility break in the language's entire history, eight years ago; removal of XML literals will be part of the second, and is only happening after they've been a) universally agreed to be a bad idea and b) deprecated for four years and counting. Yes it's not quite the extreme levels of backwards compatibility that Java offers, but it compares favourably with most languages out there.
> Scala has plenty of "magical frameworks": scalaz, akka, shapeless, the list goes on.
Maybe some parts of akka (I don't use it), but certainly not scalaz or shapeless: they're libraries, not frameworks, and there's no magic (no reflection, annotations or anything like that, aside from the one macro I mentioned), just ordinary values and ordinary functions that you call in the ordinary way (even the macro behaves like one).
> Newer Java libraries like Jackson don't need a type registry (or at least, not one that have to manually set up.)
If you adopted Scala 5 years ago, you could have had all the good stuff Java has today, 5 years ago. If you adopt Scala today you can have all the good stuff Java will be getting in the next 5 years, today.
> Pattern matching and type classes are on the menu, but not yet formally merged into Java.
How many years or decades will those "formalities" take? Java language enhancements have a history of taking much longer than originally claimed.
> Operator overloading, which tends to lead to unclear code.
The problem with traditional operator overloading is that you have to memorize which symbol corresponds to which magic method name (I can never remember what method * calls in Python, for example). Scala avoids that because it doesn't actually have operator overloading; rather, operators are just normal methods that you call in the normal way.
> The ability to embed XML into code (why?).
Already moved into an optional library, being dropped entirely in the next version.
> A collections library which is nightmarishly complex. (See https://yz.mit.edu/wp/true-scala-complexity/ )
Replaced in the next version. (And the complex parts were only ever for doing things that are completely impossible in any other language).
> So what does Scala have left?
Higher-kinded types (which let you represent secondary effects in a uniform way - obvious things like validation or async, but also custom effects like database transactions or an audit trail). Uniform representation of structures/records (via Shapeless) that lets you traverse data structures in a normal, type-safe way.
Put that together and you get a language where you never need the magical frameworks that (real-world) Java needs. No reflection-based runtime serialization that you have to control via a type registry separate from the language type system. No reflection-based database mapping that you have to control via another, subtly different type registry. No AOP decorators where you rename a method and it magically stops having a database transaction applied. No magical annotations for your http routes that tell it which string class name to load at runtime for serialization, where if you want your web threads to do something before/after you use yet another magic method or registry. No magical autowiring framework instantiating all your classes for you.
Just plain old functions and values. Standard language features (plus one macro in shapeless that might as well be part of the language for it's used) for all of the above. One standard syntax (for/yield) for effect management that all the language tools understand. Libraries for things that would be language features in most other languages, but without having to resort to the free-for-all of custom macros.
That's what Scala has. If Java catches up to that one day, great! But without higher-kinded types, and without some kind of uniform representation of records/case classes/data classes/what-have-you, it will never get close.