I suppose, though, that after spending enough time immersed in a language, even such inconsistency stops being a real obstacle to anything.
As far as I an see Scala has achieved something no other language before did:
1. For the first time, achieves a successful marriage between ML-style functional programming and class-based object-oriented programming (OOP) with subtyping a la Java. Scala achieves this by building functional programming as a special case on top of class-based OOP. Previous attempts at unification (e.g. Ocaml) tried instead to base OOP on top of typed λ-calculus.
2. Scala even improves on ML in that it fuses the language of programs with the language of module systems and brings type-inference to both (albeit partial). It fuses the two without any real compromise on each, indeed one could argue that both were improved since ML's module system doesn't have type inference.
3. Smooth integration of higher-kinded types with OO programming.
4. Having an advanced language running on the stable and well-libraried JVM eco-system. Usually languages with as much novelty as Scala, remain in academic obscurity.
The unity of Scala is witnessed by the fact that it can all be compiled down to a rather simple calculus, namely "dependent object types" (DOT) [1]. I'd say that DOT is to Scala what lambda-calculus is to Haskell. I find it hard to think of another language that combines so much expressive power with being simple and coherent.
[1] T. Rompf, N. Amin, Type Soundness for Dependent Object Types (DOT), http://lampwww.epfl.ch/~amin/drafts/dot_oopsla16.pdf
I didn't say Scala was inconsistent, only that it felt as such. I've lost access to that codebase since the end of my participation in the project, so I won't provide you with code examples, but the project was using most of the language features available to date (2015). Maybe "inconsistent" is a wrong word. "Messy" would be better. I've been familiar with many of the concepts in Scala from other languages, and here it felt like they were glued together with gratuitous use of syntax and implicit type conversions.
I apologize if my previous comment didn't state it clearly enough, but I'm talking about my impressions of the language here. I'm convinced that after enough time, the whole package starts to make sense and becomes a very powerful tool in one's hands (I have a reverse situation with pre x11 C++ - it was the first programming language I really learned, so all its idiosyncrasies people like to complain about felt completely obvious and justified to me).
One day I hope to immerse myself in type theory deep enough to actually understand the underpinning of Scala better.
If Dotty works out then we will, for the first time, have a fully specified Scala on sound theoretical footing. Along for the ride: much faster compiler, better tooling, streamlined type system, and nice-to-haves like union types and implicit function types, among other useful features.
In general, it's OK for there to be a gap between a real programming language, and its theoretical toy model. That's the gap between theory and practise. Why would you care about theory if it was as complex as practise? The ideal case (embodied in the lambda-calculus) is that the theory is much easier, but looses only a modest amount of precision.
For the complexity problem, here is how I manage it : the functional programming scala is scala, everything else is garbage included for java compatibility. It works like a charm.
I can't think of a language I could feel better with.
There are some pains associated with Scala, though. Sometimes self-inflicted by people who want it to be like Java: for example, most ORMs for Scala suck. A team at my office tried to use Hibernate to disastrous effects (Scala and Hibernate's hostile takeover of collections don't play well). Even some DSLs like Scalike tend to also be painful and unwieldy. I also dislike Play and its multitude of quirks and incompatible versions.
It used to also be the case that both Eclipse (ScalaIDE) and IntelliJ IDEA were almost unusable with Scala, in particular constantly resulting in spurious compilation errors. I've no idea if Eclipse got better -- completely got rid of it after decades of using it with Java -- but IntelliJ did get better and mostly works (though it still cannot always compile Scalike DSLs).
But even with all of the above, when I have to work with Java code again I cringe. Even with all the pain, Scala is simply better to work with for new code.
There's nothing "shaky" about Scala's complexity, it's quite stable, and not going anywhere until Dotty lands circa 2020.
Despite everything (slow compiler, average tooling, implicit/operator overloaded "magic" code bases, etc.) Scala will draw library creators (like those behind Spark, Kafka, Akka, Play, etc.) which in turn draws developers, resulting in the thriving ecosystem backing the language.
Scala will live on despite itself; the ecosystem is what will carry the language to the Dotty land and beyond.
First, IntelliJ is quite decent nowadays. So it's demonstrably possible to build a decent IDE for Scala.
Second, Eclipse itself has imploded in my opinion. Eclipse used to be a usable and reasonably fast IDE. Then, some years ago, there was noticeable increase in bloat and a downgraded performance for Java. I remember reading some major release of Eclipse, which required a refactor of its UI, didn't have any automated tests because the refactor broke them and there was a lack of volunteers willing to fix the tests. Nowadays I've stopped using Eclipse even for Java, because I cannot stand its slowness and random freezing/crashes.
I understand that not everyone has this experience, and would love to see more/better tutorials for Scala come out, but I've definitely seen several people pick it up without any problems.
I guess in Java we are spoiled - though sometimes stifling, the rigid structure and syntax help prevent people doing "bad things". It has struck me once or twice these restrictions may have been derived in part from established C++ best practices ...
Nothing requires a rewrite, but five year old code looks nothing like what people say is "best practices" now.
http://www.scala-lang.org/blog/2017/02/28/collections-rework...
Although, once you do, you can really get to work composing the features in interesting ways to get really useful effects. Like implicits + higher-kinded types to get ad hoc polymorphism. Or subtyping + pattern matching to achieve incredibly self-descriptive business logic. I would certainly agree that Scala appeals to people who like to be able to experiment and engage with more theoretical concepts while getting things done.
But let's not pretend that most languages don't have this issue. Programming with major Ruby and Python libraries tends to eventually require you to learn what's going on under the hood in the same way. I would argue that once you start digging under the surface, Scala is much more elegantly designed than those languages.
Go is about the only language that seems to say, "forget theory, we're simply about getting things done". Not my thing, but I understand the appeal!
Guys... if only experienced Scala people enjoy reading Scala code, then you kinda have an adoption problem
Of course, Scala frameworks and its use in large systems might be different things -- though, having used Scala for my day job, I'd also disagree with that.
Odersky often says that the mutability should be as 'contained' as possible in what is otherwise a largely immutable codebase. If you can reason cleanly about a black box and are sure that the mutable variables within are not going to 'escape', you get the benefits of both
1. easier to implement, imperative algos which have been around for decades. (the alternative in pure FP is to convert stuff to tail recursion, which is not always the easiest thing to do, let's just say.)
2. easier reasoning about state not leaking to the rest of the system.
I've found following these guidelines to be very helpful.
He's 100% correct (at minimum).
> the alternative in pure FP is to convert stuff to tail recursion
It's a challenge but not THAT difficult, once you get the hang of it. :) I've found conversions fun, actually. Especially when you (of course) have to learn how to trigger TCO. The irony here of course is that at the machine language level, the recursion is converted back to imperative via TCO. But IMHO the resulting recursively functional TCO code is, eh, "more beautiful"
I also prefer cleaner languages. But, in practice, I must choose between Java and Scala, and I'd choose the latter any day, with my eyes closed!