Frequently asked questions and answers about Scala. Questions are categorized for quick access to the information you need.

TL;DR
  • Version Choice: Scala 3 for new projects, Scala 2.12/2.13 when using Spark
  • val vs var: Always prefer val (immutable)
  • Instead of null: Use Option, Some, None for safe null handling
  • IDE: IntelliJ IDEA + Scala plugin (most mature)
  • Performance: Equivalent to Java, watch out for collection chaining and lambda usage

General#

General questions about learning Scala.

Should I learn Scala?

Yes. Scala is particularly useful in these cases:

  • Large-scale data processing (Apache Spark)
  • Distributed systems (Akka)
  • Projects where type safety is important
  • When you want to learn functional programming

Should I learn Scala 2 or Scala 3?

It depends on your situation.

  • New projects: Scala 3 recommended
  • Using Spark: Scala 2.12/2.13 (Spark doesn’t support Scala 3 yet)
  • Maintaining existing projects: Match the project version

The core concepts are the same in both versions, so learning one makes it easy to adapt to the other.

Is Scala difficult?

The basics are not difficult. If you have Java experience, you can pick up the basic syntax quickly.

Difficult parts:

  • Advanced type system (variance, type classes)
  • Complex usage of implicits
  • Macros/metaprogramming

Learn gradually. You don’t need to know all advanced features from the start.

Key Points
  • Scala 3 recommended for new projects, maintain Scala 2 when using Spark
  • Basics are approachable, but advanced type system requires gradual learning

Syntax#

Questions about Scala syntax.

What’s the difference between val and var?

val x = 10  // Immutable (cannot be changed)
// x = 20   // Compile error!

var y = 10  // Mutable (can be changed)
y = 20      // OK

Recommendation: Always use val when possible.

What’s the difference between def, val, and lazy val?

// Computed every time
def computed = { println("computing"); 42 }
computed  // Prints "computing"
computed  // Prints "computing"

// Computed once (eagerly)
val eager = { println("eager"); 42 }  // Prints "eager"
eager     // No output
eager     // No output

// Computed once (lazily)
lazy val deferred = { println("lazy"); 42 }
// No output yet
deferred  // Prints "lazy"
deferred  // No output

Do I need semicolons?

Usually not. Scala automatically infers semicolons at the end of lines.

val x = 1
val y = 2

// Multiple statements on one line require semicolons
val a = 1; val b = 2

What is Unit?

Unit is similar to Java’s void. It indicates no meaningful value is returned.

def printMessage(): Unit = println("Hello")

// The only value of Unit is ()
val unit: Unit = ()
Key Points
  • Use val (immutable) by default, var (mutable) only when necessary
  • lazy val initializes on first access, def recomputes on every call
  • Semicolons only needed when writing multiple statements on one line

Functional Programming#

Questions about functional programming patterns.

What are Option, Some, and None?

Option safely represents the presence or absence of a value:

def findUser(id: Int): Option[String] =
  if (id > 0) Some(s"User$id") else None

findUser(1)   // Some("User1")
findUser(-1)  // None

// Usage
findUser(1).getOrElse("Unknown")  // "User1"
findUser(-1).getOrElse("Unknown") // "Unknown"

Use Option instead of null!

What’s the difference between map and flatMap?

val opt = Some(5)

// map: A => B
opt.map(_ * 2)  // Some(10)

// flatMap: A => Option[B]
opt.flatMap(x => if (x > 0) Some(x * 2) else None)  // Some(10)

// The difference
val nested = Some(Some(5))
nested.map(_.map(_ * 2))      // Some(Some(10))
nested.flatMap(_.map(_ * 2))  // Some(10)

How does for comprehension work?

For comprehensions are transformed into flatMap, map, and withFilter:

// for comprehension
for {
  x <- Some(1)
  y <- Some(2)
} yield x + y

// Transformed to
Some(1).flatMap(x =>
  Some(2).map(y =>
    x + y
  )
)
// Result: Some(3)
Key Points
  • Use Option to safely replace null, getOrElse for default values
  • map transforms values, flatMap flattens nested containers
  • For comprehension is a more readable expression of flatMap/map chains

Troubleshooting#

Common issues and solutions during development.

“implicit not found” error

could not find implicit value for parameter ord: Ordering[MyClass]

Solution: Define or import the required implicit instance.

case class Person(name: String, age: Int)

// Define instance
implicit val personOrdering: Ordering[Person] = Ordering.by(_.age)

// Or define in companion object
object Person {
  implicit val ordering: Ordering[Person] = Ordering.by(_.age)
}

“value xxx is not a member of yyy”

Extension methods may not be imported:

import cats.syntax.all._  // Cats extension methods
import zio.prelude._      // ZIO extension methods

Compilation is too slow

  • Use incremental compilation: sbt ~compile
  • Parallel compilation: parallelExecution := true
  • Use cache: Keep .bsp directory

Red underlines in IntelliJ

  1. FileInvalidate CachesRestart
  2. Reload in sbt tab
  3. BuildRebuild Project
Key Points
  • “implicit not found” resolved by defining/importing required type class instances
  • Extension method errors: check correct import statements
  • Compilation speed improvement: use incremental compilation (sbt ~compile)

Performance#

Questions about Scala performance.

Is Scala slower than Java?

In most cases, performance is similar. Scala compiles to JVM bytecode, so runtime performance is comparable to Java.

What to watch out for:

  • Lambdas and higher-order functions create objects
  • Collection chaining can create intermediate collections
  • Use @tailrec to verify tail recursion optimization

Do immutable collections affect performance?

Scala’s immutable collections use structural sharing to be efficient:

val list1 = List(1, 2, 3)
val list2 = 0 :: list1  // Reuses list1's data

If performance is critical, use Array or mutable collections.

Key Points
  • Scala runtime performance equals Java (JVM bytecode)
  • Immutable collections are efficient via structural sharing, use Array for extreme performance
  • Verify tail recursion optimization with @tailrec

Tools#

Questions about development tool choices.

Which IDE should I use?

  • IntelliJ IDEA + Scala plugin: Most mature
  • VS Code + Metals: Lightweight and fast

Which build tool?

  • sbt: Standard Scala build tool
  • Mill: Faster alternative
  • Gradle: For mixed Java projects

Which testing framework?

  • ScalaTest: Most widely used, various styles
  • MUnit: Simple and lightweight (recommended for Scala 3)
  • Specs2: BDD style
Key Points
  • IDE: IntelliJ IDEA (mature) or VS Code + Metals (lightweight)
  • Build: sbt (standard), Mill (fast), Gradle (Java integration)
  • Testing: ScalaTest (general purpose), MUnit (Scala 3 lightweight)

Additional Questions#

If you have more questions: