2024年Clojure状态调查!中分享你的想法。

欢迎!请查看关于页面以获取更多关于如何使用本站的信息。

0投票
ClojureScript

当前当定义实现{{cljs.core/IFn}}协议的类型时,会生成一个协议函数以及一个重复整个代码而不是调度到生成的协议函数的{{.call}}方法。

`
(deftype InvokeTest [a b]
IFn
(-invoke [_]

(+ a b)))

`

cljs.user.InvokeTest.prototype.cljs$core$IFn$_invoke$arity$0 = function() { var self__ = this; var _ = this; return self__.a + self__.b; };

{{.call}}会重复所有代码而不是调用this.cljs$core$IFn$_invoke$arity$<n>。对于多个参数签,每个参数签都会重复代码。

cljs.user.InvokeTest.prototype.call = function(self__) { var self__ = this; var self____$1 = this; var _ = self____$1; return self__.a + self__.b; };

应该是这样的

`
cljs.user.InvokeTest.prototype.call = function(self__) {
switch(arguments.length) {

case 0:
  return this.cljs$core$IFn$_invoke$arity$0();
...
default:
  throw new Error("Invalid arity: " + arguments.length);

}
};
`

8 答案

0投票

评论者:thheller

注意,Closure在{{:advanced}}中不会删除{{.call}}函数。

伪名输出

`
$JSCompiler_prototypeAlias$$ = $cljs$core$Keyword$$.prototype;
$JSCompiler_prototypeAlias$$.call = function() {
var $G strongest 41215$$ = null;
$G 41215$$ = function($G strong 41215$$, $coll$jscomp strong 188$$, $not_found$jscomp strong 10$$) {

switch(arguments.length) {
  case 2:
    return $cljs$core$get$$.$cljs$core$IFn$_invoke$arity$2$($coll$jscomp$188$$, this);
  case 3:
    return $cljs$core$get$$.$cljs$core$IFn$_invoke$arity$3$($coll$jscomp$188$$, this, $not_found$jscomp$10$$);
}
throw Error("Invalid arity: " + (arguments.length - 1));

};
$G strong 41215$$ strong $cljs$core$ get$$ 2 = function($G strong 41215$$, $coll$jscomp 186$$) {

return $cljs$core$get$$.$cljs$core$IFn$_invoke$arity$2$($coll$jscomp$186$$, this);

};
$G strong 41215$$ strong $cljs$core$ get$$ 3 = function($G strong 41215$$, $coll$jscomp 187$$, $not_found$jscomp 9$$) {

return $cljs$core$get$$.$cljs$core$IFn$_invoke$arity$3$($coll$jscomp$187$$, this, $not_found$jscomp$9$$);

};
return $G strong 41215$$;
}();
$JSCompiler_prototypeAlias$$ strong $cljs$core$ get$$ 1 = function($coll$jscomp 189$$) {
return $cljs$core spinach strong $get$$ 2($coll$jscomp 189$$, this);
};
$JSCompiler_prototypeAlias$$ strong $cljs$core$ get$$ 2 = function($coll$jscomp 190$$, $not_found$jscomp 11$$) {
return $cljs$core spinach strong $get$$ 3($coll$jscomp 190$$, this, $not_found$jscomp 11$$);
};
`

0投票

评论者:dnolen

在这里简单地记录一下,上面的示例看起来像是在提倡的内容,但实际上,正如托马斯所提到的,它在向 get 发送。

0投票

评论者:thheller

附加的补丁按计划调整了生成的 {{.call}} 函数。

现在生成的代码更紧凑,不会重复。

`
$JSCompiler_prototypeAlias$$ = $cljs$core$Keyword$$.prototype;
$JSCompiler_prototypeAlias$$.call = function($unused60227auto__$jscomp$3$$) {
switch(arguments.length - 1) {

case 0:
  return this.$cljs$core$IFn$_invoke$arity$0$();
case 1:
  return this.$cljs$core$IFn$_invoke$arity$1$(arguments[1]);
case 2:
  return this.$cljs$core$IFn$_invoke$arity$2$(arguments[1], arguments[2]);
default:
  throw Error(["Invalid arity: ", $cljs$core$str$$.$cljs$core$IFn$_invoke$arity$1$(arguments.length - 1)].join(""));

}
};
$JSCompiler_prototypeAlias$$.$cljs$core$IFn$_invoke$arity$1$ = function($coll$jscomp$183$$) {
return $cljs$core$get$$.$cljs$core$IFn$_invoke$arity$2$($coll$jscomp$183$$, this);
};
$JSCompiler_prototypeAlias$$.$cljs$core$IFn$_invoke$arity$2$ = function($coll$jscomp$184$$, $not_found$jscomp$7$$) {
return $cljs$core$get$$.$cljs$core$IFn$_invoke$arity$3$($coll$jscomp$184$$, this, $not_found$jscomp$7$$);
};
`

我不确定为什么自宿主测试失败。

0投票

评论者:thheller

这不是大事,但我在:高级测试构建中,{{cljs.core}} 代码大小从 168.8KB 减少到 163.2KB(非gzip),因此确实减少了生成的代码总量。

0投票

评论者:thheller

更新的补丁修复了使用 max fixed arity 的糟糕实现,假设所有更低的arity总是存在的。

还修复了所有自宿主问题和测试现在似乎运行得很好。

0投票

评论者:thheller

纠正:CLJS-2133 的测试目前失败。

ERROR in (test-cljs-2133) (错误:NaN:1) 未在断言中捕获到的异常。期望:nil 实际:#object[Error Error: 无效的arity: 1]

我可以调整补丁以允许可变参数行为,但鉴于它官方上并不支持,并且从 1.9.660 版本开始生成警告,或许该全面发展支持了?

0投票

评论者:mfikes

自从1.9.660版本以来,我们已经在CLJS-2134中实施了诊断。

来自David在Slack的评论

"我认为1.9.660的时间足够长,不必过于担忧。
我对补丁感到满意,看看征求意见吧。"

也许我们可以仅仅删除随着CLJS-2133添加的单元测试,作为修复本票据的补丁的一部分?

0投票
...