13

私が特別な変数を持っているとしましょう:

(defvar x 20)

それから私は次のことをします:

(let ((x 1)) (eval '(+ x 1))

これは2と評価されます。

CLHSによると、evalは「現在の動的環境とnull字句環境でフォームを評価します」。したがって、2ではなく21を取得することを期待します。

私は何かが足りないのですか?

ここで、シンボルyの動的バインディングがない場合、評価します

(let ((y 1)) (eval '(+ y 1))

「変数Yはバインドされていません」という条件があります。これは、yに動的バインディングがないため、意味があります。

注:私はSBCL1.0.57を使用しています

事前にあなたの助けに感謝します!

4

2 に答える 2

8

あなたの例xでは、それは動的環境specialにバインドされていることを意味します

y特別ではないので、語彙環境にバインドされています


したがって、最初の時点ではeval、環境は次のように表すことができます。

dynamic environment:  { x : 1 } -> { x : 20, ...other global variables... } -> nil
lexical environment:  nil

シンボルxは特別なので、現在の動的環境で検索して見つけevalますxx = 1


最後の例と同じlispで実行されたとすると、2番目の環境はeval次のようになります。

dynamic environment: { x : 20,  ...other global variables... } -> nil
lexical environment: { y :  1 } -> nil

記号yは特別ではないため、現在の字句環境ではなくnull 字句環境でeval検索しても何も見つかりません。y

movこれは、lispが通常コンパイルされ、場合によっては字句環境を単純な命令に最適化できることに気付いたときに意味があります。

于 2012-07-24T19:06:06.247 に答える
6

DEFVARその変数を特別なものとして宣言します。世界的に、どこでも。また、これを簡単に削除することはできません。

これは、の変数名としてx、などの一般名を使用してはならない理由でもあります。代わりに、を使用してください。それ以外の場合、これらの共通名を持つすべての変数(ローカル変数も含む)は特別であると宣言されます。ilistDEFVAR*x**i**list*

于 2012-07-24T19:27:33.090 に答える