Search code examples
lispelisp

Lisp expression evaluated to a list, not understanding how it works


My teacher is very bad at explaining. He just gave us the question with an answer that he cannot explain resulting in myself not understanding much of it.

Is it possible for anyone to break down how this answer comes about? I understand that car returns the first element of a list and cdr returns all the elements after the first element.

Thanks in advance for reading.

Suppose the Lisp variable E has been given a value as follows:

(setf e '((-1 -2)
          ((90 91) 92 93 94 95 96 97 98)
          (9 19 29 39 49 59 69 79 89)))

Write a LISP expression which doesn't involve any numbers, but which evaluates to the list:

(-2 91 (19 29 39 49 59 69 79 89))

Answer:

(list (cadar e) (cadr (caadr e)) (cdaddr e))

Solution

  • In Common Lisp (as well as other Lisp languages) a function like cadar or cdaddr etc. (you can have up to 4 characters d or a after the first c and before the last r) is an abbreviation of a combination of the functions car and cdr with the following rule: each a correspond to a car, and each d correspond to a cdr.

    In other words, (caar x) is equivalent to (car (car x)), (caddr x) is equivalent to (car (cdr (cdr x))) and so on.

    So for istance, in your example (cadar e) means (car (cdr (car e))), that is:

    take the (car e), which is (-1 -2)
    take the cdr of the previous value, which is the list (-2)
    take the car of this list, that is the integer -2
    

    Here the other equivalences:

    (cadr (caadr e)) = (car (cdr (car (car (cdr e)))))
    (cdaddr e) = (cdr (car (cdr (cdr e))))
    

    So (list (cadar e) (cadr (caadr e)) (cdaddr e)) is equivalent to:

    (list (car (cdr (car e)))
          (car (cdr (car (car (cdr e)))))
          (cdr (car (cdr (cdr e)))))
    

    which produces the expected result (you can verify this by applying all the functions in the correct order).