Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Swift Basics  ›  Capstone Project

Functions and Closures

Swift Basics 12 minFunctions name reusable code with argument labels and default values, and closures are unnamed blocks of code passed to other functions such as sorted, filter and map.

Functions and Closures

TrailLog shows total distance, the longest hike, and a list sorted by date. Each is a small piece of logic you want to name and reuse. Functions give logic a name; closures let you hand logic to someone else, like a sort.

The rule

A function is named reusable code; a closure is the same idea without a name.

A Swift function has argument labels that make calls read like sentences:

func totalDistance(of hikes: [Hike], inMiles: Bool = false) -> Double {
    let km = hikes.reduce(0) { $0 + $1.distanceKm }
    return inMiles ? km * 0.621 : km
}

totalDistance(of: journal)                 // default: kilometres
totalDistance(of: journal, inMiles: true)
  • of is the label used at the call site; hikes is the parameter name used inside.
  • _ as a label means "no label": func format(_ km: Double) is called format(8.5).
  • = false gives a default value, so the argument can be left out.
  • -> Double is the return type. No arrow means the function returns nothing.

A closure is a block of code you can store in a variable or pass as an argument. The full form is { (parameters) -> ReturnType in body }:

let byDate = journal.sorted(by: { (a: Hike, b: Hike) -> Bool in
    return a.date > b.date
})

Swift lets you trim that, step by step, because the types are already known from sorted(by:):

journal.sorted { a, b in a.date > b.date }   // types inferred, trailing closure
journal.sorted { $0.date > $1.date }         // shorthand argument names

When a closure is the last argument, it can go after the parentheses — a trailing closure. $0, $1 are shorthand names for the first and second parameters.

The shortcut

To read a closure, find in (or the $ names): left of in is the input, right of it is the work.

Reading a closure in TrailLogStep 1 of 4
  1. The line

    let long = journal.filter { $0.distanceKm > 10 }

The trap is mixing up label and name: inside totalDistance(of hikes:) you write hikes, never of.

Drills

Answer fast — trust the rule.

quick drill

Given func format(_ km: Double) -> String, which call is correct?

quick drill

Inside func totalDistance(of hikes: [Hike]) -> Double, how do you refer to the array?

quick drill

What does [3, 12, 7].filter { $0 > 5 } return?

quick drill

Which line is a trailing closure?

Remember

  • A function is named, labelled, reusable code; a closure is an unnamed block you can pass around.
  • Read closures around in: inputs on the left, work on the right; $0 is the first input.
  • Trap: the argument label is for callers, the parameter name is for the body.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainBuild a hike summary

Write a function longHikes(in hikes: [Hike], over km: Double = 10) -> [String] that returns the names of hikes longer than km, sorted longest first. Explain the label and parameter names and each closure you use.