# chickadee » srfi-1 » unfold-right

##### Identifier search
unfold-right p f g seed #!optional tailprocedure

unfold-right constructs a list with the following loop:

```(let lp ((seed seed) (lis tail))
(if (p seed) lis
(lp (g seed)
(cons (f seed) lis))))```
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
list terminator; defaults to '().

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 right-to-left order. P says when to stop.

unfold-right is the fundamental iterative list constructor, just as fold is the fundamental iterative list consumer. While unfold-right 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-right zero?
(lambda (x) (* x x))
(lambda (x) (- x 1))
10)

;; Reverse a proper list.
(unfold-right null-list? car cdr lis)

;; Read current input port into a list of values.
(unfold-right eof-object? values (lambda (x) (read)) (read))

;; (append-reverse rev-head tail)
(unfold-right null-list? car cdr rev-head tail)```

Interested functional programmers may enjoy noting that fold and unfold-right 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 KONS KNIL (unfold-right KNULL? KAR KDR X)) = X

and

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

This combinator presumably has some pretentious mathematical name; interested readers are invited to communicate it to the author.