1

I'm new to Lisp and need help understanding this function and the evaluation of (map length '((a b c) (1 2 3 4 5) (v1 v2 v3 v4 v5 v6))))

The value is (3 5 6)

(define (map f list)    
  ; applies function f to each element of list
  (if (null? list) 
      ()
      (cons (f (car list)) 
            (map f (cdr list)))))

(define map-test-1
  (map square '(1 2 3 4 5)))
(define map-test-2
  (map length '((a b c) (1 2 3 4 5) (v1 v2 v3 v4 v5 v6))))
3
  • The expression (cons (f (car list)) (map f (cdr list))))) and how it evaluates to (3 5 6) in map-test-2 Commented May 10, 2015 at 23:21
  • yes sort of, probably need more clarity in that too Commented May 10, 2015 at 23:25
  • yes, got that so for map-test-2 it would be (cons (length a) (map length '( b c)) cons (length 1) (map length '(2 3 4 5)) cons (length v1) (map length '(v2 v3 v4 v5 v6)) and so on Commented May 10, 2015 at 23:45

1 Answer 1

3

In general, the idea of mapping is that for any list (define lst (list a b c d ... )) and function f, the value of (map f lst) is the same as the value of (list (f a) (f b) (f c) (f d) ...).


Let's simulate evaluation as a series of reduction steps:

    (map    square   '(1 2 3 4 5)   )   
;;  (map    f        list           )
=   (let ( (f        square       )       ; definition 
           (list     '(1 2 3 4 5) ) )     ; of `map`
        (if (null? list)             
          ()
          (cons (f     (car list)) 
                (map f (cdr list)))))     ; list is not `null?`, so

=   (let ( (f        square       )
           (list     '(1 2 3 4 5) ) ) 
        (cons (f     (car list))         ; car of list is 1
              (map f (cdr list))))       ; cdr is '(2 3 4 5)

=  (cons (square 1) 
     (let ( (f        square     )       ; simulate the recursive call
            (list     '(2 3 4 5) ) )     ; by updating the arguments
       (map f list)))

=  (cons (square 1) 
     (let ( (f        square     )
            (list     '(2 3 4 5) ) )
        (if (null? list) 
          ()
          (cons (f     (car list)) 
                (map f (cdr list))))))

=  (cons (square 1) 
     (let ( (f        square     )
            (list     '(2 3 4 5) ) )
        (cons (f     (car list)) 
              (map f (cdr list)))))

=  (cons (square 1) 
     (cons (square 2) 
       (let ( (f        square     )
              (list     '(3 4 5) ) )
          (map f list))))

...

As for your second example, '((a b c) (1 2 3 4 5) (v1 v2 v3 v4 v5 v6)) is the same as (list '(a b c) '(1 2 3 4 5) '(v1 v2 v3 v4 v5 v6)), i.e. it is a list with three elements in it; so the reduction becomes

(let ((mylist (list '(a b c) '(1 2 3 4 5) '(v1 v2 v3 v4 v5 v6))))
    (let ( (f        length       )       ; definition 
           (list     mylist       ) )     ; of `map`
        (if (null? list)             
          ()
          (cons (f     (car list)) 
                (map f (cdr list))))))    ; list is not `null?`, so

=   (let ( (f        length       )
           (list     mylist       ) ) 
        (cons (f     (car list))         ; car of list is '(a b c)
              (map f (cdr list))))       ; cdr is '((1 2 3 4 5) (v1 v2 v3 v4 v5 v6))

=  (cons (length '(a b c)) 
     (let ( (f        length       )     ; simulate the recursive call
            (list     (cdr mylist) ) )   ; by updating the arguments
       (map f list)))

=  (cons (length '(a b c)) 
     (let ( (f        length    )
            (list     '((1 2 3 4 5) (v1 v2 v3 v4 v5 v6)) ) )
        (if (null? list) 
          ()
          (cons (f     (car list)) 
                (map f (cdr list))))))

=  (cons (length '(a b c))
     (let ( (f        length    )
            (list     '((1 2 3 4 5) (v1 v2 v3 v4 v5 v6)) ) )
        (cons (f     (car list)) 
              (map f (cdr list)))))

=  (cons (length '(a b c)) 
     (cons (length '(1 2 3 4 5)) 
       (let ( (f        length     )
              (list     '((v1 v2 v3 v4 v5 v6)) ) )
          (map f list))))

=  (cons (length '(a b c)) 
     (cons (length '(1 2 3 4 5)) 
       (cons (length '(v1 v2 v3 v4 v5 v6)) 
         (let ( (f        length)
                (list     '() ) )
           (if (null? list)             
             ()
             (cons (f     (car list)) 
                   (map f (cdr list))))))))  ; list is now `null?`, so

=  (cons (length '(a b c)) 
     (cons (length '(1 2 3 4 5)) 
       (cons (length '(v1 v2 v3 v4 v5 v6)) 
         '())))

QED.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks incredibly helpful!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.