¿Cuál es la supuesta ganancia de productividad del tipeo dinámico? [cerrado]

82

A menudo escuché la afirmación de que los idiomas escritos dinámicamente son más productivos que los idiomas escritos estáticamente. ¿Cuáles son las razones de este reclamo? ¿No se trata solo de herramientas con conceptos modernos como la convención sobre la configuración, el uso de programación funcional, modelos de programación avanzados y el uso de abstracciones consistentes? Es cierto que hay menos desorden porque las declaraciones de tipo (por ejemplo, en Java) a menudo redundantes no son necesarias, pero también puede omitir la mayoría de las declaraciones de tipo en lenguajes estáticamente tipados que usan inferencia de tipos, sin perder las otras ventajas del tipeo estático. Y todo esto también está disponible para los idiomas modernos de tipo estático como Scala.

Entonces: ¿qué hay para decir sobre la productividad con la tipificación dinámica que realmente es una ventaja del modelo de tipo en sí?

Aclaración: estoy más interesado en proyectos grandes / medianos que en hacks rápidos. :-)

Hans-Peter Störr
fuente
10
¿Esperarías que el "dúo estático" sea más rápido o más productivo que el "dúo dinámico"?
Steve314
¿Qué quieres decir con dúo? De todos modos: puedo pensar en un par de razones por las que la escritura estática es más productiva que la escritura dinámica: más comprobaciones del compilador para errores, finalización del código, más información sobre la intención del programador en el código. Es por eso que estoy preguntando sobre lo contrario.
Hans-Peter Störr
11
Fue una broma con un punto. El "dúo dinámico" es Batman y Robin. No llamarían tanto miedo al inframundo criminal de Gotham City si se les llamara el "dúo estático". Dado que los desarrolladores son personas, las cosas superficiales pueden marcar la diferencia independientemente de lo que significan los términos.
Steve314
Mi primera pregunta es si sé lo que estoy haciendo o no. Si lo hago, entonces puedo diseñar cosas con anticipación y la escritura estática tiene sentido. Si no lo hago, tendré que cambiar muchas cosas sobre la marcha y la escritura dinámica será más fácil. Common Lisp es el mejor lenguaje que he encontrado cuando no sé lo que estoy haciendo. (Advertencia: solo he arañado a Haskell y, por lo tanto, no tengo una buena idea de la tipificación estática inferida.)
David Thornley
2
Estoy totalmente de acuerdo con John Skeet msmvps.com/blogs/jon_skeet/archive/2009/11/17/…
usuario

Respuestas:

99

De hecho, creo que está muy cerca. Tanto la escritura dinámica como la escritura estática tienen sus ventajas.

Razones para que la escritura dinámica sea más productiva:

  • Es más conciso : se puede eliminar una gran cantidad de código repetitivo si todo se escribe dinámicamente: declaraciones de tipo, lógica de conversión de texto, etc. Todas las demás cosas son iguales, el código más corto es marginalmente más rápido de escribir, pero lo más importante es que puede ser más rápido de leer y escribir. mantener (ya que no necesita pasar por muchas páginas de código para comprender lo que está sucediendo)
  • Técnicas más fáciles de "hackear" , como escribir patos y parches de mono, pueden obtener resultados muy rápidamente (aunque podrían confundirlo más adelante ...)
  • Más interactivo : podría decirse que la escritura dinámica es más adecuada para la programación interactiva tipo REPL para la creación rápida de prototipos, la depuración en tiempo real de las instancias de programas en ejecución o incluso la codificación en vivo.
  • Los casos de prueba pueden detectar los errores de tiempo de ejecución : suponiendo que esté utilizando TDD o, como mínimo, tenga un buen conjunto de pruebas, esto debería solucionar cualquier problema de escritura en su código.
  • Mejor polimorfismo : los lenguajes dinámicos tienen más probabilidades de fomentar la creación de funciones y abstracciones polimórficas, que pueden aumentar la productividad y la reutilización del código. Clojure, por ejemplo, hace un gran uso del polimorfismo dinámico en sus muchas abstracciones .
  • Prototipos : en mi opinión, los modelos de datos / objetos basados ​​en prototipos son más potentes y flexibles que las jerarquías de herencia escritas estáticamente. Es más probable que los lenguajes dinámicos permitan o fomenten un enfoque basado en prototipos, siendo Javascript un gran ejemplo.

Razones para que la escritura estática sea más productiva:

  • Mejor diseño : verse obligado a pensar en los tipos de valores en su software por adelantado puede empujarlo hacia soluciones más limpias y lógicas. (Yo digo que sí, aún es posible diseñar un código realmente malo ...)
  • Mejor comprobación del tiempo de compilación : la escritura estática puede permitir detectar más errores en el momento de la compilación. Esta es una gran ventaja, y podría decirse que es lo mejor de los idiomas estáticamente escritos en general.
  • Autocompletar : la escritura estática también puede proporcionar más información al IDE para que la autocompletación del código o la búsqueda de documentación sea más efectiva.
  • Desalienta los hacks : debe mantener la disciplina de tipo en su código, lo que probablemente sea una ventaja para el mantenimiento a largo plazo.
  • Inferencia de tipos : en algunos idiomas (p. Ej., Scala), puede obtener muchos de los beneficios de concisión de los lenguajes dinámicos que aún mantendrán la disciplina de tipos.

En promedio, mi conclusión (después de muchos años de experiencia en ambos lados de la cerca) es que la escritura dinámica puede ser más productiva a corto plazo, pero en última instancia se hace difícil de mantener a menos que tenga muy buenas suites de pruebas y disciplina de prueba.

Por otro lado, en realidad prefiero los enfoques de tipo estático en general, porque creo que los beneficios de corrección y el soporte de herramientas le brindan una mejor productividad a largo plazo.

mikera
fuente
14
+1, respuesta muy detallada. El valor del punto "Mejor comprobación del tiempo de compilación" no se puede enfatizar lo suficiente.
NoChance
8
Junto con la inferencia de tipos, también hay una sobrecarga de estilo Haskell, plantillas C ++, genéricos y quizás algunas otras características del lenguaje que brindan algunas de las ventajas de Duck-typing dentro de un marco de typing estático, siempre que el objeto proporcione la interfaz necesaria ( "grazna como un pato") puede usarlo, casi independientemente del tipo nominal de ese objeto. El "casi" se debe a que algunos enfoques requieren algún tipo de "charlatanes de este tipo como la declaración de pato relevante", por ejemplo, la declaración de "clase" en Haskell.
Steve314
45
Tengo que estar en total desacuerdo con su afirmación de que "el código más corto ... es más rápido de leer y mantener". Hay un paso intermedio, entender el código. Tuve que mantener el código de otras personas tanto en Delphi como en JavaScript, y el código de Delphi es mucho más fácil de entender porque es más detallado. Y sobre todo porque el código Delphi tiene declaraciones de tipo y el JavaScript no. Cuando se trata de algo más complejo que las primitivas, las declaraciones de tipo hacen que sea trivial ver cuáles son sus variables y qué pueden hacer, que es un conocimiento esencial para el trabajo de mantenimiento.
Mason Wheeler
21
Ruego no estar de acuerdo con la mayoría de las razones dadas aquí. Tome Haskell, que probablemente tiene el sistema de tipos más estricto que existe. Tiene un REPL (en realidad al menos dos), presenta un polimorfismo muy poderoso al hacer una coincidencia de patrones en los constructores y es tan conciso como uno puede esperar, mucho más que Javascript o Python. Así que supongo que algunas de las razones que mencionas son accidentales en lugar de inherentes a los idiomas tipados libremente.
Andrea
15
No confiaría demasiado en los "casos de prueba". No puedes compararlos con un buen sistema de tipos. Un sistema de tipos proporciona una prueba de que su función ya se llamará con al menos parámetros correctos, mientras que los casos de prueba solo pueden proporcionar evidencia empírica. Sin embargo, incluso esta evidencia se obtiene de un entorno artificial.
Ingo
56

Con los lenguajes dinámicos, puede escribir códigos basura más rápido que cuando usa un lenguaje escrito.

Una vez que haya creado rápidamente su enorme montón de cosas dinámicas, puede pasar de manera segura a otro proyecto sin tener que preocuparse por el mantenimiento a largo plazo.

Esto es ganancia de productividad :)

Estoy bromeando, pero después de haber estado involucrado en un proyecto usando 'lenguaje dinámico', me asusta la cantidad de pruebas innecesarias, documentaciones y convenciones con las que tiene que lidiar si desea tener un producto que funcione.
Y con la alegría de muchos errores de tiempo de ejecución que podrían haberse detectado en la compilación.
¡Oh, también olvidé despotricar sobre todos esos hacks y vudúes que la metaprogramación te permite introducir en tu código!

Por lo tanto, la ganancia de productividad podría ser un mito para proyectos medianos / grandes durante su vida útil.

Guillaume
fuente
11
Sí, mi experiencia es la misma. Un script perl de 100 líneas está bien, y sin herramientas tan excelentes nos hubiéramos perdido. Pero un proyecto perl de 100k líneas probablemente sea una pesadilla.
Ingo
3
... y luego tienes JavaScript (no solo dinámico sino también débilmente tipado).
Den
16

También hay una visión teórica de este problema: un sistema de tipo estático es esencialmente un probador de teoremas especializado que solo acepta el programa cuando puede probar la corrección de tipo del mismo. Todos los sistemas de tipo estático rechazan algunos programas válidos porque ningún sistema de tipo estático decidible es lo suficientemente potente como para probar todos los posibles programas de tipo correcto.

Se podría argumentar que los programas que no son comprobables por un typechecker estático son hacks y / o mal estilo, pero si ya tiene un programa válido y el typechecker no lo acepta, ciertamente está afectando su productividad a corto plazo.

Algunos casos en los que puede notar que el verificador de tipos se interpone es con contenedores genéricos y co-/ contravarianza en argumentos y tipos de retorno.

Patricio
fuente
18
Por el contrario, si ingresó erróneamente un programa incorrecto , el compilador le informa de inmediato y resalta la línea incorrecta. esto mejora su productividad, en comparación con notar una ejecución de prueba fallida y depurar para encontrar el error.
MarkJ
55
Los contenedores genéricos y la covarianza / contravarianza explícita están destinados a "interponerse en su camino" si lo hace mal. ¿Cuál es el beneficio de compilar código que fallará en tiempo de ejecución?
M.Stramm
Por lo general, el trabajo se considera 0% realizado hasta que ejecuta todas las pruebas con éxito. Solo entonces su progreso puede considerarse más que nada. Con eso en mente, no creo que valga la pena medir su productividad en algo que aún no se ha terminado.
Pijusn
-1 No aborda la pregunta real ("ganancias de productividad", ¿recuerdas?) Además, probablemente ni siquiera quieras escribir esos "programas válidos que el sistema de tipos rechaza". Solo porque puedas no significa que debas. ¿Y por qué incluso tendrías un "programa válido" que el typechecker rechaza? ¿Qué, estabas codificando un programa Javascript y de repente trataste de compilarlo en Java?
Andres F.
Esos programas válidos que el sistema de tipos rechaza pueden ayudar a acortar su código, lo que conduce a menos errores que el sistema de tipos no puede resolver (menos código = menos errores). El compilador / IDE que resalta la línea se puede hacer en lenguajes dinámicos con valores de prueba (es decir, desarrollo impulsado por REPL) para que pueda ver los valores intermedios y puedan detectar errores que su sistema de tipos no puede, así como errores de tipo. También puede usar la inferencia de tipo estático para proporcionarle advertencias de tipo.
aoeu256
15

Una ventaja que he encontrado con la mayoría de los lenguajes dinámicos es que hacen que sea más fácil escribir código más genérico. Es mucho más fácil escribir en un nivel superior de abstracción cuando no tienes que luchar contra el sistema de tipos para hacerlo.

No tiene que pensar tanto en ello: escribir código que haga algo no trivial con cualquier objeto en Java es difícil y probablemente requiera una reflexión que básicamente se tipea dinámicamente; con algo como JavaScript, escribir una función que haga algo interesante para todos los objetos es una segunda naturaleza. Un ejemplo perfecto sería una función que escribí recientemente que toma un objeto y reemplaza todos sus métodos por otros que hacen lo mismo pero que también activan un evento. No tengo idea de cómo abordar algo como esto en Java. Sin embargo, no estoy seguro de cuánto de esto se debe a los sistemas de tipos y cuánto se debe a otras diferencias de idioma.

Sin embargo, recientemente comencé a usar Haskell. Haskell me permite escribir código abstracto y genérico tan fácilmente como cualquier lenguaje escrito dinámicamente que haya usado. Mi ejemplo de Java / JavaScript anterior no tiene sentido en Haskell porque no tiene objetos, métodos, eventos o incluso mucha mutación, pero otros tipos de código genérico son realmente fáciles de escribir.

De hecho, Haskell puede escribir un código genérico que los lenguajes escritos dinámicamente no pueden; Un ejemplo perfecto es la readfunción que es básicamente lo contrario de toString. Usted puede obtener una Into una Doubleo cualquier tipo que desee (siempre y cuando sea en un determinado tipo de clase). Usted puede incluso tener polimórficos constantes , por lo que maxBoundpuede ser el máximo Int, Double, Char... etc., Todo dependiendo de qué tipo se supone que debe ser.

Mi teoría ahora es que la ganancia de productividad al usar un lenguaje dinámico siempre es en comparación con lenguajes como Java con sistemas de tipos menos capaces, más detallados y menos flexibles.

Sin embargo, incluso el sistema de tipos de Haskell tiene algunos problemas molestos que no tendría en un lenguaje de tipo dinámico. El más grande que me ha molestado es la forma en que se manejan los números; por ejemplo, tiene que jugar con el sistema de tipos para usar length(de una lista) como doble, algo con lo que no tendría problemas sin un sistema de tipos. Otra cosa molesta con la que me he encontrado es trabajar con Word8(un tipo int sin signo) y funciones que esperan Int.

Por lo tanto, en última instancia, no tener un sistema de tipos hace que sea más fácil escribir código genérico sin pensar demasiado y también evita molestias molestas de los sistemas de tipos. Nunca tiene que luchar contra el sistema de tipos en un lenguaje dinámico, pero tampoco puede confiar en él.

Tikhon Jelvis
fuente
1
Sí, por alguna razón, los sistemas numéricos son difíciles de acertar. En scala también es un desastre. Creo que los sistemas de tipos dinámicos ganan fácilmente sobre los sistemas de tipos estáticos simples en términos de facilidad para trabajar con ellos, pero pierden de los más avanzados (como Scala, Haskell, ML, etc., que usan variantes del sistema-F ).
Edgar Klerks
3
Su respuesta está bien intencionada, pero tiene errores. Primero, no es cierto que los lenguajes dinámicos "no tengan sistema de tipos", por lo que esa no puede ser la razón por la que "hacen que sea más fácil escribir código genérico". No lo hacen más fácil, como muestra su propio contraejemplo con Haskell (¡desacredita su propia afirmación!). "Nunca tienes que luchar contra el sistema de tipos" es falso: luchas contra él cada vez que debes corregir un error causado por la falta de verificación de tipo estático. Finalmente, coaccionar explícitamente lo Intdevuelto por una lista es trivial; ejemplo: 1.0 + fromIntegral (length myList)es decir, solo usar fromIntegral.
Andres F.
2
Finalmente, "escribir código rápido"! = "Ser más productivo". ¡Tu código tiene que funcionar! Si escribe un software con errores que luego debe pasar tiempo depurando y reparando, no está siendo productivo.
Andres F.
Bandera roja "sin pensar demasiado" para lo que la mayoría de la gente quiere decir cuando hablan de que los idiomas escritos dinámicamente son "más productivos"
Ataraxia
Si los sistemas tipográficos realmente mejoraron la productividad, ¿dónde están todas las aplicaciones útiles en Haskell o Idris? Creo que cosas como lo fácil que es comprender el error de tipo, la "capacidad de parcheo" (capacidad de editar su aplicación de forma impredecible) y la comprobación de errores del 90% de los documentos y la inferencia de tipos pueden ser más importantes.
aoeu256
7

P: A menudo escuché la afirmación de que los idiomas escritos dinámicamente son más productivos que los idiomas escritos estáticamente. ¿Cuáles son las razones de este reclamo? "

Esto tiene razones históricas. Si retrocede algunas décadas, los lenguajes dinámicos fueron indiscutiblemente mucho más productivos que los lenguajes estáticos (aunque también significativamente más lentos). Perl es claramente mucho más productivo que C si conoce ambos y la tarea en cuestión lo permite. Pero con el tiempo, los idiomas se han prestado mucho entre sí, y los idiomas más nuevos están reduciendo la brecha (tanto en productividad como en rendimiento).

Aquí hay algunos puntos a considerar:

Recolección de basura : la recolección de basura es un gran impulso de productividad. Creo que Java fue el primer lenguaje estático convencional con GC. Antes de esto, estático básicamente significaba administración manual de memoria. (Nota: Aquí y en lo siguiente solo estoy considerando los idiomas principales. Existen muchos lenguajes experimentales y especializados que proporcionarán contraejemplos a cualquier punto que haga).

Seguridad de la memoria : es una mejora de la productividad de la que no tiene que preocuparse por dispararse en el pie. Antes de los lenguajes estáticos "administrados" como Java, estático normalmente significaba acceso directo a la memoria. La depuración también es parte de la productividad, y el acceso inseguro a la memoria puede conducir a errores realmente oscuros.

Sistemas de tipo engorroso. Antes de la introducción de tipos parametrizados (como plantillas o genéricos) en lenguajes estáticos, las limitaciones de los sistemas de tipos estáticos solían ser una carga. Por ejemplo, en Java, tenía que rechazar explícitamente cada vez que seleccionaba un elemento de una colección. Entonces tienes la sobrecarga sintáctica de un elenco y ningún tipo de seguridad. Teniendo en cuenta lo ubicuas que son las colecciones en la programación, este fue un gran inconveniente.
Tener que declarar el tipo de todo es una gran cantidad de tipeo redundante, pero con la inferencia de tipos moderna, esto puede reducirse significativamente.

Gran biblioteca estándar. Python fue famoso como "baterías incluidas" debido a la gran biblioteca estándar. Esto en comparación con C, que tiene una biblioteca estándar muy minimalista. Pero con plataformas como Java y .net, una gran biblioteca estándar se está convirtiendo en estándar, y los lenguajes más nuevos como Scala y F # están heredando esto "gratis".

Estructuras de datos de primera clase. Los lenguajes dinámicos como Perl y Python tienen estructuras de datos integradas de primera clase como listas y mapas con atajos sintácticos convenientes para operaciones comunes. En comparación con esto, C no tiene colecciones integradas, excepto matrices de tamaño fijo.

Closures y sintaxis lambda : los lenguajes dinámicos suelen haber tenido esto desde el principio, pero los lenguajes estáticos lo han adoptado, Java más recientemente.

REPL la capacidad de probar rápidamente fragmentos de código de forma interactiva es una gran bendición. Pero aunque las herramientas IDE, como la ventana "inmediata" en Visual Studio, los lenguajes estáticos pueden emular esto hasta cierto punto.

Herramientas avanzadas : además de los puntos anteriores donde los lenguajes estáticos se están acercando a la conveniencia de los lenguajes dinámicos, los editores modernos están aprovechando el análisis estático de una manera que los lenguajes dinámicos tienen dificultades para hacer coincidir. Por ejemplo, los editores pueden proporcionar refactorizaciones automáticas seguras, algo que es estrictamente hablando imposible en un lenguaje dinámico.

En pocas palabras: Históricamente era cierto, pero hoy la respuesta es menos clara.


P: Entonces: ¿qué hay para decir sobre la productividad con la tipificación dinámica que realmente es una ventaja del modelo de tipo en sí?

Es algo difícil separar el modelo de escritura dinámica de los lenguajes dinámicos, pero como ejemplo, C # ha adoptado características más dinámicas con el tiempo, aunque su núcleo es un lenguaje estático. Esto es realmente una prueba de beneficio del modelo de tipo dinámico. Ejemplos:

Reflexión La reflexión es fundamentalmente una característica de escritura dinámica. Usted inspecciona los tipos de objetos en tiempo de ejecución que en tiempo de compilación. Cuando se introdujo, estaba mal visto, pero en C # el uso de la reflexión se vuelve cada vez más omnipresente, por ejemplo, ASP.Net MVC usa la reflexión en gran medida.

Atributos Los atributos son un ejemplo de tipeo dinámico. Puede agregar atributos arbitrarios a una clase en tiempo de compilación, y luego inspeccionar en tiempo de ejecución (a través de la reflexión) y manipular objetos basados ​​en ella. Algo así como MEP es básicamente un marco de extensión basado en un modelo de tipo dinámico.

Linq a SQL, EF mv. Los diversos transformadores Linq inspeccionan las consultas como objetos de tiempo de ejecución y generan sql sobre la marcha. No se vuelve más dinámico que inspeccionar el código en tiempo de ejecución. CodeDom es el otro lado de la moneda, donde se puede generar código en tiempo de ejecución

Roslyn Roslyn básicamente implementa eval, lo que alguna vez se consideró la característica definitoria de un lenguaje verdaderamente dinámico.

Dinámico El dynamictipo es la característica más explícitamente dinámica en C #, y se anuncia para hacer que la interacción con objetos externos y lenguajes sea más simple y productiva. Pero también se usa en Asp.net MVC por conveniencia.

El beneficio de todas las características anteriores muestra que el modelo dinámico tiene ventajas definidas incluso en un lenguaje estático con tipos parametrizados, tipos estructurales e inferencia de tipos.

JacquesB
fuente
Realmente no me gusta esta respuesta, porque casi todos los puntos no abordan la pregunta central, "¿Cuál es la supuesta ganancia de productividad de la escritura dinámica ?" No lenguajes dinámicos .
niñera
@nanny, ¿podría explicar su diferencia percibida entre los lenguajes de tipo dinámico y los idiomas dinámicos? (Es una de esas cosas borrosas). ¿Podría dar un ejemplo de un lenguaje de tipo dinámico que no sea un lenguaje dinámico, junto con definiciones claras de cada uno?
@nanny: La pregunta realmente se refiere a "lenguajes escritos dinámicamente", no solo a "escritura dinámica".
JacquesB
@MichaelT Lo siento, no estaba claro. La escritura dinámica es un aspecto de todos los lenguajes dinámicos. Esta respuesta está hablando de otros aspectos que, históricamente, los lenguajes dinámicos tienden a tener, sin abordar realmente la parte de tipeo dinámico.
niñera
1
@nanny: Básicamente estoy respondiendo esto: "A menudo escuché la afirmación de que los idiomas escritos dinámicamente son más productivos que los idiomas escritos estáticamente. ¿Cuáles son las razones de esta afirmación?" - Creo que las razones de esta afirmación son históricas y están relacionadas no solo con la escritura dinámica sino también con otras características de mejora de la productividad de los lenguajes dinámicos.
JacquesB
6

El conjunto de todas las características del lenguaje moderno es tan grande, que el tipeo estático versus dinámico solo no tiene mucho peso.

La regla es, cuanto mejores sean las características de su idioma, más corto será su código. Eso es bastante simple. Java muestra cómo la escritura estática puede salir muy mal, lo que le da a sus oponentes mucho de qué alimentarse. Las características de lenguaje mal diseñadas generalmente tienen un costo, y la escritura estática en Java es, en primer lugar, una característica obligatoria (de lo contrario, la mayoría de las personas probablemente ni siquiera la usaría) y, en segundo lugar, se ejecuta de manera deficiente.
Es por eso que, en comparación, la mayoría de los lenguajes dinámicos brillan, aunque yo diría que PHP realmente no mejora su vida en general (al menos hasta hace poco), debido a muchas otras peculiaridades no relacionadas con los sistemas de tipos.

Por otro lado, tiene muchos idiomas con sistemas de tipo expresivo que no se interponen en su camino y que incluso no son obligatorios. Y algunos de ellos incluso permiten incrustar código sin tipo, siempre que necesite escapar del sistema de tipos.

Personalmente, uso haXe, que es un lenguaje con inferencia de tipos, subtipo nominal y estructural, código sin tipo opcional, tipos de función de primera clase, tipos de datos algebraicos y macros léxicas (no del todo maduras pero extremadamente potentes), evitando al mismo tiempo la sintaxis arcana. Después de usar haXe durante aproximadamente 3 años, he llegado a una conclusión simple:

La programación se vuelve mucho más fácil, cuando su idioma no lo encierra en elecciones religiosas sobre paradigmas, sino que trata de ser una buena herramienta. Hay varios lenguajes estáticos y dinámicos y lenguajes mixtos , que tienen éxito en eso. Algunos de ellos son fáciles de aprender, los más difíciles de dominar.
Su poder proviene de la forma en que se pueden componer sus características individuales para crear fácilmente soluciones simples a problemas complejos. Esto impide una cierta ortogonalidad que solo se puede lograr a través de un delicado equilibrio de inclusión u omisión de todas las características del lenguaje exploradas hasta ahora. Si intentas agregar tipeo estático a Ruby, lo paralizarás, si intentas quitárselo a Haskell, lo aplastarías. En contraste con eso: si se lo quitaras a C, la gente apenas lo notaría y si se lo quitases a Java, algunos podrían agradecerte.

Desde mi experiencia personal, puedo decirte esto: me gusta Ruby. Amplió mis horizontes y la forma en que diseño los sistemas. En mi humilde opinión, se debe utilizar para enseñar a la gente a programar en primer lugar. Es discreto, poderoso, conciso, divertido. Entiendo por qué alguien que viene de un idioma ortodoxo lo disfrutará.
Sin embargo, a la larga, la tipificación estática permite diferir el trabajo al analizador estático y, con la inferencia de tipos, esto se realiza básicamente sin costo. El resultado es un código que es más fácil de mantener y que a menudo se ejecuta más rápido.

Pero de nuevo, la escritura estática por sí sola no puede hacer nada. Es una cuestión de combinación. Creo que en algún lugar entre F #, Scala, Nemerle, OCaml o haXe puedes encontrar tu propio óptimo. Pero eso depende en última instancia de usted, porque el lenguaje debería permitirle incrustar sus pensamientos sin esfuerzo, en lugar de obligarlo a doblarlos. Y, después de todo, nada produce más ganancia de productividad que si la programación fuera divertida.

back2dos
fuente
"La regla es que cuanto mejores sean las características de tu idioma, más corto será tu código". Esto podría deberse a la opinión en algún nivel, pero no creo que esta afirmación sea precisa. Un código más corto no ofrece demasiadas ventajas por sí solo, aparte de implicar menos tipeo en el momento de la escritura y tal vez ocupar menos espacio en el disco (que de todos modos no es un factor en los lenguajes compilados). Creo que la marca de un buen lenguaje es transmitir tanta información sobre lo que está haciendo de la manera más concisa posible. La escritura dinámica no es muy autodocumentada y, como resultado, pierde capacidad de mantenimiento
Ataraxia
Puede complementar el código de tipo dinámico con información como valores predeterminados / argumentos de palabras clave, tipos obtenidos de inferencia de tipos, inferencia de tipos dinámicos de un compilador JIT, o simplemente registrar todas las funciones [ir a través de cada función o clase en un programa en ejecución y reemplazarlas con un versión de la función que registra sus argumentos / resultados). Luego puede ver el registro de las ejecuciones anteriores de una función. Otra idea es rechazar el código que no tiene anotaciones de tipo, contratos de tiempo de ejecución o pruebas de sesión REPL de muestra, pero le da al desarrollador la opción de elegir cualquiera de los tres.
aoeu256
3

Personalmente, la única razón por la que la escritura dinámica ayudaría es si usted es un mecanógrafo realmente lento o si desarrolla funciones / métodos / locuciones gigantes que son difíciles de navegar. También debe abordar el problema de las pruebas de unidad completa. Los tipos dinámicos requieren (a menos que le guste escribir código roto) pruebas de unidad vigorosas (para asegurarse de que sus tipos dinámicos no exploten inesperadamente (es decir, la variable es principalmente duck, pero a veces es accidental). La estática se esforzará mucho más para evitar esto (y sí, puede argumentar a favor de pruebas unitarias vigorosas)

Pablo
fuente
0

Creo que antes que nada debes definir la "productividad". ¿Qué significa e incluye "productividad"?

Si por "más productivo" te refieres a escribir menos líneas de código para implementar la misma característica, entonces sí, los lenguajes de programación de escritura dinámica son más "productivos" que los lenguajes de escritura estática.

Sin embargo, si también considera el tiempo dedicado a la depuración y la corrección de errores, entonces los lenguajes de escritura dinámica pueden no ser tan productivos, porque los lenguajes de escritura dinámica tienden a llevar la verificación de errores al tiempo de ejecución mientras que, por el contrario, los lenguajes de escritura estática puede realizar alguna comprobación de errores en tiempo de compilación. Como se acepta comúnmente que, por lo general, cuanto más tarde se encuentra un error, más costoso es solucionarlo. Por lo tanto, el código de escritura dinámica puede generar una productividad generalmente igual o incluso menor que la del código de escritura estática.

yaobin
fuente
En general, no es cierto que pueda escribir una característica en menos líneas utilizando un lenguaje dinámico. ¿Qué idiomas estás comparando, de todos modos?
Andres F.
@AndresF. Oh, principalmente uso Python y C ++.
yaobin
1
Ok, pero no puedes generalizar dinámico vs estático cuando realmente estás comparando Python y C ++. C ++ no es un ejemplo particularmente representativo de un lenguaje con tipeo estático. Hay lenguajes de tipo estático extremadamente concisos, que más o menos le permiten escribir programas tan breves como con Python. Entonces, en general, su afirmación es falsa.
Andres F.
Sí, pero ¿qué pasa si editas tu programa mientras aún se está ejecutando? Cualquier problema de tiempo de ejecución simplemente ocurrirá y puede solucionarlo allí mismo. En Lisp, cada vez que obtiene un error, puede arreglar su programa y luego continuar ejecutándolo ... Sí, para rutas más complejas, las anotaciones de tipo serían buenas [tal vez pueda usar una escritura gradual como mypy & lisp], pero esas rutas más complejas también tiene la posibilidad de errores que no son de tipo, por lo que puede ser una buena idea evitar rutas complejas en cualquier idioma.
aoeu256
-1

La gran ventaja del tipeo dinámico es la productividad.

Python, Ruby, etc. tienen muchos otros impulsores de productividad además del tipeo dinámico (parámetros predeterminados, diccionarios como tipos incorporados, etc., etc.), el efecto acumulativo en la productividad del programador es impresionante.

Las penalizaciones en términos de velocidad (¡o falta de ellas!) Y consumo de recursos no son tan malas como cabría esperar y, en la mayoría de los casos, se ven más que compensadas por la velocidad y flexibilidad de desarrollo.

Hay una (muy viejo!) De papel sobre el tema aquí. Es uno de los pocos estudios realizados adecuadamente sobre la productividad del programador y muchas de las conclusiones aún son válidas.

Lo que (probablemente) sería diferente sería el estudio que se realizaría hoy:

  1. Las JVM de Java han mejorado más allá del reconocimiento.
  2. Los IDE modernos habrían mejorado la productividad de los codificadores de C ++ y Java, pero habrían hecho muy poca diferencia en los lenguajes de secuencias de comandos.
  3. C # se incluiría y probablemente estaría en el mismo estadio que Java, pero un poco mejor.

Entonces, el mensaje es a menos que el rendimiento sea un problema realmente serio, los lenguajes dinámicos aumentarán su productividad.

James Anderson
fuente
2
Mi falta de claridad es exactamente lo que hace la escritura dinámica para aumentar su productividad. El documento es interesante, sin embargo, se trata de un programa muy pequeño, y no estoy seguro de cómo esto se traslada a los miles de líneas de código en la mayoría de los programas.
Hans-Peter Störr
55
Ese estudio solo usa C, C ++ y Java como ejemplos de lenguajes estáticos, y luego intenta aplicar las conclusiones encontradas a los lenguajes de programación tradicionales en general. Los tres idiomas comparten la misma sintaxis básica, con los mismos defectos inherentes que disminuyen la productividad, lo que invalida la comparación. No es que los lenguajes estáticos no sean productivos, es que la familia C es improductiva. Si hubieran incluido un dialecto de Pascal en sus pruebas, probablemente habrían llegado a algunas conclusiones diferentes.
Mason Wheeler
@mason: hay muy pocos estudios objetivos reales en este campo. Este es uno de los pocos estudios reales con números reales, etc. ¡El programa "muestra" no es trivial! Combina elementos de manejo de diccionario, algoritmos complejos y grandes volúmenes de datos. El alto porcentaje de intentos fallidos y fallidos confirma la naturaleza no trivial de la tarea.
James Anderson el
2
-1 No estás diciendo mucho sobre lo que hace que los lenguajes dinámicos sean más productivos. Los parámetros y diccionarios predeterminados se pueden encontrar en lenguajes tipados estáticos como, por ejemplo, Scala.
Jonas
1
@JamesAnderson Peor aún, el documento al que se vinculó ni siquiera respalda su punto. Compara "lenguajes de script" (a menudo dinámicos) con " lenguajes convencionales " (a menudo estáticos). Ahora, dime, ¿qué son exactamente los idiomas "convencionales"? ¿Crees que es lo mismo que el conjunto de idiomas con escritura estática? Peor aún, el papel no es que la vieja. Para el año 2000, ya existían muchos lenguajes geniales con escritura estática que posiblemente eran más productivos que los lenguajes dinámicos.
Andres F.