ProgramGuru

Closures: pass behaviour as a value

Closures: pass behaviour as a value

A teacher may sort names alphabetically or by length. Instead of writing a separate collection type for each policy, supply a closure that decides the ordering. A closure packages executable behaviour and can capture values from its surrounding scope.

What you’ll learn

  • Supply a closure as a sorting policy.
  • Define a consistent tie-break and recognize capture lifetime issues.

Closures: pass behaviour as a value in the example

  1. Compare lengths

    A teacher may sort names alphabetically or by length.

    Compare lengths
  2. Resolve a tie

    Closure parameters and return values can be inferred from the function expecting them.

    Resolve a tie
  3. New sorted array

    Diya and Noor each have four characters, so the explicit alphabetical tie-break orders them consistently.

    New sorted array
Diya and Noor each have four characters, so the explicit alphabetical tie-break orders them consistently. Saira has five and follows them. The ternary operator chooses one expression from its Boolean condition. sorted returns a new array and does not mutate names.

How closures: pass behaviour as a value works

Closure parameters and return values can be inferred from the function expecting them. sorted(by:) asks whether one element should precede another. A trailing closure is written after the call’s parentheses. Capturing an external variable can make later behaviour depend on changing state, so consider its lifetime and meaning.

Work through closures: pass behaviour as a value

Save this complete program as main.swift and run it with the Swift toolchain. No separate input file is needed.

Swift · complete program

let names = ["Saira", "Diya", "Noor"]
let ordered = names.sorted { first, second in
  first.count == second.count ? first < second : first.count < second.count
}
print(ordered)

Expected output

["Diya", "Noor", "Saira"]

Follow the execution

Diya and Noor each have four characters, so the explicit alphabetical tie-break orders them consistently. Saira has five and follows them. The ternary operator chooses one expression from its Boolean condition. sorted returns a new array and does not mutate names.

Try this program in the Swift compiler. Paste the complete source above.

Practice: Closures: pass behaviour as a value

Your task: Why supply an alphabetical tie-break for equal-length names?

Swift · complete program

let names = ["Saira", "Diya", "Noor"]
let ordered = names.sorted { first, second in
  first.count == second.count ? first < second : first.count < second.count
}
print(ordered)

Worked answer

It makes the ordering policy explicit for ties rather than relying on assumptions about their retained order. The closure states both the primary comparison and the secondary comparison.

Write a consistent ordering policy

A sorting comparison must be consistent; returning true for both directions or changing its rule during sorting gives an invalid policy. Escaping closures can outlive the function call that stores them and can create ownership cycles when capturing class instances.

Check your decision

Why supply an alphabetical tie-break for equal-length names?
Choose one answer. You can try again.

Answer and explanation

It makes the ordering policy explicit for ties rather than relying on assumptions about their retained order.

It makes the ordering policy explicit for ties rather than relying on assumptions about their retained order. The closure states both the primary comparison and the secondary comparison.

Write a consistent ordering policy

It makes the ordering policy explicit for ties rather than relying on assumptions about their retained order. The closure states both the primary comparison and the secondary comparison. A sorting comparison must be consistent; returning true for both directions or changing its rule during sorting gives an invalid policy.

Further reading: official Swift language guide.

Reaching the recap and completing the quizzes are separate milestones.

    Next lesson: Enums and associated values →