1 puntos por GN⁺ 11 시간 전 | 1 comentarios | Compartir por WhatsApp
  • let-go es un dialecto de Clojure escrito en Go, con compilador a bytecode y una VM de pila, que funciona sin JVM como un único binario de ~10 MB
  • El arranque en frío es de unos 7 ms y, según la suite de pruebas de Clojure de jank-lang, su compatibilidad con Clojure se presenta como 4696 / 4921 assertions superadas (95.4%)
  • Su autor lo usa para CLI, scripting y servidores web; además construyó sobre let-go un runtime de contenedores sin daemon, y puede compilar a binarios independientes o a páginas web WASM autocontenidas
  • El objetivo es implementar muchas funciones de Clojure como persistent data structures, lazy seqs, transducers, protocols, records, multimethods, core.async y BigInts, además de ofrecer interop bidireccional con funciones, struct y channel de Go
  • No es un drop-in replacement de Clojure sobre JVM, no carga JARs, y los proyectos reales con dependencias de librerías requieren ajustes
  • En benchmarks sobre Apple M1 Pro se reporta tamaño de binario de 10 MB, tiempo de arranque de 6.7 ms y memoria en reposo de 13.5 MB, mostrando ventaja en unidades de ejecución más pequeñas frente a Babashka, Joker, go-joker, gloat y Clojure JVM
  • En tareas de cálculo numérico más grandes, el WASM JIT de go-joker o una JVM con HotSpot ya calentada quedan por delante; let-go se resume como similar a Babashka en la mayoría de los benchmarks algorítmicos y más de 10 veces más rápido que Joker upstream
  • Los namespaces estándar incluyen clojure.core, clojure.string, clojure.set, clojure.edn, clojure.test, clojure.core.async, io, http, json, transit, os, System, syscall, pods, entre otros
  • Puede cargar Babashka pods, por lo que puede usar ese ecosistema de pods para SQLite, AWS, Docker, vigilancia de archivos y más, y comparte ~/.babashka/pods/ con bb
  • Entre las limitaciones conocidas están la falta de implementación de Refs / STM, Agents, hierarchies, reader tagged literals, deftype, reify, clojure.spec, alter-var-root, subseq / rsubseq, así como la ausencia de detección automática de overflow de int64
  • Entre las diferencias de comportamiento, el bloque go no es una máquina de estados IOC sino una goroutine real; las regex usan re2 de Go en lugar de las regex de Java, y el sistema numérico se compone de int64 + float64 + BigInt
  • La instalación es posible con Homebrew para macOS/Linux, desde Releases para Linux, macOS y Windows en amd64/arm64, o con Go 1.22+ usando go install github.com/nooga/let-go@latest
  • lg soporta REPL, evaluación de expresiones y ejecución de archivos, y además ofrece compilación a bytecode .lgb, empaquetado como ejecutable standalone y creación de apps web WASM
  • La salida WASM consiste en un index.html autocontenido con WASM inline de unos 6 MB gzipped y un service worker; al usar el namespace term, ofrece emulación de terminal basada en xterm.js
  • El servidor nREPL integrado funciona con CIDER, Calva y Conjure; dentro de programas en Go también se puede embeber let-go mediante pkg/api como una capa de scripting para pasar valores, funciones, struct y channel de Go a la VM

1 comentarios

 
Opiniones de Hacker News
  • ¡Está bueno! Hace poco estuve experimentando con ponerle sintaxis Lisp a la semántica de Go: https://codeberg.org/veqq/Joe
    Entre los lenguajes tipo Clojure sin JVM, Janet también está muy bien, y lo he estado usando en producción desde hace un tiempo: https://janet-lang.org/
    Si quieres la VM y las bibliotecas de Lua, también está Fennel

    • Joe se ve bien. No he usado Janet directamente, pero siempre pensé que era un lenguaje que iba en su propia dirección en vez de intentar seguir a Clojure
  • También vale la pena probar este REPL de navegador en Wasm: https://gloathub.org/repl/
    Gloat es una herramienta de automatización AOT para Glojure
    El verano pasado hice posible el AOT de Glojure junto con James Hamlin, y desde entonces he seguido desarrollándolo. También estoy trabajando con marcingas(nooga) para que Gloat/Glojure/let-go colaboren bien entre sí

  • Sorprende que funcione en Plan 9
    Estaría genial que Go se volviera un lenguaje de primera clase, o sea incluido por defecto, en 9front
    Estoy trasteando con una red social para Plan 9: https://youtube.com/watch?v=q6qVnlCjcAI&si=MBCeM0QdA0WsKAe7
    Está hecha completamente con rc y awk, pero hubo partes donde habría estado bien tener algo de Go o Clojure por ahí

    • Me gustó la demo de 9social. Yo no uso Plan 9 directamente, pero siempre me inspiran las formas de hacer las cosas al estilo Plan 9
    • Empecé a distribuir binarios amd64 y arm de 32 bits para Plan 9 en los releases de GitHub
      Probé amd64 en 9front y parece que todo funciona bien. La CLI no se siente muy Plan 9 todavía, pero en algún momento me gustaría hacer el port más nativo
  • Ahora mismo hay varios dialectos de Clojure sobre Go, así que lo que más me interesa saber es cuál de ellos está completamente hosteado sobre Go y ofrece un nivel de interoperabilidad comparable al que tiene Clojure de JVM con Java
    Me gustaría poder usar desde Go lo que yo haga, y desde Clojure usar Go, e incluso armar proyectos mixtos. También estaría bueno que, aparte de la interoperabilidad, se detallara qué cosas son iguales, cuáles no y cómo difieren

    • Gloat/Glojure parece tener la mejor historia del lado del runtime hosteado gracias a su pipeline AOT a código fuente Go. En tiempo de compilación puede importar cualquier cosa de Go
      En cambio, let-go puede pasar de ida y vuelta cualquier valor de Go, incluyendo structs, funciones y canales, pero no puede traer directamente bibliotecas arbitrarias de Go sin envolverlas antes. Esas bibliotecas tienen que estar compiladas en el runtime
  • Es un detalle menor, pero en el README dice arranque en frío de 7 ms y unas líneas más abajo dice 6 ms. Capaz que se vuelve más rápido cuanto más lees el README

    • Ya lo corregí. En mi máquina da entre 6 y 7 ms, y la mediana parece estar alrededor de 6.5 ms
  • Es exactamente el tipo de port de Clojure que siempre estuve buscando
    Porque siempre pensé que la biblioteca estándar de Go y la abstracción de canales daban una API base más simple y mejor, y que además encajaría bien con APIs del estilo core.async. También satisface esa necesidad de un gran binario monolítico
    Gracias por el trabajo; cuando se me baje un poco mi nueva afición por C++26, sin duda voy a volver a mirarlo
    Además, no sé por qué Glojure no estaba en mi radar, y este también parece un proyecto excelente

    • Alguna vez pensé en la idea de crear un DSL al estilo del PHP antiguo que aprovechara internamente el runtime y los paquetes de Go
      Digo PHP antiguo porque originalmente PHP era más parecido a un DSL centrado en la web; ahora ya no. Una especie de lenguaje backend fácil de escribir, parecido a PHP pero con la potencia de Go detrás, sonaría interesante, y Clojure sería una gran elección
    • Si después llegas a usarlo de verdad, me encantaría que dejaras uno o dos issues
  • Como alternativa también está Joker: https://joker-lang.org
    Es realmente excelente y creo que está totalmente subestimado

    • Lo que más valoro de Joker es que el wrapping de bibliotecas de Go es muy fluido. Parece cubrir todo lo que ofrece Go
      Aun así, no quiero agregarle demasiadas cosas a let-go. Me gusta que quepa dentro de 10 MB
  • Ojalá el nombre del lenguaje fuera mejor que simplemente “lets-go”. ¿Qué tal “clogo”?

    • Poner nombres es difícil, pero me gusta let-go. Es un juego de palabras en varias capas
      (let [...] (go ...))
      ¡Te deja hacer let en Go!
      Clogo para mí sería no-go. Si hay otras ideas buenas, con gusto las consideraría
  • Sería muy bienvenida una PR a https://github.com/chr15m/awesome-clojure-likes