<< Previous exercise (2.29) | Index | Next exercise (2.31) >>
an alternative version of map but doesn't use cond and doesn't need to check for nil.
(define (square-tree tree)
(map (lambda (sub-tree)
(if (pair? sub-tree)
(square-tree sub-tree)
(square sub-tree)))
tree))
This problem is similar to the example "scale-tree". so we can solve it as following:
(define (square-tree1 tree) (cond ((null? tree) '()) ((not (pair? tree)) (* tree tree)) (else (cons (square-tree1 (car tree)) (square-tree1 (cdr tree)))))) (define (square-tree2 tree) (map (lambda (x) (if (pair? x) (square-tree2 x) (* x x))) tree))
In my opinion, mapping a complex procedure over a list kind of undermines the conceptual simplicity usually gained from using map. I think it's much clearer what's going on in the following solution:
(define (square-tree tree)
(if (not (pair? tree))
(square tree)
(map square-tree tree)))
It's pretty much the same idea but inside-out, instead of making a decision as to whether to recurse while mapping, we make a decision as to whether to map while recursing.
...except your solution has a major flaw: it doesn't handle nil trees (i.e. empty lists. The map solutions implicitly handles nil trees, though.
And I would disagree with your general point about map. I think that pure "map" solutions operate at a higher level of abstraction: you're simply specifying a transformation to apply to elements of an input. It's very mathematical. Procedures are functions, after all, with domains and codomains, and map makes that relationship more explicit.
jz