`unfold``p``f``g``seed``#!optional``tail-gen`procedure`unfold`is best described by its basic recursion:(unfold P F G SEED) = (if (P SEED) (TAIL-GEN SEED) (cons (F SEED) (unfold P F G (G SEED))))

- P
- Determines when to stop unfolding.
- F
- Maps each seed value to the corresponding list element.
- G
- Maps each seed value to next seed value.
- SEED
- The "state" value for the unfold.
- TAIL-GEN
- Creates the tail of the list; defaults to
`(lambda (x) '())`

In other words, we use G to generate a sequence of seed values

SEED, G(SEED), G^2(SEED), G^3(SEED), ...

These seed values are mapped to list elements by F, producing the elements of the result list in a left-to-right order. P says when to stop.

`unfold`is the fundamental recursive list constructor, just as`fold-right`is the fundamental recursive list consumer. While`unfold`may seem a bit abstract to novice functional programmers, it can be used in a number of ways:;; List of squares: 1^2 ... 10^2 (unfold (lambda (x) (> x 10)) (lambda (x) (* x x)) (lambda (x) (+ x 1)) 1) (unfold null-list? car cdr lis) ; Copy a proper list. ;; Read current input port into a list of values. (unfold eof-object? values (lambda (x) (read)) (read)) ;; Copy a possibly non-proper list: (unfold not-pair? car cdr lis values) ;; Append HEAD onto TAIL: (unfold null-list? car cdr head (lambda (x) tail))

Interested functional programmers may enjoy noting that

`fold-right`and`unfold`are in some sense inverses. That is, given operations KNULL?, KAR, KDR, KONS, and KNIL satisfying`(KONS (KAR X) (KDR X))`=`x`and`(KNULL? KNIL)`=`#t`then

`(fold-right KONS KNIL (unfold KNULL? KAR KDR X))`= Xand

`(unfold KNULL? KAR KDR (fold-right KONS KNIL X))`= X.This combinator sometimes is called an "anamorphism;" when an explicit TAIL-GEN procedure is supplied, it is called an "apomorphism."