Tipificación fuerte y débil

Sistemas de tipos de lenguajes de programación

En programación informática , una de las muchas formas en que se clasifican coloquialmente los lenguajes de programación es si el sistema de tipos del lenguaje lo hace fuertemente tipado o débilmente tipado ( tipos flexibles ). Sin embargo, no existe una definición técnica precisa de lo que significan los términos y diferentes autores no están de acuerdo sobre el significado implícito de los términos y las clasificaciones relativas de la "fuerza" de los sistemas de tipos de los lenguajes de programación convencionales. [1] Por esta razón, los escritores que desean escribir de manera inequívoca sobre los sistemas de tipos a menudo evitan los términos "tipado fuerte" y "tipado débil" a favor de expresiones específicas como " seguridad de tipos ".

En general, un lenguaje fuertemente tipado tiene reglas de tipado más estrictas en tiempo de compilación , lo que implica que es más probable que se produzcan errores y excepciones durante la compilación. La mayoría de estas reglas afectan la asignación de variables, los valores de retorno de funciones, los argumentos de procedimientos y la llamada a funciones. Los lenguajes con tipado dinámico (donde la verificación de tipos se realiza en tiempo de ejecución ) también pueden tener tipado fuerte. En los lenguajes con tipado dinámico, los valores, en lugar de las variables, tienen tipos.

Un lenguaje débilmente tipado tiene reglas de tipado más laxas y puede producir resultados impredecibles o incluso erróneos o puede realizar una conversión de tipo implícita en tiempo de ejecución. [2] Un concepto diferente pero relacionado es el tipado latente .

Historia

En 1974, Barbara Liskov y Stephen Zilles definieron un lenguaje fuertemente tipado como aquel en el que "siempre que un objeto se pasa de una función que llama a una función llamada, su tipo debe ser compatible con el tipo declarado en la función llamada". [3] En 1977, K. Jackson escribió: "En un lenguaje fuertemente tipado, cada área de datos tendrá un tipo distinto y cada proceso establecerá sus requisitos de comunicación en términos de estos tipos". [4]

Definiciones de “fuerte” o “débil”

Se ha hecho referencia a varias decisiones de diseño de lenguajes diferentes como evidencia de tipado "fuerte" o "débil". Muchas de ellas se entienden con mayor precisión como la presencia o ausencia de seguridad de tipos , seguridad de memoria , verificación de tipos estática o verificación de tipos dinámica .

El "tipo fuerte" se refiere generalmente al uso de tipos de lenguajes de programación para capturar invariantes del código y garantizar su corrección, además de excluir definitivamente ciertas clases de errores de programación. Por lo tanto, existen muchas disciplinas de "tipo fuerte" que se utilizan para lograr estos objetivos.

Conversiones de tipos implícitas y “juegos de palabras con tipos”

Algunos lenguajes de programación facilitan el uso de un valor de un tipo como si fuera un valor de otro tipo. Esto a veces se describe como "tipificación débil".

Por ejemplo, Aahz Maruch observa que “ la coerción ocurre cuando se tiene un lenguaje con tipado estático y se utilizan las características sintácticas del lenguaje para forzar el uso de un tipo como si fuera un tipo diferente (considere el uso común de void* en C ). La coerción es usualmente un síntoma de tipado débil. La conversión, por otro lado, crea un objeto completamente nuevo del tipo apropiado”. [5]

Como otro ejemplo, GCC describe esto como un juego de palabras de tipos y advierte que romperá el alias estricto . Thiago Macieira analiza varios problemas que pueden surgir cuando el juego de palabras de tipos hace que el compilador realice optimizaciones inapropiadas . [6]

Existen muchos ejemplos de lenguajes que permiten conversiones de tipos implícitas , pero de una manera segura. Por ejemplo, tanto C++ como C# permiten que los programas definan operadores para convertir un valor de un tipo a otro con una semántica bien definida. Cuando un compilador de C++ encuentra una conversión de este tipo, trata la operación como si fuera una llamada a una función. Por el contrario, convertir un valor al tipo void* de C es una operación insegura que es invisible para el compilador.

Punteros

Algunos lenguajes de programación exponen punteros como si fueran valores numéricos y permiten a los usuarios realizar operaciones aritméticas con ellos. A estos lenguajes se los suele denominar "de tipado débil", ya que la aritmética de punteros se puede utilizar para eludir el sistema de tipos del lenguaje.

Uniones sin etiquetar

Algunos lenguajes de programación admiten uniones sin etiquetas , que permiten ver un valor de un tipo como si fuera un valor de otro tipo.

Comprobación de tipos estática

En el artículo Typeful Programming de Luca Cardelli , [7] un "sistema de tipos fuerte" se describe como aquel en el que no existe posibilidad de un error de tipo en tiempo de ejecución no controlado. En otros escritos, la ausencia de errores de tipo en tiempo de ejecución no controlados se conoce como seguridad o seguridad de tipos ; los primeros artículos de Tony Hoare denominan a esta propiedad seguridad . [8]

Variación entre lenguajes de programación

Algunas de estas definiciones son contradictorias, otras son meramente independientes desde el punto de vista conceptual y otras son casos especiales (con restricciones adicionales) de otras definiciones más "liberales" (menos estrictas). Debido a la amplia divergencia entre estas definiciones, es posible defender afirmaciones sobre la mayoría de los lenguajes de programación de que están fuertemente o débilmente tipados. Por ejemplo:

  • Java , Pascal , Ada y C requieren que las variables tengan un tipo declarado y admiten el uso de conversiones explícitas de valores aritméticos a otros tipos aritméticos. A veces se dice que Java, C#, Ada y Pascal están más fuertemente tipados que C, porque C admite más tipos de conversiones implícitas y permite que los valores de puntero se conviertan explícitamente, mientras que Java y Pascal no lo hacen. Java puede considerarse más fuertemente tipado que Pascal, ya que los métodos para evadir el sistema de tipos estáticos en Java están controlados por el sistema de tipos de la máquina virtual Java . C# y VB.NET son similares a Java en ese aspecto, aunque permiten deshabilitar la verificación de tipos dinámica al colocar explícitamente segmentos de código en un "contexto inseguro". El sistema de tipos de Pascal se ha descrito como "demasiado fuerte", porque el tamaño de una matriz o cadena es parte de su tipo, lo que dificulta mucho algunas tareas de programación. Sin embargo, Delphi soluciona este problema. [9] [10]
  • Smalltalk , Ruby , Python y Self son lenguajes "fuertemente tipados" en el sentido de que se evitan los errores de tipado en tiempo de ejecución y realizan poca conversión de tipos implícita , pero estos lenguajes no hacen uso de la comprobación de tipos estática: el compilador no comprueba ni aplica reglas de restricción de tipos. El término tipado dinámico se utiliza ahora para describir el paradigma de tipado dinámico utilizado por los lenguajes de este grupo.
  • La familia de lenguajes Lisp está "fuertemente tipada" en el sentido de que se evitan errores de tipado en tiempo de ejecución. Algunos dialectos de Lisp, como Common Lisp o Clojure, admiten varias formas de declaraciones de tipos [11] y algunos compiladores ( CMU Common Lisp (CMUCL) [12] y relacionados) utilizan estas declaraciones junto con la inferencia de tipos para permitir varias optimizaciones y formas limitadas de comprobaciones de tipos en tiempo de compilación.
  • Los tipos estándar de ML , F# , OCaml , Haskell , Go y Rust se verifican estáticamente, pero el compilador infiere automáticamente un tipo preciso para la mayoría de los valores.
  • El lenguaje ensamblador y Forth pueden caracterizarse como lenguajes sin tipo . No hay verificación de tipos; es responsabilidad del programador asegurarse de que los datos proporcionados a las funciones sean del tipo apropiado.

Véase también

Referencias

  1. ^ "Qué hay que saber antes de debatir sobre sistemas de tipos | Ovid [blogs.perl.org]". blogs.perl.org . Consultado el 27 de junio de 2023 .
  2. ^ "CS1130. Transición a la programación orientada a objetos. Primavera de 2012 --versión a su propio ritmo". Universidad de Cornell, Departamento de Ciencias de la Computación. 2005. Archivado desde el original el 23 de noviembre de 2015. Consultado el 23 de noviembre de 2015 .{{cite web}}: CS1 maint: bot: estado de URL original desconocido ( enlace )
  3. ^ Liskov, B; Zilles, S (1974). "Programación con tipos de datos abstractos". ACM SIGPLAN Notices . 9 (4): 50–59. CiteSeerX 10.1.1.136.3043 . doi :10.1145/942572.807045. 
  4. ^ Jackson, K. (1977). "Procesamiento paralelo y construcción de software modular". Diseño e implementación de lenguajes de programación . Apuntes de clase en informática. Vol. 54. págs. 436–443. doi :10.1007/BFb0021435. ISBN. 3-540-08360-X.
  5. ^ Ahh. «Tipo: fuerte vs. débil, estático vs. dinámico» . Consultado el 16 de agosto de 2015 .
  6. ^ "Juego de palabras con tipos y alias estrictos - Blog de Qt". Blog de Qt . Consultado el 18 de febrero de 2020 .
  7. ^ Luca Cardelli, "Programación tipográfica"
  8. ^ Hoare, CAR 1974. Consejos sobre el diseño de lenguajes de programación. En Computer Systems Reliability , ed. C. Bunyan. Vol. 20, págs. 505–534.
  9. ^ InfoWorld. 25 de abril de 1983. Consultado el 16 de agosto de 2015 .
  10. ^ Kernighan, Brian (1981). «Por qué Pascal no es mi lenguaje de programación favorito». Archivado desde el original el 6 de abril de 2012. Consultado el 22 de octubre de 2011 .
  11. ^ "CLHS: Capítulo 4" . Consultado el 16 de agosto de 2015 .
  12. ^ "Manual del usuario de CMUCL: El compilador". Archivado desde el original el 8 de marzo de 2016 . Consultado el 16 de agosto de 2015 .
Obtenido de "https://es.wikipedia.org/w/index.php?title=Tipificación_fuerte_y_débil&oldid=1223651681"