Tuesday 31 August 2010

"show your working"—a plea for Scala coding quality

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:

  1. 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.
  2. 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!
  3. 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.

16 comments:

Matías Giovannini said...

I disagree with your "tips". Not with the content but with the intent behind them: making Scala a syntactically lighter Java. Clarity is in the eye of the beholder, and every language requires literacy. The problem with Scala is that, as a hybrid, you need literacy in two very different schools of expression: functional and object-oriented.

Stuart Roebuck said...

Matías, I have no intent to make Scala a syntactically lighter Java. Scala's syntax is more extensive and can be more complex than Java. With good style it is also typically far less verbose and consequently clearer and more succinct.

Saying that "clarity is in the eye of the beholder" is a short way of dismissing the hard and skilled work of delivery clarity. The best authors have skill and style worth learning from.

Yes, Scala is a hybrid (in the eyes of someone who was previously literate in functional and object-oriented language). Yes, Scala has depths of complexity that can require greater understanding than other simpler languages. But once a programmer has gained the literacy required to understand and code in such a language, they then benefit from learning good style.

Matt R said...

> an open source Scala library

I can take a guess as to which that library is, but, in fairness, how much Scala is written in that style?

> avoid symbols

I'd be inclined to agree with you, although one example of a symbol heavy DSL that "works", for me at least, is the combinator parser library.

Anonymous said...

"show your working"

If that's the title of your post, you should not be complaining about other people's syntax.

YOU'RE, not YOUR.

Stuart Roebuck said...

Matt, I'm not really against DSLs and DSLs are a context where symbol overloading is entirely appropriate. DSLs are great in situations which demand an succinct and appropriate language to codify something.

I think the problem arises when the enthusiasm to utilise the power of Scala leads some developers to create new languages when the old one was succinct enough and arguably more universally understandable. I guess it's a form of premature code optimisation.

Stuart Roebuck said...

Anonymous,

Amusingly I can't tell if you are joking, but if you aren't then can I clarify that "show your working" in literal terms means, "write down the steps you took when you were working the problem out". It may be that this is a particularly English use of the the English language!

I didn't mean "show you are working" which would of course be "you're" and would suggest that I am trying to encourage people to prove that they are making the effort. I don't really want that as I'm quite happy for people to be so brilliant that they produce great code and stay lazy! :)

Anonymous said...

The title is a bit confusing, I had assumed that it was a typo or misapplication of the statement "show your work" commonly given to students in math or science classes.

Anonymous said...

What about "think your clever" and "add to objects together"?

ben.biddington said...

50 method trait also seems alarming...

Ricky Clarkson said...

That's the most hilarious grammar 'correction' I've ever seen!

Anyway, you're looking at Scalaz. You will find similarly 'unreadable' code by Tony Morris and co. in Functional Java, a Java library. It's not at all Scala-specific. Scalaz is not intended for *you* to read, but rather people versed in category theory.

That said, I think mapping non-ASCII symbols to arbitrary combinations of ASCII symbols as in the example you showed is something the Scalaz guys could avoid.

Stuart Roebuck said...

Anonymous, Gramor and tipos corrected :)

Tony Morris said...

Scala is not complicated. Programming is complicated. All your example does is expose this fact.

Scalaz is intended to be understood by people versed in programming (not necessarily category theory).

I implore you to try an example of equivalent usefulness in a "less complicated language." Of course this requires you to first understand the usefulness of this example.

Nevertheless, observe the result. Complicated ain't it?

Stuart Roebuck said...

Tony, As I tried to make clear in my post I wasn't trying to pick on any one particular piece of code or author. Unfortunately some of the comments that have followed have taken a different tack and I'm not entirely clear how much of your comment responds to the post or a comment from another commenter.

So let me turn this on its head and say that it would be nice to think that over time a greater percentage of the Scala source code out there would look as well presented as that of Akka. I don't know the author and haven't used this code yet, but I was immediately impressed when I looked at the codebase that there was consistency and a good degree of thought that had been put into documenting the code, picking the function names and choosing to make internal stuff 'private'.

As for scalaz, I can't help but be impressed with anyone who takes the time and effort required to put code out there for everyone to use. If we all want to benefit from such shared resources, we need to appreciate them and help contribute to them.

I hope that as we all contribute we will be establishing styles of coding that make all the Scala code increasingly accessible, useable and maintainable.

Tony Morris said...

Hi Stuart,
I'm not defending against being "picked on." Rather, I am addressing the often-repeated and short-sighted claim that Scala is "complicated." I am doing this by using a library function that has been mentioned.

I'm happy to do it any other way, but the one mentioned just happens to be completely antonymous to complicated by making what would ordinarily be complicated code in a more complicated language such as Java into a single, type-checked function.

I am quite confident that this insight would come simply by first understanding the function under discussion, then understanding the implications. Introspection will have you admitting to yourself that actually no, it's not complicated, quite the contrary.

I don't take it personally mate. Ijust like teaching and learning.

Stuart Roebuck said...

Tony, I am not saying that Scala is inherently complicated, though it has more potential to be used in complicated ways than some more primitive languages.

I am not saying that the code snippet listed above is unnecessarily complicated given the complexity of the underlying problem it is solving.

I fully confess that I don't know what the problem is that it solves though I do technically understand what the code does.

In simple terms, the fact that I am going to have to do a lot of research around this code to see if it is something I might find useful is closer to the heart of what I'm trying to say. If the name of the method gave some clue to me about what it did that would help. Alternatively if there was a comment above that explained it's intent then that would also be a big help. As a public and not private function, having meaningful parameter names would help too.

But, perhaps this does something that is obvious to the people who want to use it and uses the terminology that they would understand. That being the case, all I need to know is that it doesn't do anything I need to know about.

Anonymous said...

I consider, that you commit an error. Let's discuss. Write to me in PM, we will talk.

 
Google Analytics Alternative