¿Cuál es la diferencia entre lenguajes de tipo estático y de tipo dinámico?
¿Qué significa cuando decimos que un lenguaje se escribe dinámicamente versus estáticamente?
Idiomas escritos estáticamente
Un lenguaje se escribe estáticamente si el tipo de una variable se conoce en el momento de la compilación. Para algunos lenguajes, esto significa que usted, como programador, debe especificar de qué tipo es cada variable; Otros lenguajes (por ejemplo: Java, C, C++) ofrecen alguna forma de inferencia de tipos , la capacidad del sistema de tipos para deducir el tipo de una variable (por ejemplo: OCaml, Haskell, Scala, Kotlin).
La principal ventaja aquí es que el compilador puede realizar todo tipo de comprobaciones y, por lo tanto, muchos errores triviales se detectan en una etapa muy temprana.
Ejemplos: C, C++, Java, Rust, Go, Scala
Idiomas escritos dinámicamente
Un lenguaje se escribe dinámicamente si el tipo está asociado con valores en tiempo de ejecución y no con variables/campos/etc. Esto significa que usted, como programador, puede escribir un poco más rápido porque no tiene que especificar tipos cada vez (a menos que utilice un lenguaje de tipado estático con inferencia de tipos ).
Ejemplos: Perl, Ruby, Python, PHP, JavaScript, Erlang
La mayoría de los lenguajes de secuencias de comandos tienen esta característica, ya que de todos modos no existe un compilador que realice una verificación de tipos estática, pero es posible que se encuentre buscando un error debido a que el intérprete malinterpreta el tipo de una variable. Afortunadamente, los scripts tienden a ser pequeños, por lo que los errores no tienen tantos lugares donde esconderse.
La mayoría de los lenguajes de escritura dinámica le permiten proporcionar información de tipo, pero no la requieren. Un lenguaje que se está desarrollando actualmente, Rascal , adopta un enfoque híbrido que permite la escritura dinámica dentro de funciones pero impone la escritura estática para la firma de la función.
La verificación de tipos es el proceso de verificar y hacer cumplir las restricciones de los tipos.
Los lenguajes de programación de tipo estático verifican los tipos en tiempo de compilación .
Ejemplos: Java, C, C++.Los lenguajes de programación tipados dinámicamente verifican los tipos en tiempo de ejecución .
Ejemplos: Perl, Ruby, Python, PHP, JavaScript.
Aquí hay un ejemplo que contrasta cómo Python (escrito dinámicamente) y Go (escrito estáticamente) manejan un error de tipo:
def silly(a):
if a > 0:
print 'Hi'
else:
print 5 + '3'
Python realiza verificación de tipos en tiempo de ejecución y, por lo tanto:
silly(2)
Funciona perfectamente bien y produce el resultado esperado Hi
. El error solo aparece si se llega a la línea problemática:
silly(-1)
produce
TypeError: unsupported operand type(s) for +: 'int' and 'str'
porque la línea relevante fue realmente ejecutada.
Por otro lado, Go realiza una verificación de tipos en tiempo de compilación:
package main
import ("fmt"
)
func silly(a int) {
if (a > 0) {
fmt.Println("Hi")
} else {
fmt.Println("3" + 5)
}
}
func main() {
silly(2)
}
Lo anterior no se compilará, con el siguiente error:
invalid operation: "3" + 5 (mismatched types string and int)