<< Previous exercise (2.21) | Index | Next exercise (2.23) >>

Saying in a different way, the bug on the second version can also be attributed to the property of cons as shown below.

1 ]=> (cons 1 2) ;Value 11: (1 . 2) 1 ]=> (cons 1 (list 2 3)) ;Value 12: (1 2 3) 1 ]=> (cons (list 2 3) 1) ;Value 13: ((2 3) . 1)

We can also find that the 2nd will have `nil` as the 1st item of the result structure instead of the square of the 1st item of the input list. So it is wrong.

---

When I continued reading this page, The above is same as Tengs's comment.

An implementation evolving an iterative process works.

```
(define (square-list items)
(define (iter l pick)
(define r (square (car l)))
(if (null? (cdr l))
(pick (list r))
(iter (cdr l) (lambda (x) (pick (cons r x))))))
(iter items (lambda (x) x)))
```

An innovative solution. Please consider, from a tyro, the following polish which doesn't fail on the empty list.

```
(define (square-list5 items)
(define (iter l pick)
(if (null? l)
(pick l)
(let ((r (square (car l))))
(iter (cdr l) (lambda (x) (pick (cons r x)))))))
(iter items (lambda (x) x)))
```

Compared with the 1st code in the exercise, here somarl's implementation *delays* the `cons` using `lambda` until the final item of the input list (Think that from the 3rd call `iter` inclusive, each call of `pick` in `(lambda (x) (pick (cons r x)))` does something like adding one wrapper `(cons r ...)` where r depends on the last iteration). So it does something like `(cons a (cons b (cons c ... (cons z '())...)))` where `a` means the 1st item and others are similar. The exercise 1st code doesn't delay and does `(cons z (cons y (cons x ... (cons a '())...)))`.

---

Also see mueen's comment in sicp-ex-2.20 which is same as roy-tobin's allowing `rest` to be `nil`.

the problem here is that Louis uses iteration and now we can only use `cdr` to get the rest of the list, so we must process the list from the tail by iteration,
and since the `answer` is originally `nil`, we can't just change the order to `(cons answer (square (car things)))` because when the program executed to the innermost iteration, the first element will be `nil`, so the result will be like `(((() . 1) . 4) . 9)`

jz