En los lenguajes de programación , el polimorfismo ad hoc [1] es un tipo de polimorfismo en el que las funciones polimórficas se pueden aplicar a argumentos de diferentes tipos, porque una función polimórfica puede denotar una serie de implementaciones distintas y potencialmente heterogéneas según el tipo de argumento (s ) al que se aplica. Cuando se aplica a conceptos orientados a objetos o de procedimiento, también se conoce como sobrecarga de funciones o sobrecarga de operadores . El término ad hoc en este contexto no pretende ser peyorativo; se refiere simplemente al hecho de que este tipo de polimorfismo no es una característica fundamental del sistema de tipos. Esto contrasta con el polimorfismo paramétrico , en el que las funciones polimórficas se escriben sin mencionar ningún tipo específico y, por lo tanto, pueden aplicar una única implementación abstracta a cualquier número de tipos de forma transparente. Christopher Strachey introdujo esta clasificación en 1967.
Enlace anticipado
El polimorfismo ad hoc es un mecanismo de envío : el control que se mueve a través de una función nombrada se envía a varias otras funciones sin tener que especificar la función exacta que se llama. La sobrecarga permite definir múltiples funciones de diferentes tipos con el mismo nombre; el compilador o intérprete se asegura automáticamente de que se llame a la función correcta. De esta manera, las funciones que agregan listas de enteros , listas de cadenas , listas de números reales , etc. podrían escribirse, y todas se llamarían agregar, y la función de agregar derecha se llamaría según el tipo de listas que se agregan. Esto difiere del polimorfismo paramétrico, en el que la función debería escribirse de forma genérica para trabajar con cualquier tipo de lista. Usando la sobrecarga, es posible que una función realice dos cosas completamente diferentes según el tipo de entrada que se le pasa; esto no es posible con el polimorfismo paramétrico. Otra forma de ver la sobrecarga es que una rutina se identifica de forma única no por su nombre, sino por la combinación de su nombre y el número, orden y tipos de sus parámetros.
Este tipo de polimorfismo es común en los lenguajes de programación orientados a objetos, muchos de los cuales permiten que los operadores se sobrecarguen de manera similar a las funciones (ver sobrecarga de operadores ). Algunos idiomas que no se escriben de forma dinámica y carecen ad polimorfismo hoc (incluyendo clases de tipo) tienen nombres de las funciones más largos, tales como print_int
, print_string
, etc. Esto se puede ver como ventaja (más descriptivo) o una desventaja (excesivamente detallado) dependiendo de un punto de vista .
Una ventaja que a veces se obtiene de la sobrecarga es la apariencia de especialización, por ejemplo, una función con el mismo nombre se puede implementar de múltiples formas diferentes, cada una optimizada para los tipos de datos particulares en los que opera. Esto puede proporcionar una interfaz conveniente para el código que debe especializarse en múltiples situaciones por razones de rendimiento. La desventaja es que el sistema de tipos no puede garantizar la coherencia de las diferentes implementaciones.
Dado que la sobrecarga se realiza en tiempo de compilación, no sustituye al enlace tardío como se encuentra en el polimorfismo de subtipificación .
Encuadernación tardía
No obstante la sección anterior, hay otras formas en las que el polimorfismo ad hoc puede funcionar. Considere, por ejemplo, el lenguaje Smalltalk. En Smalltalk , la sobrecarga se realiza en tiempo de ejecución, ya que los métodos ("implementación de función") para cada mensaje sobrecargado ("función sobrecargada") se resuelven cuando están a punto de ejecutarse. Esto sucede en tiempo de ejecución, después de que se compila el programa. Por lo tanto, el polimorfismo se obtiene al subtipificar polimorfismo como en otros lenguajes, y también se extiende en funcionalidad mediante polimorfismo ad hoc en tiempo de ejecución.
Una mirada más cercana también revelará que Smalltalk proporciona una variedad ligeramente diferente de polimorfismo ad hoc . Dado que Smalltalk tiene un modelo de ejecución de enlace tardío, y dado que proporciona a los objetos la capacidad de manejar mensajes que no se entienden, es posible implementar la funcionalidad utilizando polimorfismo sin sobrecargar explícitamente un mensaje en particular. Esta puede no ser una práctica recomendada para la programación diaria, pero puede ser muy útil al implementar proxies.
Además, aunque en términos generales la sobrecarga de constructores y métodos de clases comunes no se considera polimorfismo, existen lenguajes más uniformes en los que las clases son objetos regulares. En Smalltalk, por ejemplo, las clases son objetos regulares. A su vez, esto significa que los mensajes enviados a las clases pueden sobrecargarse y también es posible crear objetos que se comporten como clases sin que sus clases hereden de la jerarquía de clases. Estas son técnicas efectivas que pueden usarse para aprovechar las poderosas capacidades de reflexión de Smalltalk . También son posibles arreglos similares en idiomas como Self y Newspeak .
Ejemplo
Imagine un operador +
que se puede utilizar de las siguientes formas:
1 + 2 = 3
3.14 + 0.0015 = 3.1415
1 + 3.7 = 4.7
[1, 2, 3] + [4, 5, 6] = [1, 2, 3, 4, 5, 6]
[true, false] + [false, true] = [true, false, false, true]
"bab" + "oon" = "baboon"
Sobrecarga
Para manejar estas seis llamadas a funciones, se necesitan cuatro piezas de código diferentes, o tres , si las cadenas se consideran listas de caracteres:
- En el primer caso, se debe invocar la suma de enteros .
- En el segundo y tercer caso, se debe invocar la adición de punto flotante (con promoción de tipo , o coerción de tipo , en el tercer caso).
- En los casos cuarto y quinto, debe invocarse la concatenación de listas .
- En el último caso, se debe invocar la concatenación de cadenas .
Por lo tanto, el nombre en +
realidad se refiere a tres o cuatro funciones completamente diferentes. Este es un ejemplo de sobrecarga . (Tenga en cuenta la ambigüedad en los tipos de cadena utilizados en el último caso. Considere "123" + "456" en el que el programador naturalmente podría asumir la adición en lugar de la concatenación. Puede esperar "579" en lugar de "123456". Por lo tanto, la sobrecarga puede proporcionar significado diferente, o semántica, para una operación, así como diferentes implementaciones).
Referencias
- ^ C. Strachey, Conceptos fundamentales en lenguajes de programación . Notas de la conferencia para la Escuela Internacional de Verano en Programación de Computadoras, Copenhague, agosto de 1967