Disclaimer(s): ZeroTurnaround supports eliminating redeploys in Scala development with free JRebel licenses (more info). The author admits to having no Scala code in mission critical production, and would like to mention that he has lots of opinions about many things in which his expertise can be contested ;-)
Super fast intro – Why should I know about Scala?
Scala is a relatively-new, statically-typed programming language that mixes object-oriented and functional programming on the JVM. It has been getting more and more popular, because it is probably the best alternative to Java there is at the moment and has a rich type system which lets you do crazy stuff if you really want. But, as I will explain, there are some drawbacks that can detract from these benefits.
If you are a Java developer and want to get a quick intro to Scala, Daniel Spiewak wrote a good series of posts for you: Scala for Java Refugees.
Stay close to the shallow end?
There have been numerous blog posts during the past year or so that accuse Scala of being too complex or highlighting other issues with Scala adoption. Some of the criticism is fair, but I think some of it could be targeting almost any JVM language out there. Scala seems to get more of the flak because it’s more popular and possibly pulling ahead of the others (despite what TIOBE’s baffling index claims, leaving Scala out of it’s Top 50 languages for mysterious computational reasons).
And also probably because Scala actually is rather complex, but only if you want it to be.
I think of Scala as a swimming pool; there is a deep end and a shallow end, it seems that many people who haven’t learned to swim yet jump straight into the deep end. Inevitably, after splashing about for a while are surprised to find that their legs don’t quite reach the floor, or that they sank to the bottom and are startled by not being able to breathe under water.
I don’t know why this happens. Maybe it is hard to distinguish the deep end from the shallow end — it’s not quite as simple as having a glance and getting a clear picture of how deep the pool is. Maybe the deep end seems more exciting at first, when you haven’t gotten a true taste of it yet.
Why am I talking about such a dichotomy in the first place?
Because the Scala community is very diverse. It can cater both to newbies and expert type-safe library designers. Some Scala users come from an object-oriented programming background (e.g. Java), some come from a functional programming background (e.g. Haskell).
Scala blends together these programming styles, but still lets you code mostly in an “impure” imperative or mostly in a “pure” functional way. And that’s the main problem, I guess — the very different coding styles enabled by Scala means that a lot of code written by people from a school outside of your own might seem downright illegible.
Each Scala team needs to find a common style that they agree upon, or the result will be a mess. The Scala Style Guide might help with this.
But let me say straight out: This post is mostly for those coming from the Java (object-oriented / imperative) school. Some of the suggestions are very much a matter of taste, background and so on, so I’m not expecting everyone to agree with it. But let’s get on with some thoughts, opinions and comments…
Opinion Time: What to avoid in the Scala ecosystem
These things may be fun to mess with and maybe you will actually find that they are useful to you, but if you are trying to adopt Scala in a team of Java programmers, these things will not help you, and I would say they might even work against you; such as finding yourself inadvertently in the deep end. Specifically, I would avoid:
- SBT – Simple Build Tool
- Category theory
- Libraries that overuse “operator overloading”
- Collections Library Source Code
- The Cake Pattern
- The Kingdom of Verbs
- Too Functional or Too Type Safe Code
IMHO, the so-called Simple Build Tool (SBT), sucks.
It is not so simple at all and your build descriptors will be a mishmash of a DSL that uses lots of special symbols, poorly structured meta-data, and code. For example, to make my project a web project, I first had to add a plug-in dependency like this in plugins.sbt:
libraryDependencies <+= sbtVersion(v => "com.github.siasia" %% "xsbt-web-plugin" % (v+"-0.2.9"))
And then add this magic line to build.sbt:
This made me puke a little bit in my mouth, and if it has a similar effect for you, just stick with Maven, Ant, or whatever build tool you used before that has Scala support. I use Maven for all my Scala projects and don’t have any big problems with that.
Sometimes you might be more or less forced to use SBT (e.g. if you use Play 2.0). In that case you’re kinda fracked, but maybe not too badly — SBT still has some good ideas inside it. There is hope that it will get better and better, and even support a Maven mode. But at the moment, it leaves much to be desired.
2. Avoid Scalaz
If you are thinking about using Scalaz, stop now while you still have your sanity! And don’t get into arguments with the people who suggest that you use it – it is pointless. These strangers come from a completely different school of thought that values entirely different things than you – pure functional programming with very high-level abstractions represented by obscure symbols like <:::, :::>, <+>, ★, ☆, <=<, and so on – there are HUNDREDS of these.
Also, run away if you hear anyone casually utter words like: applicative, bifunctor, cokleisli, endofunctor, kleisli, semigroup, monad, monoid. Ok, the last two are maybe not so scary, but what I’m getting at is that you should also stay away from #3… >>>
Category theory is an area of mathematics full of abstractions that apply to programming in interesting and sometimes useful ways, but it will not immediately help you write better programs that are easy to understand. Eventually, you might find something of use there, but maybe it’s better to stay clear of category theory until you are really really sure that you and your team wants to go there and will benefit from it (the same goes for Scalaz, above).
Scala doesn’t have real operator overloading, as most operators are actually methods. But it allows you to use many symbols in method names. This is not bad, because it is useful in places, such as mathematical code, but some libraries take “advantage” of that feature and use easy-to-type symbols (or even not-so-easy-to-type symbols) to mean something entirely different than what those symbols commonly represent.
Again, I’ll mention Scalaz as the main culprit here, but there are many other libraries which’s authors have been a bit overly happy-go-lucky with their use of symbols in all the wrong places. SBT errs here as well, as already mentioned. Some examples:
But sometimes you may have no good choice of a library that doesn’t overuse symbols. Although I wrote a HTTP client wrapper for Scala that is mostly symbol-free (except for / and ? for constructing URLs), it was mainly for my own use and I haven’t maintained it properly.
On the other hand, Databinder Dispatch, which does use symbols a bit much (as seen from the periodic table above), is quite well maintained.
I wouldn’t suggest digging too deep into the collections library implementation. It is a breeze to use the library mostly, for example:
val (minors, adults) = people partition (_.age < 18)
But the implementation is way more complex than we’re used to in Java-land. The internal complexity pays for power, though, and is probably worth it. If you get stuck, the sources might be closer at hand than docs, but try reading some documentation anyway, before peeking into the source.
When people tell you that Scala doesn’t need dependency injection frameworks because of the cake pattern, that’s poppycock (thankfully, not many people would go quite that far). Not all projects need DI, but where it has worked in Java projects, it can work just as well in Scala projects.
The cake pattern may work fine too in many cases, but it makes your code structure unnecessarily more complex, and may force you to use some of the more advanced features of the type system that you could avoid otherwise. Personally I prefer Google Guice for dependency injection, but Spring works with Scala as well.
If Java is the Kingdom of Nouns, then Scala code can sometimes look like it’s coming from the Kingdom of Verbs. You might see code like this:
To be honest, such stringing of methods can happen in Java as well, but seems less likely there. Not everything in the above snippet is technically a verb, but there is a very long chain of methods with none of the intermediate results being named.
If you look at this code without an IDE, it is nearly impossible to understand what is going on because you know neither the types nor the names of the things. Thank god point-free style doesn’t work in Scala, or it could be worse.
Just give names to some of the intermediary results, eh? In other words, your Scala code should be from the Kingdom of Sentences, where both verbs and nouns are in equal standing. It is often possible to even mimic simple natural language sentences without creating a full-blown DSL.
This is perhaps the most controversial point I’m going to make, but try not to go too much into the functional side of the language or to achieve maximal type safety. Scala can clearly give you better type safety than Java in many cases, but there is a limit to everything. The type system is complex and if you dive very deep into it, you might just spend a lot of time satisfying the compiler for little gain instead of writing useful code. I love to occasionally play with something like shapeless, but avoid doing it in serious code.
The same is with going too functional. Often it makes sense to use
Option values instead of if-else expressions. But writing a long chain of flatMaps without naming any intermediate results is not a good style.
Overusing higher-order functions in hot code may create performance problems. In some cases, you might even have to revert to more Java-like code with mutable variables and while loops — Scala’s for loops are compiled to higher-order function calls, but while loops are low-level as in Java or C.
Still, functional programming is getting more and more popular for a reason. Concurrency and correctness might be easier to achieve with more functional code. So don’t stay completely on the imperative side of Scala, or you might not enjoy as many of the benefits as you could.
Look for more in Part 2…
In Scala: Sink or Swim? Part 2, we will look at the good parts that should actually make you consider using Scala in the first place, plus some things in Scala that you can’t really avoid, but must live with nevertheless. Please leave me comments below, or write to me at firstname.lastname@example.org. Thanks for tuning in!