如果我錯了,請糾正我,但 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()
//:*/
Names Default to Here( 1 );
x = 7;
outer function = Function( {},
{x},
x = 4;
inner function = Function( {},
Print( x )
);
Return( Expr( inner function ) );
);
func = outer function;
func()
/*:
7如果您在具有作用域持久性的詞法作用域語言(例如 Python)中執行功能等效的操作,則內部函數的封閉作用域是持久的(它是外部函數的本地作用域),並且內部函數的名稱解析函數的 x 變量是系統詞法讀取的值 4。由於JMP不使用詞法作用域,而是使用動態作用域,那麼當內部函數最終在腳本末尾執行時,它使用動態名稱解析Local -> Here -> Global(以及可能的column-)當前表的名稱)並找到值 7。
理解這種類型的行為對於在 JSL 中構建健壯的程序至關重要,我只想向任何學習/努力使用 JSL 的人指出這一點。
如果您有任何想法/不直觀的例子,請告訴我!