提问人:Giacomo Tagliabue 提问时间:2/9/2023 最后编辑:jaco0646Giacomo Tagliabue 更新时间:2/21/2023 访问量:67
作用域为调用堆栈的变量
variables that are scoped to a call stack
问:
前提:这不是一个特定于特定语言的问题,而是一个通用的编程问题,以了解某些语言是否具有这种结构,如果没有,它的原因是什么,因为它看起来非常有用?
问:什么是允许在调用堆栈级别声明变量的构造,以便只有该特定调用堆栈中的函数才能访问它?我将尝试使用 javascript 来强调这一点:
async function main() {
await Promise.all([foo(), bar()])
}
async function foo() {
await setTimeout(100);
setting (const a = 1) { // <===== set here
await setTimeout(100);
await baz();
}
}
async function bar() {
await setTimeout(100);
setting (const a = 2) { // <===== set here
await setTimeout(100);
await baz();
}
}
async function baz() {
const a = STACK_CONTEXT.a; // <===== used here
console.log(a)
}
尽管这看起来像一个全局函数,但该函数仅在正在执行的特定调用堆栈下可用。我正在使用假设关键字来强调这一点。在该特定示例中,有 2 个并行运行的调用堆栈,其局部上下文变量“a”不同。这比向下输送变量要好(如果 bar 和 baz 之间有很多函数),并且由于显而易见的原因,使用线程局部或全局变量之类的东西会具有更好的属性。我还没有遇到过具有此功能的编程语言,但我想知道为什么,因为这在许多情况下非常有用。setting
bar->baz()
答:
Java 20 添加了一个名为 Scoped Values 的孵化功能,它有点类似于 OP 示例,不同之处在于这些变量是不可变的(出于性能和安全考虑)。
JEP的最后一段提到了一些历史背景。
作用域值的灵感来自于许多 Lisp 方言为动态作用域自由变量提供支持的方式;特别是,这些变量在深度绑定的多线程运行时(如 Interlisp-D)中的行为方式。作用域值通过添加类型安全性、不可变性、封装和线程内和线程之间的高效访问来改进 Lisp 的自由变量。
所以这个想法是有先例的。
这个想法被称为“动态范围”,与“词法范围”或“静态范围”形成鲜明对比,这是当今几乎所有编程语言都使用的。
请参见:https://www.geeksforgeeks.org/static-and-dynamic-scoping/
曾经有一些关于哪个更好的争论,你可以在一些古老的语言中找到动态范围——早期的 LISP、SNOBOL、APL 等。
不过,争论现在以另一种方式解决了。词法范围可以更容易地推理程序的工作方式。
上一个:以下两个程序的时间复杂度?
评论