So like with pretty much everything you can hear people saying that Scala is trash for X or Y reason where both X and Y are completely opposite.
Most of the time you would hear the opposite, that Scala is pretty difficult because of all the functional aspects; anyways let me try to share what I think about most of the points you shared.
Scala’s attempt to ‘fuse’ FP and OOP is one of the many things that hurt its design.
AFAIK F# is also a mix so not sure what his / her point is.
Actually, the little I know about F# was because I researched about it in my university for a class on programming paradigms and the cool thing of F# was being multi-paradigm (although I believe you have like to turn one paradigm and shutdown the other, not literally).
I actually liked the idea of being multi-paradigm but never liked the syntax, similar to how I liked my FP class but never like Haskell; thankfully I learned about Scala after that.
(BTW, and a bit in rant mode, I was looking at the code I wrote for that presentation and dude, I can’t read it the syntax is way complicated; I can read and understand older Java projects but not that)
The major practical point of moving to a functional language is to get away from OO thinking.
This just shows that the person writing this doesn’t really understand what OOP is, what FP is and what imperative programming is.
Yes, one usually embrace functional programming to avoid practices common in traditional imperative and object-oriented programming languages, but that doesn’t mean that OOP as a whole is bad and that you can’t or shouldn’t use that on a functional codebase.
But overriding their meaning (and worse, semantics) to achieve that is many times worse.
No example was shown. I can’t think of a keyword that has multiple and different meanings on its own; the only two things I can think of is the multiple meaning of _
which I do agree sometimes it is abused but in general, it means “anything” or “everything”, and implicit
which depends on the rest of the line, and yes that was a pain point that is addressed in Scala 3.
Objects are great when you actually need them (EG - for components) but object- orientation is just not good in most situations. Coupling program behavior with representation generally inflicts much incidental complexity in programs.
So here he / she is contradicting himself / herself. Because nobody forces you to write Scala programs like this was Java with lambdas; even more, such style is discouraged.
See also Scala’s atrocious collections library in detail.
I have mixed feelings here.
I personally also believe that the collections library is way more complex than needed, I have discussed with many of their contributors how I personally feel most of the abstractions they provide are “useless” and how I personally would prefer if it was really a bunch of concrete types and a lot of typeclasses.
Yet, I immensely value all that the stdlib provides for us and the work and motivations of the authors and maintainers.
In the end, most of that complexity is transparent to users and it is actually pretty powerful so I would never call it “atrocious”.
Scala constantly violates the principle of least surprise nearly everywhere in its usage, whether you’re an OOP or an FP person. From which perspective was X language feature designed? One or the other, sure, but you’re typically left guessing, then referring to the spec.
Again an example would be good.
I actually have never felt surprised by a Scala feature in a bad way, I usually feel surprised for how cool / useful / interesting / powerful some of their features are.
The elephant in the room is initialization order which can cause damn hard errors, but at least we have tools to diagnose and fix that.
There is almost no consistency in or predictable model of thinking for how Scala is defined. People still can’t pinpoint what the basic programming idioms for Scala should be! This partly goes back to the fusion, but also can be blamed on Scala’s general incoherence of design.
While he / she has a point in that there are many ways to write Scala code, I always believe that is a feature, not a bug. It gives you the power of freedom.
Yes, as with everything, it has its bad things, newcomers have to choose and sometimes you may find a great library that is intended for the other style.
However, there is a minimum base with most of us agree with (yes there will always be extremists):
- Using Option instead of
null
- specially for public things.
- Being immutable in general, especially for public operations - that may be implemented in a more imperative / mutable form if that makes it more efficient or more readable.
- Prefer higher-order functions like
map
, filter
, exists
, foldLeft
, etc; instead of plain iterations.
- Take advantage of the guarantees of a strong type system.
- And many but not all like to turn errors into values instead of throwing exceptions.
Also, for newcomers they can start with just vanilla Scala and then pick up an ecosystem latter when they have more experience to make the decision.
And finally, there is usually possible to mix those ecosystems to some degree when that makes sense or when you want to migrate.
Scala is hugely complex with surprisingly little payoff in expressiveness.
Compared to what?
Like I tried googling and I do not find an equivalent of copy
nor a way to define typeclasses in f#.
Also, yeah **Scala¨¨ is complex yet I have found it easier to learn and teach than Python the king of simple languages.
This is especially true for the type system. We get the complexity of type inference multiplied by that of implicits / sub-typing / variants / etc. The complexity of the type system is combinatorial! At the same time end up with weaker type inference than F#.
Yeah, yet I mostly never have type inference problems, many of them are easy to fix and most of them will be fixed entirely on Scala 3.
On the other hand, we have all the advantages of having such a powerful type system.
Did we really need co/contravariants to make the type system even more incomprehensible than it already was? Maybe, due to its mutant fusion of OOP/FP… But that’s where coherency in design decisions must come in!
Sure and Haskell keep saying subtyping is unnecessary and that a Monad
is not an Applicative
, and Python and JS people keep saying that types are unnecessary. - Oh wait, no, they either changed their minds, or keep denying even after more and more evidence says the opposite.
Scala essentially combines the complexity of C++ with the speed of Java. It combines poor-support for generic types with a very ambitious type system. It really is the worst of many worlds.
Do this person even knows what C++ is?
What is even wrong with the speed of Java on the long run? Have you even heard of GraalVM?
What does he / she means with poor support for generics?
To avoid going on too long, Scala is just a failed experiment with a long enough feature list to attract naive programmers and functional newbies. While we should perhaps applaud the gumption it took to take such an experiment as far as Scala has been taken, now that the failure is clear in hindsight, we need to call it what it is.
Sadly that the F# experiment failed in a way that now they are waiting for C# to overcome it.
Now, really, if you are going to criticize a language it would be good to provide points of your critics.
Scala does has bad things, like anything in the world, and many of us are working to make it better.