[HN Gopher] Hy 1.0 - Lisp dialect for Python
___________________________________________________________________
Hy 1.0 - Lisp dialect for Python
Author : Kodiologist
Score : 289 points
Date : 2024-09-22 14:43 UTC (8 hours ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| blumomo wrote:
| Congratulations! I once bought your eBook on Hy, and still today
| I regularly receive notifications about your book having been
| updated. Thank you for your steady contributions. I really want
| to use Hy in one my production apps one day.
| Kodiologist wrote:
| The author of the e-book is a different guy, Mark Watson. He
| isn't involved in the development of the language.
| blumomo wrote:
| Oh, thanks. He seemed so enthusiastic about Hy :-)
|
| I just read through the author list on the Hy repo and had a
| glimpse into their blog posts. Cool stuff, great work.
| marmaduke wrote:
| I enjoyed the less serious part a lot. I wish more programming
| related projects could embrace the whimsical. That might the best
| way to honor the python tradition in any case :)
| Kodiologist wrote:
| I eliminated a lot of whimsy from Hy and its documentation
| years ago because it was distracting and created noisy test
| failures, but I did go too far at some point, and have tried to
| reintroduce a little whimsy more recently.
| paultopia wrote:
| EXCITING! Can't wait to give it a spin!
|
| (Does `let` work? I remember that being a barrier for a while.)
| Kodiologist wrote:
| Remarkably enough, yes, we got it to work, on our 3rd or 4th
| try.
| rcarmo wrote:
| Yep. I use it a lot.
| anovick wrote:
| Congrats!
|
| Could you compare the language with Clojure?
| Kodiologist wrote:
| Well, this is a little embarrassing: Clojure was one of the
| biggest influences on Hy in its youth, but that was mostly
| before I got involved in 2016. I never actually learned
| Clojure. So hopefully somebody who knows both Hy and Clojure
| well can answer. I can tell you that at run-time, Hy is
| essentially Python code, so Hy is more tightly coupled to
| Python than Clojure is to Java; a better analogy is
| CoffeeScript's relationship with JavaScript.
|
| I get the impression that Clojure tries to convince the
| programmer to avoid side-effects a lot more strenuously than Hy
| does, but it's still not a purely functional language, so I
| don't know how consequential that is in practice.
| a57721 wrote:
| Clojure has a good collection library with
| immutable/persistent data structures, but as a language it
| allows side effects and has some mechanisms to manage them.
| It is also possible to call any Java method from Clojure.
|
| Clojure does not work with Java ASTs, it translates into JVM
| bytecode directly.
| chrisrink10 wrote:
| I haven't used Hy, but I am the maintainer of a Basilisp which
| also compiles to Python and aims for reasonably close
| compatibility with Clojure if you're interested.
|
| https://github.com/basilisp-lang/basilisp
| anovick wrote:
| Cool project!
|
| Wondering how custom immutable data structures fit in with
| the Python ecosystem.
|
| Particularly, I know that NumPy arrays and Pandas
| Series/DataFrames are the popular data structures used in
| research computing in Python (for Statistics, Data Science,
| Machine Learning etc.). These data structures afaik are
| mutable, however (for performance reasons), so at least the
| aspect of immutability from Clojure cannot be easily
| integrated with the Python ecosystem.
| chrisrink10 wrote:
| This project is much younger and used by many fewer people
| than Hy, so I couldn't really speak to this besides my own
| opinions. The few who have started using it and
| contributing seem to just be using it as a way to write
| Clojure while interacting with popular Python libraries and
| tools. Kind of the same way that interacting with the Java
| ecosystem is often more pleasant from Clojure (IMO) than in
| Java itself.
|
| I've tried to facilitate strong Python interoperability
| despite the variety of otherwise incompatible features of
| each language. It's trivial to work with immutable data
| structures using Clojure idioms and then convert them to
| Python data structures (as needed) at the boundaries, but
| the immutable data structures used by Basilisp are also
| generally compatible with Python's core (read-only)
| interfaces so that conversion may also not be necessary if
| you aren't expecting the called function to perform any
| mutations.
| kayo_20211030 wrote:
| Very exciting. I'm in awe of the long-term commitment (over 10
| years) that was required to get this to 1.0.0. It renews my
| faith. Well done.
| tosh wrote:
| Does Hy also work with Mojo?
| Kodiologist wrote:
| I'm not sure. I was going to say that Mojo is proprietary
| software and so I've never tried it, but I just checked and
| apparently it's free now. If nothing else, you can probably get
| a lot of Hy code to run on Mojo via `hy2py`, if Mojo supports a
| lot of Python as it claims to.
|
| Edit: actually, confusingly, the GitHub repository for Mojo
| doesn't have an interpreter. The language is still proprietary.
| tosh wrote:
| Thank you for the hy2py pointer and kudos @ 1.0.0!
| rcarmo wrote:
| Not sure either, but it should. I do test it every year or so
| with pypy.
| knlb wrote:
| Congratulations -- and thank you! I've been playing with Hy on
| and off (tried to do transformers with it, and then released
| https://github.com/kunalb/orphism written in hy). Time to pick it
| up again and take it for a spin
| instig007 wrote:
| You can get FP compositions without throwing away Python syntax
| (as Hy does): https://github.com/thyeem/foc
| agentultra wrote:
| Wow! It has come such a long way since its early, humble
| beginnings.
|
| I saw the original lightning talk that introduced Hy to the world
| at Pycon those ages ago. Soon after I met Paul and started
| contributing to the early versions of Hy. I was responsible for
| the CL-style kwargs (you're welcome), some minor innards, and a
| library or two.
|
| Whimsy is useful, especially to keep enthusiasm up. It's nice
| when hackers can be hackers and not every thing is business.
|
| While I haven't been involved in years it brings a smile to me
| face to see the project continues apace. What a great milestone!
| chrisrink10 wrote:
| Congrats on the release! Very impressive.
| agumonkey wrote:
| Congrats. It's been a great pleasure to watch it evolve. :)
| HexDecOctBin wrote:
| Congrats! Two questions:
|
| 1. Does it support REPL-driven development? (condition system,
| breakloop, etc.)
|
| 2. Is there a standalone distribution? Distributing python in
| itself is a hassle, ideal situation would be to simply distribute
| a single Hy binary that contains all dependencies within it
| (either statically linked or as a zip file extracted in tmp
| directory).
| rcarmo wrote:
| I managed to do 2, sort of, with py2app and judicious hacking.
| You can compile everything to byte code and use Python "single
| file" deployment tools.
| tosh wrote:
| not a standalone distribution but: uvx hy@1.0.0
|
| gets you into the Hy REPL echo '(print "hi
| hn")' > hi.hy uvx hy@1.0.0 hi.hy
|
| prints "hi hn"
|
| https://docs.astral.sh/uv/guides/tools/#running-tools
|
| (context: uv can install and manage python versions)
| PaulHoule wrote:
| Generally, uv answers the objection that 'Python sux' in that
| it (1) is correct, unlike pip, and (2) is freaky fast.
| Kodiologist wrote:
| 1. I don't know what a breakloop is. Hy uses Python's exception
| system, which is more like a traditional exception system than
| Common Lisp's condition system.
|
| 2. No, sorry.
| wrs wrote:
| A breakloop is a REPL operating in the context of condition
| handling. When a condition is signaled, you can use the
| breakloop to modify state and direct how the condition should
| be handled (including fixing something local and letting the
| current function proceed by ignoring the condition).
|
| Seems like that would only be doable by altering CPython to
| at least have a hook in the initial exception processing (or
| maybe there is some magic double-underscore thing for that
| already?).
| Kodiologist wrote:
| I see. That's pretty similar to the feature set of
| [pdb](https://docs.python.org/3/library/pdb.html). You may
| then logically ask "Does Hy support pdb?". The answer is
| "sort of". I've fixed one or two bugs, but we don't test
| it. I suspect there are various features of pdb that assume
| Python syntax and would need some hooks to get working
| properly with Hy.
| ruined wrote:
| https://hylang.org/hy/doc/v1.0.0/repl
|
| >A convenient way to use this class to interactively debug code
| is to insert the following in the code you want to debug:
| (.run (hy.REPL :locals {#\* (globals) #\* (locals)}))
|
| >Or in Python: import hy; hy.REPL(locals =
| {\*globals(), \*locals()}).run()
|
| >Note that as with `code.interact()`, changes to local
| variables inside the REPL are not propagated back to the
| original scope.
| cooljoseph wrote:
| I was having some difficulty figuring out how Hy actually is
| translated to Python (and wasn't even sure if it was compiled or
| interpreted). Eventually I found on Wikipedia the following: > Hy
| is a dialect of the Lisp programming language designed to
| interact with Python by translating s-expressions into Python's
| abstract syntax tree (AST).
|
| Also, looking at the code on Github suggests this compiler is
| written in Python (see
| https://github.com/hylang/hy/blob/master/hy/compiler.py).
|
| I kind of wish this was made more clear on the main website.
| Perhaps, instead of introducing Hy as "a Lisp dialect that's
| embedded in Python", introduce it as "a Lisp dialect that
| compiles to Python's AST". The words "embedded in Python" don't
| make it very clear just _how_ it 's embedded into Python. The
| various ways you can embed a Lisp look very different and have
| very different tradeoffs.
|
| For example, off the top of my head, I could "embed" a Lisp by
| writing an interpreter (in C if I care about performance) and
| letting it be called from Python, perhaps passing in a Python
| list instead of a string to make it more "native". Or I could
| "embed" a Lisp by compiling to Python bytecode. Or I could
| "embed" a Lisp by translating it directly to Python source code.
| Etc.
|
| Regardless, interesting project!
| rcarmo wrote:
| The "embed" part stems from the fact that you can mix Python
| and Hy in a project with bi-directional calling. Works great,
| because it is all Python byte code in the end.
| PuercoPop wrote:
| The original hy annoucement makes it clear that they embed a
| Lisp by compiling with Python bytecode. You can see it in the
| following video about the 16:25 mark
|
| https://m.youtube.com/watch?v=1vui-LupKJI
| Foxboron wrote:
| and for those interested in history, Docker was first
| announced 10 minutes afterwards on the 26:24 mark.
| Kodiologist wrote:
| Now I know how those guys felt who were on the same episode
| of Ed Sullivan that introduced the Beatles.
| Foxboron wrote:
| There is a _reason_ why Hylang was one of the _first_
| official Docker images!
| Kodiologist wrote:
| > this compiler is written in Python
|
| Yes, that's right. Hy is not self-hosted.
|
| > The various ways you can embed a Lisp look very different and
| have very different tradeoffs.
|
| Hy itself provides options. Typically the process is that the
| Hy source code becomes Python AST objects, which Python then
| complies and executes, but you can also translate the Python
| AST objects into Python source text. Or you can use Python from
| Hy or vice versa: https://hylang.org/hy/doc/v1.0.0/interop
| wodenokoto wrote:
| From the readme / github page:
|
| > Hy is a Lisp dialect that's embedded in Python. Since Hy
| transforms its Lisp code into Python abstract syntax tree (AST)
| objects, you have the whole beautiful world of Python at your
| fingertips, in Lisp form.
| rcarmo wrote:
| At long last! Now I can finally clean up
| https://github.com/rcarmo/sushy (I've been poking at it over the
| years, but every time I upgraded hy portions of the syntax broke,
| or things would get moved in and out of the hyrule package, etc.)
|
| By the way, Hy works really well inside
| https://holzschu.github.io/a-Shell_iOS on the iPad, although the
| syntax highlighting in vim/neovim needs to catch up to the 0.29+
| releases and async.
|
| Although I've tried using Fennel and Guile instead over the
| years, having access to Python libraries and ecosystem is
| preferable to me, and with async I can do some very nice,
| efficient API wrangling (doing HTTPS with fine-grained control
| over socket re-use and headers remains a pain in various Schemes,
| so I very much prefer using aiohttp)
| BeetleB wrote:
| Any downsides to using Hy (over Python)? Other than my coworkers
| don't know Lisp?
|
| More concrete: Are there Python language features I can't use in
| Hy? Or performance penalties in using Hy?
| Kodiologist wrote:
| > Are there Python language features I can't use in Hy?
|
| At the semantic level, no. I work to cover 100% of Python AST
| node types with Hy's core macros. It does take me a little bit
| to implement a new core macro after the CPython guys implement
| a new feature, but you can always use the `py` or `pys` macros
| to embed the Python you need, should it come to that.
|
| > Or performance penalties in using Hy?
|
| Compiling Hy (that is, translating it to Python AST) can be
| slow for large programs (I've seen it top out at about 3
| seconds), but at runtime you shouldn't see a difference. Hy
| always produces bytecode, which can be used to skip the
| compilation step if the code is unchanged.
| rcarmo wrote:
| You take a little performance hit upon initial startup (from a
| clean filesystem, while __pycache__ folders are created). Other
| than that, mostly everything is the same.
|
| I'm now figuring out how to pack images to OpenAI REST calls
| (using my own REST wrapper), and everything is peachy. Here's
| my test snippet (mostly to b64encode the file):
| (import aiohttp [ClientSession] base64
| [b64encode] asyncio [run]) (defn
| :async pack-image [filename] (with [h (open filename
| "rb")] { "type" "image_url"
| "image_url" { "url" f"data:image/jpeg;base64,{(.decode
| (b64encode (.read h)) "utf-8")}" } }))
| (defn :async main[] (print (await (pack-image
| "request.hy")))) (run (main))
|
| This shows you async, context managers, selective imports,
| f-strings... etc. All that you need, really.
| Qem wrote:
| Lack of self-contained tooling. Idle doesn't work with Hy.
| You'll probably need to fiddle with Emacs to set your
| environment first, before being able to do anything beyond
| playing with the language in the REPL.
| rcarmo wrote:
| IDLE is not designed for this, obviously. But you can debug
| Hy using standard Python tools.
| wrycoder wrote:
| Sure - you are piling another transpilation layer on top of
| already slow Python.
|
| Why not just use something closer to the metal: Common Lisp,
| Scheme, Clojure, Racket? Especially, use a compiled language,
| instead of an interpreter.
| kazinator wrote:
| [delayed]
| cab404 wrote:
| Nu, molodtsy.
| vintagedave wrote:
| I loved the HYPE POST.[0] I work with corporate software. It is
| absolutely brilliant.
|
| [0] https://github.com/hylang/hy/discussions/2609
| Kodiologist wrote:
| Thanks. I enjoyed compiling a huge list of buzzwords to use for
| it.
| qwerty456127 wrote:
| Does PyCharm support it already?
| Kodiologist wrote:
| I don't think so?
| https://youtrack.jetbrains.com/issue/PY-48754/Support-for-hy...
| celaleddin wrote:
| Great news, congratulations!
|
| Years ago, under the influence of Lisp romanticism late into my
| university years, I worked on a domain-specific language for
| designing and analyzing control systems as my senior design
| project, using Hy! Just checked, it's been five and a half years
| to be specific. Really, time flies.
|
| Here it is for anyone curious:
| https://github.com/celaleddin/gently
|
| Since then, I've been following Hy from a distance and it's
| amazing to see it's still active. Thank you everyone involved!
| jedberg wrote:
| I looked the examples page, but it was a little disappointing.
| Every example was something that was easier (and sometimes
| shorter) in Python.
|
| It would be awesome if there were an example of something that
| _can 't_ be done in Python because it takes advantage of lisp's
| "functions are first class".
| masijo wrote:
| Also related, for the Clojure fans among us:
|
| A Clojure-compatible(-ish) Lisp dialect targeting Python 3.8+
| https://github.com/basilisp-lang/basilisp
| librasteve wrote:
| (one) nice thing about Raku is it does a surprisingly good lisp
| impression out of the box...
|
| https://www.codesections.com/blog/raku-lisp-impression/
|
| [thanks to Larry Wall's penchant for collecting stuff]
| lispm wrote:
| Strange, the Lisp example has a lot of syntax, even though the
| article claims it hasn't.
|
| letrec, lambda, or & and are not functions in Scheme.
| ashton314 wrote:
| Yay! The birth of a language is a beautiful thing.
|
| I'm curious about the macros: how are these implemented? They
| seem like pretty straightforward unhygienic Lisp macros, which is
| a little bit of a disappointment, but better some macros than
| none at all! Anything about the macro system that distinguishes
| it from the Common Lisp system? E.g. anything borrowed from
| Scheme or Racket? Docs are sparse here.
| kstrauser wrote:
| It's far from new. In 2012 I worked for a shop who used an
| internal package named "hy", and the introduction of _this_ Hy
| made our builds break in a novel and interesting way.
|
| (Also, use _something_ to insure your own internal packages
| have a higher priority, alright? That's a lesson I didn't need
| to learn twice.)
| Kodiologist wrote:
| Sparse? I got a whole chapter for ya:
| https://hylang.org/hy/doc/v1.0.0/macros
| libbrfish wrote:
| I'm wondering, is it worth learning Hy if I don't know any
| python? (coming from a clojure background) Or is python knowledge
| a prerequisite?
| Kodiologist wrote:
| Learning Python is not required to get started and do some
| simple stuff, but it is effectively required to master Hy.
| Foxboron wrote:
| Super happy Hy 1.0 has been released! It was the first proper
| open-source project I contributed towards and I don't think I
| would have been as engaged as I am in the community without it.
| nikisweeting wrote:
| I remember Hy! It blew my mind back in 2014 and is still cool
| today, it's great to see it still going and congrats on releasing
| 1.0.0!
|
| Also great timing after the recent Python Preprocessor post:
| https://pydong.org/posts/PythonsPreprocessor/
|
| Could Hy hypythetically be implemented as a preprocessor like
| https://github.com/tomasr8/pyjsx?
| Kodiologist wrote:
| Hy-pothetically, yes, you could take Hy code in and spit Python
| code out via `hy2py`. I think at one point I considered
| supporting this officially, but then decided there was really
| no advantage.
___________________________________________________________________
(page generated 2024-09-22 23:00 UTC)