Scala Introduction

Scala is a modern, JVM-based language that combines object-oriented and functional programming. It's concise, expressive, and type-safe — used by companies like Twitter, Netflix, and LinkedIn.

Why Scala?

  • Concise — Less boilerplate than Java
  • Type safe — Compile-time error catching
  • Functional — First-class functions, immutability
  • Object-oriented — Everything is an object
  • JVM — Runs on Java's battle-tested runtime
  • Scalable — From scripts to distributed systems

Scala vs Java

Java
// Java — verbose
public class Person {
    private String name;
    private int age;
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    public String getName() { return name; }
    public int getAge() { return age; }
    
    public boolean isAdult() {
        return age >= 18;
    }
}
Scala
// Scala — concise
case class Person(name: String, age: Int) {
  def isAdult: Boolean = age >= 18
}

Variables and Types

Scala
// Immutable (preferred)
val x = 10              // Int
val name = "Alice"      // String
val pi = 3.14           // Double
val active = true       // Boolean
val nums = List(1, 2, 3) // List[Int]

// Mutable (use sparingly)
var counter = 0
counter += 1

// Type annotations
val age: Int = 25
val scores: Map[String, Int] = Map("alice" -> 95, "bob" -> 87)

// Type inference — Scala figures out the type
val message = "Hello"  // Scala infers String

Functions

Scala
// Named function
def add(a: Int, b: Int): Int = a + b

// Anonymous function (lambda)
val multiply = (a: Int, b: Int) => a * b

// Higher-order function
def applyTwice(f: Int => Int, x: Int): Int = f(f(x))
applyTwice(x => x * 2, 3)  // 12

// Default parameters
def greet(name: String, greeting: String = "Hello"): String = 
  s"$greeting, $name!"

greet("Alice")              // Hello, Alice!
greet("Alice", "Hi")        // Hi, Alice!

Collections

Scala
// Lists (immutable, linked)
val numbers = List(1, 2, 3, 4, 5)
numbers.head          // 1
numbers.tail          // List(2, 3, 4, 5)
numbers.map(_ * 2)   // List(2, 4, 6, 8, 10)
numbers.filter(_ > 3) // List(4, 5)
numbers.sum           // 15

// Maps (key-value pairs)
val scores = Map("alice" -> 95, "bob" -> 87)
scores("alice")                // 95
scores + ("charlie" -> 92)    // Add entry
scores - "bob"                 // Remove entry
scores.mapValues(_ + 5)       // Add 5 to all scores

// Sets (unique elements)
val fruits = Set("apple", "banana", "cherry")
fruits + "date"         // Add
fruits - "apple"        // Remove
Set(1, 2, 3) union Set(3, 4, 5)  // Set(1,2,3,4,5)

// Chaining operations
val result = numbers
  .filter(_ % 2 == 0)   // List(2, 4)
  .map(_ * 3)           // List(6, 12)
  .sum                  // 18

Pattern Matching

Scala
// Basic matching
val x = 42
val description = x match {
  case 0 => "zero"
  case n if n > 0 => s"positive ($n)"
  case n => s"negative ($n)"
}

// Matching on types
def process(value: Any): String = value match {
  case s: String => s"String: ${s.toUpperCase}"
  case n: Int => s"Integer: ${n * 2}"
  case b: Boolean => s"Boolean: ${if (b) "yes" else "no"}"
  case _ => "Unknown"
}

// Matching on case classes
case class Point(x: Int, y: Int)
case class Circle(center: Point, radius: Double)

def describe(shape: Any): String = shape match {
  case Point(0, 0) => "Origin"
  case Point(x, y) => s"Point at ($x, $y)"
  case Circle(Point(x, y), r) => s"Circle at ($x, $y) with radius $r"
  case _ => "Unknown shape"
}

Classes and Objects

Scala
// Case class (auto-generates equals, hashCode, toString, copy)
case class User(name: String, email: String, age: Int)

val alice = User("Alice", "alice@example.com", 28)
val bob = alice.copy(name = "Bob", age = 35)  // Create modified copy

// Companion object (static methods)
object User {
  def apply(name: String, email: String): User = 
    User(name, email, 0)  // Default age
}

// Traits (like interfaces + more)
trait Drawable {
  def draw(): Unit
}

trait Resizable {
  def resize(factor: Double): Unit
}

class Rectangle(val width: Double, val height: Double) extends Drawable with Resizable {
  def draw(): Unit = println(s"Drawing rectangle ${width}x${height}")
  def resize(factor: Double): Unit = { /* ... */ }
}

💡 Tip: Prefer val over var, use pattern matching instead of if/else chains, and leverage case classes for data modeling.

Next: Scala Syntax