Sistemas de tipos: nominal versus estructural, explícito versus implícito


24

Estoy un poco confundido acerca de la diferencia entre los sistemas de tipo nominal y estructural. ¿Alguien puede explicar cómo difieren?

Por lo que entiendo:

  • Nominal: la compatibilidad de tipos se basa en el nombre del tipo.
  • Estructural: la compatibilidad de tipos se basa en la estructura de tipos, por ejemplo, en C si 2 variables son tipos de estructura con nombres diferentes pero con la misma estructura, entonces sus tipos son compatibles.

Ahora sobre explícito e implícito: ¿por qué es diferente del tipeo estático y dinámico? En la escritura estática, los tipos serán explícitos, mientras que en la escritura dinámica, los tipos son implícitos. Estoy en lo cierto?

Respuestas:


29

En un sistema de tipo dinámico, los valores tienen tipos en tiempo de ejecución pero las variables y funciones no. En un sistema de tipo estático, las variables y funciones tienen tipos conocidos y verificados en tiempo de compilación. Por ejemplo, en Python xpuede ser cualquier cosa ; en tiempo de ejecución, si es 1un número y si lo es "foo", es una cadena. Solo sabría qué tipo xestaba en tiempo de ejecución, y podría ser diferente cada vez que ejecutara el programa. En un lenguaje como Java, escribirías int xsi xfuera un número, y sabrías en tiempo de compilación que xsiempre tiene que ser un int.

Los tipos "explícito" e "implícito" se refieren a sistemas de tipo estático . La característica definitoria de un sistema estático es que los tipos se conocen en tiempo de compilación, pero no necesariamente que deben escribirse. En Java, los tipos son explícitos: debe escribirlos. Entonces, en Java, un método podría verse así:

public int foo(String bar, Object baz) { ... }

Los tipos son conocidos en tiempo de compilación (estático) y escritos (explícitos). Sin embargo, también hay idiomas que no te obligan a escribir el tipo. Pueden inferir el tipo de una función de su cuerpo y cómo se usa. Un ejemplo sería OCaml, donde puede escribir algo como:

let foo x = x + 1

Desde que lo usó +, OCaml puede descubrir que xtiene que ser un inttodo por sí mismo. Entonces, el tipo de foo( foo : int -> int) se conoce en tiempo de compilación, al igual que el ejemplo de Java. Es completamente estático. Sin embargo, dado que el compilador puede descubrir cuáles son los tipos por sí mismos, no tiene que escribirlos usted mismo: son implícitos.

En resumen: si un sistema de tipos es explícito o implícito es una propiedad de los sistemas estáticos . Es una pregunta completamente diferente de si un sistema de tipos es dinámico o estático.

A menudo, tiene sistemas de tipos que a veces son explícitos y a veces implícitos.

Por ejemplo, creo que C # le permite inferir tipos usando la varpalabra clave. Entonces, en lugar de escribir int x = 10, puedes escribir var x = 10y el compilador descubre que xtiene que ser un int. C ++ hace algo similar con auto. Estos sistemas suelen ser explícitos pero tienen alguna inferencia.

Por otro lado, hay sistemas que generalmente son implícitos pero a veces lo obligan a escribir una firma de tipo. Haskell es un gran ejemplo. La mayoría de las veces, Haskell puede inferir los tipos por ti. Sin embargo, a veces puede escribir código que es ambiguo show . read, como Haskell no puede resolver los tipos por sí solo. En este caso, se vería obligado a especificar explícitamente el tipo de showo read. Además, algunas características más avanzadas del sistema de tipos (como el polimorfismo de rango n) hacen que la inferencia sea indecidible, es decir, no se garantiza que se detenga. Esto significa que el código que usa esta función a menudo necesita firmas de tipo explícitas.


2
En realidad, hay algunos idiomas con lo que podría llamarse escritura dinámica explícita . Típicamente, esos idiomas le permiten anotar expresiones con tipos, y luego esos tipos serán verificados en tiempo de ejecución contra el tipo de tiempo de ejecución de la expresión.
Jörg W Mittag el

solo una precisión: los sistemas de tipos no son implícitos ni explícitos. Esto es solo acerca de la inferencia de tipos, que es esencialmente una forma de generar términos válidos en un sistema de tipos a partir de una sintaxis diferente (a veces no especificada).
Eduardo Pareja Tobes

Buena respuesta, pero esto no aborda la tipificación nominal vs estructural. Una edición sería genial.
lunchmeat317

7
  • static vs dynamic describe cuándo se verifican los tipos (más o menos en tiempo de compilación o en tiempo de ejecución)

  • nominal vs estructural describe cuando dos tipos se consideran iguales.

(Y hay variaciones, la más conocida es la variante de tipificación estructural que considera solo lo que se usa en lugar del tipo completo conocido como tipificación de pato).

Las cuatro combinaciones (estática nominal, estática estructural, dinámica nominal, dinámica estructural) son posibles, y los lenguajes a menudo no son puramente de una clase sino que tienen aspectos que están en otras.

Por ejemplo, los sistemas de tipos de C ++ son estáticos, en su mayoría nominales pero estructurales cuando considera las plantillas (y puede considerar parte de los problemas en torno a los conceptos en C ++ como un conflicto entre aquellos que desean pasar de escribir pato a una forma completa de escribir estructural y aquellos que quieran ir a mecanografía nominal). Y el uso de clases y herencia permite utilizar una tipificación dinámica y nominal en algunos casos.

Lenguaje con el que los sistemas de tipos dinámicos suelen utilizar la tipificación estructural, pero CLOS como aspectos nominales.


1

Estructural: la compatibilidad de tipos se basa en la estructura de tipos, por ejemplo, en C si 2 variables son tipos de estructura con nombres diferentes pero con la misma estructura, entonces sus tipos son compatibles.

Usualmente este no es el caso. La tipificación estructural significa que Bes un subtipo de Asi puede satisfacer Ala interfaz. Esto generalmente significa tener miembros con el mismo nombre; no solo la misma estructura en la memoria.

Esto difiere de la tipificación nominativa que requiere que se especifiquen supertipos en la declaración.


1

La mejor explicación que he visto de la distinción entre (en realidad subsunción de) sistemas de tipo dinámico y estático está en esta publicación de blog de Bob Harper:

Su punto principal podría resumirse como:

  • Los lenguajes dinámicos son aquellos estáticos con un solo tipo.

1
Los enlaces pueden ir mal; Debes citar los fragmentos más relevantes del artículo para que se conserven para la posteridad, incluso si el blog no funciona.
Doval

2
Seguro. Creo que en este caso la frase que agregué es suficiente :)
Eduardo Pareja Tobes
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.