0

I am trying to implement a method that has the ability to square a list that can consists of sub lists (a tree) using map.

This means that (square-tree-map (list 1 3 (list 3 4))) should return (1 9 (9 16)).

I came up with this code:

(define (square-tree-map tree)
  (define (sq x) (* x x))
  (map (lambda (t) 
         (if (pair? t) 
             (cons (square-tree-map (car t))
                   (square-tree-map (cdr t)))
             sq t)) 
       tree))

This gives the error:

if: bad syntax; has 4 parts after keyword in: (if (pair? t) (cons (square-tree-mapped (car t)) (square-tree-mapped (cdr t))) sq t)

I only see two possibilities after the if operator, not 4. Why do I get this error?

leppie
  • 115,091
  • 17
  • 196
  • 297
user2609980
  • 10,264
  • 15
  • 74
  • 143

1 Answers1

1

Turned out to be a syntax error:

(if (pair? t) 
     (cons (square-tree-map (car t))
           (square-tree-map (cdr t)))
     sq t)) 

Should be:

(if (pair? t) 
    (cons (square-tree-map (car t))
           (square-tree-map (cdr t)))
     (sq t))) 

So the error came from the fact that sq and t where counted as two.

By doing the above I saw that another if-check should be build around it to make sure we are not trying to map over a single value which is not possible:

(define (square-tree-map tree)
  (define (sq x) (* x x))
  (if (pair? tree)
      (map (lambda (t) 
             (if (pair? t) 
                 (cons (square-tree-map (car t)) 
                       (square-tree-map (cdr t)))
                 (sq t)))
           tree)
      (sq tree)))

(square-tree-map (list 1 (list 4 2) 3 5))
;; => (1 (16 4) 9 25)

In the end cons a car and a cdr is a redundant operation since l = (cons (car l) (cdr l)) by definition. A shorter solution is:

(define (square-tree-map tree)
  (define (sq x) (* x x))
  (map (lambda (t) 
         (if (pair? t) 
             (square-tree-map t)
             (sq t)))
       tree))

Thanks for your attention.

user2609980
  • 10,264
  • 15
  • 74
  • 143
  • Your last step does more than removing the call to `cons`, as now you may be calling `map` on an atom instead of a cons. – acelent Mar 13 '15 at 15:04