# Scala

Use of Scala at The Orchard is localized to a few performance-critical parts of our data pipelines. Since knowledge of the language is not widespread at the company, we want to keep the code as accessible as we can to everyone, and refrain from using esoteric features.

Stylistically, we follow the standards outlined in the [Databricks Scala Style Guide](https://github.com/databricks/scala-style-guide), which is geared towards readability and simplicity.

Some of these standards are enforced by our use of the [scalastyle sbt plugin](http://www.scalastyle.org/sbt.html). A sample configuration can be found [here](https://github.com/theorchard/royalties-compute/blob/master/scala/project/scalastyle-config.xml).

We use [scalafmt](https://scalameta.org/scalafmt/) for formatting. A sample configuration can be found [here](https://github.com/theorchard/royalties-compute/blob/master/scala/.scalafmt.conf).

## Additional guidelines

### Use of implicits

In designing our own functions, we prefer explicit parameters and conversions, choosing at present not to incur the conceptual overhead that implicits introduce.

Implicit conversions that are built in to Scala \(e.g., such as those that convert between Java and Scala objects\) or that accompany libraries \(e.g., Scalatest\) are fine to use.

### Short functions and composition

In a language like Python, inlining a function call can sometimes yield a significant performance boost.

In Scala, function calls are considerably cheaper, so we prefer very short, single-purpose functions that can be composed using functional primitives and combinators to produce more complex ones.

So we prefer this:

```scala
object HappyNumbers {

  def square(n: Int): Int = n * n

  def digits(n: Int): Seq[Int] = n.toString.map(_.asDigit)

  def nextInChain(n: Int): Int = digits(n).map(square).sum

}
```

to this:

```scala
object HappyNumbers {

  def nextInChain(n: Int): Int = n.toString.map(_.asDigit).map(n => n * n).sum

}
```

### Tuples

We prefer to avoid tuples. Case classes offer named attribute access, greatly enhancing readability, and add minimal overhead.

