英文:
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)
}
尽管看起来像全局变量,但该函数仅在正在执行的特定调用堆栈下可用。我使用假想的关键字 setting
来突出这一点。在特定示例中,有2个并行运行的 bar->baz()
调用堆栈,其本地上下文变量 "a" 不同。这比将变量传递下去要好(在 bar 和 baz 之间有许多函数的情况下),而且比使用像 threadLocal 或全局变量等东西更具有优点,显然有很多原因。我还没有遇到具有这种功能的编程语言,但我想知道为什么没有,因为这在许多情况下都非常有用。
英文:
Premise: This is not a question particular to a specific language, but rather a generic programming question to understand if some language out there has this construct, and if not, what are the reasons for it, since it seems very useful?
Question: what is a construct that allows declaring variables at a call stack level, so that only the functions inside that specific call stack can have access to it? I will try to highlight this using 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)
}
although this looks like a global, the function is only available under the specific call stack being executed. I am using the hypotetical keyword setting
to highlight that. In that specific example, there are 2 bar->baz()
call stacks running in parallel, whose local contextual variable "a" differs. this would be better than piping down the variable (in cases there are many functions between bar and baz) and would have better properties that using stuff like threadLocal or global variables, for obvious reasons. I have not encountered a programming language that has this, but I am wondering why, as this would be super useful in many cases.
答案1
得分: 1
Java 20新增了一个孵化特性,称为Scoped Values,它与OP示例有些相似,唯一的例外是这些变量是不可变的(出于性能和安全考虑)。
JEP的最后一段提到了一些历史背景。
Scoped values受到了许多Lisp方言提供对动态作用域自由变量的支持的启发,特别是这些变量在深度绑定的多线程运行时(如Interlisp-D)中的行为。scoped values通过添加类型安全性、不可变性、封装和在线程内部和跨线程之间的高效访问来改进Lisp的自由变量。
因此,这个想法有一些先例。
英文:
Java 20 adds an incubating feature called Scoped Values, which are somewhat similar to the OP example, with the exception that such variables are immutable (for performance and safety).
The final paragraph of the JEP mentions some historical context.
> Scoped values were inspired by the way that many Lisp dialects provide support for dynamically scoped free variables; in particular, how such variables behave in a deep-bound, multi-threaded runtime such as Interlisp-D. scoped values improve on Lisp's free variables by adding type safety, immutability, encapsulation, and efficient access within and across threads.
So there is some precedent for this idea.
答案2
得分: 1
这个概念称为“动态作用域”,与“词法作用域”或“静态作用域”形成对比,几乎所有编程语言都使用后者这些天。
参见:https://www.geeksforgeeks.org/static-and-dynamic-scoping/
以前有一些关于哪种更好的争论,你可以在一些旧的编程语言中找到动态作用域,比如早期的LISP、SNOBOL、APL等。
不过,现在争论已经朝另一个方向解决了。词法作用域使得更容易理解程序的工作方式。
英文:
The idea is called "dynamic scoping", contrasted with "lexical scoping" or "static scoping", which is what almost all programming languages use these days.
See: https://www.geeksforgeeks.org/static-and-dynamic-scoping/
There used to be some debate about which is better, and you can find dynamic scoping in some old languages -- early LISPs, SNOBOL, APL, etc.
The debate is now settled the other way, though. Lexical scoping makes it a lot easier to reason about how your programs work.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论