← back to programming

Hierarchical Data

Abelson & Sussman ยท 1996 ยท SICP ยง2.2

The closure property of cons: the result of combining things can itself be combined. Pairs of pairs build lists and trees. map, filter, accumulate are the universal interfaces for sequence operations — once you have them, you stop writing loops and start describing pipelines.

car cdr 1 2 3 4 ((1 2) (3 4)) โ€” pairs of pairs build trees

Sequences as lists

A list is a chain of pairs. (list 1 2 3) builds (cons 1 (cons 2 (cons 3 '()))). car takes the first element, cdr takes the rest. map applies a function to every element, producing a new list with the same structure.

Scheme

Hierarchical structures

When list elements are themselves lists, you get a tree. count-leaves recursively walks both the car and cdr of each pair. This is where the closure property pays off: the same operations that work on flat lists work on nested structures.

Scheme

Sequence operations

filter keeps elements that satisfy a predicate. accumulate (fold) combines elements with an operation. Together with map, they form a signal-processing pipeline: enumerate, then map, then filter, then accumulate. No explicit loops.

Scheme

Nested mappings

flatmap maps a function that returns a list over a list, then flattens the results into a single list. It replaces nested loops. Here it generates all ordered pairs (i, j) where 1 ≤ j < i ≤ n and their sum is prime.

Scheme

Notation reference

Scheme Python Meaning
(list 1 2 3)[1, 2, 3]Construct a list
(cons x xs)[x] + xsPrepend element
(car xs)xs[0]First element
(cdr xs)xs[1:]All but first
(map f xs)[f(x) for x in xs]Apply f to each element
(filter pred xs)[x for x in xs if pred(x)]Keep elements satisfying predicate
(accumulate op init xs)functools.reduce(op, xs, init)Fold right with initial value
(flatmap f xs)[y for x in xs for y in f(x)]Map then flatten

Translation notes

Scheme's accumulate is a right fold: it processes the last element first. Python's reduce is a left fold. For associative operations (addition, multiplication) they give the same result. For non-associative ones (subtraction, cons) they differ. The SICP convention uses right fold because it mirrors the recursive structure of lists: process the head, then recurse on the tail.

Python's list comprehensions do the work of map, filter, and flatmap in a single syntax. The Scheme decomposition is more explicit about the pipeline stages, which matters when you start composing them programmatically.

Neighbors

SICP chapters

Category theory connections

Foundations (Wikipedia)

  • wpCons โ€” the pair primitive underlying all Lisp data structures
  • wpTree (data structure) โ€” hierarchical structures from recursive pairs
Ready for the real thing? Read SICP §2.2.