3 puntos por GN⁺ 2024-09-23 | 1 comentarios | Compartir por WhatsApp
  • Se lanzó Hy 1.0.0, un dialecto de Lisp integrado en Python, tras casi 12 años de desarrollo intermitente y uso real
  • En Hy 1.x, los cambios incompatibles en elementos documentados del lenguaje implicarán un aumento de versión major, con la excepción de dejar de soportar versiones de Python que los desarrolladores de CPython ya no mantienen
  • El foco a futuro estará en corregir nuevos bugs, agregar compatibilidad con nuevas versiones de Python y dar soporte a nuevas funciones de Python sin romper el código existente de Hy 1.x.y
  • Un usuario explicó un ejemplo en el que macros de Hy reducen declaraciones del ORM de SQLAlchemy a una forma defmodel, y señaló que, al tratarse de expansión de macros, no hay costo adicional en runtime
  • Ejecutarlo directamente sobre MicroPython parece difícil por el subconjunto de la biblioteca estándar, aunque podría ser posible convertirlo con hy2py en CPython y luego usar solo construcciones soportadas por MicroPython

Lanzamiento de Hy 1.0.0

  • Se lanzó Hy 1.0.0
    • Hy es un dialecto de Lisp integrado en Python
    • Hasta el lanzamiento hubo casi 12 años de desarrollo intermitente y mucho uso real
  • La introducción y la documentación están disponibles en Hylang.org
  • El historial de versiones puede consultarse en el archivo NEWS
  • También se enlaza un texto de lanzamiento menos serio, el HYPE POST

Política de compatibilidad de 1.x

  • De ahora en adelante, los breaking changes en partes documentadas del lenguaje incrementarán el número de versión major
  • La excepción es cuando se deje de dar soporte a versiones de Python que los desarrolladores de CPython ya no mantienen
  • Se plantea la intención de que los aumentos de versión major no ocurran con frecuencia
  • El trabajo futuro se enfocará en lo siguiente
    • Corregir bugs que aparezcan
    • Agregar compatibilidad con nuevas versiones de Python
    • Dar soporte a nuevas funciones de Python de una forma que no rompa el código que funciona en Hy 1.x.y anteriores

Ejemplo de uso de macros de Hy: DSL de modelos SQLAlchemy

  • Un usuario explicó que está creando un ORM y un framework web asíncrono con Hy, ambos aprovechando bibliotecas existentes y compuestos en su mayor parte por macros
  • Se presentó un ejemplo que expresa de forma más breve, con la macro defmodel de Hy, la declaración de modelos de la Quick Start Guide del ORM de SQLAlchemy
    • Los modelos User y Address, junto con sus declaraciones de relación, se escriben en forma de S-expressions de Hy
    • defmodel es una macro que se expande a código SQLAlchemy, por lo que no tiene costo adicional en runtime
  • El usuario señaló que para este tipo de trabajo era necesario que el interior de Hy y su API se estabilizaran

Discusión sobre declaraciones de relaciones y DSL de consultas

  • El ejemplo de defmodel se extiende a varios patrones de relaciones
    • one-to-one: 1->1
    • many-to-many: *->* y deflinktable
    • campos de timestamp: :timestamp-create, :timestamp-update
  • Después de la declaración, los objetos son objetos ORM normales de SQLAlchemy 2.0, por lo que se puede escribir en Hy solo la parte del DSL del esquema de base de datos y usar Python para el resto
  • El DSL de consultas todavía está en desarrollo, y se menciona que la fluent interface no encaja bien con las S-expressions
  • Un comentario sugirió hacer que el orden sintáctico y el orden semántico de SQL coincidan, y enlazó el artículo de Google Research SQL Has Problems. We Can Fix Them: Pipe Syntax In SQL
  • Como respuesta, se dijo que podrían ser posibles formas como |> o enfoques que imiten list comprehensions, pero que el diseño final surgirá después de iterar creando y refactorizando una app pequeña

Posibilidad de MicroPython y reacción al lanzamiento

  • Surgió la pregunta de si podría funcionar sobre MicroPython en lugar de CPython
  • La respuesta apunta a que la ejecución directa parece difícil, porque MicroPython solo incluye un subconjunto pequeño de la biblioteca estándar de Python
  • Sin embargo, si se usa hy2py en CPython para convertirlo a código Python y luego se limita a construcciones soportadas por MicroPython, podría ser posible ejecutar el resultado
  • Se confirmó que el día del lanzamiento aumentó considerablemente la cantidad diaria de visitantes únicos del servidor web que aloja Hylang.org

1 comentarios

 
GN⁺ 2024-09-23
Opiniones en Hacker News
  • Me costó un poco entender cómo Hy se transforma realmente en Python, y al principio tampoco estaba seguro de si se compilaba o se interpretaba.
    Al final encontré en Wikipedia la explicación de que “Hy es un dialecto de Lisp diseñado para interactuar con Python convirtiendo s-expressions al árbol de sintaxis abstracta (AST) de Python”, y viendo el código en GitHub parece que el compilador también está escrito en Python: https://github.com/hylang/hy/blob/master/hy/compiler.py
    Creo que en el sitio principal también sería más claro presentarlo como “un dialecto de Lisp que compila a Python AST” en vez de “un dialecto de Lisp embebido en Python”. Hay varias formas de embeber Lisp, como adjuntar un intérprete, compilar a bytecode de Python o transformarlo en código fuente Python, y cada una tiene trade-offs bastante distintos.

    • En la página de README/GitHub ya dice que “Hy es un dialecto de Lisp embebido en Python y, como convierte código Lisp en objetos AST de Python, permite usar el mundo de Python en forma de Lisp”.
    • Correcto, este compilador está escrito en Python y Hy no es self-hosting.
      Normalmente el código fuente de Hy se convierte en objetos AST de Python, y Python los compila y ejecuta. Sin embargo, también es posible convertir objetos AST de Python a texto fuente Python, y hay interoperabilidad tanto para usar Python desde Hy como Hy desde Python: https://hylang.org/hy/doc/v1.0.0/interop
    • La expresión “embebido” viene de que dentro de un mismo proyecto se pueden mezclar Python y Hy y hacer llamadas en ambos sentidos.
      Al final todo se convierte en bytecode de Python, así que funciona bien.
    • En la presentación original de Hy queda claro que se embebe compilando Lisp a bytecode de Python.
      Se puede ver alrededor del minuto 16:25 en este video: https://m.youtube.com/watch?v=1vui-LupKJI
  • A medida que Hy maduró durante años, en vez de acumular azúcar sintáctica y casos especiales para volverse más Lispy y menos Pythony, parece haberse acercado más bien a una abstracción sintáctica delgada sobre el conjunto de funcionalidades de Python.
    Es decir, se orienta a enfocarse en lo esencial que es difícil imitar de otra forma, especialmente las macros. Un ejemplo reciente: match es simplemente el match nativo de Python y no hay polyfill para versiones anteriores a Python 3.10. Antes foo? era un caso especial que se transformaba mediante name mangling en is_foo, pero se eliminó; hy.eval se rediseñó para parecerse más al eval de Python; y utilidades no esenciales pero convenientes, como unless, suelen moverse al paquete Hyrule.
    Al principio me pareció una dirección contraintuitiva, pero tiene una gran ventaja: reduce la curva de aprendizaje al pasar de Python a Hy y facilita interactuar de forma consistente con paquetes de Python. Quizá también haya razones para simplificar el mantenimiento del lenguaje; si no recuerdo mal, let también necesitó como cuatro intentos hasta quedar bien.

    • En algún momento me di cuenta de que minimizar las diferencias innecesarias con Python hace que tanto mantener como usar el lenguaje sea mucho más fluido.
      Incluso cuando escribo código Hy, termino consultando la documentación de Python o de librerías Python de terceros con mucha más frecuencia que la documentación de Hy. Sentía que había varias áreas donde Python podía mejorarse, pero funciones como permitir escribir True como true por consideración a Clojure, como antes, eran simplemente complejidad innecesaria.
  • El HYPE POST me pareció buenísimo. Como alguien que trabaja en software empresarial, tiene un sentido de la sátira excelente.
    https://github.com/hylang/hy/discussions/2609

  • Ahora que por fin salió, ya puedo poner en orden https://github.com/rcarmo/sushy.
    Lo estuve tocando de a poco durante varios años, pero cada vez que actualizaba Hy se rompía parte de la sintaxis o alguna funcionalidad entraba y salía del paquete Hyrule, lo que era complicado.
    Como referencia, Hy también funciona bastante bien dentro de https://holzschu.github.io/a-Shell_iOS en iPad. Eso sí, el resaltado de sintaxis de vim/neovim tiene que ponerse al día con las versiones 0.29+ y con async.
    Mientras tanto probé Fennel y Guile, pero prefiero tener acceso a las librerías y al ecosistema de Python. Gracias a async también se puede trabajar muy bien con APIs eficientes, y en varios Scheme sigue siendo engorroso manejar HTTPS con reutilización de sockets y control fino de headers, así que me parece mucho mejor usar aiohttp.

  • Llegó realmente muy lejos comparado con sus humildes comienzos.
    Hace tiempo vi en PyCon la lightning talk que presentó Hy al mundo por primera vez, y poco después conocí a Paul y empecé a contribuir a las primeras versiones de Hy. Me encargué de los kwargs al estilo Common Lisp, algunas partes internas y una o dos librerías.
    La actitud lúdica es útil, sobre todo para mantener la pasión. Me gusta que los hackers puedan comportarse como hackers y que no todo tenga que ser negocio. No participo desde hace años, pero me alegra ver que el proyecto sigue avanzando, y lo siento como un gran hito.

  • Si eres fan de Clojure, también existe Basilisp, un dialecto de Lisp relacionado y casi compatible con Clojure, orientado a Python 3.8+.
    https://github.com/basilisp-lang/basilisp

  • No es Lisp, pero desde la perspectiva de un lenguaje de programación funcional que se transpila a Python, Coconut también es interesante: https://coconut-lang.org/
    Me da mucha curiosidad conocer experiencias de gente que haya usado Hy o Coconut en la práctica

    • Probé un poco Coconut hace unos años, y mi impresión en ese momento fue que el compilador no era lo bastante inteligente como para resultar útil
      El código generado venía con un montón de funciones auxiliares hardcodeadas al principio, y el programa era mucho más lento que escribir lo mismo en Python común
      En cambio, Hy genera código bastante cercano a algo que una persona escribiría a mano en Python, salvo por una ligera capa de indirección derivada del manejo de alcance de let y algunas diferencias alrededor de los valores de retorno. Dicho eso, ya pasó bastante tiempo, así que Coconut podría haber mejorado
  • Felicitaciones. Tengo curiosidad por dos cosas: si admite desarrollo guiado por REPL, por ejemplo si tiene algo como un sistema de condiciones o un breakloop
    También me pregunto si hay una distribución independiente. Como distribuir Python en sí es engorroso, idealmente estaría bueno poder distribuir un único binario de Hy con todas las dependencias incluidas. Podría ser con enlace estático o un archivo zip que se descomprima en un directorio temporal

    • No es una distribución independiente, pero puedes entrar al REPL de Hy con uvx hy@1.0.0
      Si ejecutas echo '(print "hi hn")' > hi.hy y luego uvx hy@1.0.0 hi.hy, imprime "hi hn"
      https://docs.astral.sh/uv/guides/tools/#running-tools
      Como referencia, uv también puede instalar y administrar versiones de Python
    • No estoy muy seguro de qué es un breakloop. Hy usa el sistema de excepciones de Python, que se parece más a un sistema de excepciones tradicional que al sistema de condiciones de Common Lisp
      No hay distribución independiente
    • La documentación del REPL tiene información relacionada: https://hylang.org/hy/doc/v1.0.0/repl
      Para depurar código de forma interactiva, puedes poner (.run (hy.REPL :locals {#\* (globals) #\* (locals)})) en el código que quieres depurar, y en Python puedes usar algo como import hy; hy.REPL(locals = {\*globals(), \*locals()}).run()
      Sin embargo, igual que con code.interact(), si cambias variables locales dentro del REPL, esos cambios no se propagan al alcance original
    • Con py2app y algo de hacking cuidadoso, alguna vez hice algo cercano al punto 2
      Puedes compilar todo a bytecode y luego usar una herramienta de distribución de un solo archivo de Python
    • Hy admite el mismo conjunto de funciones que admite Python. Es bastante bueno para depuración tradicional paso a paso o depuración post mortem, y CPython también tiene muchos hooks internos más avanzados
      Pero no hay nada como un sistema de condiciones ni handlers/restarts
  • Me gustó mucho la parte menos seria. Ojalá más proyectos de programación aceptaran la extravagancia
    Quizá esa sea la mejor forma de honrar la tradición de Python

    • Hace unos años quitamos muchos elementos juguetones de Hy y de la documentación. Distraían y generaban fallas de prueba ruidosas
      Pero en algún momento sentí que nos habíamos ido demasiado lejos, así que últimamente estoy intentando volver a incorporar un poco de juego
  • He usado Hy de forma intermitente y, al intentar crear un transformer, también publiqué https://github.com/kunalb/orphism escrito en Hy
    Creo que ya es hora de volver a sacarlo y hacerlo funcionar bien