- Sistema de tipificación
-
Sistema de tipificación
En ciencias de la computación, un sistema de tipificación define cómo un lenguaje de programación clasifica los valores y las expresiones en tipos, cómo se pueden manipular estos tipos y cómo interactúan. Un tipo indica un conjunto de valores que tienen el mismo significado genérico o propósito (aunque algunos tipos, como los tipos de datos abstractos y tipos de datos función, tal vez no representen valores en el programa que se está ejecutando). Los sistemas de tipificación varían significativamente entre lenguajes, siendo quizás las más importantes variaciones las que estén en sus implementaciones de la sintáctica en tiempo de compilación y la operativa en tiempo de ejecución.
Un compilador puede usar el tipo estático de un valor para optimizar el almacenamiento que necesita y la elección de los algoritmos para las operaciones sobre ese valor. Por ejemplo, en muchos compiladores de C el tipo de dato "flotante" se representa en 32 bits, de acuerdo con la especificación IEEE para los números de coma flotante de simple precisión. Entonces, C usa operaciones específicas de coma flotante sobre estos valores (suma de coma flotante, multiplicación, etc.).
El rango del tipo de dato limita y la forma de su evaluación afecta en el "tipificado" del lenguaje. Además, un lenguaje de programación puede asociar una operación concreta con diferentes algoritmos para cada tipo de dato en el caso del polimorfismo. La teoría de tipos de datos es el estudio de los sistemas de tipificación, aunque los sistemas de tipos de datos concretos de los lenguajes de programación se originaron a partir de los problemas técnicos de las arquitecturas del ordenador, implementación del compilador y diseño del lenguaje.
Contenido
Básicos
Asignar tipos de datos (tipificar) da significado a colecciones de bits. Los tipos de datos normalmente tienen asociaciones tanto con valores en la memoria o con objetos como con variables. Como cualquier valor simplemente consiste en un conjunto de bits de un ordenador, el hardware no hace distinción entre dirección de memoria, código de instrucción, caracteres, enteros y números en coma flotante. Los tipos de datos informan a los programas y programadores cómo deben ser tratados esos bits.
Las principales funciones que los sistemas de tipificación ofrecen son:
- Seguridad - El uso de tipos de datos puede permitir a un compilador detectar incoherencias en el significado o código probablemente inválido. Por ejemplo, podemos identificar una expresión
3 / "Hello, World"
como inválida porque no se puede dividir (de forma normal) un entero por una cadena de caracteres. Un sistema de tipificado fuerte ofrece más seguridad, pero no garantiza, necesariamente una seguridad completa (ver seguridad de la tipificación para más información). - Optimización - Un sistema de tipificado estático puede dar información muy útil al compilador. Por ejemplo, si un tipo de dato dice que un valor debe alinearse en múltiplos de 4, el compilador puede usar de forma más eficiente las instrucciones máquina.
- Documentación - En sistemas de tipificación más expresivos, los tipos de datos pueden servir como una forma de documentación, porque pueden ilustrar la intención del programador. Por ejemplo, los ítem de tiempos pueden ser un subtipo de un entero, pero si un programador declara una función como que devuelve ítems de tiempo en lugar de un simple entero, esto documenta parte del significado de la función.
- Abstracción (o modularidad) - Los tipos de datos permiten a los programadores pensar en los programas a un alto nivel, sin tener que preocuparse con el bajo nivel de la implementación. Por ejemplo, los programadores pueden pensar en una cadena de caracteres como un valor en lugar de un simple array de bytes. O los tipos de datos pueden permitir a los programadores expresar la Interfaz entre dos subsistemas. Esto localiza las definiciones requeridas para la interoperabilidad de los subsistemas y previene de inconsistencias cuando estos subsistemas se comuniquen.
Un programa normalmente asocia cada valor con un tipo de dato determinado (aunque un tipo de dato puede tener más de un subtipo). Otras entidades, como los objetos, bibliotecas, canales de comunicación, dependencias o, incluso, los propios tipos de datos, pueden ser asociados con un tipo de dato. Por ejemplo:
- Tipo de dato - un tipo de dato de un valor
- clase - un tipo de dato de un objeto
Un sistema de tipificado, especificado en cada lenguaje de programación, estipula las formas en que los programas pueden ser escritos y hace ilegal cualquier comportamiento fuera de estas reglas.
Chequeo de tipificación
El proceso de verificar e imponer los límites impuestos por los tipos de datos –chequeo de tipificación– puede ocurrir tanto en tiempo de compilación (un chequeo estático) o en tiempo de ejecución (un chequeo dinámico). Si un lenguaje impone fuertemente las reglas de tipificación (es decir, generalmente permitiendo solo las conversiones de tipo de dato automáticas que no hagan perder información), uno se puede referir al proceso como fuertemente tipificado; sino, débilmente tipificado.
Tipificado estático
Se dice de un lenguaje de programación que usa un tipificado estático cuando el chequeo de tipificación se realiza durante el tiempo de compilación, opuesto al de ejecución. Ejemplos de lenguajes que usan tipificado estático son C, C++, Java y Haskell. Comparado con el tipificado dinámico, el estático permite que los errores de programación sean detectados antes, y que la ejecución del programa sea más eficiente.
Tipificado dinámico
Se dice de un lenguaje de programación que usa un tipificado dinámico cuando el chequeo de tipificación se realiza durante el tiempo de ejecución, opuesto al de compilación. Ejemplos de lenguajes que usan tipificado dinámico son Perl, Python y Lisp. Comparado con el tipificado estático, o sistema de enlazado temprano, el tipificado dinámico es más flexible (debido a las limitaciones teóricas de la decidibilidad de ciertos problemas de análisis de programas estáticos, que impiden el mismo nivel de flexibilidad que se consigue con el tipificado estático), a pesar de ejecutarse más lentamente y más propensos a contener errores de programación.
Tipificado estático y dinámico combinados
Algunos lenguajes estáticamente tipificados tienen una "puerta trasera" en el lenguaje que permite a los programadores escribir código que no es chequeado estáticamente. Por ejemplo, los lenguajes como Java y los parecidos al C tienen una "conversión de tipos de datos forzada (cast)"; estas operaciones pueden ser inseguras en tiempo de ejecución, por que pueden causar comportamientos indeseados cuando el programa se ejecuta.
La presencia de un tipificado estático en un lenguaje de programación no implica necesariamente la ausencia de mecanismos de tipificado dinámico. Por ejemplo, Java usa tipificado estático, pero ciertas operaciones requieren el soporte de test de tipos de datos en tiempo de ejecución, que es una forma de tipificado dinámico. Ver lenguaje de programación para una discusión más amplia de la interacción entre tipificado estático y dinámico.
Chequeo de tipificación estático y dinámico en la práctica
La elección entre sistemas de tipificación dinámico y estático requiere algunas contra prestaciones.
El tipificado estático busca errores en los tipos de datos en tiempo de compilación. Esto debería incrementar la fiabilidad de los programas procesados. Sin embargo, los programadores, normalmente, están en desacuerdo en cómo los errores de tipos de datos más comunes ocurren, y en qué proporción de estos errores que se han escrito podrían haberse cazado con un tipificado estático. El tipificado estático aboga por la creencia de que los programas son más fiables cuando son chequeados sus tipos de datos, mientras que el tipificado dinámico apunta al código distribuido que se ha probado que es fiable y un conjunto pequeño de errores. El valor del tipificado estático, entonces, es que se incrementa a la par que se endurece el sistema de tipificación. Los defensores de los lenguajes fuertemente tipificados como ML y Haskell han sugerido que casi todos los errores pueden ser considerados errores de los tipos de datos, si los tipos de datos usados en un programa están suficientemente bien declarados por el programador o inferidos por el compilador.[1]
El tipificado estático resulta, normalmente, en un código compilado que se ejecuta más rápidamente. Cuando el compilador conoce los tipos de datos exactos que están en uso, puede producir código máquina optimizado. Además, los compiladores en los lenguajes de tipificado estático pueden encontrar atajos más fácilmente. Algunos lenguajes de tipificación dinámica como el lisp permiten declaraciones de tipos de datos opcionales para la optimización por esta misma razón. El tipificado estático generaliza este uso. Ver optimización de software
En contraste, el tipificado dinámico permite a los compiladores e intérpretes ejecutarse más rápidamente, debido a que los cambios en el código fuente en los lenguajes dinámicamente tipificados puede resultar en un menor chequeo y menos código que revisar. Esto también reduce el ciclo editar-compilar-comprobar-depurar.
Lenguajes estáticamente tipificados que no dispongan de inferencia (como Java), requieren que el programador declare los tipos de datos que un método o función puede procesar. This can serve as additional documentation for the program, which the compiler will not permit the programmer to ignore or drift out of synchronization. sin embargo, un lenguaje puede ser de tipificación estática sin requerir la declaración del tipo de dato (ejemplos incluyen Scala y C#3.0), así que esto no es una consecuencia de tipificación estática.
El tipado dinámico permite construcciones que algunos sistemas de tipado estatico rechazarían al considerarlas ilegales. Por ejemplo, la función eval de Python, la cual ejecuta datos arbitrarios como si fueran código. Además, el tipado dinámico es más adecuado para código de transición o para el prototipado. Desarrollos recientes en lenguajes como Haskell (por ejemplo, los tipos algebraicos generalizados), permiten a lenguajes de tipado estatico, ejecutar código a partir de estructuras de datos de una forma segura.
Dynamic typing typically makes metaprogramming more powerful and easier to use. For example, C++ templates are typically more cumbersome to write than the equivalent Ruby or Python code.[cita requerida] More advanced run-time constructs such as metaclasses and introspection are often more difficult to use in statically-typed languages.
Referencias
- Seguridad - El uso de tipos de datos puede permitir a un compilador detectar incoherencias en el significado o código probablemente inválido. Por ejemplo, podemos identificar una expresión
Wikimedia foundation. 2010.