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发表的评论:

在这里留下备忘,上述示例看起来像所建议的那样具有欺骗性,但正如托马斯所提到的,它调用的是 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 $assiumcore$$.$assiumcore$_invoke$arity$2$($coll$jscomp$183$$, this);
};
$JSCompiler_prototypeAlias$$.$cljs$core$IFn$_invoke$arity$2$ = function($coll$jscomp$184$$, $not_found$jscomp$7$$) {
return $assiumcore$$.$assiumcore$_invoke$arity$3$($coll$jscomp$184$$, this, $not_found$jscomp$7$$);
};
`

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

0

由thheller发表的评论:

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

0

由thheller发表的评论:

更新的补丁修复了使用最大固定选项的实现,假设所有较低的选项始终存在。

同时解决所有自宿主问题,测试似乎现在进行得很好。

0

由thheller发表的评论:

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

ERROR in (test-cljs-2133) (Error:NaN: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报告)
...