2013-03-24 10 views
5

レキシカル環境でシンボルを解決する関数を作成するにはどうすればよいですか?clojure - 内部のシンボルを解決する

(let [foo some-var] 
    (let [sym 'foo] 
    (resolve-sym sym))) 

「fooがバインドされているvarを取得したい。ここで

+3

http://clojuredocs.org/circumspec/circumspec.should/local-bindingsからレッツは、新しいVARSを作成しませんので、基本的に、あなたは彼らに – Ankur

+0

を解決するカントしかし、&ENVとマクロ内的環境を得ることが可能です。 – navgeet

+0

@navgeet、いいえ、できません。 '(m 1 2 3 4 5) - > '(1(2 3 4 5))'、つまり '&env'は' varargsにアクセスできます。 Clojureには、現在のレキシカル環境を取得する方法はありません。 –

答えて

4

私はこのような何かをしたい理由は完全にわからないが、それは確かに行うことができるようになります。

(defmacro local-bindings 
    "Produces a map of the names of local bindings to their values. 
    For now, strip out gensymed locals. TODO: use 1.2 feature." 
    [] 
    (let [symbols (remove #(.contains (str %) "_") 
         (map key @clojure.lang.Compiler/LOCAL_ENV))] 
    (zipmap (map (fn [sym] `(quote ~sym)) symbols) symbols))) 


(let [foo 1 bar 2] 
    (local-bindings)) 
=> {foo 1, bar 2} 
1

は、より少ないあなたが望んでいたよりもにスキューの両方である:

(define (make-let-core name value body) 
    `(CORE LET ,name ,value ,body)) 

(define (env-extend env a-name its-denotation) 
    (lambda (name) 
    (if (equal? name a-name) 
     its-denotation 
     (if env (env name) 'unknown)))) 

(define (env-base) 
    (lambda (name) 
    (if (member name '(let resolve-sym #| ... |#)) 
     'syntactic-keyword 
     'unknown))) 

(define (expand exp env) 
    (cond ((literal? exp) ...) 
     ((symbol? exp) ...) 
     ((list? exp) 
     (let ((operator (car exp)) 
       (operands (cdr exp))) 
      (cond ((symbol? operator) 
        (case (env operator) 
        ((syntactic-keyword) 
        (case operator 
         ((let) 
         (let ((bound-name (caar operands)) 
           (bound-value (cadar operands)) 
           (body (cdr operands))) 
          (make-let-core bound-name 
             (expand bound-value env) 
             (expand body 
               (env-extend bound-name 
                  'variable))))) 
         ((resolve-sym) 
         (let ((name (car operands))) 
          ;; right here 
          ...)) 
         (...))) 
        ((variable) ;; function call 
        ...) 

        ((unknown) ;; syntax error 
        ...))) 

       ((list? operator) ;; function call 
        ...) 

       (else ;; syntax error 
        ...)))) 
     (else ;; syntax error 
     ...))) 
+0

@navgeetはClojureソリューションを探しているようですが、これはそうではありません。 – dfreeman

+0

とその解決策でもありません。 – GoZoner

+0

質問は "lisp"とタグ付けされています。 –

関連する問題