haw*_*eye 5 scheme eval clojure
在Peter Norvig的史诗第7章" 人工智能编程范式"中,他描述了一个函数interp,它实际上是eval一个在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))))))))
Run Code Online (Sandbox Code Playgroud)
有趣的是 - 他称之为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) )) ) ) )
Run Code Online (Sandbox Code Playgroud)
我的问题是 - Clojure源在哪里是等效eval/ interp函数?我认为它在某处的读者代码中.
你的意思是,什么是Clojure的eval程序?这就是clojure.core/eval.文档中的此链接显示了评估的发生方式:
eval如果您对实际的源代码感兴趣,请查看Clojure的core.clj文件.特别是,代码eval看起来像这样:
(defn eval
"Evaluates the form data structure (not text!) and returns the result."
[form] (. clojure.lang.Compiler (eval form)))
Run Code Online (Sandbox Code Playgroud)
反过来,类中的eval方法Compiler(在上面的代码片段中引用,并驻留在Compiler.java文件中)如下所示:
public static Object eval(Object form) throws Exception{
boolean createdLoader = false;
if(true)//!LOADER.isBound())
{
Var.pushThreadBindings(RT.map(LOADER, RT.makeClassLoader()));
createdLoader = true;
}
try
{
Integer line = (Integer) LINE.deref();
if(RT.meta(form) != null && RT.meta(form).containsKey(RT.LINE_KEY))
line = (Integer) RT.meta(form).valAt(RT.LINE_KEY);
Var.pushThreadBindings(RT.map(LINE, line));
try
{
form = macroexpand(form);
if(form instanceof IPersistentCollection && Util.equals(RT.first(form), DO))
{
ISeq s = RT.next(form);
for(; RT.next(s) != null; s = RT.next(s))
eval(RT.first(s));
return eval(RT.first(s));
}
else if(form instanceof IPersistentCollection
&& !(RT.first(form) instanceof Symbol
&& ((Symbol) RT.first(form)).name.startsWith("def")))
{
FnExpr fexpr = (FnExpr) analyze(C.EXPRESSION, RT.list(FN, PersistentVector.EMPTY, form), "eval");
IFn fn = (IFn) fexpr.eval();
return fn.invoke();
}
else
{
Expr expr = analyze(C.EVAL, form);
return expr.eval();
}
}
finally
{
Var.popThreadBindings();
}
}
catch(Throwable e)
{
if(!(e instanceof CompilerException))
throw new CompilerException((String) SOURCE.deref(), (Integer) LINE.deref(), e);
else
throw (CompilerException) e;
}
finally
{
if(createdLoader)
Var.popThreadBindings();
}
}
Run Code Online (Sandbox Code Playgroud)
我想这并不是你所期望的那样,但考虑到Clojure在JVM之上运行这一事实,评估部分作为Java程序而不是作为Lisp程序发生是有道理的 - 就像在问题中引用的代码.