Skip to Content
Course content

182: The Scala Style Guide Highlights

Click on the "Edit" button in the top corner of the screen to edit your slide content.

I once spent an entire Tuesday arguing over a single pull request. The code was technically flawless—it passed every test and handled every edge case perfectly. But it looked like it had been written by three different people who had never spoken to one another. One method used snake_case, another used camelCase, and the bracing was a chaotic mix of K&R and Allman styles. I remember thinking, "Why are we wasting high-priced engineering hours debating where a curly bracket goes?" But as the day wore on, I realized we weren't arguing about aesthetics; we were arguing about cognitive load. When code doesn't follow a consistent rhythm, your brain spends energy parsing the shape of the code instead of the logic of the code.

Naming and the Visual Rhythm

In Scala, we generally lean toward a set of conventions that keep the codebase feeling cohesive. You'll want to use PascalCase for classes, traits, and objects, and camelCase for methods and variables. It sounds basic, but sticking to this prevents that jarring feeling when you can't tell at a glance if you're looking at a constructor or a method call.

Then there's the matter of whitespace and braces. The community standard is to keep the opening brace on the same line as the declaration. I've seen developers try to bring the "Java style" of putting braces on new lines into Scala, but in a language where we often use concise expressions and one-liners, that extra vertical space just gets in the way. Keep it tight, keep it consistent.

// Avoid this:
class UserProcessor {
  def process_data(user: User) {
    val result_value = user.name.toUpperCase
    println(result_value)
  }
}

// Do this:
class UserProcessor {
  def processData(user: User): Unit = {
    val resultValue = user.name.toUpperCase
    println(resultValue)
  }
}


The Art of Type Inference and Explicit Contracts

One of the first things people love about Scala is that you don't have to write the type for every single variable. But there's a trap here: over-reliance on inference can make your code a riddle for the next developer (who might be you in six months). My rule of thumb is simple: be implicit for local variables, but be explicit for public APIs.

If you're defining a method in a public trait or class, always specify the return type. I don't care how obvious it is. When I'm using your library, I shouldn't have to jump into your implementation details just to figure out if a method returns a List[String] or a Seq[String]. The method signature is a contract; contracts should be written in ink, not guessed at.

// Local variable? Inference is fine.
val accounts = List("Savings", "Checking") 

// Public method? Explicit is better.
def getAccountTypes(): List[String] = {
  List("Savings", "Checking")
}


Preferring Immutability Over Convenience

You'll see var in the language, but in a professional Scala codebase, var is a smell. Most of the time, if you think you need a variable, you actually need a recursive function or a fold. I've seen juniors use var to accumulate values in a loop because it feels more natural if you're coming from C# or Java, but that's a slippery slope toward thread-safety nightmares.

Similarly, avoid null like the plague. If a value might be missing, use Option. Using null in Scala is essentially opting out of the type system's safety net. It's an invitation for a NullPointerException to crash your production environment at 3:00 AM. Embrace the Some and None; it forces you to handle the empty case explicitly, which is exactly where the bugs usually hide.




📋 Practical Task

Refactoring the Chaotic Payment Gateway

Below is a snippet of code from a "legacy" payment module. It works, but it violates almost every Scala style guide highlight we just discussed: it has inconsistent naming, missing public return types, unnecessary var usage, and it uses null instead of Option.

Your Task: Rewrite this class to follow idiomatic Scala style. Specifically:

  • Fix the naming conventions to camelCase for methods and variables.
  • Add explicit return types to all public methods.
  • Replace the var accumulator with a more functional approach (like map and sum).
  • Replace the null return value with Option[Double].
class payment_gateway {
  def calculate_total(amounts: List[Double]): Double = {
    var total_sum = 0.0
    for (a <- amounts) {
      total_sum += a
    }
    total_sum
  }

  def find_transaction_fee(transactionId: String): Double = {
    val fees = Map("TX1" -> 0.50, "TX2" -> 1.20)
    val fee = fees.get(transactionId)
    if (fee == null) {
      null
    } else {
      fee.get
    }
  }
}
Rating
0 0

There are no comments for now.

to be the first to leave a comment.