Zeid Ombotimbe

Data Engineer • Code, Systems, and Life

Scala for Angry Beginners: From Frustration to Functional

Oct 15, 2024

Let me guess: you’re a perfectly competent Python developer who’s been told you need to learn Scala. Maybe it’s for a new job, maybe it’s for that Spark project, or maybe you just heard it pays well.

So you opened up a Scala file, took one look at the syntax, and felt a familiar rage bubbling up. What’s with all the underscores? Why are there seventeen different ways to define a function? And who decided that ::: was a reasonable operator?

I get it. I’ve been writing Python, SQL, and Julia for years, and when I first encountered Scala, my reaction was… let’s call it “skeptical.” But here’s the thing: Scala isn’t actually trying to make your life harder. It’s just coming from a different philosophical place.

The good news? My background with functional languages (yes, I wrote my first lines of code in Haskell) helped me see past the initial weirdness. The better news? You don’t need that background to get there too.

Why Scala Feels Like Someone’s Messing With You

If you’re coming from Python, Scala seems designed to make you angry:

But here’s the secret: Scala isn’t trying to be difficult. It’s just speaking a different language. Literally.

It’s Just Better Python

Think of Scala as Python that grew up, went to college, and came back with some fancy ideas but the same good heart.

Variables: val vs var (The Golden Rule)

// This is final, immutable, cannot be changed
val name = "Mariam"  
// Like Python's: name = "Mariam"  (but actually constant)

// This can be changed (but we rarely use it)
var age = 28
// Like Python's: age = 28

Rule of thumb: Use val 95% of the time. It makes your code predictable. Your future self will thank you.

Functions: Actually Not That Scary

# Python
def add(a, b):
    return a + b
// Scala
def add(a: Int, b: Int): Int = {
  a + b
}

// Or the shorter version when it's simple
def add(a: Int, b: Int): Int = a + b

Yes, you have to specify types. But this catches errors BEFORE you run your code. It’s like having a super-smart friend who proofreads your work.

Collections: Where Scala Actually Shines

This is where you’ll go from angry to “oh, that’s actually nice.”

# Python: filter numbers greater than 10, then double them
numbers = [5, 12, 8, 20, 3]
result = [x * 2 for x in numbers if x > 10]
// Scala: same thing, more readable
val numbers = List(5, 12, 8, 20, 3)
val result = numbers.filter(_ > 10).map(_ * 2)

// Let's break down the magic:
// .filter(_ > 10)  → keep numbers > 10  
// .map(_ * 2)      → double each number
// _ is a placeholder for "each element"

See? It reads like English: “Take numbers, filter those greater than 10, then map each to times two.”

That Weird _ Thing Explained

Those underscores were probably your first rage quit moment. They’re actually simple:

// Instead of writing:
numbers.filter(x => x > 10)

// You can write:
numbers.filter(_ > 10)

// The _ means "the parameter that's coming in"

It’s just Scala’s way of saying “I’m too lazy to name this variable, you know what I mean.”

Case Classes: Your New Best Friend

If you do anything in Scala, you’ll use case classes. They’re like Python dataclasses but with superpowers:

// Define a person in one line
case class Person(name: String, age: Int)

// Magic happens:
val mariam = Person("Mariam", 30)           // No 'new' needed!
println(mariam.name)                       // Works automatically
println(mariam)                            // Pretty printing for free!

// Compare two people (works correctly)
val mariam2 = Person("Mariam", 30)
println(mariam == mariam2)                  // true! (not comparing memory addresses)

Case classes are why Scala people look smug. They’re that good.

Pattern Matching: if/else on Steroids

# Python: handle different cases
def handle_response(response):
    if response.status == "success":
        return f"Data: {response.data}"
    elif response.status == "error":
        return f"Error: {response.message}"
    else:
        return "Unknown response"
// Scala: clean and exhaustive
def handleResponse(response: Response): String = response match {
  case Success(data) => s"Data: $data"
  case Error(message) => s"Error: $message" 
  case _ => "Unknown response"
}

// The compiler checks if you handled all cases!
// No more "oops, I forgot that one scenario"

Why You’ll Eventually Love This

I know it feels foreign now. But here’s what happens after the anger phase:

  1. The compiler becomes your best friend - it catches mistakes before runtime
  2. Your code becomes more predictable - immutability means no surprise changes
  3. Refactoring becomes safe - change code with confidence
  4. You think differently about problems - in a good way!

Your Survival Guide for Week 1

  1. Use val everywhere until someone yells at you to use var
  2. Copy-paste case class examples until they make sense
  3. Use .filter, .map, .foreach for everything collections-related
  4. When in doubt, add types - the error messages will guide you
  5. Embrace the anger - it means you’re learning

Remember: Every Scala expert was once an angry beginner. The anger means your brain is rewiring itself to think in new, more powerful patterns.

Stay angry, but keep coding. The other side is worth it.

Next time: We’ll tackle options (Scala’s answer to null) without throwing your laptop across the room.


P.S. This blog post is part of my “Scala for Angry Beginners” series. If you’re still angry after reading this, good - that means you’re learning. Leave a comment about what made you rage quit last time!


If this made you nod, laugh, or have butterflies in the stomach or elsewhere — tell me about it.