Javascript 使用Sweet.js的惰性计算宏
我刚接触JavaScript,注意到这种语言不直接支持惰性计算。本机代码会变成地狱般的锅炉板,如下所示:Javascript 使用Sweet.js的惰性计算宏,javascript,lazy-evaluation,sweet.js,Javascript,Lazy Evaluation,Sweet.js,我刚接触JavaScript,注意到这种语言不直接支持惰性计算。本机代码会变成地狱般的锅炉板,如下所示: function lazy(f) { var v = undefined; return function() { if (v == undefined) v = f(); return v; } } // 10 times larger than actual operation var foo = laz
function lazy(f) {
var v = undefined;
return function() {
if (v == undefined)
v = f();
return v;
}
}
// 10 times larger than actual operation
var foo = lazy(function() {
return 3 + 3;
});
var foo = lazy (3 + 3);
var goo = lazy {
var a = 3 + 3;
return a;
};
var goo = lazy {
var a = 3 + 3;
return a;
};
function lazy_f(f) {
var v = undefined;
return function() {
if (v == undefined)
v = f();
return v;
}
}
macro lazy {
rule { $($expr) (;) ... } => { //
lazy_f(function() $expr ...); //
} //
rules { $expr } => {
lazy_f(function() { return $expr; })
}
}
var foo = lazy (3 + 3);
var goo = lazy {
var a = 3 + 3;
return a;
};
但我发现Sweet.js并相信它可以使代码变得简单,如下所示:
function lazy(f) {
var v = undefined;
return function() {
if (v == undefined)
v = f();
return v;
}
}
// 10 times larger than actual operation
var foo = lazy(function() {
return 3 + 3;
});
var foo = lazy (3 + 3);
var goo = lazy {
var a = 3 + 3;
return a;
};
var goo = lazy {
var a = 3 + 3;
return a;
};
function lazy_f(f) {
var v = undefined;
return function() {
if (v == undefined)
v = f();
return v;
}
}
macro lazy {
rule { $($expr) (;) ... } => { //
lazy_f(function() $expr ...); //
} //
rules { $expr } => {
lazy_f(function() { return $expr; })
}
}
var foo = lazy (3 + 3);
var goo = lazy {
var a = 3 + 3;
return a;
};
所以我测试了一下:
它与一个expr一起工作。但是在某些情况下,lazy
会像这样接受一个expr块:
function lazy(f) {
var v = undefined;
return function() {
if (v == undefined)
v = f();
return v;
}
}
// 10 times larger than actual operation
var foo = lazy(function() {
return 3 + 3;
});
var foo = lazy (3 + 3);
var goo = lazy {
var a = 3 + 3;
return a;
};
var goo = lazy {
var a = 3 + 3;
return a;
};
function lazy_f(f) {
var v = undefined;
return function() {
if (v == undefined)
v = f();
return v;
}
}
macro lazy {
rule { $($expr) (;) ... } => { //
lazy_f(function() $expr ...); //
} //
rules { $expr } => {
lazy_f(function() { return $expr; })
}
}
var foo = lazy (3 + 3);
var goo = lazy {
var a = 3 + 3;
return a;
};
所以我把上面的代码安排成这样:
function lazy(f) {
var v = undefined;
return function() {
if (v == undefined)
v = f();
return v;
}
}
// 10 times larger than actual operation
var foo = lazy(function() {
return 3 + 3;
});
var foo = lazy (3 + 3);
var goo = lazy {
var a = 3 + 3;
return a;
};
var goo = lazy {
var a = 3 + 3;
return a;
};
function lazy_f(f) {
var v = undefined;
return function() {
if (v == undefined)
v = f();
return v;
}
}
macro lazy {
rule { $($expr) (;) ... } => { //
lazy_f(function() $expr ...); //
} //
rules { $expr } => {
lazy_f(function() { return $expr; })
}
}
var foo = lazy (3 + 3);
var goo = lazy {
var a = 3 + 3;
return a;
};
因为某些原因,它不起作用。我相信第一种模式$($expr)(;)…
不应该与(3+3)
匹配,但显然它正在这样做
我为此工作了一个小时,最后放弃了。如何使这两种模式同时工作
如果无法做到这一点,我想用另一种方式来实现一个expr:
lar foo = 3 + 3;
var foo_content = foo();
我也不知道怎么做。$($expr)(;)…
意味着重复匹配由分隔的单个标记代码>。你可能想要这个:
macro lazy {
// match single expression in parens
rule { ( $e:expr ) } => {
lazy_f(function() { return $e })
}
// match all of the tokens inside a curly
rule { { $expr ... } } => {
lazy_f(function() { $expr ... })
}
}
由于要将其与花括号一起使用,因此需要在宏中包含括号,如
但是,要惰性地计算表达式,如var a=lazy this.x*this.y
,需要将表达式正确绑定到this
的当前值
完整代码
函数lazyEvaluate(此对象,函数ToEvaluate){
var结果,hasResult=false;
返回函数(){
如果(结果){
返回结果;
}否则{
hasResult=true;
返回结果=functionToEvaluate.call(thisObject);
};
};
}
设lazy=macro{
统治{
{
$statements。。。
}
} => {
懒散地评估(这个,函数){
$statements。。。
})
}
规则{$expression:expr}=>{
懒散地评估(这个,函数){
返回$expression;
})
}
}
这适用于任何有效表达式。
例子
var a=5,b=2,c=lazy a*b,d=lazy{
console.log(c());
返回c()*a;
};
a=10;
console.log(c());//20
a=5;
console.log(d());//100
感谢您提供完整的解决方案!:)@RyoichiroOka请确保您包含@SeanVieira的最新编辑。我忘记将result
设置为我发布的代码中函数的结果。