Emacs 24为局部变量添加了可选的词法绑定.我想在我的模块中使用此功能,同时保持与XEmacs和以前的Emacs版本的兼容性.
在Emacs 24之前,获取闭包的最简单方法是使用lexical-let定义的形式cl-macs,它使用一些聪明的宏技巧模拟词法范围.虽然这在elisp程序员中从未如此受欢迎,但它确实有效,创建真实有效的闭包,只要你记得将它们包装起来lexical-let,就像在这个伪代码中一样:
(defun foo-open-tag (tag data)
"Maybe open TAG and return a function that closes it."
... do the work here, initializing state ...
;; return a closure that explicitly captures internal state
(lexical-let ((var1 var1) (var2 var2) ...)
(lambda ()
... use the captured vars without exposing them to the caller ...
)))
Run Code Online (Sandbox Code Playgroud)
问题是:在保留对Emacs 23和XEmacs的支持的同时,使用新词法绑定的最佳方法是什么?目前我通过定义一个特定于包的宏来解决它,它根据是否为bound和true 扩展lexical-let为普通的或者是普通的:letlexical-binding
(defmacro foo-lexlet (&rest letforms)
(if (and (boundp 'lexical-binding)
lexical-binding)
`(let ,@letforms) …Run Code Online (Sandbox Code Playgroud) 我使用胖箭头函数有以下ES6代码:
var test = {
firstname: 'David',
fn: function() {
return ['one', 'two', 'tree'].map(() => this.firstname)
}
}
console.log(test.fn())
Run Code Online (Sandbox Code Playgroud)
根据箭头函数应该如何工作,我希望this成为test对象.ES6Fiddle,Traceur和Firefox产生了预期的输出["David", "David", "David"].
chrome://flags/#enable-javascript-harmony但是,在Chrome中启用这些功能时,我会得到[undefined, undefined, undefined].如果console.log(this)它显示它是窗口对象,则在严格模式下出现错误.thisES6箭头功能的词汇是否未在V8中实现?
在为来自其他语言的人进行R编程时, John Cook说
R使用词法作用域,而S-PLUS使用静态作用域.差异可能很微妙,特别是在使用闭包时.
我发现这很奇怪,因为我一直认为词法范围和静态范围是同义词.
词汇和静态范围是否有明显的属性,或者这是一种区别,从社区到社区,人与人之间的区别?如果是这样,那么一般的阵营是什么?我如何将它们区分开来,以便在他们使用这些词语时我能更好地理解某些人的意思.
Perl中的本地变量分配的内存位置有多长(对于数组,散列和标量)?例如:
sub routine
{
my $foo = "bar";
return \$foo;
}
Run Code Online (Sandbox Code Playgroud)
"bar"函数返回后,你还可以访问内存中的字符串吗?它会持续多长时间,它是否类似于C中的静态变量或更像是从堆中声明的变量?
基本上,这在这种情况下是否有意义?
$ref = routine()
print ${$ref};
Run Code Online (Sandbox Code Playgroud) 在SICP的3.2.2节中执行以下代码
(define (square x)
(* x x))
(define (sum-of-squares x y)
(+ (square x) (square y)))
(define (f a)
(sum-of-squares (+ a 1) (* a 2)))
(f 5)
Run Code Online (Sandbox Code Playgroud)
根据该图解释.
每次应用函数时,都会创建一个新帧(标记为E1through E4),表示符号和值之间的一组绑定.当符号未绑定在框架中时,将查询该框架的封闭环境以查找该特定符号的绑定.
该图的有趣之处在于标记的所有帧E都包含在全局环境中.该文本解释说这是因为函数是在全局环境中定义的,但没有详细说明问题:
请注意,每个帧都由
square指向全局环境创建,因为这是square过程对象指示的环境.
相反,如果框架包含在调用函数的环境中,比如E3包含在E2其中E1,那么它是否是动态作用域语言如何工作的有效模型?此外,图中的框架具有相同的"父"环境的方式是因为Scheme是词法范围的吗?
当eval语句在词法变量的范围内时,该变量应该在被评估块的词法上下文中.此外,词汇变量应该在subs的词汇上下文中可用.
然而,这不起作用:
use warnings;
{
package VLE;
my $ln10 = 2.302585092994045684017991454684;
sub reval {
say eval $_[0] if @_;
}
}
package VLE;
reval( q($ln10) );
Run Code Online (Sandbox Code Playgroud)
它导致:
Variable "$ln10" is not available at (eval 1) line 1.
Run Code Online (Sandbox Code Playgroud)
但是,如果我(无用)在块中的任何位置使用词法变量,它在eval中突然可用:
use warnings;
{
package VLE;
my $ln10 = 2.302585092994045684017991454684;
sub reval {
say eval $_[0] if @_;
my (undef) = $ln10;
return 0
}
}
package VLE;
reval( q($ln10) );
Run Code Online (Sandbox Code Playgroud)
版画
2.30258509299405
Run Code Online (Sandbox Code Playgroud)
为什么会这样?
引用的破坏不是问题,因为此代码(维护引用$ln10)也失败:
use warnings;
{ …Run Code Online (Sandbox Code Playgroud) 几年前,我开始为一个领域特定语言编写一个解释器,其中包括程序员定义的函数.
起初,我使用一组简单的符号表实现了变量范围.但现在我想转向适当的词法范围(可选择闭包).任何人都可以解释词法范围背后的数据结构和算法吗?
compiler-construction closures programming-languages lexical-scope
我看过R中的其他词汇范围问题,我找不到答案.考虑以下代码:
f <- function(x) {
g <- function(y) {
y + z
}
z <- 4
x + g(x)
}
f(3)
Run Code Online (Sandbox Code Playgroud)
f(3)将回答10.我的问题是为什么?在g()代码中定义的点,z尚未赋值任何值.在什么时候g()创建的闭包?是否"向前看"功能体的其他部分?它是在g(x)评估时创建的吗?如果是这样,为什么?
我正在尝试编写一个使用线程并共享变量的简单脚本,但我不希望将此变量设置为整个脚本的全局变量.下面是一个简化的例子.
use strict;
use warnings;
use threads;
use threads::shared;
my $val:shared;
# Create threads
for my $i (1 .. 5) {
threads->create(\&do_something, $i);
}
# Wait for all threads to complete
map { $_->join(); } threads->list();
# $val is global to the script so this line will work!
print "VAL IS: $val\n";
sub do_something {
my $i = shift;
print "Doing something with thread $i!\n";
{
lock $val;
$val = "SOMETHING IS $i";
print "$val\n\n";
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
用线程1做点什么!有些是1
用线程2做点什么!有些是2 …