Este artículo explora las limitaciones de los sistemas de tipos en lenguajes de programación dinámicos, utilizando como ejemplo la propuesta de una función Map.take!/2 en Elixir. Map.take/2 es una función existente en Elixir que extrae un subconjunto de claves de un mapa, ignorando las claves inexistentes. La propuesta de Map.take!/2 busca añadir un comportamiento similar pero lanzando una excepción (KeyError) si alguna de las claves especificadas no existe en el mapa, lo cual es útil para validar la estructura de datos. Esto refleja la necesidad de una mayor seguridad en tiempo de ejecución, especialmente cuando se trabaja con mapas que actúan como registros (estructuras de datos con claves conocidas).
El artículo profundiza en los desafíos de definir una firma de tipo precisa para Map.take!/2 dentro de un sistema de tipos. La firma inicial propuesta era demasiado general, ya que no especificaba el tipo exacto del mapa resultante, lo que limitaba su utilidad para la verificación de tipos. El autor investiga cómo TypeScript, con su operador keyof, podría resolver este problema, permitiendo la inferencia de tipos más precisos para el mapa resultante. Sin embargo, incluso con TypeScript, se revela que la aplicación de restricciones de tipo puede llevar a situaciones contraintuitivas: refactorizar código para eliminar duplicación o encapsular lógica puede resultar en una pérdida de precisión en la verificación de tipos, creando una 'leaks abstraction' donde el sistema de tipos se opone a buenas prácticas de programación.
El artículo también examina un intento de solución utilizando as const en TypeScript, que, aunque parece prometedor, introduce una firma de tipo 'insound' (incorrecta) que permite la creación de mapas con combinaciones de claves que no son válidas en tiempo de ejecución. Esto ilustra la dificultad de equilibrar la expresividad y la seguridad en los sistemas de tipos, especialmente cuando se integran en lenguajes dinámicos. El artículo concluye que, a pesar de los avances en los sistemas de tipos, a menudo es necesario comprender sus limitaciones internas para escribir código correcto y mantenible, y que la búsqueda de la perfección en la verificación de tipos puede, paradójicamente, obstaculizar el desarrollo de software.
