In Peter Norvig’s epic tome Paradigms of Artifical Intelligence Programming in Chapter 7 – he describes a function interp which is effectively a simple eval function used when interpreting a bare-bones Scheme in a REPL.
(defun interp (x &optional env)
"Interpret (evaluate) the expression x in the environment env."
(cond
((symbolp x) (get-var x env))
((atom x) x)
((case (first x)
(QUOTE (second x))
(BEGIN (last1 (mapcar #'(lambda (y) (interp y env))
(rest x))))
(SET! (set-var! (second x) (interp (third x) env) env))
(IF (if (interp (second x) env)
(interp (third x) env)
(interp (fourth x) env)))
(LAMBDA (let ((parms (second x))
(code (maybe-add 'begin (rest2 x))))
#'(lambda (&rest args)
(interp code (extend-env parms args env)))))
(t ;; a procedure application
(apply (interp (first x) env)
(mapcar #'(lambda (v) (interp v env))
(rest x))))))))
Interestingly enough – the opening Chapter of Christian Queinnec’s Lisp In Small Pieces has a very similar function, he calls it eval.
;;; This is a naive evaluator for Scheme written in naive Scheme.
(define (evaluate e env)
(if (atom? e)
(cond ((symbol? e) (lookup e env))
((or (number? e) (string? e) (char? e)
(boolean? e) (vector? e) )
e )
(else (wrong "Cannot evaluate" e)) )
(case (car e)
((quote) (cadr e))
((if) (if (evaluate (cadr e) env)
(evaluate (caddr e) env)
(evaluate (cadddr e) env) ))
((begin) (eprogn (cdr e) env))
((set!) (update! (cadr e) env (evaluate (caddr e) env)))
((lambda) (make-function (cadr e) (cddr e) env))
(else (invoke (evaluate (car e) env)
(evlis (cdr e) env) )) ) ) )
My question is – where is the Clojure source is the equivalent eval/interp function? I assume it is in the reader code somewhere.
You mean, what’s Clojure’s
evalprocedure? That’d be clojure.core/eval. This link from the documentation shows how evaluation occurs:evalIf you’re interested in the actual source code, take a look at Clojure’s
core.cljfile. In particular, the code forevallooks like this:In turn, the
evalmethod from theCompilerclass (referenced in the above snippet, and residing in the Compiler.java file) looks like this:I guess that’s not quite what you expected it to be, but given the fact that Clojure runs on top of the JVM, it makes sense that the evaluation part occurs as a Java program and not as a Lisp program – as is the case in the code referenced in the question.