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.