liveBook · Manning

Postwalk

As explained in Clojure: The Essential Reference

postwalk is a Clojure function that recursively traverses a nested data structure and applies a function to each node after its children have been processed.

postwalk recursively traverses an arbitrarily nested Clojure data structure in depth-first, post-order fashion. It applies a one-argument function to every node only after recursively processing that node’s children, making it useful for transforming or reducing completed branches. section 8.4.2

Its contract is small but important:

  • Call (postwalk f form) with a one-argument function f and any form, including nil. section 8.4.2
  • Visit collections recursively and invoke f on collections and non-collection values alike. section 8.4.2
  • Usually preserve the input collection type, although transformations performed by f determine the output. section 8.4.2
  • Potentially throw UnsupportedOperationException for recognized collection types missing required operations, such as bean’s missing empty method. section 8.4.2

Observe post-order traversal

(require '[clojure.walk :refer [postwalk-demo]]) (postwalk-demo [1 [2 [3]] 4]) ;; Walked: 1 ;; Walked: 2 ;; Walked: 3 ;; Walked: [3] ;; Walked: [2 [3]] ;; Walked: 4 ;; Walked: [1 [2 [3]] 4] ;; [1 [2 [3]] 4] The leaves appear first; each containing vector appears only after its nested branch has been visited. section 8.4.1

Evaluate an expression tree

Represent a computation as maps containing :function and :children, then evaluate each node after its children: (postwalk evaluate (compound-interest-data 7.2 5000 2)) ;; 5771.936460924754 Because child expressions are resolved first, the parent function receives completed operands. section 8.4.2

Choose postwalk when processing a parent depends on transformed or evaluated descendants. Choose prewalk when the function must alter a node before descending, such as preventing traversal into a branch; both can produce equal values while producing different side effects. section 8.4.2

How Clojure: The Essential Reference covers it

How deep it goes
Explains recursive depth-first traversal, contracts, output behavior, exceptions, and expression evaluation, while deferring walk internals.
Examples
Uses nested-vector traversal output and compound-interest expression-tree evaluation.
What it assumes
Assumes familiarity with Clojure functions, collections, nesting, and recursive data; teaches traversal order from examples.
What you can do after
Apply it via clojure.walk to transform nested structures or evaluate parents after their descendants.
How it connects
Connects post-order traversal with prewalk, walk, nested data structures, and expression trees.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Clojure: The Essential Reference. The section links point to the parts of the book it draws on.