Usos para lenguajes dynamics

Mi idioma principal ahora es D, y estoy en el proceso de aprender Python porque se requiere para un curso que estoy tomando. Si bien entiendo por qué los lenguajes dynamics serían una bocanada de air fresco para las personas que progtwign en lenguajes estáticos sin inferencia de tipo o plantillas (las plantillas de IMHO son, en gran medida, la tipografía de pato en tiempo de comstackción), tengo curiosidad por los beneficios de los lenguajes dynamics incluso cuando tienes esos.

La conclusión es que, si voy a aprender Python, quiero aprender de una manera que realmente cambie mi forma de pensar acerca de la progtwigción, en lugar de solo escribir D en Python. No he usado lenguajes dynamics desde que era un progtwigdor bastante novato e incapaz de apreciar la flexibilidad que supuestamente ofrecen, y quiero aprender a aprovecharlos al máximo ahora. ¿Qué se puede hacer de forma fácil / elegante en un lenguaje interpretado de forma dinámica que es incómodo o imposible en un lenguaje estático, incluso con plantillas, polymorphism, inferencia de tipo estático y tal vez reflexión en tiempo de ejecución?

En teoría, no hay nada que puedan hacer los lenguajes dynamics y los lenguajes estáticos no. Las personas inteligentes ponen mucho trabajo en crear muy buenos lenguajes dynamics, lo que lleva a una percepción en el momento en que los lenguajes dynamics están por delante, mientras que los estáticos necesitan ponerse al día.

Con el tiempo, esto oscilará hacia otro lado. Ya varios lenguajes estáticos tienen:

  • Los generics, que hacen que los tipos estáticos sean menos estúpidos al permitirle seleccionar el tipo correcto cuando se pasan objetos, evitando que el progtwigdor tenga que lanzarlos ellos mismos.

  • Inferencia de tipos, lo que ahorra tener que perder tiempo en escribir lo que debería ser obvio

  • Cierres, que entre muchas otras cosas ayudan a separar el mecanismo de la intención, permitiéndole reunir algoritmos complicados de ingredientes en su mayoría existentes.

  • Conversiones implícitas, que le permiten simular “parches de mono” sin los riesgos que generalmente conlleva.

  • Carga de código y fácil acceso programático al comstackdor, de modo que los usuarios y terceros puedan escribir su progtwig. Utilice con precaución!

  • Sintaxis que son más propicias para la creación de lenguajes específicos de dominio dentro de ellos.

… y sin duda más por venir. El movimiento dynamic ha generado algunos desarrollos interesantes en el diseño de lenguaje estático, y todos nos beneficiamos de la competencia. Solo espero que más de estas características lleguen a la stream principal.

Hay un lugar donde no veo que se reemplace el lenguaje dynamic dominante, y es Javascript en el navegador. Simplemente hay demasiado de un mercado existente para reemplazar, por lo que el énfasis parece estar en hacer que Javascript sea mejor en su lugar.

Aquí está Steve Yegge sobre el tema.

Guido van Rossum también se vinculó a esa charla en su versión de Scala .

“Tengo curiosidad por saber cuáles son los beneficios de los lenguajes dynamics, incluso cuando los tienes”.

Comparado con el lenguaje de progtwigción D:

  • Python es un lenguaje más compacto. Le permite express tanto como D, pero utiliza muchos menos conceptos diferentes para lograrlo; menos es más .

  • Python tiene una poderosa biblioteca estándar, baterías incluidas .

No sé si D tiene indicaciones interactivas pero en Python, una shell interactiva como ipython es una parte integrada del proceso de desarrollo.

Ejemplo en Python:

def lengths(sequence): try: return sum(len(item) for item in sequence) except TypeError: return "Wolf among the sheep!" >>> lengths(["a", "b", "c", (1, 2, 3)]) 6 >>> lengths( ("1", "2", 3) ) 'Wolf among the sheep!' 

¿Cuánto tiempo crees que me llevó esto para escribir, y cuántos ciclos de comstackción, ejecución y depuración?

Si crees que mi ejemplo es trivial, puedo responder diciendo que los lenguajes dynamics hacen triviales muchas tareas de progtwigción.

En los idiomas dynamics, puede utilizar los valores de manera que sepa que son correctos. En un lenguaje de tipo estático, solo puede usar valores de manera que el comstackdor sepa que son correctos. Necesita todas las cosas que mencionó para recuperar la flexibilidad que le quitó el sistema de tipos (no estoy atacando a los sistemas de tipo estático, la flexibilidad a menudo se la quitan por buenas razones). Esta es una gran cantidad de complejidad con la que no tiene que lidiar en un lenguaje dynamic si desea usar valores de maneras que el diseñador de lenguaje no anticipó (por ejemplo, poner valores de diferentes tipos en una tabla hash).

Entonces, no es que no puedas hacer estas cosas en un lenguaje tipado estáticamente (si tienes una reflexión de tiempo de ejecución), es más complicado.

De hecho, escribí una publicación de blog sobre esto: linky . Pero ese post básicamente se puede resumir así:

Te sorprendería saber cuánta carga de tu mente es no tener que nombrar en el momento de la comstackción el tipo de variable que es. Por lo tanto, python tiende a ser un lenguaje muy productivo.

Por otro lado, incluso con buenas pruebas de unidad, también te sorprenderías de los errores estúpidos que te permites cometer.

Una gran ventaja de la escritura dinámica cuando se usan objetos es que ya no es necesario usar jerarquías de clases cuando se desea que varias clases tengan la misma interfaz, eso es más o menos lo que se llama escritura de pato. La mala herencia es muy difícil de arreglar después, esto hace que la refactorización sea a menudo más difícil de lo que es en un lenguaje como python.

El punto es que en un lenguaje dynamic puede implementar la misma funcionalidad mucho más rápido que en un lenguaje estático. Por lo tanto la productividad suele ser mucho mayor.

Las cosas como las plantillas o el polymorphism en principio te dan mucha flexibilidad, pero tienes que escribir una gran cantidad de código para que funcione. En un lenguaje dynamic esta flexibilidad casi viene gratis.

Así que creo que se ve la diferencia de manera equivocada, la productividad es realmente el punto principal aquí (al igual que la recolección de basura mejora la productividad, pero de lo contrario no te permite hacer cosas nuevas).

Con un lenguaje dynamic, es mucho más fácil tener un intérprete de línea de comandos para que pueda probar las cosas en la línea de comandos y no tenga que preocuparse por un paso de comstackción para ver si funcionan.

Encuentro lenguajes dynamics como Perl y, en menor medida, Python me permite escribir scripts rápidos y sucios para las cosas que necesito hacer. El ciclo de ejecución es mucho más corto en lenguajes dynamics y, a menudo, se necesita escribir menos código en un lenguaje estático, lo que aumenta mi productividad. Desafortunadamente, esto conlleva el costo de la capacidad de mantenimiento, pero eso es un error de la forma en que escribo los progtwigs en lenguajes dynamics, no en los mismos idiomas.

Iba a decir cierres pero encontré este hilo … (no es que entienda cómo funcionaría en un lenguaje “estático”)

Los conceptos relacionados son funciones-como-objetos de primera clase y procedimientos de orden superior . (por ejemplo, una función que toma una función como entrada y / o devuelve una función como salida)

edit: (para los nitpickers aquí) Me haré eco de un comentario que hice en la publicación de @David Locke. Los idiomas interpretados dinámicamente permiten utilizar un progtwig / proyecto de software existente junto con una función o clase pequeña creada en el momento para explorar algo de manera interactiva. Probablemente el mejor ejemplo sea la función gráfica. Si escribiera un objeto de función gráfica con una función de graph(f,xmin,xmax) , podría usarlo para explorar funciones como x 2 o sin (x) o lo que sea. Hago esto en MATLAB todo el tiempo; se interpreta y tiene funciones anónimas ( @(x) x^2 ) que pueden construirse en el indicador del intérprete para pasar a funciones de orden superior (funciones de representación gráfica, operadores derivados, buscadores de raíces, etc.).

Eche un vistazo a este ejemplo de e4x en JavaScript:

 var sales =     ; alert( sales.item.(@type == "carrot").@quantity ); alert( sales.@vendor ); for each( var price in sales..@price ) { alert( price ); } 

Especialmente, eche un vistazo a la línea:

 alert( sales.item.(@type == "carrot").@quantity ); 

En los lenguajes estáticos típicos, no puede escribir sales.item, ya que no puede saber que el artículo es propiedad de las ventas hasta el tiempo de ejecución. Esto no se limita a e4x. Puede progtwigr en un estilo similar cuando se conecta al escribir clientes SOAP o cualquier otro tipo subyacente que no conoce hasta el tiempo de ejecución. En un lenguaje estático, normalmente necesitaría ejecutar una herramienta que generará clases de stub o progtwig de una manera muy detallada. Luego, si algo cambia en un servicio web, debe volver a generar los apéndices nuevamente. Echa un vistazo al código DOM de Java:

 import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; public class Foo { public Document createDocument() { Document document = DocumentHelper.createDocument(); Element root = document.addElement( "root" ); Element author1 = root.addElement( "author" ) .addAttribute( "name", "James" ) .addAttribute( "location", "UK" ) .addText( "James Strachan" ); Element author2 = root.addElement( "author" ) .addAttribute( "name", "Bob" ) .addAttribute( "location", "US" ) .addText( "Bob McWhirter" ); return document; } } 

Definitivamente mucho más detallado que su código dynamic. Y, por supuesto, no está tipificado estáticamente. No hay forma de verificar que escribió mal el “autor” como “autor” hasta el tiempo de ejecución. Toda esta verbosidad está esencialmente ahí para permitirle capturar algo que es de naturaleza dinámica en estilo estático.

Creo que este es uno de los puntos fuertes de los lenguajes dynamics.

Los lenguajes comstackdos tienden a usarse cuando la eficiencia y la seguridad de tipos son las prioridades. De lo contrario no puedo pensar en ninguna razón por la que alguien no esté usando ruby ​​:)