Lisp quote work internally

前端 未结 2 1772
猫巷女王i
猫巷女王i 2021-01-22 11:46

How does lisp quote work internally? For example:

(quote (+ 1 (* 1 2)) )

seems to be equivalent to

(list \'+ 1 (li         


        
2条回答
  •  情歌与酒
    2021-01-22 12:12

    How does it work?

    quote is really really simple to implement. It does mostly nothing. The quote special operator just returns the enclosed object like it is. Nothing more. No evaluation. The object is not changed in any way.

    Evaluation of quoted forms

    Probably a good time to read McCarthy, from 1960:

    Recursive Functions of Symbolic Expressions and Their Computation by Machine, Part I

    Pages 16/17 explain evaluation with eval. Here:

    eq [car [e]; QUOTE] → cadr [e];
    

    or in s-expression notation:

    (cond
    
      ...
    
      ((eq (car e) 'quote)
       (cadr e))
    
      ...)
    

    Above code implements the evaluation rule for QUOTE: If the expression is a list and the first element of the list is the symbol QUOTE, then return the second element of the list.

    Equivalence of a quoted list with a list created by LIST

    (equal (quote (+ 1 (* 1 2)))
           (list '+ 1 (list '* 1 2)))
    

    The result is T. This means that both result lists are structurally equivalent.

    (eq (quote (+ 1 (* 1 2)))
        (list '+ 1 (list '* 1 2)))
    

    The result is NIL. This means that the first cons cell of the linked lists are not the same objects. EQ tests whether we really have the same cons cell object.

    • QUOTE returns a literal data object. The consequences of modifying this object is undefined. So, don't do it.

    • LIST returns a new freshly consed list each time it is called. The fresh new list will not share any cons cells with any earlier allocated list.

    So the main difference is that QUOTE is a built-in operator, which returns literal and unevaluated data. Whereas LIST is a function which creates a new,fresh list with its arguments as contents.

    See the effects with respect to EQ and EQUAL:

    CL-USER 6 > 
    (flet ((foo () (quote (+ 1 (* 1 2))))
           (bar () (list '+ 1 (list '* 1 2))))
      (list (list :eq-foo-foo    (eq    (foo) (foo)))
            (list :eq-foo-bar    (eq    (foo) (bar)))
            (list :eq-bar-bar    (eq    (foo) (bar)))
            (list :equal-foo-foo (equal (foo) (foo)))
            (list :equal-foo-bar (equal (foo) (bar)))
            (list :equal-bar-bar (equal (foo) (bar)))))
    
    ((:EQ-FOO-FOO    T)
     (:EQ-FOO-BAR    NIL)
     (:EQ-BAR-BAR    NIL)
     (:EQUAL-FOO-FOO T)
     (:EQUAL-FOO-BAR T)
     (:EQUAL-BAR-BAR T))
    

    is quote a function?

    quote can't be a function, since it returns its enclosed data unevaluated. Thus it is a special evaluation rule.

    If quote were a function, it's arguments were evaluated. But that's exactly what is NOT what quote is supposed to do.

    why does Lisp need QUOTE?

    Lisp usually uses s-expressions to write Lisp code. So s-expressions have a both purpose to denote data and we use it to write programs. In a Lisp program lists are used for function calls, macro forms and special forms. symbols are used as variables:

    (+ n 42)
    

    Here (+ n 42) is a list and n is a symbol. But we also want to use lists as data in our programs and we want to use symbols as data. Thus we have to quote them, so that Lisp will not see them as programs, but as data:

    (append '(+ n) '(42))  evaluates to (+ n 42)
    

    Thus in a Lisp program, lists and variables are by default part of the language elements, for example as function calls and variables. If we want to use lists and symbols as literal data, we have to quote them, to prevent the evaluator treating them as Lisp code to evaluate.

提交回复
热议问题