2

そこで、スキーム変数のバインドに関する質問です。私が次の機能を持っているとしましょう:

(define undefinedTest (lambda (y) (list x y)))

Guile-Scheme 2.0.3 で実行すると、x がバインドされていない変数であることが警告されます。次に、次のステートメントを実行すると

> (let ((x 'something)) (undefinedTest 'else))

エラーとそれをデバッグするオプションが表示されます。ただし、次のステートメントを実行すると:

> (define x 'something)
> (undefinedTest 'else)

(他の何か)の期待される答えが得られます。x が最上位で定義されている場合にスキームが x をバインドできるのに、let によってバインドされている場合はできないのはなぜですか。これは、関数が定義されているときにトップレベルでも定義されているため、スキームが最も近い囲み環境を検索するときに、let 環境が実際には「囲んでいる」わけではないためです。レベル"?

4

3 に答える 3

5

Scheme は、動的スコープではなく字句スコープを使用します。したがって、xthe undefinedTestsees は、xその関数から語彙的に見えるものです。この場合は、既に述べたように、トップレベルのスコープです。

于 2012-10-08T18:46:01.347 に答える
1

When undefinedTest was defined, it enclosed the environment in which it was defined; given that it was defined at the top level, it will only "see" its formal parameter y and the global environment - and the global environment doesn't contain x at that point. It's like that because Scheme is lexically scoped.

I tested the code in the question in Racket and the first line fails with the error: expand: unbound identifier in module in: x - meaning that it's not even a valid definition as interpreted by Racket.

The same example would work in a language with dynamic scoping, Scheme uses lexical scoping (a.k.a. static scoping.)

于 2012-10-08T21:21:44.890 に答える
1

レキシカル スコープは、Scheme のコア機能です。レキシカル スコープを使用すると、関数が定義された時点で可視になるため、関数に対して可視であるバインディングを常に知ることができます。対照的に、動的スコーピングは、予測が難しく、デバッグも同様に困難な驚きを生み出す傾向があります。

于 2012-10-08T22:53:52.833 に答える