如果我错了,请纠正我,但 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 的人指出这一点。
如果您有任何想法/不直观的例子,请告诉我!