This is incredibly useful when you pair it with RPC and a shared domain model.
In Java, one creates a 55 lines getter-setter class with concurrency bugs and accidental mutation risks, and maybe plus a 55 lines Builder too.
Whilst in Scala I create a 5 lines case class, immutable and thread safe, all that's needed.
* Type-safe metaprogramming (like F# type providers)
* Structural Typing
* Extension methods
* String interpolation
* Templates
* Type-safe reflection
* [Un]Checked exceptions
Try to use Kotlin sequences, co-routines, lambdas (not SAM types) or operators from Java code.
I don't want to bother with extra layers or be bound to JetBrains tooling.
It is another layer exactly because you need to translate back those bytecodes into Scala semantics when debugging, when everyone wraps Java libraries into Scala idiomatic wrappers.
I was referring to Kotlin regarding JetBrains.