Según una de las clasificaciones, los lenguajes de programación se dividen informalmente en fuertemente y débilmente tipados , es decir, que tienen un sistema de tipos fuerte o débil . Estos términos no se interpretan sin ambigüedades y se utilizan con mayor frecuencia para indicar las ventajas y desventajas de un idioma en particular. Hay conceptos más específicos que llevan a denominar a ciertos sistemas de tipo " fuertes " o " débiles ".
En la literatura en idioma ruso, el término " tipado fuerte " [1] [2] se usa a menudo ; variante común " tipado fuerte " se usa solo cuando se contrasta " tipificación débil ". Tenga en cuenta que el uso del término " estricto " en relación con el sistema de tipos de un lenguaje puede causar confusión con la semántica de evaluación estricta del lenguaje .
En 1974, Liskov y Zilles llamaron lenguajes fuertemente tipados en los que “ cuando un objeto se pasa de una función que llama a una función que llama, el tipo de ese objeto debe ser compatible con el tipo definido en la función que llama ” [3] . Jackson escribió: " En un lenguaje fuertemente tipado, cada celda de datos tendrá un tipo único, y cada proceso proclamará sus requisitos de relación en términos de estos tipos " [4] .
En el artículo de Luca Cardelli " Programación completa de tipos " 5] , un sistema de tipos se denomina "fuerte" si elimina la posibilidad de un error de coincidencia de tipos en tiempo de ejecución. En otras palabras, la ausencia de errores de tiempo de ejecución no verificados se denomina seguridad de tipos ; Los primeros trabajos de Hoare llaman a esta propiedad seguridad .
La tipificación "fuerte" y "débil" es el producto de muchas decisiones tomadas en el diseño de un lenguaje. Más precisamente, los lenguajes se caracterizan por la presencia o ausencia de seguridad de consistencia de tipo y seguridad de acceso a la memoria , así como la sincronización característica de dicho control ( estático o dinámico ).
Por ejemplo, claros ejemplos de un sistema de tipo débil son los que subyacen en los lenguajes C y C++ . Sus atributos característicos son los conceptos de fundición de tipos y juegos de palabras . Estas operaciones se admiten en el nivel del compilador y, a menudo, se las llama implícitamente. Una operación reinterpret_casten C++ le permite representar un elemento de datos de cualquier tipo como perteneciente a cualquier otro tipo, siempre que la longitud de su implementación de bajo nivel (representación de bits) sea igual y cambia su estado de una manera que no es válida para el tipo de fuente. El uso descuidado de tales operaciones es a menudo la fuente de bloqueos del programa . A pesar de esto, los libros de texto de C++ describen su sistema de tipos como " fuerte ", lo que, dada la tesis de Luca Cardelli [5] y otros, debe entenderse como " más fuerte que en C ". En cambio, en los lenguajes tipeados según Hindley-Milner , el concepto de typecasting está ausente en principio. La única forma de "convertir" un tipo es escribir una función que construya algorítmicamente un valor del tipo requerido a partir del valor del tipo original. Para casos triviales, como "convertir" un entero sin signo en un entero con signo y viceversa, estas funciones suelen incluirse en las bibliotecas estándar. El caso más utilizado de este tipo de funciones son las funciones especiales definidas con un cuerpo vacío, llamadas funciones constructoras o simplemente constructoras .
Al mismo tiempo , el sistema de tipo Hindley-Milner proporciona una tasa extremadamente alta de reutilización de código debido al polimorfismo paramétrico . Un sistema de tipos fuerte pero no polimórfico puede dificultar la resolución de muchos problemas algorítmicos, como se señaló en relación con el lenguaje Pascal [6] .
Existe la opinión de que la escritura fuerte es un elemento indispensable para garantizar la confiabilidad del software desarrollado. Cuando se usa correctamente (lo que significa que el programa declara y usa tipos de datos separados para valores lógicamente incompatibles), protege al programador de errores simples pero difíciles de encontrar asociados con el intercambio de valores lógicamente incompatibles, que a veces surgen simplemente de un simple error tipográfico.
Dichos errores se detectan incluso en la etapa de compilación del programa, mientras que con la posibilidad de conversión implícita de casi cualquier tipo entre sí (como, por ejemplo, en el lenguaje C clásico), estos errores se detectan solo durante la prueba, y no todos y cada uno. no inmediatamente, lo que a veces es muy costoso en la etapa de operación industrial.
Python es un ejemplo de un lenguaje con escritura dinámica fuerte [7] .