Peter Norvig の叙事詩本Paradigms of Artifical Intelligence Programmingの第 7 章で、彼は、REPL で必要最小限のスキームを解釈するときに使用されるinterp
事実上単純な関数である関数について説明しています。eval
(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))))))))
興味深いことに、Christian Queinnec の Lisp In Small Piecesの冒頭の章には、非常によく似た機能があり、彼はそれを と呼んでい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) )) ) ) )
私の質問は - Clojure のソースはどこにあるのですeval
かinterp
? リーダーコードのどこかにあると思います。