2016-12-12 7 views
2

Emacs Lispでは、字句的な環境はシンボルをその値にマッピングするalistで表されます。評価関数には、eval関数の第2引数として渡すことができます。Emacs Lispで関数の字句バインディングを 'eval'に渡すには?

(eval '(+ 3 var) 
     '((var . 4))) 
→ 7 

しかし、私は、ない変数、関数を渡す方法を評価者に を把握することはできません。

たとえば、次の式のいずれかがエラーを示しています。

(eval '(func 3) 
     '((func . (lambda (x) (+ 4 x))))) 
→ error: (void-function func) 
(eval '(func 3) 
     '((func . (closure (t) (x) (+ 4 x))))) 
→ error: (void-function func) 

何か助けていただければ幸いです。これについて

+0

Emacs Lispは、[Lisp-1](https://en.wikipedia.org/wiki/LISP_1)ではなく[Lisp-2](https://en.wikipedia.org/wiki/LISP_2)です。 )。 – Drew

答えて

1

方法:

(eval '(apply func (list 3)) 
     '((func . (lambda (x) (+ 4 x))))) 
+0

申し訳ありませんが、これは機能が一度だけ適用されるように制限し、最初の機能を制限します。これは私が望むものではありません。 たとえば、式は次のようになります。 '(+(func(func(func 3)))4) ? – golconda

+0

いいえ、そのような制限はありません。あなたは '(+(funcall func(funcall func(funcall func 3))))4)'を実行することができます。 – Stefan

1

は、ここであなたがそれを行うことができます方法は次のとおりです。

(defun my-eval (exp var-bindings fun-bindings) 
    (eval `(cl-flet ,(mapcar (lambda (x) (list (car x) `',(cdr x))) 
          fun-bindings) 
      (let ,(mapcar (lambda (x) (list (car x) `',(cdr x))) 
         var-bindings) 
      ,exp)) 
     t)) 

または、eval年代にvar-bindingsための組み込みサポートを使用して:

(defun my-eval (exp var-bindings fun-bindings) 
    (eval `(cl-flet ,(mapcar (lambda (x) (list (car x) `',(cdr x))) 
          fun-bindings) 
      ,exp) 
     (or var-bindings t))) 

[ところで、 Emacs Lispでは、字句的環境は以下のように表現されることは必ずしも真実ではないことに注意してください。 alist:バイトコンパイルの後、レキシカル変数にはもう名前がなく、 "the"スタックに格納され、スタック内の位置によって直接アクセスされます。 ]

+0

ありがとう!私はさらに質問をしてもらえますか? (私はかつてcl-flet/cl-labelの使用を考えましたが、以下の問題を解決できませんでした) シンボルに外部のレキシカルスコープバインディングの値が含まれているクロージャの機能はどうですか? は例えば、私が本当に望んでいたことは(((4)) (evalを「(FUNC 3) '((FUNC。(閉鎖((B。、a)のT)(x)を聞かせて のようなものでした(+ xb)))))) '7'と評価されます。 – golconda

+0

'(closure ...)'は実行時にビルドしたい値なので、コードに記述しないでください。 (func。((b。、a)t)(x)(+ xb))) 'write' \ '(func。、(lambda(x)(+ xb)) )) ')。 – Stefan

関連する問題