¿Qué características del lenguaje de progtwigción son adecuadas para desarrollar un marco de encoding en vivo?

Me gustaría construir un “marco de encoding en vivo”.

Debería explicar qué se entiende por “marco de encoding en vivo”. Lo haré comparando la encoding en vivo con la encoding tradicional.

En general, en la progtwigción tradicional se escribe código, a veces se comstack, luego se inicia un ejecutable o se abre un script en algún tipo de intérprete. Si desea modificar su aplicación debe repetir este proceso. Un marco de encoding en vivo permite que el código se actualice mientras la aplicación se ejecuta y se vuelve a cargar a pedido. Quizás esta recarga ocurra cada vez que se cambie un archivo que contenga código o por alguna otra acción. Los cambios en el código se reflejan en la aplicación a medida que se ejecuta. No es necesario cerrar el progtwig y volver a comstackrlo y reiniciarlo.

En este caso, la aplicación es una aplicación de ventana que tiene un ciclo de actualización / extracción, lo más probable es que utilice OpenGL para gráficos, una biblioteca de audio para procesamiento de sonido (SuperCollider?) Y, idealmente, una biblioteca de red.

Por supuesto, he preferido los idiomas, aunque no estoy seguro de que alguno de ellos sea adecuado para este tipo de architecture. Lo ideal sería utilizar Python, Lua, Ruby u otro lenguaje de nivel superior. Sin embargo, un amigo sugirió recientemente a Clojure como una posibilidad, así que también lo estoy considerando.

Me gustaría saber no solo qué idiomas serían adecuados para este tipo de marco, sino que, en general, qué características lingüísticas harían posible un marco como este .

Clojure tiene prácticamente todo lo que es probable que desee como lenguaje de encoding en vivo. Destacados principales:

  • REPL interactivo – para que pueda interactuar directamente con su progtwig en ejecución. Incluso cuando estoy haciendo “progtwigción tradicional”, tiendo a escribir código de manera interactiva y luego copiar los bits que me gustan a un archivo fuente. Clojure está diseñado para funcionar de esta manera: casi todo en su progtwig es inspeccionable, modificable y reemplazable en tiempo de ejecución.
  • Excelente soporte de concurrencia : puede iniciar tareas de fondo concurrentes de forma trivial con código como (future (some-function)) . Más importante aún, el STM de Clojure y el énfasis en las estructuras de datos inmutables de alto rendimiento se ocuparán de los aspectos más sutiles de la concurrencia (por ejemplo, ¿qué sucede si actualizo una estructura de datos en vivo mientras se está procesando?)
  • Disponibilidad de la biblioteca : es un lenguaje JVM para que pueda extraer todas las herramientas de audio, visuales, IO o computacionales que necesite del ecosistema de Java. Es fácil envolver estos en una o dos líneas de Clojure para que obtenga una interfaz concisa para las funciones que necesita
  • Macros : como Clojure es un lenguaje homoicónico , puede aprovechar la capacidad de Lisp para escribir macros potentes que amplían el lenguaje. Puede construir efectivamente la syntax exacta que desea usar en el entorno en vivo y dejar que el comstackdor haga todo el trabajo duro de crear el código completo entre bambalinas.
  • Escritura dinámica : los beneficios de esto se pueden argumentar de ambas maneras, pero sin duda es un gran beneficio al tratar de escribir código de forma rápida y concisa.
  • Comunidad activa con muchos proyectos interesantes : es probable que encuentre mucha gente interesada en técnicas de encoding en vivo similares en la comunidad de Clojure.

Un par de enlaces que te pueden interesar:

  • Paul Graham en Lisp – superando los promedios
  • Ejemplo de encoding de Live Clojure con el sintetizador de sonido Overtone (una interfaz para SuperCollider)

He implementado una función de encoding en vivo en Lua como parte del IDE de ZeroBrane Studio . Funciona exactamente como se describe al volver a cargar la aplicación cuando se realiza un cambio en el código. Estoy trabajando en posibles mejoras para modificar los valores en tiempo de ejecución para evitar la recarga completa de la aplicación. Es una solución basada exclusivamente en Lua y no requiere modificaciones a la máquina virtual.

Puede ver la demostración de la encoding en vivo tal como se implementa actualmente aquí: http://notebook.kulchenko.com/zerobrane/live-coding-in-lua-bret-victor-style .

En cuanto a las características de lenguaje utilizadas / requeridas, confío en:

  1. la capacidad de interrumpir / reanudar una aplicación en ejecución (esto se basa en las llamadas debug.hook y error ()),
  2. la capacidad de interactuar con la aplicación (no modificada) de forma remota (esto se realiza en función de debug.hook, TCP interacciones con el soporte de selección () para detectar si se está enviando una nueva solicitud desde la máquina host, y también en las rutinas para cambiar entre la aplicación principal y el módulo de encoding en vivo), y
  3. la capacidad de inyectar código nuevo en la aplicación (este mecanismo también utiliza co-rutinas, pero estoy seguro de que hay alternativas). También existe la posibilidad de inyectar solo un fragmento modificado, pero debe estar al nivel de una función, y si esta función es local a alguna otra función, debe incluirla también, y así sucesivamente.

Lo único que se necesita para hacer que esto funcione es una forma de enlace dynamic, por ejemplo, pasar mensajes en Erlang o eval en muchos otros idiomas.

Si tiene un enlace dynamic, entonces puede cambiar el destino de un mensaje sin afectar el mensaje, o un mensaje sin afectar al destino, siempre que se defina un destino cuando intente enviarle un mensaje y se haya definido un mensaje para Los objectives a los que lo envías, cuando lo envías.

Cuando cambie un objective, todo lo que tiene que hacer es enviar los mensajes a la versión anterior hasta que la nueva versión esté en su lugar, luego haga una pequeña actualización bloqueada para pasar a la nueva versión. De manera similar, al cambiar un mensaje, solo sirve la versión anterior hasta que la nueva esté disponible.

Sin embargo, el código fácilmente intercambiable en caliente todavía debe diseñarse como tal: la aplicación debe ser lo suficientemente modular como para que la sustitución de la implementación de un componente no cause una interrupción, y eso solo puede provenir de una progtwigción cuidadosa.

Es bueno y bueno tener ‘encoding en vivo’ en su caja de desarrollo, pero una forma de interactuar directamente con un servidor implementado lo acerca mucho más a ser ‘real’. Para ello necesitas una red REPL .

clojure proporciona esto muy bien en forma de un socket repl . Esto le permite conectarse de forma remota a la versión en ejecución de su código en su servidor tomcat implementado (por ejemplo). Luego puedes adjuntar tu herramienta de desarrollo favorita habilitada para swank y hackear.

Tcl ya tiene tal cosa. Por ejemplo, puede escribir un progtwig gui que cree una ventana separada que tenga un indicador interactivo. Desde allí puede recargar su código, escribir un nuevo código, etc.

Puedes hacer esto con cualquier juego de herramientas de GUI, aunque algunos serán mucho más difíciles que otros. Debería ser fácil con python, aunque la sangría (IMHO) hace que el uso interactivo sea un desafío. Estoy razonablemente seguro de que la mayoría de los otros lenguajes dynamics pueden hacer esto sin demasiados problemas.

Míralo de esta manera: si tu kit de herramientas te permite abrir más de una ventana, no hay razón por la que una de esas ventanas no pueda ser un indicador interactivo. Todo lo que necesita es la capacidad de abrir una ventana y algún tipo de comando “eval” que ejecuta el código que se le envía como una cadena.

python en google appengine tiene repote_api_shell.py. esta no es una suite de encoding en vivo completa – clojure en emacs w / swank-clojure ha tenido mucho más uso en la vida real en cuanto a la integración de ‘encoding en vivo’ en los ritmos de desarrollo cotidianos – pero mucha gente no se da cuenta de que esto es posible en ciertos entornos de python.

 $ PYTHONPATH=. remote_api_shell.py -s dustin-getz.appspot.com App Engine remote_api shell Python 2.7.1 (r271:86832, Jun 16 2011, 16:59:05) [GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] The db, users, urlfetch, and memcache modules are imported. dustin-getz> import models dustin-getz> models.BlogPost(title='a modern take on automated testing', link='https://docs.google.com/document/pub?id=1DUxQogBg45rOTK4c5_SfEHiQcvL5c207Ivcy-gDNx2s', dont_publish_feed=False).put() dustin-getz> items = models.BlogPost.all().filter('dont_publish_feed =', False).order('-published_date').fetch(100) dustin-getz> len(items) 58 dustin-getz> for item in items[:5]: print item.title a modern take on automated testing Notes: Running a startup on haskell the [un]necessity of superstar middle management in bigcos "everything priced above its proper value" stages of growth as a software engineer 

Smalltalk es probablemente la mejor apuesta para esto. Como a diferencia de los otros, tiene un IDE completo para la encoding en vivo, no solo un REPL

Estoy trabajando en una función de encoding en vivo para el editor Python de PyDev. Fue inspirado por la charla Inventing on Principle de Bret Victor, y he implementado una pantalla de estado de progtwig así como gráficos de tortuga. Ambos se actualizan a medida que escribes tu código Python en Eclipse.

El proyecto está alojado en GitHub , y he publicado un video de demostración , así como un tutorial .

Las características principales de Python que utilicé fueron los árboles de syntax abstracta y la ejecución dinámica de código. Tomo el código del usuario, lo analizo en un árbol y luego instrumento cualquier statement de asignación, iteraciones de bucle y llamadas a funciones. Una vez que he instrumentado el árbol, lo ejecuto y visualizo el informe o dibujo los gráficos de tortuga solicitados.

No he implementado la función de intercambio que discuten otras respuestas. En su lugar, siempre ejecuto el código para completar o un tiempo de espera. Imagino la encoding en vivo como una mejora del desarrollo guiado por pruebas, no como una forma de piratear una aplicación en vivo. Sin embargo, voy a pensar más en lo que me permitiría hacer el intercambio de piezas de una aplicación en vivo.