Hy 1.0 – un dialecte Lisp pour Python
(github.com/hylang)- Hy 1.0.0, un dialecte Lisp embarqué dans Python, a été publié après près de 12 ans de développement intermittent et d’usage réel
- Dans Hy 1.x, les ruptures de compatibilité des éléments du langage documentés entraîneront désormais une augmentation de version majeure, à l’exception de l’arrêt du support des versions de Python que les développeurs de CPython ne prennent plus en charge
- L’accent sera désormais mis sur la correction de nouveaux bugs, l’ajout de la compatibilité avec les nouvelles versions de Python et la prise en charge des nouvelles fonctionnalités de Python sans casser le code existant en Hy 1.x.y
- Un utilisateur cite comme exemple une macro Hy qui réduit les déclarations de l’ORM SQLAlchemy à une forme
defmodel, en expliquant que, comme il s’agit d’une expansion de macro, cela n’ajoute aucun coût à l’exécution - Le fonctionnement direct sur MicroPython semble difficile en raison du sous-ensemble de la bibliothèque standard, mais une conversion depuis CPython avec
hy2py, suivie d’un usage limité aux constructions prises en charge par MicroPython, pourrait être possible
Sortie de Hy 1.0.0
- Hy 1.0.0 a été publié
- Hy est un dialecte Lisp embarqué dans Python
- Sa sortie intervient après presque 12 ans de développement intermittent et de nombreux usages en conditions réelles
- La présentation et la documentation sont disponibles sur Hylang.org
- L’historique des versions peut être consulté dans le fichier NEWS
- Un billet de sortie plus léger, HYPE POST, est également lié
Politique de compatibilité 1.x
- À l’avenir, tout breaking change dans les parties documentées du langage entraînera une hausse du numéro de version majeure
- L’exception concerne l’abandon du support des versions de Python que les développeurs de CPython ne prennent plus en charge
- L’objectif affiché est d’éviter que les hausses de version majeure ne deviennent trop fréquentes
- Les travaux à venir se concentreront sur :
- la correction de bugs nouvellement découverts
- l’ajout de la compatibilité avec les nouvelles versions de Python
- la prise en charge des nouvelles fonctionnalités de Python sans casser le code qui fonctionne sur les versions précédentes de Hy 1.x.y
Exemple d’usage des macros Hy : DSL de modèles SQLAlchemy
- Un utilisateur explique qu’il développe avec Hy un ORM et un framework web asynchrone, tous deux basés sur des bibliothèques existantes et composés en grande partie de macros
- Un exemple montre comment la déclaration de modèles du SQLAlchemy ORM Quick Start Guide peut être exprimée plus brièvement avec la macro
defmodelde Hy- Les modèles
UseretAddress, ainsi que les déclarations de relations, sont écrits sous forme de S-expressions Hy defmodelest une macro qui se développe en code SQLAlchemy, donc sans coût supplémentaire à l’exécution
- Les modèles
- L’utilisateur indique que la stabilisation de l’interne et de l’API de Hy est nécessaire pour ce type de travail
Discussion sur les déclarations de relations et le DSL de requêtes
- L’exemple
defmodels’étend à plusieurs modèles de relations :- one-to-one :
1->1 - many-to-many :
*->*etdeflinktable - champs d’horodatage :
:timestamp-create,:timestamp-update
- one-to-one :
- Après déclaration, les objets restent des objets ORM SQLAlchemy 2.0 classiques, ce qui permet d’écrire uniquement la partie DSL du schéma de base de données en Hy et de garder le reste en Python
- Le DSL de requêtes est encore en cours de conception, et il est mentionné qu’une fluent interface s’accorde mal avec les S-expressions
- Un commentaire suggère de faire correspondre l’ordre syntaxique et l’ordre sémantique de SQL, en renvoyant vers Google Research et SQL Has Problems. We Can Fix Them: Pipe Syntax In SQL
- En réponse, il est indiqué qu’une forme comme
|>ou une approche imitant les list comprehensions pourrait fonctionner, mais que le design final émergera probablement après plusieurs itérations consistant à créer de petites applications puis à les refactoriser
Possibilités avec MicroPython et réactions à la sortie
- La question a été posée de savoir si Hy pouvait fonctionner sur MicroPython au lieu de CPython
- La réponse va dans le sens d’un fonctionnement direct difficile, car MicroPython n’inclut qu’un petit sous-ensemble de la bibliothèque standard de Python
- En revanche, il pourrait être possible d’exécuter le résultat après conversion en code Python avec
hy2pysous CPython, à condition de se limiter aux constructions prises en charge par MicroPython - Il a été constaté que le nombre de visiteurs uniques quotidiens du serveur web hébergeant Hylang.org a fortement augmenté le jour de la sortie
1 commentaires
Commentaires sur Hacker News
J’ai eu un peu de mal à comprendre comment Hy se transforme concrètement en Python, et au début je n’étais pas sûr non plus de savoir s’il était compilé ou interprété
J’ai fini par trouver sur Wikipedia la description suivante : « Hy est un dialecte de Lisp conçu pour interagir avec Python en transformant les s-expressions en arbre syntaxique abstrait (AST) de Python », et en regardant le code sur GitHub, le compilateur semble lui aussi écrit en Python : https://github.com/hylang/hy/blob/master/hy/compiler.py
Même sur le site principal, ce serait probablement plus clair de le présenter comme un « dialecte de Lisp compilé vers l’AST Python » plutôt que comme un « dialecte de Lisp embarqué dans Python ». Il existe plusieurs façons d’embarquer Lisp : greffer un interpréteur, compiler en bytecode Python, ou convertir en code source Python, et chacune implique des compromis assez différents
En général, le code source Hy devient des objets AST Python, que Python compile ensuite pour les exécuter. Cela dit, il est aussi possible de convertir des objets AST Python en texte source Python, et l’interopérabilité fonctionne dans les deux sens : utiliser Python depuis Hy ou Hy depuis Python : https://hylang.org/hy/doc/v1.0.0/interop
Au final, tout devient du bytecode Python, donc ça fonctionne bien
On peut le voir vers 16:25 dans la vidéo ci-dessous : https://m.youtube.com/watch?v=1vui-LupKJI
Avec sa maturation au fil des années, Hy semble s’être rapproché d’une fine abstraction syntaxique de l’ensemble des fonctionnalités de Python, plutôt que d’accumuler du sucre syntaxique et des cas particuliers pour devenir plus lispy et moins pythonesque
L’idée est donc de se concentrer sur l’essentiel, surtout ce qu’il est difficile d’imiter autrement, notamment les macros. Exemple récent :
matchn’est que lematchnatif de Python, sans polyfill pour les versions antérieures à Python 3.10. Autrefois,foo?faisait l’objet d’un cas particulier et était transformé enis_foo, mais cela a été supprimé ;hy.evala été remanié pour se rapprocher davantage duevalde Python ; et des utilitaires non essentiels mais pratiques, commeunless, sont souvent déplacés vers le package HyruleAu début, cette orientation m’a semblé contre-intuitive, mais elle présente un gros avantage : réduire la courbe d’apprentissage pour ceux qui passent de Python à Hy, tout en facilitant une interaction cohérente avec les packages Python. C’est peut-être aussi une façon de simplifier la maintenance du langage ; si je me souviens bien, il a fallu essayer environ quatre fois avant d’avoir un
letcorrectQuand j’écris du code Hy, je consulte bien plus souvent la documentation Python ou celle de bibliothèques Python tierces que la documentation Hy elle-même. J’ai l’impression qu’il y avait plusieurs façons d’améliorer Python, mais des fonctionnalités comme l’ancienne possibilité d’écrire
Truesous la formetruepour ménager Clojure n’étaient finalement qu’une complexité inutileLe HYPE POST était vraiment excellent. En travaillant dans le logiciel d’entreprise, je trouve son sens de la satire particulièrement juste
https://github.com/hylang/hy/discussions/2609
Maintenant que c’est enfin sorti, je vais pouvoir remettre de l’ordre dans https://github.com/rcarmo/sushy
J’y touche par petites étapes depuis des années, mais à chaque montée de version de Hy, une partie de la syntaxe cassait ou bien des fonctionnalités entraient puis sortaient du package Hyrule, ce qui compliquait les choses
Au passage, Hy fonctionne aussi plutôt bien sur iPad dans https://holzschu.github.io/a-Shell_iOS. En revanche, la coloration syntaxique de vim/neovim doit encore rattraper les versions 0.29+ et l’asynchrone
Entre-temps, j’ai aussi essayé Fennel et Guile, mais le plus intéressant reste d’avoir accès aux bibliothèques et à l’écosystème Python. Grâce à l’asynchrone, on peut aussi faire efficacement du travail sur des API, et dans beaucoup de Scheme, gérer HTTPS tout en réutilisant les sockets et en contrôlant finement les en-têtes reste encore pénible, donc je préfère largement utiliser aiohttp
Quand on compare avec les débuts modestes du projet, le chemin parcouru est impressionnant
J’avais vu à l’époque le lightning talk de PyCon qui présentait Hy au monde pour la première fois, et peu après j’ai rencontré Paul puis commencé à contribuer aux premières versions de Hy. Je me suis occupé des
kwargsà la Common Lisp, de certains éléments internes, ainsi que d’une ou deux bibliothèquesLe côté joueur est utile, surtout pour entretenir l’enthousiasme. C’est agréable de voir des hackers se comporter en hackers et de constater que tout n’a pas besoin d’être dicté par le business. Je ne suis plus impliqué depuis des années, mais ça fait plaisir de voir le projet continuer d’avancer, et cela ressemble à un très beau jalon
Pour les fans de Clojure, il existe aussi dans le même registre Basilisp, un dialecte de Lisp proche d’une compatibilité Clojure, ciblant Python 3.8+
https://github.com/basilisp-lang/basilisp
Ce n’est pas du Lisp, mais Coconut est aussi intéressant si on le considère comme un langage de programmation fonctionnelle transpillé vers Python : https://coconut-lang.org/
J’aimerais vraiment connaître les retours de personnes qui ont réellement utilisé Hy ou Coconut
Il collait tout un tas de fonctions auxiliaires codées en dur en haut du code généré, et le programme était bien plus lent que si on avait écrit la même chose en Python ordinaire
À l’inverse, Hy génère un code assez proche de ce qu’un humain écrirait à la main en Python, à part un léger niveau d’indirection dû à la gestion de la portée de
letet quelques différences autour des valeurs de retour. Cela dit, beaucoup de temps a passé pour Coconut, donc il a peut-être été amélioréFélicitations. J’ai deux questions : est-ce que cela prend en charge le développement piloté par le REPL, par exemple avec un système de conditions ou quelque chose comme breakloop ?
Je me demande aussi s’il existe une distribution autonome. Comme la distribution de Python elle-même est pénible, l’idéal serait de pouvoir distribuer un unique binaire Hy contenant toutes les dépendances. Que ce soit par lien statique ou sous forme d’un fichier zip décompressé dans un répertoire temporaire, peu importe
uvx hy@1.0.0Après
echo '(print "hi hn")' > hi.hy, exécuteruvx hy@1.0.0 hi.hyaffiche"hi hn"https://docs.astral.sh/uv/guides/tools/#running-tools
À noter que uv peut aussi installer et gérer les versions de Python
Il n’existe pas de distribution autonome
Pour déboguer du code de manière interactive, on peut insérer
(.run (hy.REPL :locals {#\* (globals) #\* (locals)}))dans le code à déboguer, et en Python on peut écrireimport hy; hy.REPL(locals = {\*globals(), \*locals()}).run()Cependant, comme avec
code.interact(), modifier des variables locales dans le REPL ne se propage pas à la portée d’originepy2appet un hacking prudentOn peut tout compiler en bytecode, puis utiliser les outils de distribution en fichier unique de Python
En revanche, il n’y a pas de système de conditions ni de handlers/restarts
J’ai beaucoup aimé l’aspect moins sérieux. J’aimerais que davantage de projets de programmation adoptent la fantaisie
C’est peut-être même la meilleure façon d’honorer la tradition Python
Mais à un moment, j’ai eu l’impression qu’on était allé trop loin, donc récemment nous essayons de réintroduire un peu de cette fantaisie
J’utilise Hy de façon intermittente depuis un moment, et en essayant de créer un transformer j’ai aussi publié https://github.com/kunalb/orphism, écrit en Hy
On dirait qu’il est temps de le ressortir et de le faire vraiment tourner