- λ-2D es un experimento de lenguaje en el que el dibujo mismo funciona como código, y busca tanto expresiones visuales difíciles de manejar en lenguajes de texto como la forma estética de los programas
- La base del lenguaje es el cálculo lambda, y parte de la idea de que una estructura más cercana a la evaluación que a un orden fijo de ejecución se parece a la forma en que observamos un dibujo
- Usa símbolos basados en cuadrículas y cables para representar el flujo de datos, de modo que sea fácil de dibujar a mano pero también interpretable por una máquina
- Como el cálculo lambda puro tiene poca usabilidad, se agregan azúcares sintácticos e interfaces de interacción como números, operadores matemáticos, marcos y deslizadores
- La implementación actual convierte los programas λ-2D en una sola expresión de JavaScript para ejecutarlos, aunque todavía quedan límites como su apariencia similar a un diagrama de circuitos y dificultades de aprendizaje y escaneo
Un experimento de lenguaje para programar con dibujos
- λ-2D es un experimento de lenguaje de programación no verbal que parte de la pregunta: “¿se puede programar a través de dibujos?”
- Ya existen varias líneas de lenguajes no basados en texto
- El objetivo del diseño se resume en tres puntos
- Aprovechar el hecho de que los programas se dibujan para incorporar funciones difíciles de lograr en lenguajes basados en texto
- Evitar situaciones donde haya tan pocas instrucciones que incluso un programa simple sea difícil, o tantas que deje de ser minimalista y complique el procesamiento por visión por computadora
- Hacer que el programa en sí sea visualmente atractivo, al punto de convertirse en un dibujo que uno quisiera enmarcar y colgar
Cálculo lambda y representación basada en cuadrículas
- λ-2D toma como base del lenguaje el cálculo lambda en lugar de un enfoque imperativo o de bajo nivel
- El cálculo lambda está más cerca de la “evaluación” que de la “ejecución”, y eso conecta con la forma en que la mirada recorre un dibujo sin un orden específico, siguiendo puntos, líneas, formas y composición
- La estructura inicial es un sistema basado en cuadrículas
- El usuario puede dibujar una línea continua que atraviese varias cuadrículas
- Cada cuadrícula se interpreta finalmente como uno de un conjunto finito de símbolos
- Es una solución intermedia: fácil de dibujar para las personas y fácil de parsear para la computadora
Símbolos de función y flujo de datos por cables
- El cálculo lambda tiene solo dos instrucciones básicas
- Aplicación de función
- Definición de función
- λ-2D representa la aplicación de función con un símbolo en forma de copa y la definición de función con la letra griega λ
- Como en el cálculo lambda básico, una función siempre recibe un solo argumento y produce una sola salida
- Para manejar varios argumentos, se usa currificación (currying), conectando varias funciones
- Los cables entre símbolos actúan como rutas por donde fluye la información
- En esta etapa, el lenguaje es técnicamente Turing completo, pero su uso real es muy incómodo, por lo que se añadieron símbolos extra como números y operadores matemáticos
- Estos símbolos extra son azúcar sintáctico
- Si se quiere, también se pueden usar solo estructuras de cálculo lambda puro como los Church numerals
Marcos, datos de dibujo y deslizadores
- λ-2D busca extender de forma más natural la experiencia de Scratch, donde se dibujan sprites en el mismo editor y se usan de inmediato
- Los marcos consisten en rodear con cables una zona específica del lienzo y colocar un símbolo de visualización en la esquina superior izquierda
- Los garabatos dentro de esa zona pueden usarse como datos
- Se puede esbozar directamente la forma de una función matemática para usarla, por ejemplo, en animaciones
- La forma se trata como dato sin una etapa separada para encontrar primero la ecuación
- También se introducen deslizadores que pueden arrastrarse en tiempo de ejecución
- Sirven para controlar el programa de manera paramétrica
- En el futuro también se contemplan otros elementos de GUI
El editor y los símbolos de 5×5
- La idea inicial surgió de programas de ejemplo dibujados a mano en cuadernos con puntos
- Como la parte de visión por computadora para escanear programas en papel aún no estaba lista, primero se creó un editor simple para dibujar programas en digital
- Cada símbolo está hecho con 5×5 píxeles para que sea fácil colocarlo en un lienzo cuadriculado
- El usuario también puede hacer dibujos a mano alzada como si usara una herramienta de lápiz
- Lo que empezó como una medida provisional fue acercándose poco a poco a un editor con varias funciones
El problema de la salida en un lenguaje puramente funcional
- λ-2D es puramente funcional y no tiene estado, por lo que es difícil implementar una instrucción
printconvencional - La salida implica un cambio de estado, y para esperar que se produzca en un orden específico también habría que asumir un orden de evaluación de expresiones
- La solución consiste en redefinir “salida” de forma funcional
- Se pasa un lienzo vacío a una función
- Se recibe de vuelta un nuevo lienzo con píxeles modificados para que se vea como texto o como el garabato deseado
- El lenguaje está diseñado en torno a lienzos y píxeles, no a cadenas y caracteres
Conversión a JavaScript y visualización de la ejecución
- El parser básico convierte todo el programa λ-2D en una expresión equivalente de JavaScript
- El JavaScript resultante es una sola expresión gigante llena de paréntesis; es ineficiente, pero funciona
- Como el parser actual emite JavaScript y deja la ejecución real al motor de JavaScript del navegador, es difícil visualizar el proceso de ejecución real
- En cambio, el proceso de parseo sí se puede visualizar con facilidad, y puede verse parecido a la ruta que recorrería un intérprete por recorrido de árbol al ejecutar el programa
- Si a la animación de parseo se le añaden sonidos por símbolo, se puede “escuchar” la ejecución del programa como si fuera una canción
- El resultado se parece más al sonido de un extraño videojuego de computadora de la era de los 8 bits
- Puede verse en el demo en línea en
Menu > Program > Animated Run
Limitaciones pendientes y siguientes pasos
- λ-2D comenzó originalmente como parte de una investigación más amplia sobre dibujar programas con lápiz y papel y recibir retroalimentación interactiva mediante realidad aumentada
- A medida que el proyecto se volvió más interesante, pasó a ser un proyecto independiente
- Aún no cumple por completo sus objetivos iniciales
- Los programas tienden a parecer más diagramas de circuitos que dibujos
- No es fácil tener certeza de que sea sencillo de aprender para el público general
- Puede que tampoco sea fácil para un sistema de visión por computadora escanearlo sin errores
- Después de refinar más λ-2D, se planea diseñar otros lenguajes de programación que puedan integrarse en sistemas que traten los dibujos como computación
- La versión beta de λ-2D puede probarse en línea, y el código fuente del parser y del editor se publicará pronto en GitHub
1 comentarios
Opiniones en Hacker News
Si te gusta este tipo de cosas, el trabajo de ingeniero de proyectos de automatización podría resultarte divertido, o al menos familiar.
Los diagramas de bloques funcionales (FBD) son bastante parecidos: los bloques funcionales se conectan con líneas y el orden de ejecución se define por el orden de los bloques. Los bloques en sí pueden ser como funciones integradas del motor, o pueden ser bloques compuestos. El diagrama se ejecuta una vez por cada ciclo de control y, por lo general, si no hay bloques de salto, cada bloque se ejecuta exactamente una vez por ciclo de control, independientemente de si cambian o no las entradas.
Así se implementa la lógica de control de todo, desde cervecerías hasta plantas petroquímicas. Trabajo en la parte de UI de sistemas de control basados en FBD, así que veo estas cosas todos los días.
Se parece a BitGrid[1], pero no es lo mismo. Imagino algo como una versión extremadamente simplificada de un FPGA, con bits marchando en paralelo sobre una cuadrícula.
Esta idea podría tener una utilidad enorme —petaflops para las masas— o no; al final depende de cuánta energía consuma un DFF en un ASIC. El número que llevo mucho tiempo buscando es la potencia estática y la energía para cargar un bit.
El modelo de programación también es un problema. Nadie quiere colocar lógica directamente sobre una cuadrícula; todos quieren abstraerlo lo antes posible. No tengo suficiente concentración como para resolver esa parte.
Mientras exploraba esto descubrí el autómata celular de Von Neumann[2] y los autómatas celulares de Nobili[3], que nunca había visto pese a llevar décadas interesado en ideas parecidas. Es frustrante lo poco descubrible que es esta área de la informática.
Ambos comparten la misma base absurda: un conjunto de FSA define un espacio de celdas de tamaño infinito, y todos los FSA tienen la misma función de transición de estados o conjunto de reglas. Siento que justo esa “simplificación” los empuja al terreno del code golf.
[1] https://github.com/mikewarot/Bitgrid
[2] https://en.wikipedia.org/wiki/Von_Neumann_cellular_automaton
[3] https://en.wikipedia.org/wiki/Nobili_cellular_automata
Si alguien quiere continuar con la idea de BitGrid, se lo agradecería.
En la parte que dice “técnicamente, en este punto el lenguaje es Turing completo, pero es extremadamente doloroso de usar, así que viola mi regla de diseño #2”, mis Lambda Diagrams[1] se quedaron en la etapa 1.
Al final de esa página están enlazadas todas las demás notaciones gráficas de cálculo lambda que conozco, y acabo de agregar esta también.
[1] https://tromp.github.io/cl/diagrams.html
Ahora puedes afirmar que creaste un lenguaje que hace que el navegador diga “¡para mí todo esto es griego!”, así que me parece un logro bastante genial.
Eso ya lo dejamos atrás en los 90, cuando aparecieron las pantallas de alta resolución.
https://worrydream.com/AlligatorEggs/
Este tipo de cosas también se ha intentado en LabVIEW, y se ve lo difícil que es llevarlas lejos. También se ha hecho en programas de generación de sonido/música; Max [max] es prácticamente el original en ese campo.
Puedes construir cosas, pero se vuelven desordenadas muy rápido. ¿Se ven bien? Yo diría que no.
[max] https://en.wikipedia.org/wiki/Max_(software)
Los flujos de señal complejos son mucho más fáciles de seguir en una disposición visual —sobre todo en un diagrama donde los valores numéricos en tiempo real se muestran animados— que en bloques de texto estáticos.
En versiones recientes de Max/MSP también existe
mc, que ofrece conexiones multicanal para múltiples señales iguales sin tener que crear líneas/nodos separados, y~geny JavaScript permiten nodos de programación basados en texto.Este tipo de “lenguajes de programación por bloques” parecen prometedores porque abstraen mediante cajas negras y cajas dentro de cajas. Me pregunto si el problema es una mala implementación, que no se saben usar, o que el paradigma en sí no funciona.
Algo a considerar es que normalmente los usan personas que no conocen la programación ni la abstracción. Alguien que programe bien quizá no haría un desastre, pero entonces bien podría escribir código directamente, así que queda medio ambiguo.
Coincido en que LabVIEW es horrible. No solo por este problema: las actualizaciones rompen todo, el tema de las licencias también, y en general es un dolor de cabeza.
Había una pequeña comunidad de desarrolladores profesionales de LabVIEW que, en general, escribía código muy bueno y muy legible. Era distinto a lo que le resulta familiar a la mayoría, pero era bueno.
Dicho eso, dejé ese mundo hace unos años, porque las señales de que LabVIEW terminaría muriendo eran claras, sin importar lo que pudiera hacerse con él.
Desde que escuché hablar por primera vez de las redes de Petri hace unos 10 años, me interesaron las especificaciones formales gráficas.
Siempre sentí que, si en lugar de notación matemática y lenguajes intimidantes hubiera representaciones gráficas, los ingenieros aprovecharían mejor los métodos formales. Lamentablemente, cada vez que les mostraba redes de Petri a otros ingenieros, perdían el interés casi de inmediato.
Antes de abandonar el doctorado en la University of York, trabajé con algo llamado RoboChart y RoboSim[1], que en la práctica podrían ser más accesibles. Aunque están bastante ligados a la semántica de robótica. Como proyecto personal, he intentado adaptar y ampliar RoboSim para que sea más útil en el mundo de redes y servidores.
[1] https://robostar.cs.york.ac.uk/robotool/
Esto me encanta. En especial, me gusta aún más que esté implementado en JavaScript.
Los puristas se revolcarán en la cama o en la tumba, pero al menos eso seguramente facilitó mucho la visualización y los pasos posteriores de audio. Lo visual está increíble, y el siguiente paso parece ser traducir de algún modo la estructura de alto nivel de programas existentes a este formato. Seguramente hay bastantes geeks que pagarían por colgar en la pared el algoritmo de Dijkstra o el algoritmo de retropropagación de una red neuronal artificial.
La parte que me pareció interesante fue que, como el lenguaje es demasiado puramente funcional y completamente sin estado, no se puede implementar una sentencia
print. La salida implica cambiar el estado, y esperar que se imprima en un orden determinado implica asumir que las expresiones se evalúan en algún orden.¿No es eso simplemente decir que “no es imperativo”? Aun así, me da curiosidad cómo codificarían el estado. Quizá podrían introducir variables, por ejemplo ícono+color, y ordenar sentencias individuales según un eje o ambos ejes.
“El área de los lenguajes de programación no verbales no está sin explorar”.
Desde la segunda oración arranca con una triple negación agresiva.
Me hizo pensar en Wireworld, de 1987. Por supuesto, también tiene artículo en Wikipedia [1].
Vi un contador de 8 bits implementado en Wireworld y era bastante impresionante. Aunque esto parece un poco más conciso.
[1]: https://en.wikipedia.org/wiki/Wireworld
Aunque ahora es difícil jugarlo, porque la página web[1] y la versión de Steam dependían de Flash, y hay que meterse con reimplementaciones de Flash de terceros.
Aun así, creo que su implementación del funcionamiento de semiconductores es mucho mejor que Wireworld.
[1] https://www.zachtronics.com/kohctpyktop-engineer-of-the-peop...
Enlace directo a la demo en línea: https://l-2d.glitch.me/
Estos son otros entornos/lenguajes de programación muy visuales que encontré. Son distintos de otros tipos de programación visual que conectan nodos con líneas.
Se podrían clasificar de otra forma, pero no sé cómo llamarlos.
Piet https://www.dangermouse.net/esoteric/piet.html
Turnstyle https://jaspervdj.be/turnstyle/ https://github.com/jaspervdj/turnstyle
Markovjunior https://github.com/mxgmn/MarkovJunior
Cellpond https://cellpond.cool/ https://github.com/TodePond/CellPond https://www.youtube.com/watch?v=xvlsJ3FqNYU
Imagegram https://zaratustra.itch.io/imagegram
Color Code http://colorcode.bananabanana.me/ https://www.youtube.com/watch?v=5M5hy9xsqKc Color Code 2 http://colorcode2.bananabanana.me/ https://www.youtube.com/watch?v=tTvvX4sjZWw Splaty Code http://splatycode.bananabanana.me/ https://www.youtube.com/watch?v=gd_e85lAKOs (creado por Muril Polese https://github.com/murilopolese/ http://gallery.bananabanana.me/)
Alchemy Online https://maxbittker.github.io/alchemy-online/ https://github.com/MaxBittker/alchemy-online