2012-05-05 47 views
5

Peter Norvig's में महाकाव्य टोम Paradigms of Artifical Intelligence Programming अध्याय 7 में - वह एक समारोह interp का वर्णन करता है जो प्रभावी रूप से एक सरल eval फ़ंक्शन का उपयोग करता है जब एक आरईपीएल में नंगे हड्डियों की योजना का अर्थ होता है।अभिभावक 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'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 समारोह है है? मुझे लगता है कि यह कहीं भी पाठक कोड में है।

उत्तर

6

आपका मतलब है, क्लोजर की eval प्रक्रिया क्या है? वह clojure.core/eval होगा। दस्तावेज़ से यह link दिखाता है कि कैसे मूल्यांकन होता है:

  • सहभागितापूर्ण तरीके से, आरईपीएल
  • एक धारा से पढ़ने के तरीकों में से एक दृश्य पर में, भार या लोड फ़ाइल
  • प्रोग्राम के माध्यम से, eval
के माध्यम से

यदि आप वास्तविक स्रोत कोड में रुचि रखते हैं, तो क्लोजर की core.clj फ़ाइल पर एक नज़र डालें। विशेष रूप से, eval के लिए कोड इस तरह दिखता है:

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(); 
     } 
} 
:

(defn eval 
    "Evaluates the form data structure (not text!) and returns the result." 
    [form] (. clojure.lang.Compiler (eval form))) 

बारी में, Compiler वर्ग (ऊपर टुकड़ा में संदर्भित, और Compiler.java फ़ाइल में रहने वाले) से eval विधि इस तरह दिखता है

मुझे लगता है कि यह उतना ही नहीं है जितना आप चाहते थे, लेकिन यह तथ्य दिया गया कि क्लोजर JVM के शीर्ष पर चलता है, यह समझ में आता है कि मूल्यांकन भाग जावा प्रोग्राम के रूप में होता है, न कि लिस्प प्रोग्राम के रूप में - जैसा कि है प्रश्न में संदर्भित कोड में मामला।

+1

ओपी अब बहुत निराश है - उसने क्लोजर के गंदे रहस्य को पाया कि eval क्लोजर नहीं है :) –

+0

@MarkoTopolnik दरअसल! । और मैं भी हूं - मेरा मतलब है, थोड़ा निराश:/ –

+0

ग्रेट - इसके लिए धन्यवाद। क्या मैं यह मानने में सही होगा कि क्लोजरस्क्रिप्ट में कोई eval function नहीं है? रिच हिकी क्लोजरस्क्रिप्ट परिचय बातचीत को देखने से मुझे यह इंप्रेशन मिला। – hawkeye