Scala Anonymous Functions
An anonymous function is a function without a name. You define it inline, exactly where it is needed, without the def keyword. In Scala, anonymous functions are also called function literals or lambda expressions. They are essential for working with higher-order functions like map, filter, and foreach.
Basic Syntax
// Named function
def double(x: Int): Int = x * 2
// Anonymous function (same behavior)
val double = (x: Int) => x * 2
println(double(5)) // 10
(x: Int) => x * 2
│ │
└─ parameter └─ body (expression after =>)
Passing Anonymous Functions Inline
val numbers = List(1, 2, 3, 4, 5)
// Inline anonymous function
val doubled = numbers.map((x: Int) => x * 2)
println(doubled) // List(2, 4, 6, 8, 10)
// Type can be inferred
val doubled2 = numbers.map(x => x * 2)
println(doubled2) // List(2, 4, 6, 8, 10)
Underscore Shorthand
When a parameter appears exactly once in the body, replace it with _:
val nums = List(10, 20, 30, 40)
// Full form
nums.map(x => x + 5)
// Underscore shorthand
nums.map(_ + 5) // same result: List(15, 25, 35, 45)
nums.filter(_ > 15) // List(20, 30, 40)
nums.foreach(println) // prints each element
// Two parameters — each _ represents the next unused parameter
nums.foldLeft(0)(_ + _) // 100 (same as (acc, x) => acc + x)
_ + 5 is short for x => x + 5
_ > 15 is short for x => x > 15
_ + _ is short for (a, b) => a + b
Multi-line Anonymous Functions
val words = List("hello", "world", "scala")
val processed = words.map(word => {
val upper = word.toUpperCase
val starred = s"★ $upper ★"
starred
})
processed.foreach(println)
// ★ HELLO ★
// ★ WORLD ★
// ★ SCALA ★
Multi-line bodies go in curly braces. The last expression in the block is the return value.
Multiple Parameters
val add = (a: Int, b: Int) => a + b
println(add(3, 7)) // 10
List(1, 2, 3, 4, 5).reduceLeft((acc, x) => acc + x) // 15
val pairs = List((1, 2), (3, 4), (5, 6))
pairs.map { case (a, b) => a + b } // List(3, 7, 11)
Storing Anonymous Functions
val isEven: Int => Boolean = _ % 2 == 0
val square: Int => Int = x => x * x
val greet: String => String = name => s"Hello, $name!"
println(isEven(4)) // true
println(square(9)) // 81
println(greet("Diya")) // Hello, Diya!
// Use stored functions with collections
val nums = List(1, 2, 3, 4, 5, 6)
nums.filter(isEven).map(square).foreach(println)
// 4
// 16
// 36
Partial Function Syntax with case
val describe: Any => String = {
case n: Int => s"integer: $n"
case s: String => s"text: $s"
case _ => "something else"
}
println(describe(42)) // integer: 42
println(describe("hello")) // text: hello
println(describe(3.14)) // something else
Anonymous Functions vs Named Functions
Anonymous Named
────────────────────────── ─────────────────────────────
Inline, no name Has a name, defined with def
Stored in a val Defined as a method
Cannot be recursive directly Can be recursive
Ideal for short, one-time use Ideal for reuse and documentation
Practical: Sorting with Custom Comparator
case class Product(name: String, price: Double, rating: Double)
val products = List(
Product("Headphones", 2999.0, 4.5),
Product("Keyboard", 1499.0, 4.8),
Product("Mouse", 799.0, 4.2),
Product("Monitor", 18000.0, 4.7)
)
// Sort by price ascending
val byPrice = products.sortBy(_.price)
byPrice.foreach(p => println(f"${p.name}%-12s ₹${p.price}%8.0f"))
// Mouse ₹ 799
// Keyboard ₹ 1499
// Headphones ₹ 2999
// Monitor ₹ 18000
// Sort by rating descending
val byRating = products.sortBy(-_.rating)
byRating.foreach(p => println(f"${p.name}%-12s ★${p.rating}%.1f"))
// Keyboard ★4.8
// Monitor ★4.7
// Headphones ★4.5
// Mouse ★4.2
Building a Mini Pipeline
val transactions = List(-200, 500, -50, 1000, -300, 750)
val report = transactions
.filter(_ > 0) // keep credits only
.map(_ * 0.9) // apply 10% fee
.map(x => f"₹$x%.0f") // format as currency
.mkString(", ")
println(s"Credits after fee: $report")
// Credits after fee: ₹450, ₹900, ₹675
Anonymous functions are the glue between pipeline stages. Each _ or x => represents a small, focused transformation — readable, composable, and concise.
