Menu
Coddy logo textTech

Returning Closures

Part of the Logic & Flow section of Coddy's Swift journey — lesson 41 of 56.

You saw makeCounter return a closure. The same trick lets you build configurable behaviour: take parameters once, get a function back that uses them many times.

func multiplier(_ k: Int) -> (Int) -> Int {
    return { n in n * k }
}

let triple = multiplier(3)
let tenfold = multiplier(10)
print(triple(4))                  // 12
print(tenfold(4))                 // 40

The returned closure captures k, so each multiplier(...) call produces a brand-new closure with its own k.

This pattern is the core of "strategy" code in Swift: write a function that takes a configuration and returns a closure, then pass the closure to map, filter, sorted(by:), or anywhere else a function-shaped value is expected.

challenge icon

Challenge

Medium

Build two closure factories:

  • greaterThan(_ k: Int) -> (Int) -> Bool: returns a predicate that's true when its argument is strictly greater than k
  • scaleBy(_ k: Int) -> (Int) -> Int: returns a function that multiplies its argument by k

Read three lines:

  1. An integer threshold
  2. An integer scale
  3. A comma-separated list of integers, the nums

Print three lines:

  1. The numbers above the threshold (filter with the closure from greaterThan), joined with ,
  2. The same numbers, scaled (map with scaleBy), joined with ,
  3. How many made it through

For input 5 / 3 / 2,7,3,8,9, the output is:

7,8,9
21,24,27
3

Cheat sheet

A closure factory is a function that captures a parameter and returns a new closure configured by it:

func multiplier(_ k: Int) -> (Int) -> Int {
    return { n in n * k }
}

let triple = multiplier(3)
print(triple(4))   // 12

Each call produces a brand-new closure with its own captured value of k. The returned closures can be passed directly to map, filter, sorted(by:), etc.:

func greaterThan(_ k: Int) -> (Int) -> Bool {
    return { n in n > k }
}

let nums = [2, 7, 3, 8, 9]
let filtered = nums.filter(greaterThan(5))  // [7, 8, 9]
let scaled = filtered.map(multiplier(3))    // [21, 24, 27]

Try it yourself

let threshold = Int(readLine()!)!
let scale = Int(readLine()!)!
let nums = readLine()!.components(separatedBy: ",").map { Int($0)! }

// TODO: greaterThan, scaleBy; filter then map; print joined and count
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Logic & Flow