gpt4 book ai didi

clojure - Clojure 源中的父 eval(阅读器)函数?

转载 作者:行者123 更新时间:2023-12-04 18:48:14 25 4
gpt4 key购买 nike

Peter Norvig's史诗巨著Paradigms of Artifical Intelligence Programming在第 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))))))))

有趣的是—— Christian Queinnec's的开篇 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功能?我假设它在某个地方的阅读器代码中。

最佳答案

你的意思是,什么是 Clojure 的 eval程序?那就是 clojure.core/eval .此 link文档中显示了评估是如何发生的:

  • 交互式地,在 REPL 中
  • 在从流中读取的一系列表单上,通过加载或加载文件
  • 以编程方式,通过 eval

  • 如果您对实际的源代码感兴趣,请查看 Clojure 的 core.clj 文件。特别是 eval 的代码看起来像这样:
    (defn eval
    "Evaluates the form data structure (not text!) and returns the result."
    [form] (. clojure.lang.Compiler (eval form)))

    反过来, 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();
    }
    }

    我想这不是你所期望的,但考虑到 Clojure 运行在 JVM 之上的事实,评估部分作为 Java 程序而不是 Lisp 程序发生是有道理的——就像在问题中引用的代码。

    关于clojure - Clojure 源中的父 eval(阅读器)函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10462262/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com