请分享您的想法,参与2024 Clojure调查!

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

0
ClojureScript

当前在使用实现{{cljs.core/IFn}}的类型时,除了生成的协议fn外,还生成了一个重复整个代码的{{.call}}方法,而没有调用生成的协议fn。

`
(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 $G41215$$ = null;
$G
41215$$ = function($G__41215$$, $coll$jscomp$188$$, $not_found$jscomp$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__41215$$.$cljs$core$IFn$_invoke$arity$2$ = function($G__41215$$, $coll$jscomp$186$$) {

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

};
$G__41215$$.$cljs$core$IFn$_invoke$arity$3$ = function($G__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__41215$$;
}();
$JSCompiler_prototypeAlias$$.$cljs$core$IFn$_invoke$arity$1$ = function($coll$jscomp$189$$) {
return $cljs$core/get$$.$cljs$core$IFn$_invoke$arity$2$($coll$jscomp$189$$, this);
};
$JSCompiler_prototypeAlias$$.$cljs$core$IFn$_invoke$arity$2$ = function($coll$jscomp$190$$, $not_found$jscomp$11$$) {
return $cljs$core/get$$.$cljs$core$IFn$_invoke$arity$3$($coll$jscomp$190$$, this, $not_found$jscomp$11$$);
};
`

0

评论由:dnolen

在此简要说明,上述示例看似与建议的内容一致,但实际上,正如Thomas所说,它正处理到get

0

评论者:thheller

附上的补丁按照计划调整了生成的{{.call}} fn。

现在的生成代码更加紧凑,没有重复。

`
$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

更新的补丁修复了错误的实现,该实现假设所有低阶arity都会始终存在。

还修复了所有自宿主问题,现在测试似乎都顺利通过了。

0

评论者:thheller

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

在(test-cljs-2133)中发生错误(Error:NaN:1)未捕获的异常,不在断言中。期望:nil 实际:#object[Error Error: Invalid arity: 1]

我可以调整补丁以允许变元行为,但既然它尚未正式支持,并且自1.9.660以来就生成了警告,可能现在是完全移除支持的时候了?

0

评论者:mfikes

自1.9.660版本以来,我们已经通过CLJS-2134放置了诊断工具。

Slack上David的评论

"我认为1.9.660已经足够长,不必过于担心它
我对补丁很满意,我们将看看反馈是什么"

也许我们可以简单地删除在CLJS-2133中添加的单元测试?作为此票的补丁的一部分?

0
参考:https://clojure.atlassian.net/browse/CLJS-3003(由thheller报告)
...