JMP スコープ -- 動的スコープと語彙スコープ、および JSL 学習の一般的な混乱私が間違っている場合は修正してください。ただし、JMP にはスコープ永続性のない動的スコープがあるようです (擬似名前空間を除く)ここ、窓、箱)。これは、参照カウンタを使用して完全なスコープの永続性を備えた字句スコープを備えた多くの一般的なプログラミング言語とは対照的です。
これは、JMP の奇妙なスコープ システムを操作するのに必要な直観を得るまで、私にとって非常に頭を悩ませることになりました。これは多くの人にとって大きな混乱点であると思います。動的スコープを使用するプログラミング言語はそれほど多くありません (LISP は重要な例外であり、JSL は LISP といくつかの類似点があります)。
JSL ドキュメント チームには、この違いを指摘し、動的スコープをよりよく理解する方法に関するリソースやリンクを提供することをお勧めします。これは、名前解決を行う標準的な方法ではないためです。
以下に例を示します。外部関数のローカル スコープは return ステートメントの直後にクリアされ、内部関数の名前解決は動的です (現在の呼び出しスタックに基づいて)。
Names Default to Here( 1 );
x = 7;
outer function = Function( {},
{x},
x = 4;
inner function = Function( {},
Print( x )
);
Return( Name Expr( inner function ) );
);
func = outer function;
func()
/*** OUTPUT ***
7スコープ永続性を備えた字句スコープの言語 (Python など) で機能的に同等のことを行う場合、内部関数の囲みスコープは永続的で (外部関数のローカル スコープです)、内部関数の名前解決は永続的になります。関数の x 変数は、システムの字句読み取りからの値 4 です。JMP は字句スコープを使用せず、動的スコープを使用するため、スクリプトの最後で内部関数が最終的に実行されるときに、ローカル -> ここ -> グローバル (および場合によっては列) の動的名前解決を使用します。現在のテーブルの名前) を調べ、値 7 を見つけます。
このタイプの動作を理解することは、JSL で堅牢なプログラムを構築するために重要です。JSL を学習している/苦労している人にはこの点を指摘しておきたいと思います。
何か考えや直感的ではない例があれば教えてください。
自動化とスクリプト作成データアクセスRe: JMP スコープ -- 動的スコープと語彙スコープ、および JSL 学習の一般的な混乱これは真実であり、言語を学習する際に間違いなく私を混乱させました。もう 1 つの欠点は、JSL が用語書き換え言語これは、その式オブジェクトのおかげで、スコープに関しては LISP 的ですが、マクロの処理方法に関しては LISP 的ではないことを意味します。
私が知る限り、一般的に使用されている他の用語書き換え言語は Wolfram 言語だけです。私は確かなことを言えるほど CS に精通しているわけではありませんが、用語書き換えパラダイムは厳密には Lisp のマクロよりも強力であると主張する人がいるのを聞いたことがあります。その一方で,Wolfram言語は単なるm式の実装であり,Lispはs式で十分だと判断したという主張も聞いたことがあります.
いずれにせよ、JSL の式システムはほとんどすべての人にとって馴染みのないものであり、式を操作するための関数の人間工学は彼らにとって何の有利にもなりません。このフォーラムで、用語書き換え機能の代わりに文字列操作や Parse() を使用する例が非常に多く見つかるのには理由があります。
Re: JMP スコープ -- 動的スコープと語彙スコープ、および JSL 学習の一般的な混乱私自身は CS の担当者ではありませんが、用語の書き換えに関するこの内容は非常に興味深いです。参考にしていただきありがとうございます。これからこのうさぎの穴で一晩中起きています...
Re: JMP スコープ -- 動的スコープと語彙スコープ、そして JSL 学習における一般的な混乱その
func = outer function;
func();
私を困惑させました。
実行後
func = outer function();
内部関数の定義は変数 func に格納されます。
これが表示(関数)が返す値である理由です
func = Function({},Print(x));
この時点で、外部関数と内部関数に関する情報はすべて消えてしまいます。
したがって、 関数()はPrint(x) を実行し、 7を出力します。
編集:
実のところ、メインの投稿に書かれた内容と比べて新しいことは何もありません。
まさに JSL プログラマーの「2D ビュー」です。
Re: JMP スコープ -- 動的スコープと語彙スコープ、そして JSL 学習における一般的な混乱JMP は関数定義内の変数をそのまま保持します。現在の値に自動的に置き換えられることはありません。
だから、その後
x = 4;
inner function = Function( {}, Print( x ));
inner function is defined as
Function( {}, Print( x ));
内部関数のxを外部関数のxに置き換えるには、次のような事前評価が必要です。
Names Default to Here( 1 );
x = 7;
outer function = Function( {},
{x},
x = 4;
Eval(Eval Expr( inner function = Function( {},
x= Expr(x);
Print( x )
)));
Return( Name Expr(inner function));
);
func = outer function;
func() // prints 4
編集: 他の単語と同じ 2D ビュー。
Re: JMP スコープ -- 動的スコープと語彙スコープ、そして JSL 学習における一般的な混乱私は柵越しにちらっと見てみました。
def outer():
y=4
def inner():
print(y)
return inner
f = outer()
y = 7
f() # -> 4
したがって、Python は 3 を返します。inner が定義されている場合、y は語彙コンテキストでこのように定義されるためです。
「定義」 - それとも「返された」?
もう一度見てみましょう:
def outer():
y=4
def inner():
print(y)
y=-100
return inner
f = outer()
y = 7
f()
-> -100