3 Punkte von GN⁺ 2024-09-23 | 1 Kommentare | Auf WhatsApp teilen
  • Hy 1.0.0, ein in Python eingebetteter Lisp-Dialekt, wurde nach rund 12 Jahren intermittierender Entwicklung und praktischem Einsatz veröffentlicht
  • In Hy 1.x führen Breaking Changes an dokumentierten Sprachelementen zu einer Erhöhung der Major-Version; ausgenommen ist das Einstellen der Unterstützung für Python-Versionen, die von den CPython-Entwicklern nicht mehr unterstützt werden
  • Der künftige Fokus liegt auf neuen Bugfixes, dem Hinzufügen der Kompatibilität mit neuen Python-Versionen und der Unterstützung neuer Python-Funktionen auf eine Weise, die bestehenden Hy-1.x.y-Code nicht bricht
  • Ein Nutzer nennt als Beispiel, wie sich mit Hy-Makros SQLAlchemy-ORM-Deklarationen in die Form defmodel verkürzen lassen, und erklärt, dass es sich um eine Makro-Erweiterung handelt und daher keine zusätzlichen Laufzeitkosten entstehen
  • Ob Hy direkt auf MicroPython läuft, scheint wegen des Teilmengen-Umfangs der Standardbibliothek schwierig; möglich wäre aber, in CPython mit hy2py zu konvertieren und anschließend nur Konstrukte zu verwenden, die von MicroPython unterstützt werden

Veröffentlichung von Hy 1.0.0

  • Hy 1.0.0 wurde veröffentlicht
    • Hy ist ein in Python eingebetteter Lisp-Dialekt
    • Bis zur Veröffentlichung gab es fast 12 Jahre intermittierende Entwicklung und viel praktischen Einsatz
  • Einführung und Dokumentation gibt es auf Hylang.org
  • Die Versionshistorie ist in der NEWS-Datei zu finden
  • Als weniger ernster Begleittext zur Veröffentlichung ist außerdem der HYPE POST verlinkt

1.x-Kompatibilitätsrichtlinie

  • Künftig führen Breaking Changes in dokumentierten Teilen der Sprache zu einer Erhöhung der Major-Version
  • Eine Ausnahme gilt, wenn die Unterstützung für Python-Versionen eingestellt wird, die von den CPython-Entwicklern nicht mehr unterstützt werden
  • Es wird betont, dass Major-Versionserhöhungen nicht häufig vorkommen sollen
  • Der Fokus der künftigen Arbeit liegt auf Folgendem
    • Beheben neu auftretender Bugs
    • Hinzufügen der Kompatibilität mit neuen Python-Versionen
    • Unterstützung neuer Python-Funktionen auf eine Weise, die Code nicht bricht, der in früheren Hy-1.x.y-Versionen funktioniert

Beispiel für den Einsatz von Hy-Makros: SQLAlchemy-Model-DSL

  • Ein Nutzer erklärt, dass er mit Hy ein ORM und ein asynchrones Web-Framework entwickelt; beide nutzen bestehende Bibliotheken und bestehen größtenteils aus Makros
  • Gezeigt wird ein Beispiel, wie sich die Modelldeklaration aus dem SQLAlchemy ORM Quick Start Guide mit dem defmodel-Makro von Hy kürzer ausdrücken lässt
    • Die Modelle User und Address sowie ihre Beziehungen werden in Hy-S-Expressions geschrieben
    • defmodel ist ein Makro, das zu SQLAlchemy-Code expandiert, daher entstehen keine zusätzlichen Laufzeitkosten
  • Der Nutzer erklärt, dass die Stabilisierung des Hy-Kerns und der API für solche Arbeiten notwendig sei

Diskussion zu Beziehungsdeklarationen und Query-DSL

  • Das defmodel-Beispiel wird auf mehrere Beziehungsmuster erweitert
    • one-to-one: 1->1
    • many-to-many: *->* und deflinktable
    • Zeitstempelfelder: :timestamp-create, :timestamp-update
  • Nach der Deklaration sind die Objekte normale SQLAlchemy-2.0-ORM-Objekte, sodass nur der Datenbankschema-DSL-Teil in Hy geschrieben werden kann und der Rest in Python
  • An einer Query-DSL wird noch gearbeitet; es wird erwähnt, dass ein fluent interface nicht gut zu S-Expressions passt
  • Ein Kommentar schlägt vor, SQL so zu gestalten, dass syntaktische und semantische Reihenfolge zusammenpassen, und verlinkt auf Google Researchs SQL Has Problems. We Can Fix Them: Pipe Syntax In SQL
  • Darauf wird geantwortet, dass Formen wie |> oder Ansätze, die list comprehensions nachahmen, möglich sein könnten, das endgültige Design aber wohl erst nach wiederholtem Bauen kleiner Apps und Refactoring entstehen werde

MicroPython-Möglichkeiten und Reaktionen auf die Veröffentlichung

  • Es wird gefragt, ob Hy statt auf CPython auf MicroPython laufen könnte
  • Die Antwort lautet, dass ein direkter Betrieb schwierig erscheint, weil MicroPython nur einen kleinen Teil der Python-Standardbibliothek enthält
  • Allerdings könnte man mit hy2py in CPython zunächst in Python-Code umwandeln und das Ergebnis dann ausführen, sofern man sich auf Konstrukte beschränkt, die von MicroPython unterstützt werden
  • Am Tag der Veröffentlichung wurde ein starker Anstieg der täglichen einzigartigen Besucher des Webservers beobachtet, der Hylang.org hostet

1 Kommentare

 
GN⁺ 2024-09-23
Hacker-News-Kommentare
  • Es war etwas schwer nachzuvollziehen, wie Hy tatsächlich in Python umgewandelt wird, und anfangs war ich mir auch nicht sicher, ob es kompiliert oder interpretiert wird.
    Am Ende fand ich auf Wikipedia die Erklärung, dass „Hy ein Lisp-Dialekt ist, der darauf ausgelegt ist, s-Expressions in den abstrakten Syntaxbaum (AST) von Python zu übersetzen, um mit Python zu interagieren“, und der GitHub-Code lässt vermuten, dass auch der Compiler in Python geschrieben ist: https://github.com/hylang/hy/blob/master/hy/compiler.py
    Auf der Hauptseite wäre es wohl klarer, Hy als „Lisp-Dialekt, der zu Python-AST kompiliert“ zu beschreiben statt als „in Python eingebetteten Lisp-Dialekt“. Es gibt viele Möglichkeiten, Lisp einzubetten — etwa durch Anflanschen eines Interpreters, Kompilieren zu Python-Bytecode oder Umwandlung in Python-Quelltext — und die jeweiligen Trade-offs unterscheiden sich deutlich

    • Auf der README-/GitHub-Seite steht bereits: „Hy ist ein in Python eingebetteter Lisp-Dialekt, der Lisp-Code in Python-AST-Objekte umwandelt, sodass man die Python-Welt in Lisp-Form schreiben kann.“
    • Stimmt, dieser Compiler ist in Python geschrieben, und Hy ist nicht self-hosting.
      Normalerweise wird Hy-Quellcode zu Python-AST-Objekten, und Python kompiliert und führt diese dann aus. Es ist aber auch möglich, Python-AST-Objekte in Python-Quelltext umzuwandeln, und Interoperabilität ist ebenfalls möglich, also Python in Hy oder Hy in Python zu verwenden: https://hylang.org/hy/doc/v1.0.0/interop
    • Die Formulierung „eingebettet“ kommt daher, dass man Python und Hy innerhalb eines Projekts mischen und bidirektionale Aufrufe machen kann.
      Am Ende wird alles zu Python-Bytecode, daher funktioniert das gut
    • In der ursprünglichen Hy-Präsentation wird klar gesagt, dass Lisp kompiliert und als Python-Bytecode eingebettet wird.
      Das sieht man etwa bei 16:25 im folgenden Video: https://m.youtube.com/watch?v=1vui-LupKJI
  • Während Hy über die Jahre gereift ist, scheint es eher zu einer dünnen syntaktischen Abstraktion über dem Python-Feature-Set geworden zu sein, statt immer mehr syntaktischen Zucker und Sonderfälle anzuhäufen, um lispiger und weniger pythonisch zu werden.
    Der Fokus liegt also auf dem Kern, der sich anders kaum nachbilden lässt, insbesondere auf Makros. Ein aktuelles Beispiel: match ist einfach Pythons natives match, und es gibt kein Polyfill für Versionen vor Python 3.10. Früher wurde foo? als Sonderfall zu is_foo gemangelt, aber das wurde entfernt; hy.eval wurde so überarbeitet, dass es näher an Pythons eval ist; und nette, aber nicht essenzielle Utilities wie unless werden oft in das Paket Hyrule ausgelagert.
    Anfangs wirkte das kontraintuitiv, aber es hat große Vorteile: Die Lernkurve beim Wechsel von Python zu Hy wird flacher, und die Interaktion mit Python-Paketen wird konsistenter. Vielleicht geht es auch darum, die Sprachwartung zu vereinfachen; wenn ich mich richtig erinnere, brauchte es etwa vier Versuche, bis let richtig hinbekommen wurde

    • Irgendwann wurde klar, dass es sowohl die Wartung der Sprache als auch ihre Nutzung deutlich reibungsloser macht, unnötige Unterschiede zu Python zu minimieren.
      Wenn ich Hy-Code schreibe, schaue ich viel öfter in die Python-Dokumentation oder in die Doku von Third-Party-Python-Bibliotheken als in die Hy-Dokumentation. Es gab viele Punkte, an denen man Python verbessern konnte, aber frühere Features wie die aus Rücksicht auf Clojure eingeführte Möglichkeit, True als true zu schreiben, waren letztlich nur unnötige Komplexität
  • Der HYPE POST war wirklich großartig. Aus Sicht von jemandem, der im Enterprise-Software-Bereich arbeitet, ist das Satiregefühl hervorragend.
    https://github.com/hylang/hy/discussions/2609

  • Jetzt, da es endlich draußen ist, kann ich wohl https://github.com/rcarmo/sushy aufräumen.
    Ich habe über Jahre immer wieder daran herumgebastelt, aber bei jedem Hy-Upgrade gingen Teile der Syntax kaputt oder Features wanderten ins Hyrule-Paket hinein und wieder heraus, was unerquicklich war.
    Nebenbei: Hy läuft auch ziemlich gut innerhalb von https://holzschu.github.io/a-Shell_iOS auf dem iPad. Allerdings muss das Syntax-Highlighting in vim/neovim noch zu den Releases ab 0.29+ und zu Async aufschließen.
    Ich habe in der Zwischenzeit auch Fennel und Guile verwendet, aber der Zugriff auf Python-Bibliotheken und -Ökosysteme ist einfach besser. Dank Async kann man auch effizient mit APIs arbeiten, und in vielen Schemes ist es weiterhin umständlich, mit HTTPS zu arbeiten und dabei Sockets wiederzuverwenden sowie Header fein zu steuern, sodass ich aiohttp deutlich bevorzuge

  • Verglichen mit den bescheidenen Anfängen ist das Projekt wirklich weit gekommen.
    Ich habe damals den Lightning Talk auf der PyCon gesehen, in dem Hy der Welt erstmals vorgestellt wurde, und kurz darauf Paul getroffen und angefangen, zu frühen Hy-Versionen beizutragen. Ich habe mich um Common-Lisp-artige kwargs, einige Interna und ein oder zwei Bibliotheken gekümmert.
    Verspieltheit ist nützlich und hilft besonders dabei, die Begeisterung aufrechtzuerhalten. Es ist schön, dass Hacker sich wie Hacker verhalten dürfen und nicht alles Business sein muss. Ich bin seit Jahren nicht mehr beteiligt, aber es freut mich zu sehen, dass das Projekt weiter vorankommt, und es fühlt sich wie ein großartiger Meilenstein an

  • Für Clojure-Fans gibt es in diesem Zusammenhang auch Basilisp, einen Lisp-Dialekt, der stärker auf Clojure-Kompatibilität setzt und Python 3.8+ als Ziel hat.
    https://github.com/basilisp-lang/basilisp

  • Kein Lisp, aber aus der Perspektive einer funktionalen Programmiersprache, die nach Python transpiliert, ist auch Coconut interessant: https://coconut-lang.org/
    Mich würden Erfahrungsberichte von Leuten wirklich interessieren, die Hy oder Coconut tatsächlich benutzt haben

    • Ich habe Coconut vor ein paar Jahren ein wenig ausprobiert, und mein Eindruck damals war, dass der Compiler nicht klug genug war, um wirklich nützlich zu sein.
      An den Anfang des erzeugten Codes wurden massenhaft fest einkodierte Hilfsfunktionen gehängt, und das Programm war viel langsamer als wenn man denselben Inhalt in normalem Python geschrieben hätte.
      Hy dagegen erzeugt, abgesehen von einer kleinen zusätzlichen Indirektion durch die Scope-Behandlung von let oder Unterschieden rund um Rückgabewerte, Code, der ziemlich nah an Python-Code ist, den ein Mensch von Hand schreiben würde. Allerdings ist seit Coconut auch viel Zeit vergangen, also könnte es inzwischen verbessert worden sein
  • Glückwunsch. Ich habe zwei Fragen: Unterstützt es REPL-getriebene Entwicklung, also zum Beispiel so etwas wie ein Condition System oder eine breakloop?
    Außerdem würde mich interessieren, ob es eigenständig ausführbare Distributionen gibt. Schon die Verteilung von Python selbst ist umständlich, daher wäre es ideal, eine einzelne Hy-Binärdatei mit allen Abhängigkeiten ausliefern zu können. Ob statisch gelinkt oder als ZIP-Datei, die in ein temporäres Verzeichnis entpackt wird, wäre mir egal

    • Keine eigenständig ausführbare Distribution, aber mit uvx hy@1.0.0 kann man in die Hy-REPL gehen.
      Wenn man nach echo '(print "hi hn")' > hi.hy anschließend uvx hy@1.0.0 hi.hy ausführt, wird "hi hn" ausgegeben.
      https://docs.astral.sh/uv/guides/tools/#running-tools
      Übrigens kann uv auch Python-Versionen installieren und verwalten
    • Ich weiß nicht genau, was breakloop ist. Hy verwendet Pythons Ausnahmesystem, das eher einem traditionellen Ausnahmesystem als dem Condition System von Common Lisp entspricht.
      Eigenständig ausführbare Distributionen gibt es nicht
    • In der REPL-Dokumentation steht etwas dazu: https://hylang.org/hy/doc/v1.0.0/repl
      Um Code interaktiv zu debuggen, kann man in den zu debuggenden Code (.run (hy.REPL :locals {#\* (globals) #\* (locals)})) einfügen, und in Python kann man etwas wie import hy; hy.REPL(locals = {\*globals(), \*locals()}).run() verwenden.
      Allerdings werden, genau wie bei code.interact(), Änderungen an lokalen Variablen innerhalb der REPL nicht in den ursprünglichen Scope zurückübertragen
    • Mit py2app und vorsichtigem Hacken habe ich schon etwas gemacht, das nahe an Punkt 2 herankommt.
      Man kann alles zu Bytecode kompilieren und dann Pythons Single-File-Deployment-Tools verwenden
    • Hy unterstützt einfach denselben Funktionsumfang, den Python unterstützt. Für traditionelles Step-Debugging oder Post-mortem-Debugging ist es ziemlich gut, und in CPython gibt es auch viele weitergehende interne Hooks.
      Aber ein Condition System oder handlers/restarts gibt es nicht
  • Der weniger ernste Teil hat mir sehr gefallen. Ich wünschte, mehr Programmierprojekte würden Skurrilität zulassen.
    Vielleicht ist das sogar die beste Art, die Python-Tradition zu ehren

    • Vor ein paar Jahren haben wir viel von der Verspieltheit aus Hy und der Dokumentation entfernt, weil sie ablenkend war und laute Testfehlschläge verursacht hat.
      Irgendwann hatte ich dann aber das Gefühl, dass wir zu weit gegangen sind, und in letzter Zeit versuchen wir, wieder ein wenig Verspieltheit zurückzubringen
  • Ich habe Hy immer wieder mal benutzt und auch https://github.com/kunalb/orphism veröffentlicht, das ich in Hy geschrieben habe, während ich versucht habe, einen Transformer zu bauen.
    Es scheint an der Zeit zu sein, es wieder hervorzuholen und richtig laufen zu lassen