2011-09-18 7 views
7

Uno de los problemas, para algunos de nosotros, con Javascript es la falta de sobrecarga del operador. Esto hace que escribir bibliotecas numéricas sea incómodo. Por ejemplo, podríamos querer escribir algo como:Implementación de la sobrecarga del operador en Javascript a través de un transpiler

var a = new BigInteger(5); 
var b = new BigInteger(10); 
var c = a + b; 

Una posible solución es transpile una lengua con la sobrecarga de operadores de Javascript. Si bien es factible (reemplazando operadores por llamadas a funciones y controles de tipo), parece que el consenso es que esto es imposible sin matar el rendimiento. CoffeeScript ha rechazado la idea por esta razón:

https://github.com/jashkenas/coffee-script/issues/846

Pero ¿Realmente no hay soluciones inteligentes?

Por ejemplo, podría ser posible que el tipo de polipasto compruebe los bucles apretados o utilice alguna otra tubería donde los compiladores de JS modernos puedan optimizar la separación adicional cuando los tipos son numéricos.

Ideas?

+0

¿Podría falsificar la tipificación estática con notación húngara? Su código explotaría espectacularmente sin mensaje de error si mezcla incluso un tipo en cualquier lugar, por supuesto. – evan

+0

Hay un artículo aquí re. Sobrecarga del operador JS ... http://www.2ality.com/2011/12/fake-operator-overloading.html –

Respuesta

1

Mire como Scala implementado Sobrecarga de operadores:

Se define que cada operador es una llamada a un método en un objeto, por lo que su ejemplo podría ser:

var c = a["+"](b); 

Si se detiene aquí, usted podría implementar trivialmente sobrecarga de método, la función debería verificar los valores pasados ​​por param. Si desea desarrollar una mejor solución, tome la programación de Odersky en Scala y lea un momento para leer todas sus ideas sobre cómo solucionaron el problema (¡una solución muy buena!)

+1

Esto solo funciona si está rediseñando el idioma desde cero (como fue el caso de Scala). Realmente no puedes convertir a un operador monomórfico en uno polimórfico por un capricho :( – hugomg

2

¿Está seguro de que necesita su gran números para ser utilizables por funciones antiguas escritas con números normales en mente (que usan los operadores tradicionales)? Si solo necesita la sobrecarga para su propia conveniencia en las funciones sobre las que tiene control, puede obtener un operador personalizado diferente para bignums.

Por ejemplo, se podría escribir un compilador para convertir de forma segura

var d = a <+> b <*> c; 

en

var d = (a).add((b).multiply(c)); 

o tal vez, si se desea que las conversiones automáticas ...

var d = toBignum(a).add(toBignum(b).multiply(toBignum(c))); 

Realmente no te veo bei ng capaz de forzar la sobrecarga en una implementación existente sin una gran molestia. Si bien podría reemplazar teóricamente todas las ocurrencias de + con < +> y así sucesivamente, las implementaciones actuales de Javascript no están optimizadas para esto y ni siquiera quiero empezar a pensar qué pasaría si intentara pasar un bignum a uno de los nativos. C++ funciones que están bajo el capó.


edición: Sin necesidad de sustituir la clase de número entero de base es el punto importante aquí (nota cómo en el enlace que le diste, anulando es lo primero que el tipo quiere ...). No creo que pueda encontrar una optimización "mágica" aunque no tenga control sobre cuál de las muchas implementaciones JS está utilizando el cliente.

Si realmente no te gusta un operador personalizado como < +> la única forma de distinguir un operador normal + (no deberías entrometerse) de un operador de lujo + (quieres hacer cosas bignum) sería estar forzando algún tipo de sistema de tipeo ad-hoc sobre Javascript, quizás a través de comentarios, sintaxis personalizada o (como se menciona en un comentario) notación húngara. Solo conformarse con un nombre de operador personalizado que odie menos sería menos hackish, IMO.

+0

No me preocupan las antiguas funciones de Javascript. Y una nueva sintaxis como <+> es demasiado difícil para mi gusto, ya que + es lo que significa. Mi esperanza es que exista una optimización conocida que siga en el compilador que pueda ser explotada. – Tristan

+0

Editado la respuesta ... – hugomg