在第7章Peter Norvig's史詩鉅著Paradigms of Artifical Intelligence Programming - 他描述了一個功能interp
這實際上是解釋在REPL一個最基本的計劃時使用一個簡單的eval
功能。Clojure源中的父eval(reader)函數?
(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'sLisp 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
功能?我假設它在讀者代碼的某處。
OP現在非常失望 - 他發現了Clojure的骯髒祕密,eval不是Clojure :) –
@MarkoTopolnik確實! 。我也是 - 我的意思是有點失望:/ –
太好了 - 謝謝你。假設ClojureScript沒有eval函數,我會正確嗎?這是我從觀看Rich Hickey ClojureScript介紹講話中得到的印象。 – hawkeye