通过转译器在Javascript中实现操作符重载
Implementing operator overloading in Javascript via a transpiler
对于我们中的一些人来说,Javascript的一个问题是缺乏操作符重载。这使得编写数字库变得很尴尬。例如,我们可能想要这样写:
var a = new BigInteger(5);
var b = new BigInteger(10);
var c = a + b;
一个可能的解决方案是将带有操作符重载的语言翻译成Javascript。虽然可行——用函数调用和类型检查替换操作符——但共识似乎是,这在不影响性能的情况下是不可能的。CoffeeScript拒绝了这个想法,原因如下:
https://github.com/jashkenas/coffee-script/issues/846但是真的没有聪明的解决方案吗?
例如,可以将类型检查从紧循环中提升出来,或者使用其他管道,当类型是数字时,现代JS编译器可以优化掉添加的赘物。
想法?
你真的确定你需要你的大数是可用的旧函数写正常的数字在头脑中(使用传统的操作符)?如果您只是为了方便而需要对您控制的函数进行重载,则可以通过使用不同的自定义操作符来处理二进制数。
例如,您可以编写一个编译器来安全地转换var d = a <+> b <*> c;
到
var d = (a).add((b).multiply(c));
或者,如果你想要自动转换…
var d = toBignum(a).add(toBignum(b).multiply(toBignum(c)));
我真的不认为你能够在没有大麻烦的情况下对现有的实现强制重载。虽然理论上你可以用<+>等替换所有+的出现,但目前的Javascript实现并没有为此进行优化,我甚至不想开始考虑如果你试图将一个大值传递给底层的本地c++函数会发生什么。
edit:不需要重写基整数类是这里的重点(注意在你给出的链接中,重写是这家伙想要的第一件事…)。我不认为你将能够找到某种"神奇"的优化,尽管你无法控制客户端正在使用的众多JS实现中的哪一个。
如果你真的不喜欢像<+>这样的自定义操作符,区分普通+操作符(你不应该干预)和花哨+操作符(你想做大的东西)的唯一方法是在Javascript之上强制某种特殊的类型系统,可能是通过注释、自定义语法或(如注释中提到的)匈牙利符号。在我看来,选择一个你不太讨厌的自定义操作符名字会显得不那么粗俗。
看看Scala是如何实现运算符重载的:
他们定义了每个操作符都是对对象的方法调用,所以你的例子是:
var c = a["+"](b);
如果停在这里,可以简单地实现方法重载,函数必须检查param传递的值。如果你想开发一个更好的解决方案,请参考Odersky的Scala编程书,花点时间阅读他们如何解决问题的所有想法(这是一个非常好的解决方案!)
解决性能下降的一个可能选择是使用AST转换并将每个操作符转换为功能,如a * b
=>a.multiply(b)
.
对于性能敏感的代码,瓶颈,提示编译器不应该进行转换,类似于CoffeeScript语法发出原始JS的方式。
- 如何使用动画实现纸张推车
- 客户端服务器REST API captcha实现
- 如何实现此布局
- Meteor忘记了密码的实现
- 使用Native Sockets在Android中实现WebSockets
- 在样板文件中实现Ajax
- instanceof是如何在JavaScript中实现的
- 如何正确实现Jquery多选小部件
- 实现一个建立在google.com之上的自定义搜索引擎
- 多个组件是如何实现的
- window.location使用jquery mobile实现chrome跳转
- 如何在OpenERP中实现网络摄像头
- Node.js使用Series函数(模式?)实现流控制时出现意外结果
- javascript加密实现,包括可信否认
- 实现比较方法的最佳实践是什么;s的比较类型是在运行时选择的
- 如何让程序员在javascript中实现正确的回调
- 如何使用自定义辅助对象(handler)实现嵌套的每个循环
- AngularJS智能表全局配置实现
- Expressjs/AngularJS:实现req-flash后出错
- 通过转译器在Javascript中实现操作符重载