JS: Polimorfismo
Teoría: Polimorfismo paramétrico
La palabra "polimorfismo" puede tener diferentes significados dependiendo del contexto. Cuando los programadores hablan de polimorfismo en lenguajes imperativos, generalmente se refieren al "polimorfismo de subtipos". Por otro lado, los programadores en lenguajes funcionales se refieren al "polimorfismo paramétrico". Vamos a hablar sobre este último.
En esta lección aparece código en TypeScript. No te preocupes si no lo entiendes completamente. Nuestro objetivo es comprender los conceptos, no TypeScript.
En la biblioteca lodash, hay una función llamada _.concat() que combina las matrices (arrays) que se le pasan:
Esta función combina cualquier tipo de array, independientemente del tipo de datos que contengan. Intentemos implementarla nosotros mismos.
Observa detenidamente este código. ¿Se realizan operaciones en los datos dentro del array? La respuesta correcta es no. Estos datos se transfieren de un array a otro, pero no se realiza ninguna operación sobre ellos. Nuestra nueva función concat(), al igual que la original _.concat(), puede trabajar con arrays que contienen cualquier tipo de datos.
Para los desarrolladores que solo han trabajado con lenguajes dinámicos, este comportamiento puede parecer natural, pero en los lenguajes estáticos no es tan sencillo.
En TypeScript, al crear un array, se especifica el tipo de los elementos de ese array. Para el primero es number, para el segundo es string. Agregar un elemento de un tipo diferente al array resultará en un error:
Las funciones que operan en arrays esperan un tipo específico:
Observa la firma de la función concat(): (arr1: number[], arr2: number[]): number[]. A diferencia de la versión en JavaScript, aquí se especifica que los parámetros de entrada son arrays de números number[]. Esto significa que la función no funcionará para arrays de strings ni para ningún otro tipo de datos.
¿Qué significa esto en la práctica? Una cosa muy simple y triste. Tendremos que implementar una función similar para cada tipo a pesar de que el algoritmo interno es completamente idéntico.
Aquí es donde entra en juego el polimorfismo paramétrico. Los lenguajes estáticos tienen que introducir construcciones especiales en el lenguaje que permitan describir algoritmos similares sin importar el tipo del parámetro. En algunos lenguajes se llaman plantillas (C++) o genéricos (TypeScript, Java, C#):
En este código, aparece el tipo T, que precisamente permite utilizar cualquier tipo dentro del array. Ahora el método concat() funciona de manera similar a su contraparte en JavaScript.
El polimorfismo paramétrico permite escribir algoritmos genéricos para tipos compuestos, lo que en algunos casos reduce significativamente la cantidad de código. A veces, esto puede complicar la solución, pero para la mayoría de las operaciones típicas, la complejidad no aumenta mucho. Esto se puede ver en el código anterior.
En los lenguajes dinámicos, no se necesita polimorfismo paramétrico para implementar algoritmos genéricos. Cualquier colección puede contener cualquier tipo de datos en cualquier momento. Gracias a esto, no es necesario introducir construcciones adicionales en el lenguaje ni aprender nuevos conceptos.
En la literatura, el uso del polimorfismo paramétrico a menudo se denomina programación genérica.
Completado
0 / 14