Search code examples
lispcommon-lispland-of-lisp

Cadr of a list involving assoc function


I have looked around on the net and cant find an answer to my query. I would really appreciate if someone could provide a good answer without down rating this post.

In Lisp car, cdr are used on data mode like '(whatever here) which makes sense to me.

Now, in the book Land of Lisp the author is explaining how to build a text engine and suddenly he uses the following description to make a function.

(defun describe-location (location nodes)
  (cadr (assoc location nodes)))

Can I ask why is he doing a cadr on a list and how come it provides a response and not an error? shouldn't it be a data mode i.e with a quote in front of the opening bracket '(whatever here)?

and also why is he using assoc as in (assoc location nodes) and not (assoc 'garden *nodes*)

Isn't the second correct way to use assoc ? I may be missing the big picture and as such would really appreciate someone explaining these key points please.

Many thanks!


Solution

  • I remember the book, lots of fun.

    assoc just returns cons, car of which is equal to given value. It's like find function with parameter :key #'car. So, for example:

    CL-USER> (assoc 'a '((a "letter a") (b "letter b") (c "letter c")))
    (A "letter a")
    

    so since we get here the whole cons, car of which satisfies the test, we can further apply cadr for this cons and get associated value:

    CL-USER> (cadr (assoc 'a '((a "letter a") (b "letter b") (c "letter c"))))
    "letter a"
    

    It's all for executable code. In data mode you just get lists, not forms, so it will not be executed, try for yourself:

    CL-USER> '(car '(a "letter a"))
    (CAR '(A "letter a"))
    

    Data mode allows one to store lists as data, without trying to execute them. That's why author uses data mode for defining descriptions of rooms in the game, but in function we need to execute forms to get the result.

    What for the second part of your question, it's just author's design anyway. Of course you can put

    (assoc 'garden *nodes*)
    

    but it will have the same effect and only work for garden location.