问题标签 [lexical-scope]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
scheme - 使用 let/set “记住”值的方案函数
我是 Scheme 的新手,并试图了解函数中出现的某些值如何在多种用途中持续存在。采取以下柜台:
我无法弄清楚(并且在任何地方都没有找到解释),是为什么next
每次使用时都不会重置为 0 count
。
perl - Perl 的词法范围的编译指示是如何实现的?
autodie
根据文档,编译指示(如)是词法范围的。
这是否适用于所有加载的模块use
?据我所知,use
几乎与以下内容相同:
BEGIN
发生在编译时,并且 require 没有词法范围。那么如何autodie
知道它的范围呢?
emacs - emacs 词法作用域和带引号的变量名
我正在尝试 Emacs 词法作用域(Emacs 24 的新特性)之间add-to-list
的相互作用,发现相互作用令人困惑,我不知道如何理解它。这是一个最小的示例,除了我使用set
而不是add-to-list
. (set
类似于add-to-list
它通常采用带引号的变量名)
上面的代码按顺序打印“mature apple”、“mature apple”、“by set”。第一个打印结果“成熟的苹果”与词法作用域的预期一致(支持词法闭包),在这里看到并不奇怪。但是第二次和第三次打印的结果让我感到惊讶。好像(set 'a "by set")
只是识别和影响 name 的全局绑定a
。
这是预期的行为吗?或者这是一个错误?如果有意,如何理解这种行为?
我是否正确地假设set
只要词法范围打开,它总是会影响全局绑定?
使用(eval '(progn ...) nil)
时,事情会按照动态作用域的预期工作,并且 的行为与这种情况下的行为(set 'a ...)
相同(setq a ...)
。只有当一个人同时使用词法作用域和带引号的变量时,才会出现这个问题。
更新:
根据手册,这似乎是一种预期的行为。在Void Variables上,手册说
在词法绑定规则下,值单元只保存变量的全局值,即任何词法绑定结构之外的值。当一个变量被词法绑定时,局部值由词法环境决定;如果其符号的值单元格未分配,则该变量可能具有局部值。
和词法绑定
symbol-value、boundp 和 set 等函数仅检索或修改变量的动态绑定(即其符号值单元格的内容)。
symbol-value、boundp、set 是通常用带引号的变量名 ( (symbol-value 'var) (boundp 'var) (set 'var 123)
) 调用的函数。这些函数仅获取或设置符号的值单元格,并且在词法绑定规则下,值单元格仅保存全局值。所以在词法绑定下,使用带引号的变量只能获取或设置全局值(除非变量是特殊变量)。尽管结果既不是词汇(苹果)也不是动态(香蕉)看起来仍然很奇怪。
emacs - Emacs:defun 或 defmacro 主体中的代码不能引用周围的词法变量?
2013 年 5 月更新:从 GNU Emacs 24.3.1 开始,(let .. (defun..)) bytecompiles 很好,没有警告,bytecompiled 代码与未编译代码一样工作。只是不要忘记将文件变量添加lexical-binding: t
到要进行字节编译的文件中。现在不需要在此问题末尾的解决方法。
Lexical Binding - Emacs Lisp Manual有这一段:
请注意,symbol-value、boundp 和 set 等函数仅检索或修改变量的动态绑定(即其符号值单元格的内容)。此外,defun 或 defmacro 主体中的代码不能引用周围的词法变量。
我不确定我是否理解了第二句话的意思。在下面应该以词法绑定模式运行的代码中,defun 主体中的代码成功地引用了 name 的词法绑定值n
。
这句话只是说 (let .. (defun ..)) 是一种不好的做法吗?
解决方法:
这是测试上述代码的代码:
r - `getClasses()` 中默认环境的模糊变化(标准函数与正式 S4 方法)
关于“环境嵌套”/词法范围,我很难弄清楚这里到底发生了什么:
问题
where
函数中参数的默认值getClasses()
似乎会有所不同,具体取决于getClasses()
是在标准 R 函数中调用还是在正式 S4 方法中调用。它被.externalCallerEnv()
哪个似乎是惰性评估的“对象”控制,从而导致变化(见下面的编辑)
问题
从正式的 S4 方法内部调用时,如何设置与在标准函数内部调用where
时的默认值相同的值?getClasses()
插图
您将在下面找到上述“问题行为”的简短说明
1) 自定义类
我有许多当前来自.GlobalEnv
.
让我们以这一个作为他们所有人的代表
2)列出可用的类
通过 argument where
, functiongetClasses
让我选择寻找类的环境。
以下似乎无处不在.GlobalEnv
,因此找不到我的班级;没关系:
现在我只.GlobalEnv
查找类A
;这也很好:
3) 创建自定义标准查找函数
当我将查找通过getClasses
放入标准函数中时(这只是所需功能的第一部分,我想getClasses()
在该方法内部进行计算,而不是将其返回值作为形式参数传递),一切仍然正常
4) 创建正式的 S4 方法
但是,一旦我将所有内容都放入正式的 S4 方法getClasses()
中,用于查找类的标准环境似乎发生了一些变化
以前,"A" %in% foo1(where=NULL)
是FALSE
(需要),而现在是("A" %in% foo2(where=NULL)
不需要)。TRUE
任何想法如何foo2()
以完全相同的方式表现foo1()
?
编辑 2012-08-29
正如 Josh O'Brien 在下面的评论中指出的那样,这种变化可能是由惰性评估引起的。
调试foo1()
你进入调试跟踪器;点击<RETURN>
4 次,然后输入get("where")
:
在控制台中,点击<RETURN>
1 次,然后键入evList
:
键入Q
以退出当前调试运行
现在再次运行所有内容,但调试调用略有不同
在控制台中,点击<RETURN>
5 次,然后键入evList
:
现在输入get("where")
:
现在where
指向namespace:methods
调试`foo2()'
你进入调试跟踪器;点击<RETURN>
4 次,然后输入get("where")
:
然后点击<RETURN>
1 次,然后键入evList
:
键入Q
以退出当前调试运行
现在再次运行所有内容,但调试调用略有不同
点击<RETURN>
5 次,然后输入evList
:
现在输入get("where")
:
evList
并注意与where
之前的调试运行相比的不同值。键入Q
以退出当前调试运行。
这对我来说似乎有些奇怪,但从语言设计者的角度来看可能是有道理的。一旦我知道如何显式设置where
为指向与namespace:methods
.
emacs - Emacs 中的词法作用域:与旧版 Emacsen 的兼容性
Emacs 24 为局部变量添加了可选的词法绑定。我想在我的模块中使用这个功能,同时保持与 XEmacs 和以前的 Emacs 版本的兼容性。
在 Emacs 24 之前,获得闭包的最简单方法是使用 中lexical-let
定义的形式cl-macs
,它通过一些巧妙的宏技巧来模拟词法范围。虽然这在 elisp 程序员中从未如此流行,但它确实有效,创建了真正有效的闭包,只要你记得将它们包装在 中lexical-let
,就像在这个伪代码中一样:
问题是:在保留对 Emacs 23 和 XEmacs 的支持的同时,使用新的词法绑定的最佳方式是什么?目前,我通过定义一个特定于包的宏来解决它,该宏根据是否绑定和为真扩展lexical-let
为普通宏:let
lexical-binding
这个解决方案有效,但感觉很笨拙,因为新的特殊形式不标准,不能正确突出显示,不能进入 under edebug
,并且通常会引起注意。有没有更好的办法?
编辑
两个更智能(不一定是好的)解决方案的想法示例,允许代码继续使用标准表单来创建闭包:
使用建议或编译器宏来
lexical-let
扩展至仅当仅分配给let
在词法范围内的符号时。这个建议只会在 的字节编译期间被临时激活,因此对于 Emacs 的其余部分来说,它的含义保持不变。lexical-bindings
lexical-let
foo.el
lexical-let
使用宏/code-walker 工具将
let
非前缀符号编译到lexical-let
较旧的 Emacsen 下。这将再次仅适用于foo.el
.
如果这些想法带有过度设计的味道,请不要惊慌:我不建议按原样使用它们。我对上述宏的替代方案感兴趣,其中包获得了更好的可移植使用闭包的好处,代价是加载/编译的一些额外复杂性。
编辑 2
由于没有人采取一种解决方案来允许模块在 Emacs 的其余部分继续使用let
或lexical-let
不破坏它们,我接受 Stefan 的回答,其中指出上述宏是实现它的方法。除此之外,答案通过使用bound-and-true-p
和添加 edebug 和 lisp-indent 的优雅声明来改进我的代码。
如果有人对此兼容层有替代建议,或者上述想法的优雅实现,我鼓励他们回答。
javascript - Javascript 中存在哪些类型的范围?
我知道有全局范围,还有可嵌套的功能范围。但是 Javascript 中还有其他类型的作用域或闭包吗?
当我们讨论这个话题时,范围和闭包之间有什么区别?
javascript - 从 jQuery.getJSON 返回一个 JSON blob
我有一个函数,我正在调用一个返回 JSON blob 的 MVC 控制器,其中包含一些后端操作的内容。此 JSON blob 用于填充呈现给最终用户的表。
我的功能目前看起来像这样:
...还有一个如下所示的调用动作:
当我运行调用它的网页/操作时,我会按照给定的顺序得到以下结果:
我尝试了一些其他配置(.getJSON() 的 .complete,直接从 $.getJSON() 返回一个值)以尝试将回调中的“数据”回显到封闭范围的 blob 变量,但到目前为止,该 blob 似乎仅在 getJSON 回调中具有价值。
话虽如此,我也知道 JavaScript 是一种词法范围的语言,所以它可能是所有匿名函数链正在执行的问题。
问题:我可以看到我的 blob 在 $.getJSON 中正确显示。现在,我该如何取出我的斑点?
javascript - 如果没有块范围,独立块的意义何在?
您可以使用这样的独立积木......
这来自:http ://eloquentjavascript.net/chapter3.html#p3c7ae609
但是有这样的块有什么意义呢?它的用途是什么?
scheme - 就 SICP 的评估环境模型而言,词法与动态范围
在SICP 的第 3.2.2 节中,执行以下代码
用这张图来解释。
每次应用函数时,都会创建一个新框架(由E1
through标记E4
),它表示符号和值之间的一组绑定。当符号未绑定在框架中时,将查询该框架的封闭环境以获取该特定符号的绑定。
该图的有趣之处在于,所有标记为 的帧E
都包含在全局环境中。文中解释说这是因为函数是在全局环境中定义的,但没有详细说明这个问题:
请注意,由 所创建的每个帧都
square
指向全局环境,因为这是square
过程对象所指示的环境。
相反,如果框架包含在调用函数的环境中,比如E3
包含在E2
其中,又包含在 中E1
,那么这是否是动态范围语言如何工作的有效模型?此外,图中的框架是否具有相同的“父”环境,因为 Scheme 是词法范围的?