2

CommonLispの変数にS式をバインドしています。

(defvar x '(+ a 2))

ここで、呼び出されたときに、それが定義されたスコープ内の式を評価する関数を作成したいと思います。私はこれを試しました:

(let ((a 4))
  (lambda () (eval x)))

(let ((a 4))
  (eval `(lambda () ,x)))

しかし、これらは両方とも問題を引き起こします。EVALはトップレベルでコードを評価するため、式に含まれる変数をキャプチャできません。LETフォームをEVALに入れることができないことに注意してください。解決策はありますか?

編集:それで、EVAL問題の解決策がない場合、他にどのようにそれを行うことができますか?

編集:私が何をしようとしているのかについて質問がありました。私はコンパイラを書いています。式が定義されている字句環境で変数が閉じられたs式を受け入れたい。確かにそれをマクロとして書く方が良いかもしれません。

4

5 に答える 5

5

必要なバインディングを持つコードを作成する必要があります。コードを LET で囲み、コードで使用できるようにするすべての変数をバインドします。

(defvar *x* '(+ a 2))

(let ((a 4))
  (eval `(let ((a ,a))
           ,*x*)))
于 2009-03-05T13:15:41.877 に答える
3

CLISP は、レキシカル環境でフォームを評価するための拡張機能を実装しています。拡張機能であるという事実から、標準に準拠した方法でそれを行うことはできないと思います。

(ext:eval-env x (ext:the-environment))

http://clisp.cons.org/impnotes.html#eval-environを参照してください。

于 2008-10-19T02:54:18.123 に答える
2

あなたが解決したい本当の問題は何ですか?ほとんどの場合、あなたは間違った方法でそれに取り組もうとしています。レキシカル バインディングは、外部から取得したランダムなものではなく、スコープ内でレキシカルに表示されるもの用です。

たぶん、動的閉鎖が必要ですか?そのようなことは Common Lisp には存在しませんが、いくつかの Lisp 方言 (私が理解している限りでは Pico Lisp など) には存在します。

同様に、次のことができることに注意してください。

(defvar *a*)
(defvar *x* '(+ *a* 2))  ;'

(let ((a 10))
  ;; ...
  (let ((*a* a))
    (eval *x*)))

ただし、本当にこれが必要かどうかをよく考えることをお勧めします。

于 2008-10-20T19:30:37.913 に答える
0

Common Lisp では、 *evalhook*を定義して、環境を に渡すことができます(eval ...)*evalhook*プラットフォームに依存しません。

于 2008-10-20T15:08:59.937 に答える