Search code examples
macroslispelispelisp-macro

Lisp - "list 'if x y nil" what is usage of the tick (') symbol and "list" function here?


I am taking a programming language principle class where the professor talks about macro using Lisp (Precisly, Elisp). However, he didn't teach us how to write this language. As a result, I am trying to learn myself.

However, there are something that I just can't understand regarding the use of "tick" (') in Lisp. I do, however, understand the basic use. For example, if we have (cdr '(a b c)) it will give us a list (b c). Without the tick symbol, (a b c) would be evaluated as a function.

In the code written by my professor, I have noticed a strange use of "tick" symbol that I can't really understand the usage:

; not sure why there is a "'" in front of if and it is being added to a list ??
(defmacro myand(x y) (list 'if x y nil))  

; Another example. Tick symbol before "greater than" symbol ? and made into a list?
(list 'if (list '> x y))

The uses of list and tick symbol just doesn't really make sense to me. Can anyone explain what is going on here? I suppose this is something special to Lisp


Solution

  • The 'tick symbol' is ': '<x> is syntactic sugar for (quote <x>) for any <x>. And (quote <x>) is simply <x> for any object <x>.

    quote is needed in Lisp because programs in Lisp often want to reason about things which would have meaning as parts of Lisp programs, and need to say 'this isn't part of this program: it's data'. So, for instance, if I have a list of the form

    ((a . 1) (b . 2) ... (x . 26)) and I want to look up a symbol in it, I might write a function like this:

    (defun ass (key alist)
      (if (null? alist)
          '()
        (if (eql (car (car alist)) key)
            (car alist)
          (ass key (cdr alist)))))
    

    Then when I wanted to look up, say x, I would have to say (ass (quote x) ...) because if I said (ass x ...) then x would be treated as a variable, and I don't want that: I want the symbol x.

    In your example you are looking at programs which write Lisp programs – macros in other words – and these programs need to spend a lot of their time manipulating what will be Lisp source code as data. So in your myand macro, what you want is that

    (myand x y)
    

    should be rewritten as

    (if x y nil)
    

    Which is the same thing. So to construct this you need a list of four elements: the symbol if, the two variables and the symbol nil. Well you can make a list with list:

    (list 'if x y 'nil)
    

    Except that it turns out that the value of the symbol nil is just itself (nil is rather special in many Lisps in fact), so you can not bother quoting that: (list 'if x y nil) (I personally would have quoted it in this case, to make it clear what was literal and what was being evaluated, but that's probably not common).