There are some truly powerful and unique things about Lisps, but I wish articles like this would stop including REPLs and hot-reloading. The former have been table stakes for interpreted languages (and some compiled ones!) for years, and the latter is neither unique nor particularly widely used (hot reloads have to tangle with state and patching, so resetting the world for ease of reasoning is considered a best practice for a reason).

> The former have been table stakes for interpreted languages

I used to think so too back in the day when I was getting into Clojure. It was much later when I realized that when Lisp people talk about the REPL they’re usually talking not so much about the interactive CLI where you can evaluate commands easily but more so the ability to connect your program to a live session where you can quickly evaluate forms within your text editor and in the context of your running application, which enables much more interactive development than in other interpreted languages.

you can do that in a python debugger?

the python debugger is cool but is an inferior experience. It isn't only about a REPL, but about the editing experience, and about the language being thought from the ground up for long-living programs. See: https://mikelevins.github.io/posts/2020-12-18-repl-driven/

[dead]

You've been able to do this in Ruby since I can remember. Not a lot of editors take advantage of it though...

No. There is real, palpable, practical, functional difference between working a Lisp REPL and a REPL in a non-homoiconic languages - Ruby, Python, Haskell, etc. Every single stage there in Read-Eval-Print-Loop differs.

Man, it gets so exhausting trying to convince every PL critic who grabs a single (or a couple) of axis of any language and tries to dispute the value of a language without ever understanding the holistic, overall experience working with it.

Like, I don't understand, do people think that tons of Clojurians or Common Lispers who fall in love with the language after decades of working and getting seasoned in literally dozens of different PLs are on some kind of delusional trip or something?

Guys, just take a gander at Clojurians Slack; see what people are working on, what kind of stuff they're building; check their profiles. Many of them are the battle-scarred veterans of coding. Sure, some of them may have wrong opinions, but surely they can't be all wrong, can't they?

> There is real, palpable, practical, functional difference between working a Lisp REPL and a REPL in a non-homoiconic languages

Smalltalk is not homoiconic, and it's REPL experience is equivalent (I'd argue somewhat better, but that's mostly a tooling thing, see the commercial CL implementations as examples of improvements over SBCL + Emacs + Slime). Homoiconicity is not the trait that makes the CL REPL experience better than others, it's that it includes a very good debugger, the compiler, hot code reloading, the ability to redefine classes and update current instances, and so on.

That's the tooling, not the language, that provides the experience. Nothing about being non-homoiconic prevents other languages from having a comparable (or even better) experience.

> Nothing about being non-homoiconic

Nothing about being statically/dynamically typed. Nothing about being functional/OOP/relational/logic. Nothing about being pure/side-effecty/strict/lazy. Nothing about being compiled/interpreted. Nothing about imperative/procedural/stack-oriented.

You can pick just about any single or (few) aspects about any language. Heck, it doesn't even have to be a programming language and you can find things to complain about.

You know that there are three genuine, true, legit ways to build robust, bug-free, performant software? Three! The problem? Nobody knows what they are and that's why we are all doomed to keep bashing on everyone else's choices and opinions.

"Better experience" is not dictated by "features". Better experience comes, well, with experience.

I suppose it's my own fault. I tried focusing on "holistic, overall experience", yet still picked a single aspect to chime in.

[flagged]

Huh? First time I hear that my account is "regarded" and not just, but "widely" too. What part of your fragile ego my words hurt, I wonder?

I wrote GGP as a Lisp user and enjoyer—not pretending to deep experience, but definitely am well acquainted. And neither the REPL nor live reloading are important differentiators. Neither is the ability to attach a REPL to a running program: plenty of languages have that built in (Erlang, Ruby), and many others support it through popular third party tooling (e.g. Pyrasite for Python, and—ironically—the class executor for the Clojure REPL for arbitrary non-Clojure JVM programs). Many Lisps’ REPL tooling is very nice, and the language lends itself well to REPL-oriented development. But those aren’t “uniquely Lisp” features as you and many others claim.

Homoiconicity is a "uniquely Lisp" feature and it doesn't seem like you've fully grokked the implications and differences between homoiconic and non-homoiconic. I'm not making this up - every step there in Read-Eval-Print-Loop does differ. That is easily verifiable info.

Eval differs very slightly from, say, an interpreter with a very non-syntactic AST, due as you say to homoiconicity. Neither read, print, nor loop differ in any Lisp-specific or qualitative way. And the differences in eval’s behavior don’t change anything significant about the REPL user’s experience (other than that they’re writing Lisp). So what do you mean?

Specifically, cached state and behaviors still need to be reconciled with new inputs/overrides during “eval”, and no Lisp has an easy answer to those (neither, as far as I know, does any other language). Avoidance of closure state via late binding and a convention of reliance on very simple data structures help Lisp’s REPL/hot-patch story, and that is indeed nice, but it’s far from “guaranteed ease/safety of REPL patching” or a totally different paradigm.

> don’t change anything significant about the REPL user’s experience

Perhaps you have never tried/heard of nextjournal/clerk, scicloj/clay, djblue/portal, vlaaad/reveal or just simply tried building a simple web scraper with Playwright running on nbb. Oh, and hyperfiddle/electric - something like that would not be very trivial without homoiconicity.

[deleted]

Why do you think other people who have fallen in love with, say, Ruby, are less experienced in other languages? They just have less of a cult.

You sweet, summer child, just so you know, I have existed for nearly half a century in this world where the larger part of it I have spent dealing in computing. I have seen and dealt with more programming languages (including Ruby) than you can count with your fingers and toes and that number keeps growing still. I'm not advocating for any particular language, runtime, framework or paradigm - do use whatever your heart desires.

I'm simply pointing out that there is a meaningful difference in REPLs in homoiconic and non-homoiconic PLs. You don't have to listen to me, this is easily verifiable information. Google it, ask LLMs, try it yourself, or ignore the notion entirely - it's completely up to you. But let's not get too intimate and slide into insulting one another - you have no idea who I am and what cults I'm specifically fond of.

Apparently you're not experienced enough to have used a Lisp that doesn't have a REPL, nor a non-Lisp that does have a good one.

You obviously haven't implemented a Lisp either, because then you'd understand what homoiconicity actually gives you. And also how a REPL is implemented (since you wouldn't just get one for free, it's a tool to implement).

You're wrong on every count about my experience. And once again, please: I'm just saying that stages in Read-Eval-Print-Loop does have differences in homoiconic and non-homoiconic languages. THAT'S ALL I SAID. There's zero controversial taste in that statement. None. I'm not bashing on Ruby, or Python, or any language you favor. I'm not telling you to use this or that. I'm just pointing out at specific differences that exist.

So if you implement a non-homoiconic language in SBCL or Racket does the REPL blow up? Is Rhombus language a psy-op?

Implementing C-like language in Lisp runtime - your interpreter reads C-like source, parses it to your own AST structs, and evaluates those. The host being homoiconic says nothing about the guest. You would have to write a guest REPL anyway (if you want one).

Rhombus built on Racket, yes, means it reuses Racket's machinery: the macro expander, the module system, the compiler, the runtime. But it doesn't mean it inherits Racket's parenthesized syntax.

Racket's expander does not operate on text. It operates on syntax objects (shrubbery). It has its own REPL, because the Read stage has to parse shrubbery syntax, not s-expressions. So, my original point stands - REPLs do have differences for homo and and non-homoiconic PLs.

Please be less of an asshole.

You’re an asshole too for talking like that.

I am not an asshole for pointing it out though, I’m likable.

iLemming: creating a new user just to say that seems a bit over the top.

I don't know who that is. I don't play stupid social games to win stupid social prizes. Why would I create a new account and yet keep replying with another one? I have single accounts pretty much everywhere, except Reddit - they shadowbanned my first one when I posted while connected to a VPN (apparently that's not allowed). You can easily use some OSINT tools to confirm that.

Again though: please don't be an asshole. You're doing a disservice to Lisp.

Da fuk you're talking about? Where the heck am I being an asshole? I have not used a foul language or insult in this thread once, even when someone accused me of being in a cult. Don't patronize me, even if you bought a moral authority on a discount - I'm not your fucking child. No matter how many times you say "please" and call me "asshole" I won't correct anything in my behavior because there's nothing to correct to begin with. What "disservice"? a) I could't care less about Lisp's popularity b) You seriously think someone, anyone would be like "don't look at Lisp... because there's one jerk in this specific HN thread. He said something in 2026. Eight levels nested down..."

High testo, huh.

Oh wow, how quickly you changed from being "a good citizen containing an asshole" to being an asshole on your own. Good job, keep checking your mailbox, your medal should arrive shortly.

I would, but apparently I'm in a cult. Truth be told - I'm in multiple ones. Still trying to decide which one is my favorite.

Tell me your knowledge of Ruby is surface level without telling me...

I used Clojure when it first came out, I've used Common Lisp for years, I've also used languages like Smalltalk and many others.

Yes, Lisp environments are nice, but sometimes I think Lispers are so insular they don't realize that other languages have similar things. R, Julia and Ruby have similar environments. Smalltalk is next level.

And homoiconicity is great for macros and parsing but it's late-binding that enables the live programming behaviour, which isn't exclusive to Lisp.

Also if you'd ever gotten deep into say, SB-ALIEN, you'd know the limitations too; Common Lisp isn't magic, it can't just redefine say, instantiated structs in memory. It relies on pointers then switching references on the fly.

[flagged]

> they don't realize that other languages have similar things

Yes they do. God, how did you (and apparently you're not alone) read my rant and still got it 100% backwards? I specifically hinted about not picking a single aspect of a language - REPL or whatever. What is so confusing about my wording on "holistic, overall experience working with it"?

Apart from your rant, this is the most pertinent part of what you said:

> There is real, palpable, practical, functional difference between working a Lisp REPL and a REPL in a non-homoiconic languages

And it's false. There's nothing special about a REPL in a homoiconic language. Homoiconicity has nothing to do with a REPL or tools.

I do however think SBCL has a very nice environment with great tools (especially it's compiler) and that's why I've used it a lot over the years, but I really think you underestimate the environments in other languages (including the "holistic, overall experience").

> And it's false. There's nothing special about a REPL

You are wrong. You might be correct about the workflow but still wrong about the semantics. Pedantically, your notion is false, because homoiconism gives the REPL a genuine capability (program-as-manipulable-data across the read/eval boundary) that non-homoiconic REPLs lack.

Can you parse code into an in-memory representation and can you eval?

If yes, then you can do everything that Lisp repls can.

The parser being slightly more complex than parsing s-expressions doesn't materially change anything.

I did not say anything about s-expressions. I said "homoiconicity". S-expressions are not an absolute requirement for homoiconic features. You keep poking me with your "knowledge" as if I'm trying to sell you snake oil and you feel obligated to defend and retaliate. I don't need to prove anything to you, I'm not your ignorant professor attempting to instil you with some defunct truths that exist solely in my head. Do your own research. Or don't, who cares.

> and the latter is neither unique nor particularly widely used (hot reloads have to tangle with state and patching, so resetting the world for ease of reasoning is considered a best practice for a reason).

For what it's worth, hot reload is very widely used in Dart/Flutter. When you are writing UI code using a reactive style framework where rendering the UI appears to be "generate a new UI from scratch on each frame", it's more straightforward to have an intuition about what does and doesn't get reloaded.

It's not perfect, of course. But it works really well for the kind of changes you make when iterating on a user experience.

Largely agreed.

I do think it is worth highlighting how many advanced parts of hot-reloading have already been covered in Common Lisp. Same with highlighting how the REPL is largely not used to directly type into, but is instead a very powerful interface for tools to interact with a running image.

But, again agreed that simply these existing are not that notable today.

Not all Lisp dialects have well-developed hot patching systems. The OOP system has to be carefully designed for it. What if a class definition is superseded by a reload, but there are existing instances? The Common Lisp dialect of Lisp has useful answers to questions like this, but not necessarily every Lisp you come across.

Even Bash supports hot-reloading. I've developed modules that are updated in place by sourcing:

   $ . /path/to/script.sh

Generally speaking, the pain of handling hot patching depends highly on the structure of your codebase and the reason for hot patching to begin with. For a structure-of-arrays architecture, or for fixing logic errors at run-time, it's really no big deal at all.

It is limited utility, but if you start out from the mindset it's something you'll use a lot, those limitations start disappearing rather quickly.

But with Clojure and immutable by default, hot reload is a real thing, it sounds like not just on JVM but even among lisps.

Clojure barely let you import packages without restarting the JVM recently in its life.

Can you expand on that? I am mildly experienced with Clojure, and much more so with the JVM and I see no reason for that to happen (besides perhaps some kind of module shenanigans or importing stuff that requires special flags?)

But it has this capability and had it for a while. What's your complain?

Ehh, no. In fact, other Lisps are actually slightly better at hot reloading because they're not hampered by the JVM's limits.

Check out stuff like CHANGE-CLASS or whole image loading.