I've used more Rust tools, and jobs are outside few niches non-existent.
Not recently though, right now it seems the market has just been completely obliterated and it is hard to find any kind of job, regardless of the tech stack.
I see that sbcl itself is alive and doing rather well, but other than that the landscape is fairly grim.
So you design from the core logic and write shim to external dependencies. Instead of bringing deps from the get go.
Yeah but i don’t want to. Let’s say i need to connect to rds using iam authentication.
I don’t want to write code for that, i want to use a library.
I don’t want a library that works with chicken scheme but not on sbcl and maybe on cmucl.
I know i can, i don’t want to. I want to reuse code written and maintained by other people.
All the people that had that need wrote code for that. And I guess they don’t want to do unpaid work by providing a full fledged library.
> I know i can, i don’t want to. I want to reuse code written and maintained by other people.
Then I guess Lisp is not for you.
Aaand back to square one. Go tell to most of the industry and you get the lisp curse.
Thank you for proving me correct.
Given this elitist mindset of the lisp community, no wonder there’s a thing called “lisp curse”.
But then once I read the second paragraph, I agree with you. Lisp is doing fine in terms of important ecosystem libraries. The article sets that as the context when it asserts as fact that "established libraries are incredibly stable, tested by hundreds of thousands of developers, included in thousands of CI pipelines and maintained by experts on the topic."
It's akin to how Linux isn't a OS but a family of OS with same core.
And you haven't even seen the Clojure<->C++ interop in Jank. Anyone who has even the slightest clue of what's up says this is some kind of blackmagicfuckery.
I mostly don't use Lisp for work; we have some Clojure services, but they rarely require any attention - mostly when we need to bump dependencies. But I use a Lisp for personal stuff and I switch between different dialects multiple times a day - Elisp, Babashka, nbb, Fennel, Jolt, Jank - and the overhead is virtually none. I can't say the same thing about switching between JS/TS, even though I have used them for far longer than any Lisp.
And I am left wondering if it is that great why didn't it take over. I think you are ignoring some minor things that make it unpalatable for the most programmers.
Gonna pushback on this. Adoption is proof of fitness to purpose in the Worse is Better way.
> Nix has steep learning curve
Not what I meant. I meant more in praise vs. how little you can see it in the wild.
> I am not ignoring them, I speak from my heart
I believe you speak from the heart, the same way I believe NixOS people speak from the heart. Or OpenBSD enthusiasts. The issue isn't the passion, but the way that passion biases you to overlook some corner.
I suspect in Lisp/Clojure case it's the lack of a large community and performance issues. Either the community is uninterested in making Lisp fast, too splintered or ignoring benchmarks.
We really do have a good idea because we can see how much every language is used on github and we can see bulk job listings on the internet.
Just because the majority is required to be on Python, doesn't mean it's the best stack for solving problems.
So which is it? Secretly popular or it doesn't matter that it's unpopular because it's so great anyway?
Gathering language stats for Lisp is also challenging, because it's not a single PL - it's a whole family of dialects.
If you take them all together, they still don't amount to much.
Modern Lisp landscape is very, very different from LISP you're talking about (invented in the 50s).
The old lisp landscape actually had some people using it.
It might be time to accept that most experienced programmer have heard of and used lisp or a variant at some point and it just didn't offer a real pragmatic advantage. It was very influential when the alternative was putting in assembly instructions using their hex codes, but modern languages have adopted all the best parts. The parts that are still unique like s-expressions, macros and 'code as data' haven't really paid off as much as people like to pretend. If you have every program writing their own crazy DSL, things get very squirly very fast, because every program becomes it's own niche language.
Mixing 'code and data' is the same thing. The key to simplicity is to use simple straightforward data structures and keep the data and execution as separate as possible because data is static and easy.
It has been 70 years and many ideas were hugely influential while some others ended up doing more harm than good. People thought inheritance was a great idea for 20-30 years too and we're still trying to fix that damage.
Not really, because if companies use it they will mention it when hiring. It isn't back up by any real information. You're basically saying that all data says the opposite, but it's used a ton because of the one example company. This is like when people say haskell is about to take over because someone at facebook used it for an email filter. Everyone gives the same exact example. Every popular language has about a million examples.
Then you are trying to argue that customers or growth of one company has to do with language adoption. Do you realize that this seems like a desperate backwards rationalization of what you wish was true?
watch some talks from Clojure conferences
I have, they are obsessed with the rabbit hole of language pagentry and never seem to end up solving real problems. It's all about more and more complex language mechanics and labels of complicated techniques.
Both. "There's more than the stats show" and "popularity doesn't measure fitness" don't contradict each other.
Saying it doesn't matter that it isn't popular contradicts it being popular.
Do you know where emacs lisp ranks? 49th, behind a half dozen languages I've never heard of and configuration languages.
Most didn't adopt connecting to a running process and redefining one function while it runs Those still change how the work feels day to day.
Agreed
Great ideas are timeless
Agreed, that's why lisp has been so influential. That doesn't mean it is objectively a good choice by today's standards.
the grand idea of Lisp as a practical notation for lambda-calculus is timeless
Maybe, but the truth is no one cares about that because it doesn't mean anything to productivity or better software.
You're basically fighting with me if math still matters. Dude, of course it fucking does.
This is a nonsense statement that doesn't relate to the conversation. You're giving something a label that no one is asking for then saying the label is super important. No one cares about this, people can already do what they want.
I never said Clojure or Lisp is "about to take over", besides you're trying to use one spam-filter system inside a PHP company example, against CircleCI, Metabase, Walmart, Grammarly, ITA/Google Flights, Cisco, Rate.com, Funding Circle, Netflix and bunch of other teams that use it in production.
> I have, they are obsessed with the rabbit hole of language pagentry
Just a random example from Netflix guys: https://www.youtube.com/watch?v=gJ9UZlr6C6M
There's tons of different real-life use case talks. From Boeing/Embraer, from Funding Circle, from CircleCI, from tons of smaller startups running things on prod. You're just insisting of something you haven't even bothered to give a critical look at.
> That doesn't mean it is objectively a good choice by today's standards.
Okay, tell me more about "today's standards". What do you mean? No language is "objectively a good choice". A choice is good or bad for a team, a problem and a set of constraints.
It is a great choice for specific use cases. Fintech startups notably finding that to be very true.
> it doesn't mean anything to productivity or better software.
Clojure's immutable data by default rules out a whole class of concurrency bugs, and I already gave you the real-world example: Nubank scaled to thousands of engineers on Clojure and Datomic. That is a large bet on the language at a large scale, but you're just choosing to ignore that. I get it, every niche language has its "company X uses it". But once again, I'm not advocating for a single PL specifically. I'm preaching the idea of a language. The idea you're just outright dismissing because "it would have converted everyone a long time ago."
I've been working in this field for decades. I have gone through over a dozen language stacks: different paradigms, tons of tooling, techniques, patterns, hype cycles and silver bullet calls. If I've learned anything, it's that the majority is not only not always right, but in most cases it is flat-out wrong.
You don't have to trust me on this (some rando on HN), just listen to renowned CS veterans with big names - Guy Steele Jr., Alan Kay, Sussman, John Carmack, Crockford, Yukihiro Matsumoto, Paul Graham, Uncle Bob, Steve Yegge, Dijkstra, Brendan Eich, Karpinski - there are tons of names who'd agree that Lisp is an everlasting idea.
Lisp endures. It is thriving; there are new Lisp dialects coming out every few years. Some of them are serious tools, not toys. You can realistically run Lisp on pretty much any platform today.
I'm not suggesting everyone should just drop whatever they use and switch. I'm just saying there are some ideas that are worth understanding and your view on where Lisps stands today is misguided.
> This is a nonsense statement that doesn't relate to the conversation.
I.e., "lambda-calculus doesn't help anyone ship software". Yeah, maybe you're right. Yet it is still in there, whether we want it or not - it explains why the software we ship behaves the way it does. So maybe it's worth understanding the language that explains it best.
I didn't say you did.
CircleCI, Metabase, Walmart, Grammarly, ITA/Google Flights, Cisco, Rate.com, Funding Circle, Netflix and bunch of other teams that use it in production.
So which is it? It's popular or it's not popular but popularity doesn't mean anything?
Also naming a bunch of big companies doesn't mean much. When there are 10,000 employees, a few people are going to do something with niche tools. That isn't what these companies were built on and it's just a cheap use of their name. Again, it's like haskell people saying, "no on uses it? ever heard of facebook??" and it turns out to be one small program over the last 25 years of thousands of programmers' work.
Okay, tell me more about "today's standards".
Maybe you should tell me, because your comment is basically an appeal to authority without real numbers to back it up. You aren't talking about crucial features much or why you even like it.
Clojure's immutable data by default rules out a whole class of concurrency bugs
In practice this ends up being a feature with silver bullet believers like haskell's lazy evaluation, but when people try to make it work in practice the performance hits and awkwardness just don't give any benefits because you're fighting how a computer works, and if you really need it it can be replicated and used in specific situations. You can already make things const in system language and you can make structures and architectures that rely on copying data for certain parts of parallelism.
I've been working in this field for decades.
So have all the people not using lisp.
just listen to renowned CS veterans with big names
Listen to them say what exactly? You just listed a bunch of names as if that somehow makes a concrete or technical point. Most of those people don't ever use lisp in the first place so I'm not sure what this is supposed to say. "Uncle bob" is a buffoon snake oil salemen that knows less than nothing.
Lisp endures. It is thriving
Then why is the most popular lisp emacs lisp, which is less popular than 'vim script', starlark, gherkin, solitidy etc.
https://innovationgraph.github.com/global-metrics/programmin...
there are new Lisp dialects coming out every few years
Not sure this has accomplished much.
your view on where Lisps stands today is misguided.
I don't think it is. Everything points to it being influential but not used. After 70 years it might be time to accept this reality.
I think you're confusing my pragmatism for an enthusiasm of a novice. I agree, sometimes you have to let it go, and I have. I started my coding journey with BASIC, in college I learned Pascal, C and Assembly, then Turbo Pascal, then later Delphi. You might be too young to remember how huge Borland was back then and I used their tech profusely. There was a period where I coded in Actionscript and VB, picked Macromedia, started making web-pages. I even worked in some esoteric language where all the operators were in Russian - I was working on a ERP system in Dubai with my Slavic friends. Then I picked some Perl and PHP. Following Heilsberg's work on Pascal, I went to .Net, when the guy moved from Borland to Microsoft. I switched from VB to VB.net, then to C#, I picked up some F# later. I developed games for Silverlight, remember that one? I was an early adopter of Typescript, forcing my team to switch from their beloved Coffeescript, that was at the time when GitHub in their style guide was explicitly asking to use Coffeescript for new projects instead of JS. I tried almost every available altJS option - Livescript, IcedCoffescript, Purescript, ELM, Reason, Fay, Haste and GHCJS. I was heavily invested into CLR only later to realize that it started feeling like a mental prison. I switched to Python on the backend. That's when I first time saw Clojure and blindly rejected it - it looked too weird. I then learned some Haskell, tried Idris, did Ruby, Golang, etc. etc.
Anyway, the point I'm trying to make - there are numerous tech pieces that I have completely parted with, with absolutely zero regret. Some pieces still remain practical - they simply work. I don't miss Pascal, Perl, Ruby or PHP. Yet I don't see any reason to bury Lisp. It just works. It remains an enormously practical tool with zero meaningful alternatives.
I can tell you with conviction that using babashka for bash-scripting, or nbb for node stuff like simple web-scrapers is far, far better experience than the alternatives. Reducing huge Lua boilerplate to a five-liner Fennel macro feels liberating. And nothing, just nothing even remotely comes close to what I do and can do with Emacs.
Trust me, another 50 years will pass, yet Lisp will remain. I can clearly see that; the idea of Lisp is simply way too practical to die. Would it ever become popular in a big team setting? Nobody can predict that. Perhaps it never will. Maybe there will be new Rusts, Kotlins and ML-like things, with Lisp carrying on in the shadows.
It's great that you have conviction but no matter how forcefully you say something this seems like your own personal journey to becoming obsessed with lisp.
That's fine, but it doesn't mean it is being used. Listing people and companies and languages with no context isn't real data.
Trust me, another 50 years will pass, yet Lisp will remain. I can clearly see that;
It has been 70 years and plenty of ideas have remained even though the actual languages are niche. You seem very confident that you can predict the future. Does this future predicting ability apply outside of 70 year old computer languages?
the idea of Lisp is simply way too practical to die.
The idea didn't, it's in the languages people use.
Today, when mainstream languages have stolen much from Lisp, the benefit of using a language where you can generally just add a gem, egg, or crate is much higher than the benefit of the one thing that is still unique to Lisp: macros. Reflection is inelegant as hell when you compare, but it will get you almost all the way macros do.
At the same time, typed languages have become much more like dynamic languages. The types have disappeared into var and let statements; they are now inferred rather than repeated. Pattern matching has been added, and more—without compromising the benefits for larger teams and larger code bases.
Purists will disagree, but I haven't seen a real world problem solved in Lisp that I couldn't also solve in other languages.
And yes, I am interested in being proven wrong. I want to know what kind of problems still exist that are that hardcore. But I suspect a big part of it is that those who code in this still think the "hello world" for Java looks something like this:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
when in reality it now looks like this: void main() {
println("Hello World");
}
and in C# it looks like this: Console.WriteLine("Hello, World!");
And comes with full first class support for Linux and Mac.Lisp is an intellectual tower and has given an incredible amount to the programming community in terms of ideas and a playground for people to try things. I'm not denying any of that — it should be celebrated. But my thesis is this: most of that has been moved, copied, stolen, and adapted to mainstream programming languages.
Turing completeness makes "I couldn't also solve" an impossibly high bar.
But if what you mean is, you haven't seen macros used in ways that make you wish your day-job programming language had macros, that's fixable.
https://brl.sourceforge.net/brl_4.html#SEC31
Now, as a non-Lisper, I have to wait and hope the maintainers of programming languages I use will take useful syntax from other languages. Back when I was an active Lisper, I could take such syntax myself.
About back then, Perl/PHP/Python/Java/Ruby were never as good at pulling groups out of rows of SQL, but people could work around that by taking more time, writing more code, being more careful. So if you haven't seen macros used to make it better, you don't realize you're missing out on a huge deal. Maybe you just have a vague idea that things could be better, but you're too busy finding and fixing bugs to pursue this thought.
> if what you mean is, you haven't seen macros used in ways that make you wish your day-job programming language had macros, that's fixable.
is not true at all anymore? Or is it only true under very specific circumstances (if so, what are they)?
Also true if you want a shorthand syntax for defining a variable where the name of the variable is meaningful. JavaScript takes care of the most common case with destructuring assignment, but with macros you could make such syntax yourself.
Don't get me wrong I'm a macro fan. I've worked with some elegant codebases using metaprogramming but it's been challenging bringing people up to speed with super clear efficient - but novel - code,
Other projects that were just down the line Java boilerplate built on a well understood library worked just as well in other ways.
Personally I think reducing cognitive load is key, I've found people don't have the energy to work with clever code, even if it makes writing it a delight.
... and then llms happened, and I now don't write code at all but closely review a fire hose of mediocrity that gets the job done. I don't want that too magical.
it's the developer experience
(and the combination of all features, including homoiconic macros)
> a real world problem
You can solve anything with enough sweat ;)
One example? Routific's core algorithm is written in CL (source: its author on HN). Why not Java, like everybody on his field at this time? Because it was too tedious (there's a blog post somewhere). His prototype evolved in efficient production code, now the heart of the company.
> my thesis: most of that…
agreed on "most". Many features appear here and there in other languages. But there's the parts and the whole.
And the living platform ("stop writing dead programs"), still unique (with Smalltalk).
In fact the main reason I hang around Java and .NET as my main tools, is that those development environments have taken many key features from those programming languages and development experience, to the point that where they still lose to them isn't that much relevant.
Additionally, now with AI code generation, the actual programming language matters even less, natural language can be translated to whatever programming language one feels like, at the whim of a Markdown paragraph describing the desired output, assuming it is supported on the model being used.
However it is kind of sad that we lost the last AI wave from Lisp/Prolog to Python, losing good machine code generation in the process.
Can you think of some domains where Common Lisp is a better choice than other languages? I have enjoyed Clojure for a lot of things, but I have not really found the features of SBCL useful for the kind of work I do.
For instance, restarts without unwinding the stack are cool, but for a server that's going to be running in production, it's not something I really leverage. I could use conditions to change the context of code called downstream, but I just haven't had a reason to do this yet.
This is an old blog entry about their Lisp history, https://www.siscog.pt/en-us
https://www.siscog.pt/en-us/blog/35-years-of-lisping-at-sisc...
Then you have ITA Software bought by Google, and the reason they have Lisp style guide,
https://google.github.io/styleguide/lispguide.html
Autocad has used Lisp as main scripting language for quite some time, although they also do .NET as well nowadays,
https://help.autodesk.com/view/OARX/2026/DEU/?guid=GUID-037B...
Note that everyone talks about SBCL, but forget that the ones that survive the Lisp machines like experience are LispWorks and Allegro Common Lisp,
Which if you want to have a taste how it looked like back in the day, some folks are trying to keep Interlisp-D memory from Xerox PARC alive.
(coalton-toplevel
;; Type classes are defined with the define-class keyword
(define-class (Eq :a)
(== (:a * :a -> Boolean)))
(define-type Color
Red
Green
Blue)
;; Type class instances are defined with the define-instance keyword
(define-instance (Eq Color)
(define (== a b)
(match (Tuple a b)
((Tuple (Red) (Red)) True)
((Tuple (Blue) (Blue)) True)
((Tuple (Green) (Green)) True)
(_ False))))
;; Type declarations can have constraints
(declare is-eql (Eq :a => (:a * :a -> String)))
(define (is-eql a b)
(if (== a b)
"They are equal"
"They are not equal"))
;; Multiple constraints must be wrapped in parentheses
(declare double-is-eql ((Eq :a) (Eq :b) => (:a * :a * :b * :b -> String)))
(define (double-is-eql a b c d)
(if (and (== a b) (== c d))
"Both pairs are equal"
"The pairs are not both equal")))The `(define-class (Eq :a) ...)` block is defining a type class called `Eq` with a type parameter named `:a`. Think of this as an interface that can be added after the fact. Most (all?) major OOP languages only allow you to declare interfaces when you declare a class, but in Haskell, and in Coalton that takes a lot of inspiration from Haskell, you can declare "interfaces" (typeclasses) on any pre-existing type, including ones coming from a library. Here, the `Eq :a` interface means that there must be a function called == (in Lisp even the operators are defined as functions) that takes two parameters of type :a and returns a Boolean.
`(define-type Color ...)` is defining a simple enum type. (You can do a lot more with it, of course, but this example is kept simple). Then `(define-instance (Eq Color) ...)` is saying "The type called Color is an instance of the typeclass (interface) called Eq". And since Eq requires a function called `==`, inside the define-instance block you have to define that function for the Color type. The pattern-matching should be simple enough that I don't think I need to explain it.
Now, the thing that makes this more powerful than interfaces is something I already touched on. Here the Color type is declared and then its typeclass instances are defined right away, which is the normal thing to do when you're creating a new type: keep all its code together. But if that Color type had come from another library that you imported, you would still be able to say "oh, and this Color type does implement Eq: here's the definition of == as applied to Color values". You're not restricted to only the interfaces that the library author thought to apply: you can take someone else's code and add interfaces to it! There have been several times when I really wished that were possible in C#.
Finally, the constraints before the => fat arrow are like declaring your function parameters as `public T isEqual<T>(T a, T b) where T : IEquatable`. This allows Coalton to catch, at compile time, any call to `is-eql` with parameters for which the `==` function is not defined.
There's plenty more at https://coalton-lang.github.io/manual/topics/whirlwind-tour/.
I mean it must employ gradual typing, right? So that it can interface with existing code that is untyped
But there are definite advantages to having Coalton know your types, which is why they give you a `(declare foo Integer)` form. This doesn't compile to any code, it's a compiler hint that tells Coalton that it can assume `foo` is an int, not a float64/double, which allows it to pick at compile time which implementation of + gets used in `(+ foo 5)`.
The 2025 video introducing Coalton at https://www.youtube.com/watch?v=of92m4XNgrM gives an example of what Coalton can do with knowing types. Robert Smith (the presenter, and the primary creator of Coalton) gives an example of a Fast Fourier Transform function that uses generic numeric types so you can call it on any number type: float32, float64, int-modulo-a-prime, whatever. He then benchmarks it, and it takes about 1 second to run 2 million times. Then he adds the single compiler hint `(monomorphize)` above the function declaration. This tells Coalton "Hey, instead of doing a dispatch table lookup in this function and calling different + implementations based on the type of the parameters, I want you to create two different copies of this function, one that will call the specialized float32 math functions, and the other one that will call the specialized float64 math functions." (Or three copies if you also called it with your int-modulo-prime number type). This eliminates a dispatch-table lookup and allows the compiler to produce much more specialized code. It comes at the expense of larger binaries, of course: he's explicit about how this is trading speed for size, so it's an opt-in choice you make (by adding a `(monomorphize)` declaration above the function definition) rather than something that Coalton defaults to.
But I've digressed. Yes, I believe (though note my caveat about not having used Coalton yet) that it would use dynamic types for code whose types it can't infer. But I'm pretty sure it would also give you a warning. If it gives you an error, the solution is to add a `(declare [name] [type])` line in the appropriate place.
Code that is untyped—Common Lisp code—is run in (lisp ...) forms [0] which requires the user to annotate the type and adds dynamic type checks to it to ensure it meets the contract the programmer specified.
Also, the whole cult-like attitude from a number of people in the Lisp community was a big turn-off. All that “if you don’t get Lisp, you’re not smart enough, haven’t got enough experience, or just haven’t tried hard enough” BS gets pretty tiresome. Lisp is really simple. There isn’t much to “get”. Haskell/LEAN was much harder for me to “get” than Lisp. And LEAN absolutely blew my mind. Lisp didn’t.
Other than that, the Common Lisp ecosystem is doing well thank you very much. Many contributors to SBCL, regular contributions to the important ecosystem libraries, vivid projects (Lem), new editors (mine) and plugins (OLIVE), some companies picking Lisp and somehow supporting the ecosystem (hosting conferences, contracting implementors). https://github.com/CodyReichert/awesome-cl/ · https://github.com/azzamsa/awesome-lisp-companies/ And yes, new vibe-coded projects too. Some are useful (ICL, cl-tuition…), some reinventing the wheel (badly) went nowhere. For some, we'll see.