[HN Gopher] Hy 1.0 - Lisp dialect for Python
___________________________________________________________________
Hy 1.0 - Lisp dialect for Python
Author : Kodiologist
Score : 433 points
Date : 2024-09-22 14:43 UTC (1 days 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.
| __mharrison__ wrote:
| Most pandas experts recommend against mutating (or using
| inplace=True) with pandas.
| 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
| benrutter wrote:
| That library looks like some seriously cool wizardry! I'm
| excited to play around with it later
| 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.
| nerdponx wrote:
| 1. It supports the same set of features that python supports,
| which is pretty good when it comes to things like traditional
| step through and postmortem debugging. And CPython Supports a
| lot of internal hooks if you want to do really advanced dark
| magic. But it doesn't have anything like the condition system
| or handlers/restarts.
| 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!
| Slackwise wrote:
| The actual statement in the video is:
|
| > ...because this is a frontend like LLVM or GCC that
| compiles instead of bytecode, uh, to Python AST, um, so this
| Lisp compiles entirely to Python
|
| @ https://youtu.be/1vui-LupKJI?t=1020
| 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:
| If I were to guess, it's to be able to use the all the
| packages in the Python ecosystem, directly. It's for
| situations in which Python is already a given. In fact, it's
| probably the case that many Python programmers can't even use
| this, due to being in a situation in which even the poor
| syntax is nonnegotiable.
| BeetleB wrote:
| I do use Racket. And over half the time I switch to Python
| because I don't want to author libraries that already exist
| in Python.
| vindarel wrote:
| this 100%. We have some options today to run Python from CL
| when necessary:
|
| https://github.com/digikar99/py4cl2-cffi
|
| https://github.com/marcoheisig/lang
| 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.
| zoom6628 wrote:
| That post deserves its own star rating! Absolutely brilliant.
| __MatrixMan__ wrote:
| > I guide the development of Hy as a morally ambiguous
| iconoclast not totally averse to indefinite nominal executive
| rule, or "MAINTAINER" for short.
|
| Hehe, clever.
| 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
| codr7 wrote:
| There's nothing wrong with CL macros.
|
| Quite the opposite, they are more powerful than the
| alternatives.
|
| Macros are power tools, dumbing them down for safety is missing
| the point.
| 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.
| cfiggers wrote:
| That's how I'm using Hy at my job--I write Hy then hy2py it
| into Python, lightly polish the compiled Python for human
| consumption, and then share that with my Python-fluent but
| Lisp-illiterate coworkers.
| mark_l_watson wrote:
| Wonderfull!
|
| I wrote a book oh Hy, so now tomorrow I will update all the
| examples to version 1.0
|
| Not counting work on my book, I don't use Hy more than perhaps
| five hours a month, but it is a fun language, with good Emacs
| support. Thanks!
| Kodiologist wrote:
| You're welcome. There are no actual breaking changes from
| 0.29.0, so you're already up to date if you got that far.
| aidenn0 wrote:
| Does Hy offer any features that Python lacks (e.g. dynamic
| binding)? I find the syntax of Lisp to be the least compelling of
| its many features.
| Kodiologist wrote:
| Yes, such as: metaprogramming via macros and reader macros;
| arbitrary compile-time computation; removal of restrictions on
| mixing statements and expressions; and other arities for
| Python's binary operators. See
| http://hylang.org/hy/doc/v1.0.0/whyhy#hy-versus-python
|
| Dynamically shadowing global variables is not built-in, but
| easy to write a macro for if you want it. See e.g.
| https://stackoverflow.com/a/71618732
| notepad0x90 wrote:
| I'm almost convinced people are pretending to like the Lisp
| syntax. I just don't get it.
|
| I looked at the Hy vs Python comparison, Hy is just as (if not
| more) verbose as Python and harder to read and reason about.
|
| Honest inquiry here, what is the appeal or benefit of the Lisp
| syntax? is it just that some people have a subjective preference
| for it?
| ungamedplayer wrote:
| I find non lisp harder.
|
| In blub lang based on c:
|
| Fn(Val Val Val) to f(1,2,3) or
|
| Val fn val 3 + 3
|
| In blub lang based on lisp
|
| (Fn val val...)
| troad wrote:
| I don't think (fn x y z) is all that different to fn(x, y, z).
| The lack of finicky operator order or other syntax footguns is
| nice. You're basically looking at the AST as you work. You're
| one fewer layer of abstraction removed from the logic you are
| composing.
|
| In real world Lisp, alignment conventions are used that make
| even a fairly nested function readable at a glance. You'd also
| generally work using something like paredit, so you're kind of
| shuffling the S-expressions around like legos. It's not a
| language that you'd want to write in something like Notepad.
|
| The most important thing about the syntax, though, is that
| since it's basically the AST, a Lisp macro can effectively
| manipulate the AST directly and on the fly. This is incredibly
| powerful, and would be hard to achieve in an Algolian language
| like Python.
| bachback wrote:
| Code thats written in Lisp is using AST differently. It makes
| the process of generating machine code much easier. This in
| turn enables macros which is meta programming not available in
| non Lisp languages. However on the other hand I tried this
| avenue and since most modern computing is not Lisp based it
| severely limits its potential. I'm hoping for a Rust based
| Clojure or variant. Clojure has the problem its based on the
| java ecosystem which has severe downsides. A lisp thats based
| on python doesnt make much sense to me personally python isnt a
| good language to write other languages in. I think Zig and Rust
| would be the interesting choices. One attempt:
| https://github.com/clojure-rs/ClojureRS
|
| See also: https://paulgraham.com/avg.html
| notepad0x90 wrote:
| Wouldn't it make more sense then to compile existing
| languages to a Lisp? From what you said, it sounds like the
| goal of Lisp making generation of machine code faster/easier?
| Or is it that forcing programmers to encode there intent into
| a Lisp removes guessing and optimization overhead for the
| compiler?
| cess11 wrote:
| You can invent another syntax with Lisp/Scheme macros if
| you want. When compiled or interpreted it will be macro-
| expanded, and then likely transpiled to an AST and then
| compiled into byte- or machine code.
|
| Take a look at Racket languages for some examples.
|
| Lisp syntax with the parens and so on means editing is
| inherently structural, which makes it relatively easy to
| reason about and restructure the code. In Python spaces
| have double meanings, both as separator between tokens and
| as a block separator, similar to e.g. {} or () in other
| languages. That makes structural editing relatively hard.
| codr7 wrote:
| Read macros, ordinary macro bodies have to follow
| ordinary syntax rules.
| bachback wrote:
| yes, you can think of Lisp almost as an intermediate
| language. Lisp probably lends itself well to machine code
| generation but I haven't done enough assembly to really
| know that. its not designed for that, its just a side
| effect of the language primitives being very very short.
| you can write a basic Lisp interpreter in a few hours
| yourself https://norvig.com/lispy.html. Creating a decent
| compiled language takes a lot longer than that. Lisp only
| requires 5 or so primitives and it doesn't have a grammar.
|
| it is a bit ackward for humans but machines can process it
| better because it has less structure. for example what I
| thought is that Lisp could potentially be a great choice to
| interop with Large Language Models with, because its
| potentially shorter code. Good clojure code can be 5-10x
| shorter than python code. With LLMs size of code matters a
| lot.
| itishappy wrote:
| As I understand, that's pretty much exactly how WASM works.
| It can output either a `.wasm` binary or the same code in a
| `.wat` text format that looks like this:
| (func (param i64) (result i64) local.get 0
| i64.eqz if (result i64) i64.const 1
| else local.get 0 local.get 0
| i64.const 1 i64.sub call 0
| i64.mul end)
|
| https://en.wikipedia.org/wiki/WebAssembly#Code_representati
| o...
| chr15m wrote:
| Some concrete advantages that come from a simple, uniform,
| machine-readible syntax that your text editor itself can
| understand and manipulate:
|
| - It makes editing and refactoring code faster. With a single
| keystroke you can do things like popping bits of code in or out
| of scope, deleting logical blocks of code etc. It's fast.
|
| - It's hard to explain without trying it, but it is faster and
| less error prone to e.g. grab a section of code inside a
| function and break it out into a separate function. If your
| lisp is functional this is even smoother (hy is not as
| functional as it could be last time I checked).
|
| - You never have to think about syntax. Python for example has
| different syntax for different operations and introduces new
| syntax relatively frequently. By contrast in a lisp the syntax
| for setting a variable looks the same as the syntax for looping
| and for everything else. It's all just function calls.
|
| - If you have an nREPL set up (it's like the python repl but
| it's an API your editor can talk to) it makes it easier to run
| segments of code that are embedded inside other bits of code.
| E.g. you might have some complicated piece of maths or string
| manipulation in a function. You can run and try it out in
| isolation without executing the entire function.
|
| - Metaprogramming. This is a bit overhyped for most
| programmers, but having the code as a data structure means you
| can add new language features from your own code, build DSLs,
| and have code that modifies other code more easily than in
| other languages. I try not to use metaprogramming and macros
| much, but I use a lot of things that smarter people than me
| have made with them.
|
| These features are a bit hard to appreciate without trying
| them. Highly recommended!
| lispm wrote:
| > By contrast in a lisp the syntax for setting a variable
| looks the same as the syntax for looping and for everything
| else. It's all just function calls.
|
| Not really.
|
| Setting a variable in Lisp is not a function call. IF is also
| not a function call. Defining a function is also not a
| function call. Loop operations like DO, DOLIST, DOTIMES, ...
| are also not function calls. Lots of things are not function
| calls. Macro forms are also not function calls.
| chr15m wrote:
| Yes, my apologies, I should have said "it all looks like
| function calls".
| lispm wrote:
| (let ((a 10) (b 20) c) (declare (type (integer 0
| *) a b c)) (setf c (* a b)) c)
|
| Above is a LET expression, a variant of a lambda
| application.
|
| It does not look like a function call. It looks like an
| operator list form, with LET as the operator. The next
| element is not a function call or similar, but a binding
| list with three variable definitions, two of them having
| an init value. Next to the binding list is a declaration
| form, with a type declaration for the local variables.
| Then a sequence of forms, a body, which is evaluated top
| down and the last value ist returned. There is a setf
| form, for setting a variable. The variable in the setf
| form is not evaluated, it will be set to the value of the
| second argument.
|
| Neither LET, DECLARE, TYPE, INTEGER, or SETF are
| functions. They have different syntax and/or semantics
| from function calls.
|
| Thus we have:
|
| * special control flow
|
| * a LET syntax which is not looking like a function call
|
| * a lexical scope created by LET
|
| * a type declaration with special syntax
|
| * special evaluation rules, unlike evaluation of a
| function form
|
| A Lisp user will need to learn that IF, WHEN, AND, ...
| and a lot of other operators are not functions....
| codr7 wrote:
| Depends:
|
| https://github.com/codr7/sharpl
| anentropic wrote:
| Surely all programming languages have machine-readable
| syntax?
| chr15m wrote:
| They do. Parsing and manipulating it is easier with a LISP
| and this means the tooling to do so is ubiquitous because
| anybody can do it.
| Phiwise_ wrote:
| By analogy, programmers like LISP over other syntax for the
| same reason that creative children like LEGO over other toys.
| It's not that the pieces in the box are more beautiful than any
| other individual example of molded plastic, but because they
| are purpose-built to be the maximizing mold such that a box
| full of them gives more flexibility and potential than a box of
| any other shape you might choose. Lisp syntax is the way it is
| to create a human-machine interface with as much similarity
| between the two sides as possible, so the human approaches
| machine power when you write code, and the machine approaches
| human reasonability when you inspect running code.
|
| For examples, McCarthy's original purpose was to demonstrate
| the effectiveness of a symbolic differentiation process he had
| dreamt up, so he devised the syntax and meta-circular evaluator
| of lisp to make it maximally obvious from the program text that
| the differentiation system was mathematically correct, while
| keeping it maximally obvious from the program model definition
| that it was computationally concrete. In response to new trends
| in the programming field, Lispers write mind-bending books like
| "Let over Lambda", "The Art of the Metaobject Protocol", or
| "Software Design for Flexibility" to show that, when your
| syntax and model is right, you can radically change how you
| solve problems not by rewriting your spec or switching
| languages but by just adding more lisp to the lisp you already
| have, which has the same simplicity as radically increasing the
| sculptures a child can make by just adding more lego to the
| lego they already have.
|
| Lisps, on the other hand, tend to add features as just more
| convenient versions of things they can already do: Macrology
| for self-adapting code? Just lisp functions on lisp data
| structures corresponding to lisp functions. Actors for a
| concurrent execution model? Lisp functions as lisp data
| parameterized by higher-order lisp functions. Composable
| continuations for error handling? A lisp function exploring a
| lisp data structure of lisp data structures of lisp functions.
| It's turtles all the way down. Paul Graham points out that you
| can understand the social hype the presence or absence of a
| feature like operator overloading as a consequence of friction-
| ful syntaxes, while lispers care much less because replacing a
| function you don't prefer with one you do for your use case is
| straightforward in a friction-free syntax. When he decided to
| build a reddit clone for tech entrepreneurs he didn't need an
| outside data system just to get started, he only had to spin up
| a pool of threads for sessions to directly modify s-expression
| literals in memory, which he could save or modify by printing
| straight to disk and load by just reading the lisp syntax back
| into memory like all lisp code is, with no execution
| intermediary like languages such as the Pythons tend to have
| complicating things enough to make comparatively big services
| like a whole database for a private gossip forum worth the
| effort. The syntax doesn't make lisp first-order beautiful, it
| makes lisp the hacker's local maximum, which is second-order
| beautiful, and honestly isn't much harder to get into the habit
| of reading once you know it's worth it.
| nibbula wrote:
| Exactly. When certain smug people come about I just humor them.
| Like, "oh isn't that nice", when I'm really holding my nose
| internally. Like who dumped a bunch of toenail clippings in
| your code? When I see Lisp my reaction is like when my dog
| makes a mess on my carpet. And macros? You get paid to write
| code. Is it too much to write a few more lines? Python's nice
| and all, but Algol, that's a rugged person's language, feels
| very solid. Not like this squishy Lisp. Like how many parens do
| I have to type?? Please.
| reddit_clone wrote:
| Not sure if this is sarcasm or trolling.
|
| If trolling, it is not very subtle. :-)
| blarg1 wrote:
| I find lisp horrible for procedural code but fine for
| functional code for some reason.
| reddit_clone wrote:
| Compared to other languages, 'lisp syntax' is very minimal. It
| is just a prefix notation with parenthesis for enclosing
| expressions, the first item usually being a function. There are
| only a handful of special forms to learn, which deviate from
| this.
|
| The real power of lisp IMHO lies in: - Repl
| driven, dynamic development. This is hard to explain. Its like
| chocolate. You have to try it. You either love it or hate it.
| - Macros. This is again enabled by the 'lisp syntax. Actually
| lack of it...'.
|
| Here is an example I recently ran into when checking out Hy
|
| https://github.com/hylang/hy/discussions/2608#discussioncomm...
|
| This shows how much you can abstract, hide the noise without
| any runtime penalties..
| spit2wind wrote:
| Whoa, congrats! Been watching this project for years, seeing the
| steady progress toward a 1.0. It's been no small feat. Congrats!
| Excited for you!
| aitchnyu wrote:
| Does it (or other lisps) interact with Python static typing?
| Kodiologist wrote:
| 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.
| giessel wrote:
| Congrats!
| fhchl wrote:
| Not a Lisp, but also an interesting take on a functional
| programming language that transpiles to Python is Coconut
| (https://coconut-lang.org/).
|
| I'd be seriously interested in hearing from people that have
| actually used any of these two and what their experience was.
| nerdponx wrote:
| I played around with Coconut many years ago and my impression
| was that the compiler was not smart enough to be useful. The
| generated code had a big pile of helper functions hardcoded at
| the top, and the program was much slower than the equivalent
| plain Python.
|
| By contrast Hy generates Python code that is very close to what
| you might write by hand, apart from some indirection when it
| comes to scoping with `let` and some variations around
| returning values.
|
| Maybe Coconut has improved though, it's been a long time.
| rogerallen wrote:
| Is there a wisp frontend? Seems like it would be appropriate. :-)
| https://github.com/stereobooster/wisp
| jollyjerry wrote:
| This reminds me of Berkeley's CS61A when it was taught with
| Scheme. One of the projects was writing a schema interpreter for
| scheme. It felt silly, but was a great small project to show case
| recursion, trees, and blurring the distinct between data and
| code.
| mcejp wrote:
| I would like to make the observation that as Hy matured over the
| years, instead of accumulating syntactic sugar and special cases
| to grow more Lispy, less Pythony, it seems to have generally gone
| the opposite way. That is, becoming a thinner _syntactic_
| abstraction of Python 's feature set, focusing on the essentials
| that cannot be emulated in any other way (macros)
|
| A few examples from recent releases:
|
| - "match" is just native Python "match" -- it doesn't even
| polyfill for pre-3.10 Python versions (in the TypeScript world
| this would be _unthinkable_ )
|
| - "foo?" used to mangle to "is_foo" as a special case, but this
| has been removed
|
| - "hy.eval" has been overhauled to be more like Python's "eval"
|
| - nice-to-have but non-essential utilities ("unless") get often
| pushed out into the Hyrule package
|
| For me this direction was counter-intuitive at first, but it has
| some very nice outcomes; for one, it simplifies the learning
| curve when coming over to Hy from Python, and it makes it easier
| to consistently interact with Python packages (arguably the main
| reason to use Python in the first place!)
|
| Or maybe it's just a matter of simplyfing maintenance of the
| language; IIRC, "let" took like 4 attempts to get right :)
|
| In any case, congratulations on this great milestone!
| Kodiologist wrote:
| 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.
| mcejp wrote:
| It is true that Hy really shines in those cases where it
| adopts an existing Python feature and adds meaningful
| quality-of-life improvements: anonymous functions without
| limitations; multiple iteration in for-loops; relaxed
| character set for identifiers. Things that seem completely
| obvious, once you have them.
|
| It also demonstrates that elegance in a Lisp-on-Python is
| reached in a very different way than elegance in a stand-
| alone language, since it becomes an art of making the best
| out of what is already there.
___________________________________________________________________
(page generated 2024-09-23 23:01 UTC)