Lenguajes de tipo dinámico versus lenguajes de tipo estático


¿Cuáles son las ventajas y limitaciones de los lenguajes de tipo dinámico en comparación con los lenguajes de tipo estático?

Véase también: ¿qué pasa con el amor de los lenguajes dinámicos (un hilo mucho más argumentativo...)

Author: Community, 2008-09-24

9 answers

La capacidad del intérprete para deducir conversiones de tipo y tipo hace que el tiempo de desarrollo sea más rápido, pero también puede provocar errores de tiempo de ejecución que simplemente no puede obtener en un lenguaje de tipo estático donde los captura en tiempo de compilación. Pero cuál es mejor (o incluso si eso siempre es cierto) se discute acaloradamente en la comunidad en estos días (y desde hace mucho tiempo).

Una buena toma del tema es de Mecanografía Estática Donde Sea Posible, Mecanografía Dinámica Cuando sea necesario: El Fin de la Guerra Fría Entre lenguajes de programación por Erik Meijer y Peter Drayton en Microsoft:

Los defensores de la tipificación estática argumentan que las ventajas de la tipificación estática incluir la detección temprana de errores de programación (por ejemplo, prevención añadir un entero a un booleano), mejor documentación en forma de firmas de tipo (por ejemplo, incorporando número y tipos de argumentos cuando resolución de nombres), más oportunidades para optimizaciones de compiladores (p. ej. sustitución de llamadas virtuales por directo llamadas cuando el tipo exacto de la el receptor se conoce estáticamente), mayor eficiencia en el tiempo de ejecución (por ejemplo, no todos los valores deben llevar una dinámica tipo), y un mejor tiempo de diseño experiencia del desarrollador (por ejemplo, conocer tipo del receptor, el IDE puede presentar un menú desplegable de todos miembros aplicables). Tipificación estática los fanáticos tratan de hacernos creer que "well-typed programs cannot go wrong" (en inglés). Mientras que esto ciertamente suena impresionante, es una vacua instrucción. La comprobación de tipo estático es un abstracción en tiempo de compilación del comportamiento en tiempo de ejecución de su programa, y por lo tanto, es necesariamente solo parcialmente sonido e incompleto. Esto significa que los programas todavía pueden salir mal debido a propiedades que no son rastreadas por el comprobador de tipo, y que hay programas que mientras no pueden ir wrong no se puede comprobar. El impulso para hacer menos escritura estática causas parciales y más completas tipo los sistemas se vuelven demasiado complicados y exótico como atestiguado por conceptos tales como "tipos fantasma" [11] y "tipos tambaleantes" [10]. Esto es como tratando de correr un maratón con una pelota y la cadena atada a tu pierna y gritando triunfalmente que casi hecho a pesar de que los rescató después de la primera milla.

Defensores de dinámicamente tipeado idiomas argumentan que la escritura estática es demasiado rígido, y que la suavidad de dinámicamente lenguajes los hace ideal para sistemas de prototipado con cambio o requisitos desconocidos, o que interactúan con otros sistemas que cambian de forma impredecible (datos y integración de aplicaciones). Por supuesto, los idiomas dinámicamente tipeados son indispensable para tratar con verdad comportamiento dinámico del programa como método interceptación, carga dinámica, código móvil, reflexión en tiempo de ejecución, etc. En la madre de todos los papeles en scripting [16], John Ousterhout argumenta que sistemas estáticamente tipeados los lenguajes de programación hacen que el código sea menos reutilizable, más detallado, no más seguro, y menos expresiva que dinámicamente lenguajes de scripting mecanografiados. Este argumento es repetido literalmente por muchos los defensores de dinámicamente tipado lenguajes de scripting. Argumentamos que esto es una falacia y cae en el misma categoría que el argumento de que el la esencia de la programación declarativa es eliminando la asignación. O como John Hughes dice [8], es una lógica imposibilidad de hacer un idioma más potente al omitir funciones. Defender el hecho de que retrasar todo la comprobación de tipo al tiempo de ejecución es una buena cosa, está jugando tácticas de avestruz con el hecho de que los errores deben ser capturados tan temprano en el proceso de desarrollo como posible.

 136
Author: Vinko Vrsalovic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-04 15:18:23

Los sistemas de tipo estático buscan eliminar ciertos errores estáticamente, inspeccionando el programa sin ejecutarlo e intentando probar su solidez en ciertos aspectos. Algunos sistemas son capaces de detectar más errores que otros. Por ejemplo, C# puede eliminar excepciones de puntero nulo cuando se usa correctamente, mientras que Java no tiene tal poder. Twelf tiene un sistema de tipos que en realidad garantiza que las pruebas terminarán, "resolviendo" el problema de detención .

Sin embargo, ningún tipo el sistema es perfecto. Con el fin de eliminar una clase particular de errores, también deben rechazar ciertos programas perfectamente válidos que violan las reglas. Esta es la razón por la que Twelf realmente no resuelve el problema de la detención, solo lo evita lanzando un gran número de pruebas perfectamente válidas que terminan de manera extraña. Del mismo modo, el sistema de tipos de Java rechaza la implementación de Clojure PersistentVector debido a su uso de arrays heterogéneos. Funciona en tiempo de ejecución, pero el sistema de tipos no puede verificar se.

Por esa razón, la mayoría de los sistemas de tipos proporcionan "escapes", formas de anular el comprobador estático. Para la mayoría de los lenguajes, estos toman la forma de casting, aunque algunos (como C# y Haskell) tienen modos completos que están marcados como "inseguros".

Subjetivamente, me gusta la escritura estática. Implementado correctamente (sugerencia: no Java), un sistema de tipo estático puede ser una gran ayuda para eliminar errores antes de que se bloqueen el sistema de producción. Los lenguajes tipeados dinámicamente tienden a requerir más unidad probando, que es tedioso en el mejor de los casos. Además, los lenguajes de tipo estático pueden tener ciertas características que son imposibles o inseguras en sistemas de tipo dinámico (vienen a la mente conversiones implícitas). Todo es una cuestión de requisitos y gusto subjetivo. No construiría el próximo Eclipse en Ruby más de lo que intentaría escribir un script de respaldo en Assembly o parchear un kernel usando Java.

Oh, y la gente que dice que " x escribir es 10 veces más productive than y typing" are simply blowing smoke. La escritura dinámica puede "sentirse" más rápido en muchos casos, pero pierde terreno una vez que realmente intenta hacer que su aplicación de fantasía ejecute. Del mismo modo, la tipografía estática puede parecer la red de seguridad perfecta, pero un vistazo a algunas de las definiciones de tipos genéricos más complicadas en Java envía a la mayoría de los desarrolladores a buscar anteojeras. Incluso con los sistemas de tipos y la productividad, no hay una bala de plata.

Nota final: no preocúpese por el rendimiento al comparar la escritura estática con la dinámica. JITs modernos como V8 y TraceMonkey están llegando peligrosamente-cerca de rendimiento de lenguaje estático. Además, el hecho de que Java en realidad compila un lenguaje intermedio inherentemente dinámico debería ser una pista de que para la mayoría de los casos, la escritura dinámica no es el gran asesino de rendimiento que algunas personas hacen que sea.

 118
Author: Daniel Spiewak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-29 22:08:27

Bueno, ambos son muy, muy, muy mal entendidos y también dos cosas completamente diferentes. que no son mutuamente excluyentes.

Los tipos estáticos son una restricción de la gramática del idioma. Se podría decir que las lenguas de tipo estático estrictamente no están libres de contexto. La simple verdad es que se vuelve inconveniente expresar un lenguaje sanamente en gramáticas libres de contexto que no tratan todos sus datos simplemente como vectores de bits. Los sistemas de tipos estáticos son parte de la gramática de el lenguaje, si lo hay, simplemente lo restringen más de lo que una gramática libre de contexto podría, las comprobaciones gramaticales por lo tanto ocurren en dos pasadas sobre la fuente realmente. Los tipos estáticos corresponden a la noción matemática de la teoría de tipos, la teoría de tipos en matemáticas simplemente restringe la legalidad de algunas expresiones. Como, no puedo decir 3 + [4,7] en matemáticas, esto es debido a la teoría de tipos de la misma.

Por lo tanto, los tipos estáticos no son una forma de 'prevenir errores' desde una perspectiva teórica, son una limitación de gramatical. De hecho, siempre que+, 3 e intervalos tengan las definiciones teóricas de conjuntos habituales, si eliminamos el tipo system 3 + [4,7] tiene un resultado bastante bien definido que es un conjunto. los' errores de tipo de tiempo de ejecución ' teóricamente no existen, el uso práctico del sistema de tipos es evitar operaciones que para los seres humanos no tendrían sentido. Las operaciones siguen siendo solo el desplazamiento y la manipulación de bits, por supuesto.

El problema es que un sistema de tipos no puede decidir si tal las operaciones van a ocurrir o no si se permite que se ejecute. Al igual que en, particionar exactamente el conjunto de todos los programas posibles en aquellos que van a tener un 'error de tipo', y los que no lo son. Puede hacer solo dos cosas:

1: demostrar que los errores de tipo van a ocurrir en un programa
2: demostrar que no van a ocurrir en un programa

Esto podría parecer que me estoy contradiciendo a mí mismo. Pero lo que hace un comprobador de tipo C o Java es rechazar un programa como 'no gramatical', o como lo llama 'error de tipo' si no puede tener éxito en 2. No puede probar que no van a ocurrir, eso no significa que no van a ocurrir, solo significa que no puede probarlo. Podría muy bien ser que un programa que no tenga un error de tipo sea rechazado simplemente porque no puede ser probado por el compilador. Un ejemplo simple es if(1) a = 3; else a = "string";, seguramente ya que siempre es cierto, la rama else nunca se ejecutará en el programa, y no se producirá ningún error de tipo. Pero no puede probar estos casos de una manera general, por lo que es rechazado. Esta es la mayor debilidad de muchos lenguajes estáticamente tipeados, al protegerte contra ti mismo, también estás necesariamente protegido en casos en los que no lo necesitas.

Pero, contrariamente a la creencia popular, también hay lenguajes tipeados estáticamente que funcionan según el principio 1. Simplemente rechazan todos los programas de los que pueden probar que va a causar un error de tipo, y pasan todos los programas de los que no pueden. que tienen errores de tipo en ellos, un buen ejemplo es Tiped Racket, es híbrido entre escritura dinámica y estática. Y algunos argumentarían que se obtiene lo mejor de ambos mundos en este sistema.

Otra ventaja de la tipificación estática es que los tipos se conocen en tiempo de compilación, y por lo tanto el compilador puede usar esto. Si en Java hacemos "string" + "string" o 3 + 3, ambos + tokens en texto al final representan una operación y un dato completamente diferentes, el compilador sabe cuál elegir entre los tipos solo.

Ahora, voy a hacer una declaración muy controvertida aquí, pero tengan paciencia conmigo: 'escritura dinámica' no existe.

Suena muy controvertido, pero es cierto, se escribe dinámicamente idiomas son desde una perspectiva teórica tipo. Solo son lenguajes tipeados estáticamente con un solo tipo. O simplemente, son idiomas que de hecho son generados gramaticalmente por una gramática libre de contexto en la práctica.

¿Por qué no tienen tipos? Debido a que cada operación está definida y permitida en cada operante, ¿qué es un 'error de tipo de tiempo de ejecución' exactamente? Es de un ejemplo teórico puramente un efecto secundario. Si hacer print("string") que imprime una cadena es una operación, entonces también lo es length(3), la primera tiene el efecto secundario de escribir string a la salida estándar, la segunda simplemente error: function 'length' expects array as argument., eso es todo. Desde una perspectiva teórica no hay tal cosa como un lenguaje dinámicamente tipeado. Están sin tipo

Muy bien, el la ventaja obvia del lenguaje 'dinámicamente tipado' es el poder expresivo, un sistema de tipos no es más que una limitación del poder expresivo. Y en general, los lenguajes con un sistema de tipos de hecho tendrían un resultado definido para todas esas operaciones que no están permitidas si el sistema de tipos se ignorara, los resultados simplemente no tendrían sentido para los humanos. Muchos idiomas pierden su integridad Turing después de aplicar un sistema de tipos.

La desventaja obvia es el hecho de que las operaciones pueden ocurrir lo que produciría resultados que no tienen sentido para los humanos. Para evitar esto, los lenguajes tipeados dinámicamente típicamente redefinen esas operaciones, en lugar de producir ese resultado sin sentido, lo redefinen para tener el efecto secundario de escribir un error, y posiblemente detener el programa por completo. Esto no es un 'error' en absoluto, de hecho, la especificación del lenguaje generalmente implica esto, esto es tanto comportamiento del lenguaje como imprimir una cadena desde una perspectiva teórica. Tipo por lo tanto, los sistemas obligan al programador a razonar sobre el flujo del código para asegurarse de que esto no suceda. O de hecho, reason so that it does happen también puede ser útil en algunos puntos para la depuración, mostrando que no es un 'error' en absoluto, sino una propiedad bien definida del lenguaje. En efecto, el único remanente de 'escritura dinámica' que la mayoría de los idiomas tienen está protegiendo contra una división por cero. Esto es lo que es la tipificación dinámica, no hay tipos, no hay más tipos que eso cero es un tipo diferente que todos los otros números. Lo que la gente llama un 'tipo' es solo otra propiedad de un dato, como la longitud de un array, o el primer carácter de una cadena. Y muchos lenguajes dinámicamente escritos también te permiten escribir cosas como "error: the first character of this string should be a 'z'".

Otra cosa es que los lenguajes dinámicamente tipeados tienen el tipo disponible en tiempo de ejecución y generalmente pueden comprobarlo y tratar con él y decidir a partir de él. Por supuesto, en teoría no es diferente de acceder al primer char de una matriz y ver lo que es. De hecho, puede hacer su propia C dinámica, solo use un solo tipo como long long int y use los primeros 8 bits para almacenar su 'tipo' y escribir funciones en consecuencia que lo comprueben y realicen una adición flotante o entera. Tiene un lenguaje estáticamente escrito con un tipo, o un lenguaje dinámico.

En la práctica, todo esto muestra que los lenguajes de tipo estático se utilizan generalmente en el contexto de la escritura de software comercial, mientras que los de tipo dinámico los idiomas tienden a ser utilizados en el contexto de la solución de algunos problemas y la automatización de algunas tareas. Escribir código en lenguajes tipeados estáticamente simplemente toma mucho tiempo y es engorroso porque no puedes hacer cosas que sabes que van a salir bien, pero el sistema de tipos aún te protege contra ti mismo por errores que no cometes. Muchos codificadores ni siquiera se dan cuenta de que lo hacen porque está en su sistema, pero cuando se codifica en lenguajes estáticos, a menudo se evita el hecho de que el sistema de tipos no te dejará hacer cosas que no pueden salir mal, porque no puede probar que no salgan mal.

Como señalé, 'tipeado estáticamente' en general significa caso 2, culpable hasta que se demuestre su inocencia. Pero algunos lenguajes, que no derivan su sistema de tipos de la teoría de tipos en absoluto usan la regla 1: Inocente hasta que se demuestre lo contrario, que podría ser el híbrido ideal. Así que, tal vez Tiped Racket es para ti.

También, bueno, para un ejemplo más absurdo y extremo, actualmente estoy implementando un lenguaje donde los' tipos ' son verdaderamente el primer carácter de una matriz, son datos, datos del 'tipo', 'tipo', que es en sí mismo un tipo y datum, el único datum que tiene a sí mismo como un tipo. Los tipos no son finitos o limitados estáticamente, pero se pueden generar nuevos tipos basados en información de tiempo de ejecución.

 44
Author: Zorf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-29 17:33:33

Quizás el mayor "beneficio" de la escritura dinámica es la curva de aprendizaje más superficial. No hay un sistema de tipos que aprender ni una sintaxis no trivial para casos de esquina, como las restricciones de tipo. Eso hace que la escritura dinámica sea accesible a muchas más personas y factible para muchas personas para quienes los sofisticados sistemas de tipos estáticos están fuera de su alcance. En consecuencia, la tipificación dinámica se ha popularizado en contextos de educación (por ejemplo, Scheme / Python en el MIT) y lenguajes específicos de dominio para no programadores (por ejemplo, Mathematica). Los lenguajes dinámicos también se han popularizado en nichos donde tienen poca o ninguna competencia (por ejemplo, Javascript).

Los lenguajes de tipo dinámico más concisos (por ejemplo, Perl, APL, J, K, Mathematica) son específicos de dominio y pueden ser significativamente más concisos que los lenguajes de tipo estático de propósito general más concisos (por ejemplo, OCaml) en los nichos para los que fueron diseñados.

Las principales desventajas de la tipificación dinámica son:

  • Errores de tipo en tiempo de ejecución.

  • Puede ser muy difícil o incluso prácticamente imposible lograr el mismo nivel de corrección y requiere mucho más pruebas.

  • No hay documentación verificada por el compilador.

  • Rendimiento deficiente (generalmente en tiempo de ejecución, pero a veces en tiempo de compilación, por ejemplo, Stalin Scheme) y rendimiento impredecible debido a la dependencia de optimizaciones sofisticadas.

Personalmente, creció en lenguajes dinámicos, pero no los tocaría con un polo de 40' como profesional a menos que no hubiera otras opciones viables.

 23
Author: Jon Harrop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-19 18:09:37

De Artima Tipeo: Fuerte vs. Débil, Estático vs. Dinámico artículo:

La tipificación fuerte evita las operaciones de mezcla entre tipos no coincidentes. Para mezclar tipos, debe usar una conversión explícita

La tipificación débil significa que puede mezclar tipos sin una conversión explícita

En el documento de Pascal Costanza, Tipificación Dinámica vs. Estática-Un Análisis Basado en Patrones (PDF), afirma que en algunos casos, estática la escritura es más propensa a errores que la escritura dinámica. Algunos lenguajes de escritura estática te obligan a emular manualmente la escritura dinámica para hacer "Lo correcto". Se discute en Lambda el Último .

 11
Author: Mark Cidade,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-01 14:06:15

Depende del contexto. Hay muchos beneficios que son apropiados para el sistema de tipo dinámico, así como para el tipo fuerte. Soy de la opinión de que el flujo de lenguaje de tipos dinámicos es más rápido. Los lenguajes dinámicos no están restringidos con atributos de clase y el compilador pensando en lo que está sucediendo en el código. Tienes algo de libertad. Además, el lenguaje dinámico generalmente es más expresivo y resulta en menos código, lo cual es bueno. A pesar de esto, es más propenso a errores que también es cuestionable y depende más de la cobertura de la prueba unitaria. Es un prototipo fácil con lang dinámico, pero el mantenimiento puede convertirse en una pesadilla.

La principal ganancia sobre el sistema de tipo estático es el soporte IDE y seguramente el analizador estático de código. Te vuelves más seguro del código después de cada cambio de código. El mantenimiento es la paz de la torta con tales herramientas.

 2
Author: AndrewG,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-30 21:47:27

Hay muchas cosas diferentes acerca de los lenguajes estáticos y dinámicos. Para mí, la principal diferencia es que en los lenguajes dinámicos las variables no tienen tipos fijos; en cambio, los tipos están vinculados a valores. Debido a esto, el código exacto que se ejecuta es indeterminado hasta el tiempo de ejecución.

En implementaciones tempranas o ingenuas, esto es un gran arrastre de rendimiento, pero los JITs modernos se acercan tentadoramente a lo mejor que puede obtener con la optimización de compiladores estáticos. (en algunos casos marginales, incluso mejor que eso).

 0
Author: Javier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-24 04:34:15

Se trata de la herramienta adecuada para el trabajo. Tampoco es mejor el 100% del tiempo. Ambos sistemas fueron creados por el hombre y tienen defectos. Lo siento, pero apestamos y hacemos cosas perfectas.

Me gusta la escritura dinámica porque se sale de mi camino, pero sí los errores de tiempo de ejecución pueden arrastrarse que no planeé. Donde como la escritura estática puede corregir los errores antes mencionados, pero conducir a un programador novato(en lenguajes tipeados) loco tratando de convertir entre un char constante y una cadena.

 0
Author: J.J.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-24 05:47:49

Tipificación estática: Los lenguajes como Java y Scala son de tipo estático.

Las variables tienen que ser definidas e inicializadas antes de ser usadas en un código.

Para ex. int x; x = 10;

Sistema.fuera.println (x);

Tipificación dinámica: Perl es un lenguaje de escritura dinámico.

No es necesario inicializar las variables antes de que se utilicen en el código.

Y = 10; utilice esta variable en la parte posterior del código

 -3
Author: Prakhyat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-27 07:12:52