¿Pueden los lenguajes estáticos y de tipo dinámico ser vistos como diferentes herramientas para diferentes tipos de trabajos?

9

Sí, se han hecho preguntas similares, pero siempre con el objetivo de descubrir "cuál es mejor".

Lo pregunto porque surgí como desarrollador principalmente en JavaScript y realmente no tengo mucha experiencia escribiendo en lenguajes estáticamente escritos.

A pesar de esto, definitivamente veo valor en aprender C para manejar operaciones exigentes en niveles más bajos de código (lo que supongo que tiene mucho que ver con estático vs dinámico en el nivel del compilador), pero lo que estoy tratando de entender es si hay contextos de proyecto específicos (¿tal vez ciertos tipos de operaciones dinámicas intensivas en datos?) que involucran otras cosas además del rendimiento donde tiene mucho más sentido ir con Java o C # frente a algo como Python.

Erik Reppen
fuente
55
La respuesta es sí". Cada tipo de lenguaje, de hecho cada idioma, tiene sus fortalezas y debilidades, por lo que se adapta mejor a algunas tareas que a otras.
ChrisF
Es interesante que uses C como ejemplo, ya que es el tipo de lenguaje más débilmente tipeado que puedes concebir y aún llamarlo estáticamente tipado. C no es rápido debido al sistema de tipos, las verificaciones de tipos ocurren en tiempo de compilación. C es rápido porque hay pocas o ninguna medida de seguridad y controles para evitar que te dispares en el pie. y porque se compila a binarios nativos.
sara

Respuestas:

10

Sí definitivamente.
La escritura dinámica tiene ventajas definidas en los casos en que desea poder tratar todo como un solo tipo. La serialización / deserialización es uno de los ejemplos clásicos. Esta es la razón por la cual tanta programación web se realiza en lenguajes de secuencias de comandos de tipo dinámico: se adaptan bien a una tarea que implica una gran cantidad de conversión de todo tipo de datos hacia y desde cadenas.

Por otro lado, para la programación de aplicaciones, los lenguajes estáticos funcionan mucho mejor porque tratar de tratar todo como un solo tipo no es un requisito con frecuencia. A menudo desea tener estructuras de datos eficientes con datos representados como sí mismos y que no se conviertan a otros tipos con mucha frecuencia. Esto hace que las características de la escritura dinámica sean un inconveniente en lugar de un beneficio, por lo que las aplicaciones se escriben casi exclusivamente en lenguajes de escritura estática.

Mason Wheeler
fuente
3
@Erik: No estoy seguro de decir eso. Las cosas cambian durante el desarrollo. Los requisitos pueden cambiar, o se da cuenta de que no está implementando un requisito correctamente y que el código debe actualizarse. Poder cambiar una cosa y usar los errores de compilación resultantes para mostrarle dónde encontrar todo lo que necesita ser cambiado proporciona un gran impulso a la conveniencia y la velocidad de desarrollo que pierde en los idiomas donde esa técnica no está disponible. Esa es una de las razones por las que simplemente no ves aplicaciones complicadas desarrolladas en lenguajes dinámicos.
Mason Wheeler
99
@Mason Wheeler: Muy buena respuesta. + 1 Agregaría que la verificación de tipo estático también ayuda a encontrar errores antes al hacer que el compilador verifique la corrección del tipo. Por ejemplo, depuré un programa Ruby de 200 líneas ayer y hubo dos errores relacionados con el tipo que solo pude detectar al ejecutar el programa. No quiero pensar qué sucede en un proyecto de 100000 líneas. Por lo tanto, la escritura dinámica le brinda más flexibilidad, lo cual es bueno en los contextos que ha descrito, al precio que no puede encontrar ciertos errores en el momento de la compilación. Por lo tanto, la tipificación estática no solo está relacionada con la eficiencia, sino también con la corrección.
Giorgio
1
@MasonWheeler Dos años y mucho más C # y Java de lo que pensaba para más tarde, ahora estaría en desacuerdo con un par de cosas. Las aplicaciones web complejas se realizan completamente con lenguajes dinámicos. La compilación frente al tiempo de ejecución no tiene sentido cuando puede realizar cambios que son visibles de inmediato. Y he desarrollado la opinión de que todo el alboroto sobre los tipos tiene mucho más sentido en un lenguaje de procedimiento que en un lenguaje que se supone que es impulsado por OOP, donde los datos no deberían cambiar de manos constantemente en primer lugar.
Erik Reppen
1
@Erik: * wince * Primero, juzgar la escritura estática como un concepto de Java es como juzgar los automóviles como un concepto de Pinto. Y segundo, cualquier cosa donde los cambios puedan ser "visibles de inmediato" no es, por definición, un programa muy complejo, porque incluso con hardware moderno, los programas complejos requieren bastante tiempo para preparar el código, ya sea un compilador o un intérprete ( o un compilador JIT) haciendo la preparación. Incluso las aplicaciones web más impresionantes tienden a ser programas muy simples respaldados por bases de datos muy complejas, lo cual es un asunto completamente diferente.
Mason Wheeler
1
La capacidad de hacer abstracciones complejas es ortogonal a tener un sistema de tipo estático frente a dinámico, y también ortogonal a la velocidad. Existen sistemas de tipo estático que permiten abstracciones increíblemente poderosas (aunque a veces arcanas). Tener cambios que aparecen instantáneamente también es independiente del sistema de tipos: ciertamente puede construir intérpretes para los idiomas tipados estáticamente.
Rufflewind 01 de
4

Desde mi punto de vista, si puede trabajar de forma natural dentro de un lenguaje tipado estáticamente, entonces el tipeo estático es el camino a seguir. En general, el propósito de un sistema de tipos es evitar que realice operaciones con una semántica indefinida, como (string) "hello" + (bool) true. Tener el nivel adicional de seguridad que le impide realizar estas operaciones puede ser una buena manera de evitar errores en su código, incluso sin pruebas unitarias extensas. Es decir, la seguridad de tipos proporciona otro nivel de confianza en la corrección semántica de su código.

Pero los sistemas de tipos son muy difíciles de corregir. Yo no creo que es un sistema de tipo perfecto en la naturaleza en el momento de escribir estas líneas. (Por "sistema de tipo perfecto", me refiero a un sistema de tipo estricto, que no requiere anotaciones de código detallado, que no genera errores de tipo falso positivo, y cuyos errores de tipo son fáciles de entender para el programador). Además, puede será difícil entender los sistemas de tipos realmente buenos que existen. Cuando estaba aprendiendo Haskell, no puedo decirte la cantidad de errores de tipo oscuro que recibí al intentar escribir lo que me pareció (para mí) el código correcto. Por lo general, el código no era realmente correcto (lo cual es un punto a favor del sistema de tipos), pero tomó muchode trabajo para comprender los mensajes de error del compilador, para poder corregir los problemas subyacentes. En los lenguajes OO, puede que eventualmente te encuentres pensando "este argumento debería ser contravariante con el tipo de entrada, no covariante", o (más probablemente) volver a los tipos de letra para escapar de los límites del sistema de tipos. Los sistemas de tipos pueden ser mucho más complicados de lo que piensas.

Por lo que vale, entiendo que la dificultad de encontrar buenos sistemas de tipos es parte de lo que motivó a Gilad Bracha a incluir soporte de sistemas de tipos conectables en Newspeak.

Aidan Cully
fuente
Pruebas de unidades WRT, estoy completamente de acuerdo. Siempre se ve gente que dice "si tiene buenas pruebas unitarias, pueden verificar la corrección de tipo por usted". Eso siempre me recordó cómo Paul Graham (quien cree firmemente que la escritura dinámica siempre es algo bueno) dice que un lenguaje que te hace hacer manualmente el trabajo del compilador porque es un lenguaje defectuoso. Sorta te hace parar y pensar ...
Mason Wheeler
Creo que muchas de las preocupaciones sobre los 'peligros' de los lenguajes escritos dinámicamente no tienen en cuenta cómo escribimos estas cosas. Gran parte de Python y JS se pueden escribir al estilo de la consola. Compilación de tornillos vs. tiempo de ejecución, puedo probarlo ahora mismo y ver qué sucede. Sin embargo, creo que estás en un muy buen punto. Nada me vuelve más loco en el desarrollo web del lado del cliente que cuando todos los proveedores de navegadores supuestamente buenos dan un paso confuso a un código horrible, mientras que IE6 o 7 hace lo inesperado, que es salir mal cuando se supone que debe hacerlo en lugar de simplemente, bueno ... chupando de una manera más típica.
Erik Reppen
Los tipos de discrepancia de @ mason-wheeler son errores trivales, y no es que los lenguajes dinámicos no verifiquen los tipos, sino que solo están en tiempo de ejecución. Según mi experiencia, la mayoría de los lenguajes estáticos tienen el mismo nivel de cobertura de las pruebas unitarias, no pierden ninguna prueba al hacer que el compilador verifique los tipos con anticipación, y los lenguajes dinámicos no tienen que agregar pruebas específicas para verificar los tipos. , el sistema de tiempo de ejecución verifica sus tipos, si su prueba de unidad cubre su método, los detectaría.
jbtule
4

Son herramientas diferentes, pero no es por rendimiento. Se trata de complejidad .

Los lenguajes dinámicos generalmente apuntan a la máxima flexibilidad, y trae falta de validación y una especie de garantía. Entonces, es muy poderoso en programas a pequeña escala, pero se vuelve casi imposible mantener programas a gran escala (complejidad).

Los lenguajes estáticos generalmente apuntan a la máxima validación. Su primer objetivo suele ser detectar errores (o errores) lo antes posible. Se hacen muchas garantías para la validación. Entonces es más difícil de aprender y comenzar, pero a medida que los programas se hacen más grandes, proporciona una mejor validación del programa con mucho menos costo (esfuerzos de codificación).

Como resultado, los lenguajes dinámicos generalmente se ajustan a programas pequeños (me refiero a muy pequeños) como páginas web dinámicas, DSL de navegador web (¡no para aplicaciones de navegador!) O scripts de shell. Los lenguajes estáticos se adaptan mejor a las programaciones del sistema o cualquier otra cosa.

Las descripciones anteriores son algo sobre lenguajes muy puramente dinámicos o estáticos. La mayoría de los lenguajes de la vida real se encuentran entre ellos y muestra varias características.

Consulte aquí para obtener más detalles: https://softwareengineering.stackexchange.com/a/105417/17428

Eonil
fuente
1
"los lenguajes dinámicos generalmente se ajustan a programas pequeños (quiero decir, muy pequeños)": en mi experiencia, puede usar lenguajes dinámicos también para aplicaciones de tamaño medio (y, por supuesto, hay personas que los usan con éxito para aplicaciones grandes). Estoy de acuerdo en que cuanto más grande sea la base del código, más podrá beneficiarse de las comprobaciones estáticas proporcionadas por lenguajes estáticos.
Giorgio
2
@Giorgio Bueno, eso es quizás porque soy adicto a las cosas de validación estática. Es muy dulce para mí, y literalmente no puedo vivir sin ellos, incluso a pequeña escala: p
Eonil
Veo las ventajas de los lenguajes estáticos (y he votado tu respuesta). Recientemente he estado usando Python y Common Lisp y admito que en la práctica obtienes buenos resultados si usas un diseño limpio y, especialmente en Python, si escribes suficientes pruebas. Estos lenguajes pueden ser muy efectivos para construir un prototipo que luego pueda convertirse fácilmente en su código de producción. Pero sí, para los proyectos más complejos me gustaría tener tanta ayuda como sea posible, así que prefiero un lenguaje estático.
Giorgio
1

Actualmente programo en lenguajes de tipo estático (C # y F #), pero disfruto programando en lenguajes dinámicos (Smalltalk, Ruby). Hay muchas ventajas y desventajas que las personas asocian con un tipo frente a otro que tienen más que ver con el idioma que cuando se imponen los tipos. Por ejemplo, los lenguajes dinámicos generalmente tienen una sintaxis más limpia y concisa, sin embargo, F # y OCaml con su sistema de inferencia de tipos tienen una sintaxis tan limpia como cualquier lenguaje dinámico. Y con la escritura estática, tiene refactorizaciones automáticas reales y autocompletado, pero Smalltalk, con todo el código fuente en una base de datos y cada método compilado por separado, fue el primer idioma en tener refactorizaciones automáticas serias, y funcionó muy bien. En última instancia, los lenguajes dinámicos y estáticos modernos de hoy en día son de tipo seguro, que es el aspecto más importante de su sistema de tipos,

jbtule
fuente
A veces sospeché que la escritura estática es solo una pequeña parte de la ecuación de lo que hace que un lenguaje sea más o menos flexible. Creo que de lo que también estoy empezando a darme cuenta es que muchos desarrolladores prefieren un conjunto de rieles cómodos para guiarlos en lugar de tener un reinado libre para hacer cosas absurdamente peligrosas como sobrecargar a los operadores. VS me da ganas de patear cachorros a veces, pero definitivamente tengo curiosidad por F # y lo que dijiste al respecto me tiene aún más curiosidad. Supongo que esto es algo más que solo la cosa de C # donde puedes convertir a un tipo más inclusivo implícitamente.
Erik Reppen
@erik, Oh sí, más que tipeo implícito y var: Inferencia de tipo F #
jbtule
-1

Ahora es 2015, lo que agrega algunos fragmentos interesantes a la conversación:

  1. Partes importantes del mundo del backend empresarial están considerando o comenzando a usar Python (dinámico) en lugar de Java (estático estricto)
  2. El mundo frontend empresarial está viendo cosas como AngularJS v2, basado en TypeScipt: una extensión escrita de Javascript.

Por lo tanto, los chicos del backend están cansados ​​de la camisa de fuerza innecesaria de la escritura estricta, mientras que los chicos de la interfaz están cansados ​​del caos de la escritura dinámica.

Muy irónico: me pregunto si se encontrarán en el medio, o se cruzarán con el estallido sónico de una fecha límite que pasa ... ;)

Cornel Masson
fuente
A menos que proporcione alguna prueba, yo afirmaría que en el peor de los casos, el mundo del backend está haciendo la transición a Go, pero Dios no lo permita. El mito de que un lenguaje de programación estático siempre tiene mucha ceremonia ha sido desmentido durante mucho tiempo con sistemas de inferencia más potentes e implementaciones REPL sólidas
Den
Hay muchos backeps dinámicamente escritos en uso a grandes escalas. Django, en particular, es muy popular en el periodismo y dirige los back-end del NYT, The Guardian y el Washington Post. Walmart se está ejecutando en Node. El único mito es la idea de que no se puede escribir para escalar sin tipos estáticos. Y después de haber pasado un tiempo pensando en algunos desastres de bases de código heredados de Java con los que me he encontrado, creo que las personas que se sienten cómodas al hacerlo están mejor si trabajan con estática o dinámica.
Erik Reppen
De hecho, prefiero tener un equipo experto de Python en mi proyecto de gran empresa, en lugar de uno pobre de Java. Solo para aclarar mi posición: publiqué la respuesta anterior como una evaluación de
Cornel Masson
De hecho, prefiero tener un equipo calificado de Python en mi proyecto de gran empresa, que uno pobre de Java. Solo para aclarar: publiqué la respuesta anterior como una observación sobre las tendencias que estoy viendo en mi base de clientes, red industrial e investigación general. El backend tradicionalmente estricto abarca menos rigor, la interfaz tradicionalmente más flexible, más. Ni siquiera es una opinión sobre cuál es "correcto" (si lo hay), no estoy seguro de por qué me votaron negativamente. Quizás la ironía se haya perdido ...
Cornel Masson