The recent debate about the complexity of Scala over Java and other languages has lead me to bemoan the quality of some significant chunks of Scala code currently circulating in the public domain.
I probably should just be patient as the cycle of programming language maturity is a common one. In the early days of a language, in the absence of coding standards and common practice, people grab at the new features of a language and enthusiastically use them with little awareness of the consequences. As a language matures, the community of developers adopts and polices standards to the extent that a newby developer soon finds themselves instructed on the basics of what to do or not to do.
There's a lot of Scala code out there that feels like it's been put together by spotty adolescents with too many hormones and not enough common sense. Okay, I'm being harsh, I'm a Scala newby too, but I think it really is time we started to get a bit more focused on developing some good coding practice and mentoring each other towards maturity.
I'm going to start with a simple issue which is close to the recent complexity debate...
Extremes of pure functional style encourage code obscurity
Functional programming is great, but taken to an extreme functional programming can:
- encourage short meaningless function names.
- discourage temporary named variables which help to explain what is going on.
- encourage the creation of large numbers of small functions which obscure the modular interfaces.
Take this function as a slightly extreme example:
def ^!!||^(implicit f: Foldable[IN]) : Kleisli[Option, String, NonEmptyList[List[Char]]] = kleisli((p : String) => {(this !!|| p).toNel })
I'm not trying to pick on anyone here, so apologies to the author, but this method is one of over 50 public methods in a single Scala trait of an open source Scala library. Is it any surprise that people think Scala is complicated?
So, here are my Scala programming tips for the day:
- Minimise your modular interface: in other words, keep your publicly accessible functions, properties and classes, etc. to a minimum. If it doesn't need to be public make it private. Why? ... because developers reading your code shouldn't be left swimming around trying to find what's important and what isn't. If you create a function that is only used by one other function, define it within the function that requires it. This makes it absolutely clear that it is only there to support the other.
- Use meaningful names and avoid symbols: if your readers can't figure out what a method is supposed to do then chances are neither will you in a few months time! The use of symbols for function names is a curse of the current trend in DSLs (Domain Specific Languages). Yes, do define a
+
method to add two objects together, but don't write functions called,~>
,~~>
and~%>
and think you're clever! - Don't be afraid to use vals to store partial results in your function rather than trying to string everything together into one long expression. Not just does this simplify the code by breaking it down into smaller parts, it also provides you with the opportunity to "show your working" by assigning partial results to values with meaningful names. I doubt an assignment to a
val
has any impact on performance. But I'll leave it someone more qualified in bytecode to back me up on that.
Okay. That's me done for today. Don't miss out on this great Scala community style guide. A really valuable contribution to Scala maturity.