Skip to Content
Course content

143: Scalafmt for Code Formatting

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

I've spent far too many hours of my career in pull requests arguing about whether a brace should be on the same line or the next, or whether we should use two spaces or four for indentation. It's a waste of mental energy. In any professional Scala project, the answer isn't "better guidelines"β€”it's an automated formatter. For Scala, that's Scalafmt.

Taming a Messy Report Generator

Let's look at some code I wrote in a rush. It works, but it's an eyesore. I've got inconsistent spacing, weird alignment in my case classes, and some haphazard indentation in the logic. This is exactly the kind of code that makes a teammate sigh when they open a PR.

case class UserReport(id:Int, name:String,  email:String,
    department:String,
    status:String)

object ReportService {
  def processReports(reports: List[UserReport]) = {
    reports.filter(_.status == "Active")
      .map(r => s"Report for ${r.name} (${r.department})")
      .toList
  }
  
  def formatHeader(title: String, date: String) = {
    s"--- $title --- \n Date: $date \n ----------------"
  }
}

Instead of manually fixing this, I'm going to let Scalafmt handle it. First, I need to add the plugin to my project. I'll add the sbt-scalafmt plugin to my project/plugins.sbt file:

addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2")

Defining the House Style

Scalafmt doesn't guess how you like your code; it looks for a configuration file. I'll create a file named .scalafmt.conf in the root of my project. I'll start with a basic setup that mimics the common community standards.

version = "3.7.14"
runner.dialect = scala213 
 indentation.spaces = 2
maxColumn = 100

Now, I can just run sbt scalafmt in my terminal. When I do, the tool sweeps through my source files and snaps everything into place. My UserReport case class is suddenly aligned, and the spacing in ReportService becomes consistent without me touching a single key.

Correcting my Over-zealous Wrapping

Here is where I usually mess up. I sometimes try to be "too clean" with my line lengths. I decided I wanted my code to be very narrow, so I changed maxColumn to 60 in my config file, thinking it would make the code easier to read on a split-screen editor.

I ran sbt scalafmt again, and it was a disaster. My simple processReports method, which was perfectly readable on one or two lines, got chopped up into a vertical tower:

def processReports(
    reports: List[UserReport]
) = {
  reports
    .filter(_.status == "Active")
    .map(r => s"Report for ${r.name} (${r.department})")
    .toList
}

It looks "organized," but it's actually harder to scan because it takes up way too much vertical space. I realized I'd over-constrained the formatter. I went back into .scalafmt.conf and bumped maxColumn back up to 100. I ran the command one more time, and the code snapped back to a balanced, readable state. The lesson here: don't let the formatter fight your natural reading flow; tune the config until the tool helps you, rather than hinders you.




πŸ“‹ Practical Task

Standardizing the Legacy Transaction Processor

You've been handed a legacy file called TransactionProcessor.scala that is a formatting nightmare. Your goal is to bring it up to team standards using Scalafmt.

The Messy Code:

case class Transaction(id:Long, amount:Double,   currency:String,
    timestamp:Long,
    merchantId:String)

object TransactionProcessor {
  def calculateTotal(txs:List[Transaction], filterCurrency:String) = {
    txs.filter(t => t.currency == filterCurrency).map(_.amount).sum
  }
  def logTransaction(t:Transaction) = {
    println(s"Processing transaction ${t.id} for amount ${t.amount} ${t.currency}")
  }
}

Your Requirements:

  1. Create a .scalafmt.conf file.
  2. Set the version to "3.7.14".
  3. Set the runner.dialect to scala213.
  4. Set indentation.spaces to 2.
  5. Set maxColumn to 80.
  6. Apply the formatting to the TransactionProcessor code and provide the final, cleaned-up version of the Scala code.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.