web-dev-qa-db-ja.com

Rでの語彙スコープの理解

Rプログラミング言語の設計の評価について この論文ngated copy )を読んでいて、字句スコープに関する特定の例を理解できない(またはその欠如) )。

4ページで、著者はwith関数の使用例を以下に示します。

with(formaldehyde, carb*optden)

彼らは続けて言う:

鋭い読者は、上記の例がRがレキシカルにスコープされているという私たちの主張と衝突することに気づくでしょう。よくあることですが、Rはレキシカルにスコープ指定されるところまでスコープされます。 Rは何よりも動的言語であり、実行中のプログラムのデータと表現への完全なリフレクトアクセスを備えています。上記の例では、環境を反射的に操作することによるwithsteps字句スコープの実装。これは、遅延評価、動的名前検索、およびコードをテキストに変換して戻す機能の組み合わせによって行われます。

with.default <- function(env, expr, ...)
  eval(substitute(expr),env, enclose=parent.frame())

この関数はsubstituteを使用して2番目の引数の未評価の解析ツリーを取得し、最初の引数を字句的に囲む環境で構成された環境でevalを使用して評価します。 ‘... ’は、追加の引数を破棄するために使用されます。

この場合のwith関数の使用は、どのように字句スコープの原則に違反していますか?

18
tchakravarty

通常、Rの文脈で説明すると、字句スコープとは、関数内の自由変数(関数で使用されているが、関数で定義されていない変数)が関数の親環境で検索されることを意味します。 、呼び出し側の環境(親フレームとも呼ばれます)とは対照的に、with.defaultには自由変数がないため、例ではnotが使用されているため、字句スコープの違反を示しています。センス。

たとえば、これは字句スコープを示しています。

x <- 1
f <- function() x
g <- function() { x <- 0; f() }
g() # 1

fdefinedである環境で1が定義されているため、答えは1です。 Rが次のように動的スコープをエミュレートする方法を示すことができます。

f <- function() eval.parent(quote(x))
g() # 0

追加:

以下のコメントで、@ hadleyは、著者がwith.defaultへの2番目の実際の引数が字句的に評価されておらず、この解釈がありそうな事実に言及している可能性があることを示唆しました。周囲の字句環境に対して相対的に評価される代わりに、with.defaultの2番目の実引数が、substituteを使用する式としてwith.default関数に読み込まれ、evalを使用して最初の引数に対して相対的に評価されます。字句スコープの定義は、広範囲に議論されたとしてもめったに定義されていないはずですが、典​​型的な議論Rに関しては、それを自由変数の扱いと呼びます。たとえば Gentleman&Ihaka を参照してください。

27
G. Grothendieck