Skip to content
Lesson 4 of 11

Step 1 of 5 · Reading · ~1 min

Learn

Functions

Functions that take or return other functions are higher-order. Scala's standard library leans heavily on them.

def apply3Times(f: Int => Int, x: Int): Int = f(f(f(x)))

val doubled = apply3Times(_ * 2, 1)   // 8

Underscore syntax _ * 2 is shorthand for (x: Int) => x * 2 — each _ becomes a parameter in order.

Classic higher-order on collections:

val nums = List(1, 2, 3, 4, 5)
nums.map(_ * 2)                  // List(2, 4, 6, 8, 10)
nums.filter(_ % 2 == 0)          // List(2, 4)
nums.reduce(_ + _)               // 15
nums.fold(100)(_ + _)            // 115
nums.forall(_ > 0)               // true
nums.exists(_ > 4)               // true

This is where Scala feels different from Java — write composable transformations instead of explicit loops.

The underscore trap

An underscore stands for a parameter only when you have not already declared one. Writing _ => declares a parameter and then throws its name away, so a later _ in the same literal has nothing left to stand for:

nums.filter(_ % 2 == 0)        // fine: the _ IS the parameter
nums.filter(x => x % 2 == 0)   // the same function, spelled out
nums.filter(_ => _ % 2 == 0)   // error: missing parameter type

The compiler reports missing parameter type for expanded function, which reads as a type problem but is really this shape problem. Pick one form and stay in it: a bare underscore for the whole expression, or a named parameter with =>. Never both.

Up nextLists and VectorsCollections

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…