
Hy – A Lisp-flavored Python - tosh
https://hy.readthedocs.io/en/stable/
======
IgorPartola
As a heavy user of Python, and someone who grew up with the "curly braces"
languages, I have a question for y'all. Is this really readable?

    
    
        (setv result (- (/ (+ 1 3 88) 2) 8))
    
    

Or rather is it more readable than

    
    
        result = ((1 + 3 + 88) / 2) - 8
    

I just... Do you just get used to this, or is it something that you have to
keep struggling with? Especially given that the latter is how we do math the
rest of the time?

~~~
breck
I'm a Lisper (and Pythoner) and strongly agree, the first one is not readable.
I would say it's gross. It boggles my mind that Lispers haven't taken that
problem seriously. I have taken it very seriously and have been working on it
for years.

I just started publishing my results.

[http://breckyunits.com/the-flaw-in-lisp.html](http://breckyunits.com/the-
flaw-in-lisp.html)

What I've discovered is that the parentheses are __completely __unnecessary in
Lisp, and in fact cause much harm by making Lisp harder to read and maintain
in the long run. Drop the parentheses in Lisp by switching to whitespace
/geometry for syntactic structure and you suddenly have the dream language.

Your example above would be something like:

    
    
      setv result
       -
        /
         + 1 3 88
         2
        8
    

You might think that looks a little strange too at first, but the neat thing
about that code is you can write it on a piece of graph paper, draw lines
around each word, connect the indented nodes, and you'd have a tree
visualization of your syntax code without doing a single transformation of the
source.

~~~
kod
Yeah, whitespace sensitive languages are a great idea...

Until you permanently lose user data because of a pull request that contained
whitespace changes.

Yes, I've seen this happen in production, yes it could have been prevented in
other ways... but why invite disasters like that upon yourself?

~~~
simonh
Have you really never seen a bug in curly brace code due to a misplaced curly
bracket hidden by incorrect indenting? Or code that was just really difficult
to understand and modify accurately because it was indented inconsistently
with the braces? And yes there are tools that can help with that, but...

I worked on Quartz for a few tears, that's over 10 million lines of Python
code and many thousands of commits per day. If concerns like that really were
anything more than nitpicking, projects like that would know about it.

~~~
kazinator
Discrepancy between actual code structure and indentation is susceptible to
diagnosis by machine. That's the beauty of having a bit of redundancy in the
representation.

Recent GCC now has a warning for indentation that doesn't match code
structure. (Had to recently patch a breakage in GNU Binutils in an embedded
distro due to this being a -Werror).

------
taneem
The online demo is amusing/creative: [https://try-
hy.appspot.com/](https://try-hy.appspot.com/)

------
alschwalm
Hy is a great project. One unfortunate thing, though, is that no one has been
able to successfully implement `let`, which makes writing idiomatic lisp
almost impossible. I'm curious if anyone can actually prove it can't be done
or is just very difficult (or too slow to be useful).

~~~
nerdponx
What is it about `let` that makes it so hard to implement?

~~~
tuturto
I actually wrote a short blog post about this just recently:
[https://engineersjourney.wordpress.com/2017/08/01/history-
of...](https://engineersjourney.wordpress.com/2017/08/01/history-of-let/)

In short, let kept running into trouble with yield, exceptions, breaking out
of loops and such. It would have been really tricky (probably close to
impossible) to get everything working correctly.

~~~
bshanks
In case i ever find myself designing a programming language, what facilities
would Python have to support in order to allow 'let' to work? It seems to me
that in theory Hy could solve the problem with which variables are to be
marked 'nonlocal' by doing a lot of additional code analysis (is this
correct?).

I gather that the main remaining problem is that break, continue, yield,
async, await work differently if you covertly introduce a new function scope.
Would it be sufficient if scopes could have explicit labels and break,
continue, yield took an argument that said which label to break/continue/yield
out of? Would that solve the problem with async, await too?

If Hy did extensive code analysis to determine where to introduce 'nonlocal',
and if Python's break/continue/yield took this extra argument, would
implementation of 'let' by Hy then become possible or are there still
additional impediments that i am missing?

~~~
bshanks
(tuturto responded to the parent of this comment at
[https://engineersjourney.wordpress.com/2017/08/01/history-
of...](https://engineersjourney.wordpress.com/2017/08/01/history-of-
let/#comment-292) )

------
smaili
Excerpt:

> Hy is a wonderful dialect of Lisp that's embedded in Python.

> Since Hy transforms its Lisp code into the Python Abstract Syntax Tree, you
> have the whole beautiful world of Python at your fingertips, in Lisp form!

------
macdice
Interesting that it uses defun, like Common Lisp, the main Lisp-2 dialect, and
yet it's clearly a Lisp-1, like Scheme. After (defun f (n) (+ n 1)),
evaluating f shows that it's a function (just as in Python, which is a
Lisp-1). My first thought, for what it's worth, is that if the namespace
semantics is like Scheme it'd be better to follow Scheme idioms rather than
Common Lisp, so code can be easily ported. On the other hand, this is only my
first minute using Hy so what do I know. Looks really neat!

~~~
kazinator
EuLisp (pretty much defunct) is also a Lisp-1 dialect with _defun_.

------
etiam
There's even a couple of kernels for IPython/Jupyter. The best I've seen so
far is
[https://github.com/Calysto/calysto_hy](https://github.com/Calysto/calysto_hy)

I'd like to move to Hy for much more of what I currently do in Python, but so
far I've been too lazy to find/create good editor support for it. For actual
projects of some size the loss of context help, documentation, various
completions, etc seems like too high a price to pay.

~~~
zitterbewegung
I think the highest cost is really collaboration with others. If you ever want
help with your project or if people even want to use it you are dealing with
only Hy users and disregarding regular Python users. I do like the concept of
Hy though.

~~~
etiam
It's restrictive that way, no doubt.

On the other hand, I suspect that as subsets go, Hy programmers would be a
good one.

And I'm not sure the impact on getting people to use it would necessarily be
_that_ bad. It's just an extra import hy away to use modules written in Hy
just as usual from Python, after all.

------
winter_blue
Since Python doesn't support multi-line lambdas, how do they support the
analog in LISP? It's almost necessary for any dialect of LISP to support
lambdas (i.e. functions) that contain a LISP 'do' [1] which lets you group
statements. Do they chain together expressions/statements with continuations
or something?

[1]
[http://www.lispworks.com/documentation/lw60/CLHS/Body/m_do_d...](http://www.lispworks.com/documentation/lw60/CLHS/Body/m_do_do.htm)

~~~
joejev
Python lambdas are just syntactic sugar for creating a function object. The
ast can just build a named function and use it in the needed expression.

~~~
kazinator
However, that approach seems rather backwards compared to having an anonymous
function primitive which is used as the basis for the lambda one-line-only
sugar, as well as named functions (which simply establish a binding between a
name and the anonymous thing).

~~~
aoeusnth1
Why should the programmmer care about whether the underlying function is named
or not?

~~~
jwdunne
I imagine some kind of analogue to gensym would work there. The name can be
throw away and guaranteed unique in scope.

In fact, a lot of SICP examples have you define a function within a function
with a name like "iter" for TCO recursion. It'd work like that.

Edit: seems like gyka below confirms that's how it works. I should have read
on!

------
kzisme
Shout out to @paultag (Author/Creator of Hy) - he's an awesome guy who has
written some really cool stuff.

~~~
boxy_brown
This, Paul is someone I look to as a model open source contributor in so many
ways.

[https://twitter.com/nedbat/status/861696880790704128](https://twitter.com/nedbat/status/861696880790704128)

> How many people can say they have worked with [Sally] Yates, and have
> written exemplary Dockerfiles?

~~~
paultag
Thank you so much. I'm deeply humbled and extremely grateful for this. It's
the nicest thing I've read all week, and really brightened my day up. Thank
you!

~~~
srean
May I shower some humble upvotes sir.

Does Hy work with Pypy ? A jitter lisp would be cool

~~~
paultag
It does! We run tests on pypy, and it for sure works. I did at one point even
test hy with rpython, I can't remember if that will still work or not, but it
did compile like 4 years ago :)

~~~
srean
Fantastic!

------
dvdt
One fun application: I used Hy to control my liquid handling robot,

[https://twitter.com/dtsao/status/891038101706989568](https://twitter.com/dtsao/status/891038101706989568)

------
gcoda
Reason I am trying it - best "hello world" example ever.

(print "I was going to code in Python syntax, but then I got Hy.")

------
nathancahill
This is my go-to for toy projects over the last couple years. Great execution
all around. Be aware, if you don't like puns, this isn't the language for you.

~~~
sn9
So you're saying that if you don't like puns, you should get off your Hy
horse?

~~~
kerkeslager
Nothing so aggressive. He's just saying they hold puns in Hy esteem.

------
souenzzo
See also

[https://github.com/pixie-lang/pixie](https://github.com/pixie-lang/pixie)

~~~
nerdponx
I wanted to get into Pixie but last I heard it was a dead project.

~~~
souenzzo
It's not "dead"
[https://www.youtube.com/watch?v=1AjhFZVfB9c](https://www.youtube.com/watch?v=1AjhFZVfB9c)
It's a weekend project, for fun. Functions that are work will not stop to
work. I'm using it and I pretend to contribute when I find a problem.

~~~
nerdponx
Great to hear. I'm still not sold on CL as "my Lisp of choice", so I would be
happy to give Pixie a shot.

------
kronos29296
The entire thing is full of puns really too much of puns related to hy. Cool
project. Python joined Erlang and Java with a lisp flavour of its own with Hy.
Hope we get a let expression soon.

------
asimjalis
I have been using Hy as an alternative to Python. It is delightful to use.
Highly recommended.

~~~
cheez
What kind of projects have you used it for?

~~~
rcarmo
My blog/wiki engine is written in an older version of Hy:

[https://github.com/rcarmo/sushy](https://github.com/rcarmo/sushy)

I'm currently re-writing it in Python 3.6 because Hy has taken a hard stance
in backwards compatibility and deprecated "let" (with a replacement macro, but
still) and isn't tackling async (both for understandable, but sad reasons), so
it doesn't really work for me anymore.

But while it did, I loved it to bits. Python with a LISP syntax is just
wonderful, and if someone ever finds a way to add back the stuff I like, I'm
more than willing to deal with the quirks.

~~~
chuckdries
I know python, and last semester I took a class that briefly touched (lightly
kissed?) LISP for a few weeks. I have a passing familiarity and I really loved
the very small amount that I saw. I'd like to learn more, can you go into more
detail on the usage of let and how one would go without it?

~~~
flavio81
and to directly answer your question, there a are many things you can do with
let. Let binds a "form" to a symbol.

    
    
        (let ((pi 3.14))
         ... code goes here ... )
    

So within the "code" part, that is, within that lexical environment, the
symbol "pi" exists and is bound to float number 3.14

(Alternatively, you don't need to set a initial value.)

One of the interesting uses of let is that it can also redefine _dynamic
variables_ (aka _special_ variables, think of them as "global variables).

So for example let's assume i define _timeout_ to 300, so within my whole
_package_ , this _special variable_ has the value of 300. Let's suppose this
variable is going to be read by function "my-function", and others.

So i create this special variable:

    
    
        (defparameter *timeout* 300)
    

Now, despite the above, let's suppose i want to call "my-function" but with a
timeout of 1000. I can just do this in my code:

    
    
        (let ((*timeout* 1000))
             (my-function))
    

So, inside this "let", when "my-function" gets executed, the timeout will be
1000. Outside of this, it will still be 300.

Let, thus, allows you easy use of lexical environments.

Another use is creating _closures_ by using the combination of "let" with
"lambda."

------
dmoney
Unicode identifiers make me uncomfortable. I have no idea how I would type
that circular one in the "sharp macro" section (short of copying and pasting),
and I'm imagining seeing those missing-character boxes all over the place.

~~~
yorwba
I think that example was more tongue-in-cheek than anything (after all, who
would want to write their code in reverse). But if you use e.g. the fcitx
input on Linux, you can just press Ctrl-Alt-Shift-U, type "circle arrow", and
select "↻" (clockwise open circle arrow) from the list. The fuzzy matching is
pretty awesome, I hope similar Unicode handling will come to all platforms in
the future.

------
yablak
As a tensorflow dev, with several years experience writing clojure at a
previous startup, I believe this is the most natural language for writing
tensorflow models (or theano. basically any graph building dsl that has any
real complexity and has been bolted onto python).

Suddenly TF's cond and while_loop and context controls all fit naturally into
the language.

My favorite technical post in recent memory.

------
udkl
While both have their own personalities, has anyone done a side by side syntax
and feature comparison of clojure and Hy ?

~~~
ealhad
“Keep in mind we’re not Clojure. We’re not Common Lisp. We’re Homoiconic
Python, with extra bits that make sense.” — Hy Style Guide

That said, Hy takes _a lot_ from Clojure.

~~~
flavio81
> That said, Hy takes a lot from Clojure.

Oh oh... That scares me. Clojure -as a Lisp-like language running on the JVM-
is a good idea but i have some reservations regarding how that idea got
implemented.

~~~
ealhad
I can only agree with you. I don't like some of the syntactic choices of
Clojure, and sadly some of those are in Hy.

------
robobro
Has anyone ever used Hy for CGI stuff? It may be possible to port Hackernews
to it, just for fun..

------
cuspycode
I used Hylang to program an Arduino Yún a few years ago, via cross-
compilation. This was a very nice experience, since it allowed me to use the
great Python ecosystem without having to be limited by Python the language.

------
partingshots
Now CS61A can finally go back to teaching purely in Scheme again.

------
amelius
Is this like clojure, but for python instead of java?

~~~
kirbyfan64sos
Yup, although Hy tries to stay much closer to Python's semantics than Clojure
to Java's.

------
droidist2
How does this work with tooling though, like step debugging and refactoring in
IDEs like PyCharm, or with iPython notebooks?

------
wodenokoto
Will this give me lisp in jupyther notebooks?

~~~
mmaul
You can already have lisp (common) in jupyter notebooks via cl-jupyter. Here
is an example [https://github.com/mmaul/clml.tutorials/blob/master/CLML-
Win...](https://github.com/mmaul/clml.tutorials/blob/master/CLML-Wine-pca-k-
means-and-hierarchical-clustering.ipynb)

If you want to use Hy in a note book you will need a jupyter kernel for it and
I belive there is one called hy_kernel

------
evanwolf
Next on the wishlist: an APL inside Python.

------
sridca
A decade ago I wrote something like this using Racket (formerly MzScheme)!
[https://github.com/srid/boalisp](https://github.com/srid/boalisp)

------
yoodenvranx
> Hy

This must be the worst submission title in the history of HN.

~~~
asimjalis
It is possibly the shortest.

~~~
hk__2
I got curious and I checked; there have been a few one-character submissions
so it’s not the shortest.

    
    
         ⊥: https://news.ycombinator.com/item?id=7530548
         {: https://news.ycombinator.com/item?id=7729399
         M: https://news.ycombinator.com/item?id=4367006
    

In total (at least in the [fh-bigquery:hackernews.stories] BQ dataset), there
have been 15 non-deleted submissions with a one-character title.

------
tills13
hy more like why

