Beneficios de la Vida Real de los Lenguajes Dinámicos?


Estoy explorando varias posibilidades para desarrollar un nuevo sistema (aplicación web).

Soy un tipo "anticuado", orientado a objetos en la naturaleza (convertido de procedimental hace muchos años). Jugué con Python y estudié un poco Ruby, pero francamente me siento atraído por usar las herramientas de Microsoft (C#, ASP.NET MVC). Todo esto de escribir en tiempo de ejecución, sin errores de compilador en cosas básicas, etc. solo hace que mi vida sea más difícil cuando se trata de construir aplicaciones grandes y complejas.

I escuchar constantemente a la gente hablar de las grandes cosas que se pueden hacer con los lenguajes dinámicos, pero a excepción de ejemplos con perros, gatos y la rapidez con la que se puede codificar una forma fresca de contar las cosas, la "fuerza industrial" de Visual Studio solo parece eliminar las pequeñas cosas aseadas que ofrecen los lenguajes dinámicos, especialmente ahora que tiene versiones expresas gratuitas de VS y versiones completas disponibles de forma gratuita para empresas de nueva creación.

Siento que me estoy perdiendo algo aquí, porque las grandes aplicaciones son de hecho siendo desarrollado con lenguajes dinámicos, entonces, ¿cuáles son esas grandes cosas que estos lenguajes le permiten hacer, al mirar aplicaciones grandes y complejas? ¿Qué te puede hacer regalar la fuerza de VS?

Author: Roee Adler , 2009-06-25

9 answers

"qué tan rápido puedes codificar" me preocupa tanto que felizmente renuncié a la larga y lenta tarea de compilar las cosas.

Ventajas de los lenguajes dinámicos.

  1. No compilar, no construir. Simplemente Codifique y pruebe, seguido de implementar en producción.

  2. Gratificación inmediata. No hay tiempo para retorcerme las manos sobre lo que podría ser una llamada API. Simplemente escríbalo interactivamente en el prompt de Python >>> y vea lo que realmente hacer.

  3. Ciclos de diseño muy, muy cortos. En lugar de crear cuidadosamente una jerarquía de clases con definiciones de interfaz de bonificación y declaraciones abstractas y anulaciones adecuadas, puedo codificar las clases, probarlas unitariamente y terminar.

  4. Menos código. La introspección dinámica del lenguaje reduce el volumen de la fuente. No escribo estas cosas en mis aplicaciones; dependo de frameworks para hacer esto por mí. Pero el código basado en framework es a menudo muy corto; no hay declaraciones duplicadas que son tan comunes en Java, donde tienes que repetir cosas en una configuración XML.

  5. Sin misterios. Como decimos en la comunidad de Python: "Usa la fuente, Luke."No hay ambigüedad en lo que hace un framework o lo que realmente significa una API.

  6. Flexibilidad Absoluta. A medida que cambian nuestros requisitos, no tenemos que luchar con cambios devastadores que rompen toda la arquitectura. Podemos triv trivialmente make hacer cambios en algunas clases porque El Duck Typing de Python elimina la necesidad de adaptar las definiciones de interfaz que faltan donde no pensamos que serían necesarias. Simplemente no son ninguno; el código que no escribimos es código que no tenemos que arreglar o mantener.

  7. Resiliencia. Cuando nuestros actuarios tienen un pedo cerebral, no tenemos que pasar meses descubriendo cómo integrar este nuevo modelo de suscripción más sofisticado en las aplicaciones. Casi cualquier cosa puede ser exprimida. Una vez más, esto es estrictamente una consecuencia de pato teclear. Nos liberamos de integrarlo a la fuerza en una arquitectura que no podía anticipar un nuevo modelo de negocio.

  8. Dado que la fuente es la aplicación, la fuente puede ser su propio archivo de configuración. No tenemos archivos de configuración XML o INI en alguna sintaxis externa. Tenemos archivos de configuración en Python. El marco de Django hace esto y seguimos su ejemplo. Tenemos declaraciones de datos muy complejas para demostraciones de ventas y pruebas unitarias. El super complejo data es en realidad una colección de objetos Python que habrían venido de una base de datos except excepto omitted que omitimos cargar la base de datos. Es más sencillo simplemente ajustar el constructor de objetos Python en lugar de cargar una base de datos SQL.

[BTW. Después de más de 30 años de desarrollo de software en Cobol, Fortran, PL/I, Java, C, C++, estoy cansado de la optimización manual de nivel relativamente bajo que la mayoría de los lenguajes compilados requieren. Hace años, leí un comentario sobre la ineficiencia de la mayoría de los compiladores: nos lleva a crear sistemas de compilación elaborados para trabajar alrededor de las limitaciones del compilador. Solo necesitamos make porque cc es muy lento.]


Editar

La programación dinámica no te convierte en un genio. Solo ahorra mucho tiempo. Todavía tienes que gestionar el proceso de aprendizaje. Las cosas que no sabes son difíciles en todos los idiomas. Un lenguaje dinámico le da ventaja al permitirle proceder de forma incremental, descubriendo una cosa nueva a la vez sin haber hecho mucho de trabajo de diseño solo para encontrar que sus suposiciones estaban equivocadas.

Si desea escribir mucho código basado en una API mal entendida, entonces un lenguaje dinámico puede ayudar. Usted es libre de escribir una gran cantidad de código que se bloquea y se quema en un lenguaje: C#, VB, C++, Java o Python. Siempre puedes escribir código que no funcionará.

El compilador le da una advertencia anticipada de que el código no funcionará. Por lo general, no compilar es una gran pista. Sin embargo, todavía puede escribir una gran cantidad de código que compila y falla todas las pruebas unitarias. El compilador solo comprueba la sintaxis, no la semántica.

Python puede darte una advertencia anticipada de que el código no funcionará. Por lo general, no se puede hacer que se ejecute de forma interactiva. Sin embargo, todavía puede escribir una gran cantidad de código que falla todas las pruebas unitarias.

 19
Author: S.Lott,
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-06-25 12:52:21

La tipificación estática es una forma de optimización prematura. Te obliga a tomar decisiones detalladas por adelantado, cuando es posible que no tengas el conocimiento para tomarlas. No ayuda particularmente a la corrección del programa a menos que cree suficientes tipos para tener sentido lógico. Hace que sea difícil cambiar las estructuras de datos sobre la marcha.

Lo que se obtiene es una cantidad muy limitada de comprobación de corrección: muy limitada porque no separa las formas de usar ints, por ejemplo. Supongamos que estamos tratar con filas y columnas; ambas son probablemente ints, pero las variables de fila y columna no deben usarse indistintamente. También obtienes optimización, que puede ser algo muy útil, pero no vale la pena ralentizar el desarrollo inicial. Puede compensar la comprobación de corrección escribiendo las pruebas apropiadas.

El sistema de tipos Common Lisp es bueno para esto. Todos los objetos de datos conocen su tipo, y puede especificar explícitamente ese tipo si lo desea.

Una especie de ejecución de bucle de evaluación el modelo hace que sea muy fácil probar rutinas mientras las escribes. No tienes que escribir pruebas explícitamente por adelantado (aunque no hay nada que te impida hacer eso); puedes escribirlas y ejecutarlas sobre la marcha (y luego puedes refinar eso en un conjunto de pruebas - piensa en ello como desarrollo de pruebas incrementales).

No tener un largo paso de compilación hace que sea más fácil hacer un desarrollo basado en pruebas, porque es mucho más rápido ejecutar pruebas. Usted no tiene que romper lo que está haciendo cada es hora de probar.

Cuando escucho a la gente quejarse de los lenguajes dinámicos, me acuerdo de la gente quejándose de los sistemas de control de versiones sin bloqueos exclusivos. A algunas personas les toma mucho tiempo darse cuenta de lo que ganan al mudarse a un VCS moderno, e igualmente a algunas personas les toma mucho tiempo apreciar los lenguajes dinámicos.

 6
Author: David Thornley,
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-06-25 14:12:38

En general, prefiero hablar de lenguajes "interactivos" en lugar de lenguajes "dinámicos". Cuando solo tiene un ciclo de edición/compilación/ejecución, cualquier cambio toma mucho tiempo. Bueno, al menos en el orden de "necesidad de guardar, compilar, comprobar el informe de compilación, prueba de ejecución, comprobar los resultados de la prueba".

Con un lenguaje interactivo, generalmente es fácil modificar una pequeña parte, luego probar inmediatamente los resultados. Si tus pruebas aún tardan un tiempo lomg, no has ganado mucho, pero generalmente puedes prueba en casos más pequeños. Esto facilita el desarrollo rápido. Una vez que tenga una implementación correcta conocida, esto también ayuda a la optimización, ya que puede desarrollar y probar sus funciones nuevas y mejoradas rápidamente y experimentar con diferentes representaciones o algoritmos.

 5
Author: Vatine,
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-06-25 11:38:12

Aquí hay partes de mi respuesta a una pregunta anterior similar ( Sé C#. ¿Seré más productivo con Python?):

Yo vengo de un fondo de C#/. NET. Comenzó a programar en. NET en abt. 2001, y casi al mismo tiempo se introdujo a Python. En 2001, mi tiempo pasado en C # vs. en Python fue de aproximadamente 90% C# / 10% Python. Ahora, la relación es 5% C# / 95% Python. En mi empresa, todavía mantenemos una línea de productos basada en. NET. Pero todas las cosas nuevas se basan en Python.

Hemos creado aplicaciones no triviales en Python.

En mi experiencia, lo que me hace más productivo en Python vs C#, es:

  • es un lenguaje dinámico. El uso de un lenguaje dinámico a menudo le permite eliminar capas arquitectónicas completas de su aplicación. Pythons dynamic nature le permite crear abstracciones reutilizables de alto nivel de una manera más natural y flexible (en cuanto a sintaxis) que en C#.
  • Bibliotecas. Las bibliotecas estándar y muchos de los las bibliotecas de código abierto proporcionadas por la comunidad son de alta calidad. El rango de aplicaciones para las que se usa Python significa que el rango de bibliotecas es amplio.
  • Ciclo de desarrollo más rápido. Ningún paso de compilación significa que puedo probar los cambios más rápido. Por ejemplo, al desarrollar una aplicación web, el servidor de desarrollo detecta los cambios y vuelve a cargar la aplicación cuando se guardan los archivos. Ejecutar una prueba unitaria desde mi editor es solo una pulsación de tecla de distancia, y se ejecuta instantáneamente.
  • "Fácil acceso" a características de uso frecuente: listas, comprensiones de listas, generadores, tuplas, etc.
  • Sintaxis menos detallada. Puede crear un framework web Python basado en WSGI en menos líneas de código que su típico archivo. NET web.config: -)
  • Buena documentación. Buenos libros.
 3
Author: codeape,
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
2017-05-23 12:17:05

¡Proyectiles interactivos! Esta es una gran ganancia de productividad. Simplemente inicie irb / python para sentarse frente al shell interactivo (para ruby y python respectivamente). A continuación, puede probar interactivamente sus clases, funciones, experimentar con la expresión (ideal para expresiones regulares), diferentes sintaxis y algoritmos. Este es un verdadero patio de juegos para programadores y una gran herramienta para depurar también.

Solo dos centavos sobre los errores:

Todo esto escribiendo en tiempo de ejecución, sin compilador errores en cosas básicas, etc sólo hace mi vida es más difícil cuando se trata de construcción de grandes aplicaciones complejas.

Los errores detectables del compilador son el tipo de errores que detectará cuando ejecute varias pruebas automáticas (unitarias, funcionales, etc.)...) y los que usted debe escribir de todos modos. Probablemente Linus Torvalds puede decir: Pruebas de regresión"? ¿Qué es eso? Si compila, es bueno, si arranca es perfecto pero tiene miles de probadores que harán el trabajo para él. Ah y el uso interactivo shells usted está recibiendo la retroalimentación automática sobre su sintaxis como cuando compila la aplicación, pero el código se ejecuta en su lugar.

 2
Author: j t,
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-06-25 13:48:53

También me gusta escribir estática. Pero no encuentro que lo extraño tanto cuando estoy escribiendo Python, (siempre y cuando las clases que estoy usando estén bien documentadas - y yo diría que ninguna característica del lenguaje nos salvará de la mala documentación). Tampoco echo de menos la mayoría de las características dinámicas de Python al escribir C++ (lambdas, I miss: bring on C++0x incluso si la sintaxis es horrible. Y La lista de comprensiones).

Para la detección de errores, la mayoría de los errores de" tipo incorrecto pasado "y" método incorrecto llamado " no son sutil, por lo que la principal diferencia es que las excepciones reemplazan los errores del compilador. Tienes que asegurarte de ejecutar cada ruta de código y todas las rutas de datos significativas, pero por supuesto que lo estás haciendo de todos modos para proyectos serios. Sospecho que es raro que sea difícil probar todas las clases que podrían asignarse a una variable dada. El principal problema es que las personas acostumbradas a C++ han aprendido a apoyarse en el compilador, y no se esfuerzan por evitar grandes clases de errores que el compilador atrapará. En Python tienes la opción de pensar en ello mientras codificas, o esperar hasta que se ejecuten las pruebas para averiguarlo. Del mismo modo, la operación de "refactorización automática" de C++ de "cambiar los parámetros y ver qué falla al compilar" necesita alguna modificación en Python si desea localizar todos los sitios de llamadas.

Por lo tanto, debe asegurarse de que está ejecutando el subconjunto correcto de pruebas, ya que una prueba de unidad completa de una aplicación Python grande tomará mucho más tiempo de lo que es aceptable en la fase de "compilación" de su código C++ actual / compile/code/compile/code/compile / test cycle. Pero ese es exactamente el mismo problema que no querer reconstruir todo en C++.

La escritura estática gana cuando es realmente difícil ejecutar su código (por ejemplo, con dispositivos incrustados, o especialmente entornos de servidor extraños que no puede reproducir localmente), porque detecta más errores antes del punto en el que está jugando con cables serie y rsync. Pero es por eso que quieres un emulador independientemente de lo que idioma en el que está escribiendo, y por qué para el código de servidor serio tiene un entorno de prueba adecuado si las máquinas del desarrollador no pueden simular la producción.

Además, vale la pena recordar que muchos errores y advertencias del compilador de C++ no son realmente sobre su diseño, son sobre el hecho de que hay muchas formas diferentes de escribir código que parece correcto, pero se comporta completamente mal. Los programadores de Python no necesitan advertencia de que han insertado accidentalmente un trigraph, o pointer, porque no tienen un preprocesador psicótico, o optimizaciones basadas en un alias estricto.

 1
Author: Steve Jessop,
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-06-25 14:09:54

Mi experiencia

He trabajado con ambos, probablemente alrededor de una década con cada profesional, en total.

Anecdóticamente he pasado mucho más tiempo tratando de hacer que los lenguajes tipeados estáticamente entiendan lo que quiero hacer (probablemente semanas – quizás meses en total) que he pasado corrigiendo errores causados por errores de tipo dinámico (¿quizás una hora o dos al año?).

Estudios

La gente ha intentado bastante duro para obtener evidencia de que uno u otro es mejor en términos de productividad del programador, pero la revisión más reciente que he leído dice que no hay evidencia sólida para ninguno de los dos.

Totalitario

El análisis de tipos estáticos es útil en algunas situaciones. No creo que no deba ser inherentemente cocido en tu lenguaje. Debe ser una herramienta dentro de su entorno de computación interactiva, junto con sus pruebas, su REPL, sus refactores, sus documentos, su codificación alfabética, etc.

Los sistemas de tipo estático pueden hacerte pensar en cosas útiles. Esto es especialmente cierto en un idioma como Haskell con Clases de Tipos y Mónadas (que confieso que todavía no entiendo). Esto es algo bueno, pero siento que es totalitario creer que es siempre algo bueno. Deberías pensarlo cuando sea apropiado. Un idioma no debe hacerte pensar en él o ser consciente de él desde el principio del desarrollo.

Ambos Demasiado Restrictivos y No Lo Suficientemente Restrictivos

Los sistemas de tipo estático que no están completos tienen una expresividad limitada. ¿Por qué hacer eso en el idioma usando un nuevo idioma específico de dominio especial solo para hablar de tipos? Ahora su idioma establece el nivel exacto de expresividad al que tiene acceso. ¿Quieres más? Es necesario volver a escribir el código o actualizar el idioma. Quieren menos? No tienes suerte, usa un idioma diferente.

En su lugar, ¿por qué no usar un lenguaje dinámico base para describir tipos y sistemas de tipos cuando lo desee? Como biblioteca. Es más expresivo; más poderoso( si se desea); más flexible; y significa un lenguaje base más pequeño.

Repetitivo

Los lenguajes estáticamente tipeados parecen alentar la generación de código o repeticiones. No estoy seguro si esto es inherente. Tal vez un sistema macro suficientemente poderoso lo superaría. Estoy comparando el estado de las burlas para pruebas en Swift con el de objective c.

Monolítico

Los lenguajes estáticamente tipeados parecen alentar aplicaciones monolíticas - esta es una opinión y una observación que no puedo respaldar, pero parece sostener They Ellos, o las herramientas con las que vienen, parece alentar las aplicaciones y el pensamiento monolíticos.

Por el contrario, en entornos de computación interactiva no se construye una nueva aplicación, sino que se extiende el sistema para que haga más. Los sistemas que conozco (máquinas Lisp, Smalltalk y Unix – sus herramientas tienen una interfaz dinámicamente mecanografiada entre ellas) usan la mecanografía dinámica para ensamblar partes.

Deberíamos construir pequeñas extensiones a un todo, en lugar de se propone construir nuevas aplicaciones completas, por lo que esta tendencia monolítica, si existe, es perjudicial.

Velocidad

Los compiladores JIT de seguimiento dinámico más rápidos producen código rápido, y todavía son una tecnología bastante joven. Aún así, también podría hacer esto con un lenguaje estáticamente escrito.

A largo plazo

Sospecho que a largo plazo, terminaremos con entornos que admiten un potente análisis estático, donde podrá declarar tipos y protocolos, y el sistema le ayudará a ver si están satisfechos, o le ayudará a mostrar los tipos implícitos. Pero no necesitarás para hacer eso.

 1
Author: Benjohn,
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
2016-09-07 21:24:43

Considere el caso donde usted tiene una subrutina que toma un solo argumento:

sub calculate( Int $x ){ ... }

Ahora tus requisitos cambian, y tienes que lidiar con múltiples argumentos:

multi sub calculate( Int $x ){ ... }
multi sub calculate( Int @x ){
  my @ret;
  for @x -> $x {
    push @ret, calculate( $x );
  }
  return @ret;
}

Observe que hubo muy pocos cambios entre las diferentes versiones.

Ahora, ¿qué pasaría si descubriera que realmente debería haber estado usando números de coma flotante:

multi sub calculate( Num $x ){ ... }
multi sub calculate( Num @x ){
  my @ret;
  for @x -> $x {
    push @ret, calculate( $x );
  }
  return @ret;
}

Ese fue un cambio más pequeño que antes, y tenga en cuenta que cualquier pieza de código que llame a estas subrutinas sería seguir trabajando sin un solo cambio.

Estos ejemplos fueron escritos en Perl6

 0
Author: Brad Gilbert,
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-06-25 15:43:07

Sé que ha pasado un tiempo, pero las respuestas aceptadas listan propiedades que no se limitan a los lenguajes de escritura dinámica. Por ejemplo, #4 (menos código) también es cierto para Scala (si mal no recuerdo). Definitivamente es cierto de Groovy (que está construido sobre Java, por lo que técnicamente groovy es estático y dinámico). El único con el que estoy de acuerdo es #7 (resiliencia)

De wikipedia,

El lenguaje de programación dinámico es a ... lenguaje de programación de alto nivel que, en tiempo de ejecución, ejecute muchos comportamientos de programación comunes que los lenguajes de programación estáticos realizan durante la compilación. Estos comportamientos podrían incluir la extensión del programa, añadiendo nuevo código, extendiendo objetos y definiciones, o modificando el sistema de tipos. El programador dinámico también puede incluir escritura dinámica.

Desde mi experiencia, las ventajas de los lenguajes dinámicos son menos código/código más eficiente y mejores "mejores" prácticas (como una fuerte cultura de pruebas)... cosas que no son específico para lenguajes dinámicos.

Hablando de cultura de prueba, ciertos entusiastas del lenguaje dinámico (Ruby en particular) afirman que todas las pruebas que escriben (test infection) les permite refactorizar aplicaciones fácilmente. Tiendo a no comprar esta afirmación - - - las pruebas mal escritas (que son muy, muy fáciles de escribir) tienden a convertirse en una pesadilla de mantenimiento.

Para resumir: los lenguajes dinámicos tienden a hacer que la entrega del producto sea rápida, la aplicación puede o no ser fácil de mantener, pero son horribles para aplicaciones de alto rendimiento (aplicaciones compiladas estáticamente son mucho, mucho más rápido)

 -1
Author: U Avalos,
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
2014-12-30 21:14:14