Search code examples
lispevalcommon-lispdynamic-binding

Function name and dynamic binding in Common Lisp


I'm reading Peter Norvig's Paradigms of AI. In chapter 6.2, the author uses code like below (not the original code, I picked out the troubling part):

Code Snippet:

(progv '(op arg) '(1+ 1)
(eval '(op arg)))

As the author's original intent, this code should return 2, but in sbcl 1.1.1, the interpreter is apparently not looking up op in the environment, throwing out op: undefined function.

Is this implementation specific? Since the code must have been tested on some other lisp.

p.s Original code


Solution

  • You probably mean

    (progv '(op arg) '(1+ 1)
      (eval '(funcall op arg)))
    

    Edit(2013-08-21):

    PAIP was written in pre-ANSI-Common-Lisp era, so it's possible the code there contains a few noncompliances wrt the standard. We can make the examples work with the following revision:

    (defun match-if (pattern input bindings)
      "Test an arbitrary expression involving variables.
      The pattern looks like ((?if code) . rest)."
      (and (eval (reduce (lambda (code binding)
                           (destructuring-bind (var . val) binding
                             (subst val var code)))
                         bindings :initial-value (second (first pattern))))
           (pat-match (rest pattern) input bindings)))
    
    ;; CL-USER> (pat-match '(?x ?op ?y is ?z (?if (eql (?op ?x ?y) ?z))) '(3 + 4 is 7))
    ;; ((?Z . 7) (?Y . 4) (?OP . +) (?X . 3) (T . T))
    ;; CL-USER> (pat-match '(?x ?op ?y (?if (?op ?x ?y))) '(3 > 4))
    ;; NIL