Sistema de tipos

conjunto de reglas que asignan una propiedad llamada tipo a varias construcciones de las que un programa informático consta, tales como variables, expresiones, funciones o módulos From Wikipedia, the free encyclopedia

En ciencias de la computación, un sistema de tipos define cómo un lenguaje de programación clasifica los valores y las expresiones en tipos y define cómo se manipulan e interactúan estos tipos. Un tipo de dato indica un conjunto de valores que tienen el mismo significado, propósito o representación. Los sistemas de tipificación varían significativamente entre lenguajes, siendo quizás la distinción más significativa la de sistema interpretado en contraposición a compilado.

Un compilador o intérprete puede usar el tipo de un valor para optimizar el almacenamiento en memoria, la elección de los algoritmos para operaciones sobre ese valor o determinar la validez de una operación concreta. 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. Con esta información, C limita las operaciones sobre estos a las específicas de coma flotante y, en caso de que exista ambigüedad de operaciones, elige las correctas para el tipo.

El tipo de una expresión limita las operaciones aplicables a la misma. Además, un lenguaje de programación puede asociar una operación con diferentes algoritmos dependiendo del tipo de dato mediante el mecanismo del polimorfismo. En matemáticas y lógica, la teoría de tipos es el estudio de los sistemas de tipos. Los sistemas de tipos concretos de los lenguajes de programación se originaron, basándose en estos estudios, para solventar los problemas técnicos que presentaban las arquitecturas de los computadores y reducir todo lo posible proliferación de errores de los lenguajes de programación.

Significado

Asignar tipos de datos (tipificar) da significado a colecciones de bits. Los tipos de datos son asociaciones de valores en la memoria con un sistema para interpretarlos. En un lenguaje orientado a objetos, por ejemplo, asignar una clase a una variable es equivalente a darle a esa variable las características (atributos y métodos) propios de la clase.

Como cualquier valor simplemente consiste en un conjunto de bits de un ordenador, el hardware no hace distinción entre direcciones de memoria, códigos de instrucción, caracteres, enteros o números de coma flotante. Los tipos de datos informan a los programas y desarrolladores acerca de la correcta interpretación y las operaciones aplicables sobre una expresión o valor.

Utilidad

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 la operación de división no está definida sobre un entero y una cadena de caracteres.

Un sistema de tipado ofrece más seguridad, pero no garantiza la ausencia de errores (ver seguridad de la tipificación para más información).

Optimización

Un sistema de tipado estático puede proveer al compilador de información adicional, como la longitud de una variable, útil para la alineación de la memoria, así reduciendo la cantidad de cargas de página o reasignaciones por falta de espacio, al compactarse la representación de los datos.

Documentación

En sistemas de tipificación más expresivos, los tipos de datos pueden servir como una forma de documentación, al ilustrar la intención del programador y limitar los usos incorrectos de operaciones definidas.

Por ejemplo, las variables con significado "duración temporal" pueden ser representados como enteros, pero si un programador declara una función como que devuelve un elemento de tipo "duración" que sea un subtipo de entero en lugar de un entero genérico, codifica parte del significado de la función en su valor de retorno.

Abstracción

Los tipos de datos permiten generalizaciones versátiles que reduzcan la complejidad de operaciones. Si se define un tipo lista de items de tipo genérico, una implementación genérica de operaciones puede ser codificada sin tener en cuenta la longitud de cada elemento de la lista o de la forma concreta de los mismos.

Además, los tipos de datos pueden permitir a los programadores expresar la Interfaz entre dos subsistemas, enumerando los requerimientos para la interoperabilidad de los subsistemas y evitando inconsistencias cuando estos subsistemas se comuniquen. Por ejemplo, suponiendo dos sistemas, uno codificado en Java y otro en Python, si se define un estándar de representación de datos como JSON, cualquier valor de Java que sea representado siguiendo este sistema podrá ser decodificado por Python a un valor equivalente sin importar la forma o representación concreta de los datos.

Expresiones tipables

Un programa normalmente asocia expresiones con un tipo de dato determinado (que puede o no ser subtipo de otros). Esta asignación es arbitraria y, dependiendo del lenguaje, muchos constructos diferentes pueden o no ser asignados tipos muy específicos o genéricos.

En lenguajes imperativos, muchas expresiones válidas no tienen valor de retorno y estas, por tanto, no tienen ningún tipo asignado.

En la familia de lenguajes orientados a objetos, es costumbre que exista un supertipo del que hereden todos los otros tipos y que en esta relación se incluyan todos los valores de variables y algunas de las expresiones del lenguaje.

En los lenguajes funcionales, sin embargo, y por herencia del lambda cálculo, en el que no existe ninguna distinción entre valor y variable, todas las expresiones suelen tener un valor de retorno definido, si bien suele existir un tipo nulo de retorno para operaciones que no sean puras.

Algunos ejemplos de expresiones tipables son:

  • Variables - Según el tipo de dato que almacenen. Puede o no ser provisto por el programador durante su definición.
  • Operaciones con variables - Según el tipo al que sean evaluadas. Esto incluye la aplicación de funciones u operaciones matemáticas.
  • Bibliotecas - Determinados lenguajes representan módulos o bibliotecas con un tipo o clase específicos que permitan acceso a los valores definidos en su interior.
  • Condicionales - En determinados lenguajes, los condicionales son interpretados como expresiones que se evalúan al valor de retorno de cada una de sus ramas.

Durante evaluación o compilación de un lenguaje de programación, el sistema de tipado comprueba las expresiones tipables para asegurar que se comportan de acuerdo a las reglas definidas y así evitar el uso incorrecto de sus valores.

Chequeo de tipificación

El proceso de verificar e imponer los límites impuestos por los tipos de datos –comprobación (chequeo) de tipificación– puede ocurrir tanto en la compilación (una comprobación estática) como en la ejecución (una comprobación dinámica). Si un lenguaje impone fuertemente las reglas de tipificación (es decir, generalmente permitiendo solo las conversiones explícitamente denotadas o que aseguren la conservación de la información), uno se puede referir al proceso como fuertemente tipado; si no, será débilmente tipado.

Tipado estático

Se dice de un lenguaje de programación que usa un tipado estático o sistema de enlazado temprano cuando la comprobación de tipificación se realiza durante la compilación, y no durante la ejecución. Ejemplos de lenguajes que usan tipado estático son C, C++, Java y Haskell. Comparado con el tipado dinámico, el estático permite que los errores de tipificación sean detectados antes, y que la ejecución del programa sea más eficiente y segura a cambio de una menor flexibilidad debida a la falta de información proporcionada por las entradas dinámicas del programa.

Tipado dinámico

Se dice de un lenguaje de programación que usa un tipado dinámico cuando la comprobación de tipificación se realiza durante su ejecución en vez de durante la compilación. Ejemplos de lenguajes que usan tipado dinámico son Perl, Python y Lisp. Comparado con el tipado estático, el tipado dinámico es más flexible (debido a las limitaciones teóricas de decidibilidad de los algoritmos de tipado estático causadas por la falta de información durante el chequeo), pero se ejecuta más lentamente y es más propenso a contener errores durante la ejecución.

Tipado estático y dinámico combinados

Algunos lenguajes estáticamente tipados tienen una "puerta trasera" en el lenguaje que permite a los programadores escribir código que no es comprobado 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 durante la ejecución, porque pueden causar comportamientos indeseados cuando el programa se ejecuta. Otros lenguajes de programación como C# utilizan declaraciones de tipos de datos dinámicos en un ambiente estático, permitiendo la flexibilidad casi completa de un lenguaje dinámico en un lenguaje estático.

La presencia de un tipado estático en un lenguaje de programación no implica necesariamente la ausencia de mecanismos de tipado dinámico. Por ejemplo, Java usa tipado estático, pero ciertas operaciones requieren el soporte de test de tipos de datos durante la ejecución, que es una forma de tipado dinámico. Ver lenguaje de programación para una discusión más amplia de la interacción entre tipado 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 contraprestaciones.

El tipado estático busca errores en los tipos de datos durante la 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 tipado estático. El tipado estático aboga por la creencia de que los programas son más fiables cuando son chequeados sus tipos de datos, mientras que el tipado dinámico apunta al código distribuido que se ha probado que es fiable y un conjunto pequeño de errores. El valor del tipado estático, entonces, se incrementa a la par que se endurece el sistema de tipificación. Los defensores de los lenguajes fuertemente tipados 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 tipado 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 tipado 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 tipado estático generaliza este uso. Ver optimización de software

En contraste, el tipado 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 tipados puede resultar en menores comprobaciones y menos código que revisar. Esto también reduce el ciclo editar-compilar-comprobar-depurar.

Lenguajes estáticamente tipados 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. Esto puede hacer la veces de documentación adicional del programa, que el compilador no permitirá que el programador ignore o 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 estático 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 estático, ejecutar código a partir de estructuras de datos de una forma segura.

El tipado dinámico típicamente hace que la metaprogramación sea menos verbosa. Por ejemplo, los genéricos de C++ requiere una escritura más descriptiva que su equivalente en Ruby o Python, precisamente porque es necesario especificar los tipos implicados.[cita requerida]

Controversia

Hay frecuentemente conflictos entre aquellos que prefieren la tipificación fuerte y/o estática y aquellos que se inclinan por la tipificación dinámica, libre o débil. El primer grupo aboga por la detección temprana de errores durante la compilación y el aumento de rendimiento en tiempo de ejecución, mientras que el segundo grupo aboga por los prototipos rápidos que son posibles con un sistema de tipificación dinámico.[2]

Véase también

Referencias

Enlaces externos

Related Articles

Wikiwand AI