Lesson 7 / 25

First-Class and Higher-Order Functions

Functions that take or return functions.

Functions are ordinary values

A language has first-class functions when functions can be assigned to variables, stored in data structures, passed as arguments and returned from other functions. A higher-order function is one that takes a function as an argument or returns one. Familiar examples are Array.prototype.map, filter, sort with a comparator, setTimeout and event listeners. Higher-order functions let you separate the what varies (the function you pass) from the what stays the same (the iteration, retry or timing logic).

Passing behaviour around

When functions are values, you can store them, pass them and return them, which is the basis of most FP techniques.

Three ideas: higher-order functions, closures, and map/filter/reduce.
Figure 3.1 — Functions in, functions out, functions over collections.

Taking and returning functions

A retry wrapper and a comparator factory.

// Takes a function: generic retry logic, caller supplies the action
async function withRetry<T>(action: () => Promise<T>, attempts = 3): Promise<T> {
  let lastError: unknown;
  for (let i = 0; i < attempts; i++) {
    try { return await action(); } catch (e) { lastError = e; }
  }
  throw lastError;
}

// Returns a function: build comparators from a key
const by = <T>(key: (t: T) => number) =>
  (a: T, b: T) => key(a) - key(b);

type Item = { name: string; price: number };
const items: Item[] = [{ name: 'pen', price: 2 }, { name: 'book', price: 12 }];
const cheapestFirst = [...items].sort(by(i => i.price)); // copy, then sort

A power drill and its bits

The drill (higher-order function) provides the motor; the bit you plug in (the passed function) decides whether it drills, screws or sands.

Quick check: Which is a higher-order function?

  • A function that accepts a callback as an argument
  • Any function with more than three parameters
  • A function declared at the top of a file
  • A function that returns a number
Answer

A function that accepts a callback as an argument — Higher-order means it works with functions as values.