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 x
puede ser cualquier cosa ; en tiempo de ejecución, si es 1
un número y si lo es "foo"
, es una cadena. Solo sabría qué tipo x
estaba en tiempo de ejecución, y podría ser diferente cada vez que ejecutara el programa. En un lenguaje como Java, escribirías int x
si x
fuera un número, y sabrías en tiempo de compilación que x
siempre 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 x
tiene que ser un int
todo 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 var
palabra clave. Entonces, en lugar de escribir int x = 10
, puedes escribir var x = 10
y el compilador descubre que x
tiene 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 show
o 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.
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.
fuente
Usualmente este no es el caso. La tipificación estructural significa que
B
es un subtipo deA
si puede satisfacerA
la 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.
fuente
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:
fuente