HN user

Kodiologist

292 karma

http://arfer.net

Posts1
Comments35
View on HN

Admittedly, I've tried not to document the implementation. Yeah, they're pretty much simple dirty Common Lisp macros. Internally, they're functions that are called with the arguments converted to models (via `hy.as-model`), and then the return value is converted to a model. If a macro's first parameter is named `_hy_compiler`, it gets access to the current compiler object; this is undocumented since it's only meant for internal use. Reader macros have no parameters, but can access the current reader object as `&reader`. When it's defined, a reader macro is added to the current reader's dispatch table.

Yeah, at a certain point I realized that both the maintenance and the use of the language became much slicker if unnecessary deviations from Python were minimized. After all, when I'm writing Hy code, I'm usually spending a lot more time referring to the documentation of Python or third-party Python libraries than the documentation of Hy. I felt there were a number of ways Python could be improved upon, but e.g. the old feature that let you spell `True` as `true` in deference to Clojure was just a needless complication.

You can add all the same type annotations as in Python, but from what I've seen, type-checkers expect Python source text and don't just use standard Python introspection, so you'll need to use `hy2py` first to actually check your program's types.

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.

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.

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.

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

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.

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.

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.

Homoiconic Python 2 years ago

Hy slower than Python? It shouldn't be, at least at run-time. I maintain Hy. If you notice any meaningful performance differences, that's a bug.

Hissp 3 years ago

As the Hy maintainer, I'd say that assessment is pretty accurate, at least on the Hy side.

Why Hy? 4 years ago

In Hy, you can include Python with `py`, as in

    (py "(-b + sqrt(b*b - 4*a*c))/(2*a)")
Why Hy? 4 years ago

1. Nope, sorry.

2. That's right. Hy depends much more on finicky details of Python than most Python packages do, particularly Python's AST, so each 3.x release of Python usually requires some changes to Hy to support it. Each Hy release supports (at least) all versions of Python 3.x that have been fully released and are not yet at end of life.

3. More precisely, we're trying to take more of our conventions from Python rather than Clojure. See https://news.ycombinator.com/item?id=31250992

Why Hy? 4 years ago

Cool, I'm a Hy guy; glad to meet you. Hy in its early years imitated Clojure syntax much more closely, and Clojure compatibility may've been implicitly a goal even if it never got to the point of cross-testing. These days we prefer to think of Clojure as one of several possible influences.

Why Hy? 4 years ago

I've been trying to steer the syntax towards imitating Python more than Clojure, the idea being that you frequently need to rapidly switch between reading Python and Hy (as when you're writing a Hy program while consulting documentation for a Python library), so it helps to minimize friction there. Thus e.g. `True` must now be capitalized that way, Python-style; `true` used to be allowed as well. But whether a more Pythonesque Hy is more or less confusing than a more Clojuresque Hy is admittedly a matter of taste.

Why Hy? 4 years ago

I've been working on Hy since 2016 and I've frequently encountered, but never understood, the sentiment that Hy isn't a "real Lisp". What makes for a real Lisp? There have been dozens (hundreds?) of Lisps over the decades, and if they all have a defining characteristic that Hy lacks, I don't know what it is. Certainly Lisps have varied in how scoping works, among other things.

Why Hy? 4 years ago

I'm not familiar with Jupyter internals, but I think functions would work well for this. Hy allows multi-statement anonymous functions, and you can do stuff like `((fn [] … ))` to define and immediately call the function. One advantage of this over `let` is that it allows old locals to be garbage-collected. If memory isn't an issue, though, `let` should work well.