Scala Programming Guidesscala-basicsscala-tutorial

Scala in Five Minutes | Scala Programming Guide

By Dmitri Meshin
Picture of the author
Published on
Scala in Five Minutes - Scala Programming Guide

What is Scala?

Scala is a modern, statically-typed programming language that runs on the Java Virtual Machine (JVM). The name itself is short for "scalable language," and that philosophy permeates every design decision. It's not just a minor dialect of Java—it's a fundamentally different approach to thinking about how we write code.

At its core, Scala unifies two seemingly opposed paradigms: object-oriented programming (OOP) and functional programming (FP). In Scala, everything is an object—your integers, your functions, your types — but everything is also composable in the functional style. This isn't a compromise; it's the point. You get the expressiveness of functional patterns without abandoning the pragmatism of OOP when you need it. This unique blend allows you to write elegant, maintainable code that scales from small scripts to massive distributed systems.

Scala compiles to JVM bytecode, which means:

  • You run on proven, battle-hardened virtual machines in production.
  • You can call Java code directly from Scala (and vice versa).
  • You get the JVM's garbage collection, optimization, and stability for free.
  • Your deployment story is familiar: JARs, classpath, all the tools you know.

This JVM foundation is crucial: it means you inherit decades of production hardening and performance tuning. The JVM startup might be slower than Go or Rust, but once running, it competes with any language on Earth.

Why Scala Matters Today

The tech industry has learned a hard lesson: concurrency is hard, side effects are dangerous, and testability matters. Scala addresses these concerns head-on by making immutability the default and providing powerful abstractions for managing state and side effects.

Industry adoption: Companies like Twitter, Airbnb, LinkedIn, Spotify, and Netflix built (and continue to build) critical infrastructure in Scala. Apache Spark, the de facto standard for big data processing, is written in Scala. Akka, one of the best actor frameworks ever created, is Scala-native. Kafka, Finagle, ZIO—the list of production-grade tools continues to grow. When Netflix streams 300 million hours of content per day, a significant portion flows through Scala infrastructure. That's not a coincidence.

The ecosystem: Because Scala runs on the JVM, you inherit decades of Java libraries. But Scala has its own vibrant ecosystem: Cats and Scalaz for functional abstractions, Play Framework for web applications, Fs2 and Akka Streams for streaming data, and libraries like ScalaTest and Specs2 that make testing a joy rather than a chore. You're not locked into Java libraries alone—you have world-class tools built by and for Scala developers.

Developer experience: Scala's type system is powerful enough to catch real bugs at compile time, yet the compiler is smart enough to infer types so you don't drown in annotations. The language itself is expressive—you can often say what you mean in fewer lines, with greater clarity, than Java. Write a complex data transformation in Java with 50 lines of nested loops and stream builders, or express it elegantly in Scala with a handful of clear operations. Both compile, both run; one is more joyful to write and maintain.

Installing Scala

You have three main options:

Option 1: SDKMAN (Recommended)

If you're on macOS or Linux, SDKMAN is the cleanest path:

# Install SDKMAN if you don't have it
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"

# Install Scala
sdk install scala 3.3.1
sdk install sbt 1.9.7

# Verify
scala --version
sbt --version

Option 2: Coursier

Coursier is a powerful JVM artifact fetcher and launcher. It's language-agnostic and very fast:

# On macOS with Homebrew
brew install coursier/formulas/coursier

# Or for any OS, download from https://get-coursier.io

# Install Scala
coursier install scala sbt

scala --version
sbt --version

Option 3: Direct Download

You can download Scala directly from scala-lang.org, but you'll need to manage your PATH manually. This works, but SDKMAN or Coursier are more convenient.

Your First Scala Program in the REPL

The REPL (Read-Eval-Print Loop) is your best friend for learning. It lets you experiment with Scala interactively, getting immediate feedback without the compile-run cycle. Launch it with:

scala

You'll see:

Welcome to Scala 3.3.1
scala>

Let's write a small program about a music playlist:

// Define a simple playlist tracker
// This is our first real Scala code!

scala> val playlistName = "Synthwave Nights"
val playlistName: String = Synthwave Nights

scala> val songCount = 42
val songCount: Int = 42

scala> val averageLengthSeconds = 215.5
val averageLengthSeconds: Double = 215.5

scala> val totalPlaylistSeconds = songCount * averageLengthSeconds
val totalPlaylistSeconds: Double = 9051.0

scala> val totalMinutes = totalPlaylistSeconds / 60
val totalMinutes: Double = 150.85

scala> println(s"$playlistName has $songCount songs, totaling ${totalMinutes.toInt} minutes")
Synthwave Nights has 42 songs, totaling 150 minutes

Notice what happened here:

  • Scala inferred the types of our values without us explicitly declaring them. 42 is clearly an Int. 215.5 is clearly a Double. The compiler looked at each assignment and determined the type automatically.
  • We used string interpolation with the s"" prefix to embed expressions directly in strings. This is far cleaner than string concatenation or printf-style formatting.
  • The compiler told us what types it inferred, right there in the output. This transparency is invaluable for learning.
  • Everything is immutable by default—we used val, not var. Once you assign a value, it cannot change. This might feel restrictive at first, but it's one of Scala's greatest strengths.

That's Scala in a nutshell. Let's move to a real file.

Compiling and Running a Standalone Program

Create a file named Playlist.scala:

/**
  * Playlist.scala
  * A small program to manage music playlist metadata.
  * This demonstrates Scala's basic syntax and how programs are organized.
  */

// Main execution point: extend App to make this file immediately runnable
object PlaylistApp extends App {

  // A case class to represent a song (we'll explore case classes in depth later)
  // For now, think of it as a data container
  case class Song(title: String, artistName: String, durationSeconds: Int)

  // Create a few songs
  val song1 = Song("Midnight City", "M83", 244)
  val song2 = Song("Neon Dreams", "The Midnight", 238)
  val song3 = Song("Midnight Pretenders", "Kavinsky", 211)

  // Store them in a List (an immutable ordered collection)
  val playlist = List(song1, song2, song3)

  // Calculate total duration
  val totalSeconds = playlist.map(_.durationSeconds).sum
  val totalMinutes = totalSeconds / 60
  val remainingSeconds = totalSeconds % 60

  // Print the results
  println("=== Playlist Report ===")
  println(s"Total songs: ${playlist.length}")
  println(s"Total duration: ${totalMinutes}m ${remainingSeconds}s")
  println("\nSongs:")

  // Iterate over each song and print details
  // This is a functional style—no explicit loop counter
  playlist.foreach { song =>
    println(s"  - ${song.title} by ${song.artistName} (${song.durationSeconds}s)")
  }
}

Compile with:

scalac Playlist.scala

This creates a .class file. Run it with:

scala PlaylistApp

You should see:

=== Playlist Report ===
Total songs: 3
Total duration: 12m 33s

Songs:
  - Midnight City by M83 (244s)
  - Neon Dreams by The Midnight (238s)
  - Midnight Pretenders by Kavinsky (211s)

Alternatively, you can use scala-cli (modern one-file scripts):

scala-cli Playlist.scala

This is much faster for quick prototyping.

Scala 2 vs Scala 3 at a Glance

Scala 2 (latest: 2.13.x) has been the industry standard for over a decade. It's mature, stable, and production-proven everywhere. The syntax is familiar to anyone who's used Java, and countless libraries continue to target it. A massive amount of production code runs on Scala 2 today, and it will likely continue to do so for years.

Scala 3 (current: 3.3.x) was released in 2021 and represents a generational improvement. It streamlines syntax, improves the type system, and makes the language feel more cohesive. Notable differences:

FeatureScala 2Scala 3
Indentation rulesBraces requiredOptional (Python-like)
SyntaxClassicalRefined, cleaner
Type systemPowerful but complexMore intuitive
Given instancesImplicitsGivens (cleaner)
EnumsSealed classes (verbose)Native enum support
Pattern matchingGoodExcellent (better guards)

For this book, we're using Scala 3, but 95% of what we cover applies to both. If you're forced to work in a Scala 2 codebase, you'll adapt easily. However, for new projects and learning, Scala 3 is the right choice today. The language is more approachable, the error messages are clearer, and the standard libraries have received significant polish.

The migration from Scala 2 to 3 is supported; major libraries have ported. Tooling is excellent. There's no reason to start new projects in 2 unless you have a specific constraint (such as legacy infrastructure or team expertise).