← back to programming

Higher-Order Functions

Abelson & Sussman · 1996 · SICP §1.3

Functions that take functions as arguments or return functions as values. This is the mechanism of abstraction — patterns become parameters.

f g h in out compose functions that take and return functions abstraction over patterns

Procedures as arguments — summation

Three procedures — sum of integers, sum of cubes, sum of the pi series — share the same structure. The only difference is which function to apply and which term comes next. Extract the pattern: sum takes term and next as arguments.

Scheme

Lambda — anonymous procedures

Sometimes naming a procedure is overkill. lambda creates a procedure without binding it to a name. It's the same mechanism as define — just without the name.

Scheme

Let — local bindings

let creates local variables. It's syntactic sugar for an immediately-applied lambda. The scope is the body of the let expression.

Scheme

Procedures as returned values

Functions that return functions are the other half of higher-order programming. average-damp takes a function and returns a smoothed version. This is the building block for Newton's method and fixed-point search.

Scheme

Newton's method as abstraction

Newton's method finds zeros of a function. Expressed as a fixed-point search on the Newton transform. The whole thing composes from pieces we already have: fixed-point, average-damp, the derivative. Each layer names one idea.

x y y = x y = f(x) x₀ x₁ x₂ x* fixed-point: iterate f until f(x) = x
Scheme

Notation reference

Scheme Python Meaning
(lambda (x) body)lambda x: bodyAnonymous function
(let ((a v1) (b v2)) body)a = v1; b = v2; bodyLocal bindings
(define (f g) (lambda (x) ...))def f(g): return lambda x: ...Return a procedure
(compose f g)compose(f, g)f after g
(fixed-point f guess)fixed_point(f, guess)Find x where f(x) = x
Neighbors

Other reading pages

Foundations (Wikipedia)

Translation notes

Python's lambda is limited to single expressions; Scheme's lambda takes a full body. For multi-statement procedures-as-values, Python uses def inside def. The let form has no direct Python equivalent — Python uses sequential assignment, which allows later bindings to reference earlier ones (unlike let, where all bindings are evaluated in the enclosing scope). SICP also introduces let* for sequential binding, which matches Python's behavior more closely.

Ready for the real thing? Read SICP §1.3.