The real "[Common] Lisp curse" is that once you taste it, there's no going back.
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.
rmunn 16 hours ago [-]
Since you mentioned the mine editor you must be aware of Coalton, but since you didn't mention Coalton I'll mention it here. Coalton is a Lisp library that basically adds static typing, type inference, and Haskell-style typeclasses on top of Common Lisp. (If you've never encountered type classes, then think of interfaces in the OOP language you know best. Type classes are what interfaces should have been: they can do everything interfaces can, and many things interfaces can't). Here's an example from the Coalton docs, which should be pretty self-explanatory; go read https://coalton-lang.github.io/manual/topics/whirlwind-tour/ if you want to see more.
(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")))
rmunn 13 hours ago [-]
For anyone who might not have encountered typeclasses before, the example might not be quite as self-explanatory as I thought it would be, so I'll explain that example a little.
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.
Thanks for the detailed explanation. I'm very familiar with Haskell, so this all feels very natural. How good is the type inference in practice? Is it a good as Haskell? And are there any places where you'd rather use vanilla common lisp?
reikonomusha 10 hours ago [-]
Inference uses roughly the same algorithm and type system as Haskell (depending on what flavor of it... GHC has tons of extensions). It supports everything in the standard Haskell type system, as well as a few common extensions of Haskell, including multiparameter type classes, functional dependencies, etc.
nextaccountic 13 hours ago [-]
About static typing and type inference: what does it do with code that it can't infer? It turns into a dynamic type ala Typescript, or it gives a type error?
I mean it must employ gradual typing, right? So that it can interface with existing code that is untyped
reikonomusha 12 hours ago [-]
Coalton infers and checks all types for pure Coalton code; there's no such thing as a dynamic or untyped expression.
Code that is outside of the purview of Coalton—raw Common Lisp code—is run in explicit (LISP ...) forms [0] which require the user to annotate the type and they add dynamic type checks to ensure the enclosed code meets the contract the programmer specified (unless UNSAFE is used [1]).
If I've understood https://coalton-lang.github.io/manual/topics/whirlwind-tour/... correctly (and please do read it for yourself because I might be misunderstanding it: I haven't used Coalton yet, only read the manual), Coalton will guess a type in some cases (such as numbers, but not only numbers). I don't know whether it gives warnings or errors for types it can't infer, but since it's based on Common Lisp I would assume it would give a warning and continue with an unknown type.
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.
brlewis 20 hours ago [-]
Reading the first paragraph of the article, I agree with them that Lispers don't collect as many dependencies.
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."
znpy 22 hours ago [-]
I don’t really see that either.
I see that sbcl itself is alive and doing rather well, but other than that the landscape is fairly grim.
Unironically the most successful modern day lisp is clojure, that mostly piggybacks the jvm and can reuse most java libraries and frameworks.
skydhash 20 hours ago [-]
The thing about lisp, it’s that it’s fairly expressive. You only need a few foundational libraries (mostly algorithms) and it’s very easy to build on the rest. In something like Python, or Go, once you define a conceptual model in a library, you need another library for the glue code to bind it to another ecosystem. In Lisp, almost everything is using the basic list, alist, and plist,…
So you design from the core logic and write shim to external dependencies. Instead of bringing deps from the get go.
znpy 7 hours ago [-]
> You only need a few foundational libraries (mostly algorithms) and it’s very easy to build on the rest.
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.
skydhash 4 hours ago [-]
> I don’t want to write code for that, i want to use a library
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.
znpy 3 hours ago [-]
> 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”.
tomjen3 20 hours ago [-]
Lisp missed its timing. When it was above and beyond everything else and a totally different world, it was way too expensive and way too inefficient.
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.
brlewis 20 hours ago [-]
>Purists will disagree, but I haven't seen a real world problem solved in Lisp that I couldn't also solve in other 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.
Xirdus 19 hours ago [-]
Not GP and not Lisp programmer. But I'm curious about what you said. If you had to name one popular app or web service (>10,000 monthly unique users) that'd be much easier to clone in Lisp than in Python or Rust, specifically due to macros - what would that be?
brlewis 18 hours ago [-]
I'm not active with any Lisp these days myself, either. Back in Web 1.0 days, when a lot of apps were transforming streaming rows of SQL results into grouped HTML entities, I used macros to implement something akin to SQL's LEAD and LAG, but at the application level. I don't have time, so I have to leave it as an exercise to the reader why it would take more verbosity to implement this in another language.
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.
Xirdus 18 hours ago [-]
Is there any such syntax remaining? Sure, 20 years ago it was a pain to do manipulations of more than 1 element at a time. But nowadays everyone and their dog has some form of iterator combinators that make it a one liner. Even C++, although the line gets quite wide. Is there anything that, as of 2026, you seriously miss having in your day job language (and that language isn't Java)?
brlewis 15 hours ago [-]
I'm having fun in TypeScript and only casually missing the capabilities of macros. It's Turing-complete, so doing the equivalent things is a simple matter of programming. And I'm almost always processing JSON structures, not SQL result rows, so I don't miss being able to write syntax like `sql-repeat` on a day-to-day basis.
Xirdus 13 hours ago [-]
Languages are no more Turing-complete than they were 50 years ago. If lack of Lisp macros was such a huge deal back then it affected day to day web development, then surely it must be affecting us all in this day and age too. Arguably, using JSON instead of SQL should make such macros even more important due to the unnesting of data we need to do. So why isn't it?
brlewis 59 minutes ago [-]
About today, JavaScript is good at referencing JSON. You don't need macros to make it better at it.
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.
outworlder 15 hours ago [-]
Macros don't make it easier to 'clone' software. They make it easier to write software, any software.
15 hours ago [-]
vindarel 16 hours ago [-]
> the one thing unique
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 (edit: and we're not talking only about syntax) (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).
pjmlp 7 hours ago [-]
As big Smalltalk / Lisp / ML languages fanboy, I mostly agree with you.
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.
And I have seen many real problems solved with Lisp, regardless, that is why commercial Lisps like LispWorks and Allegro are still in business.
Capricorn2481 4 hours ago [-]
> And I have seen many real problems solved with Lisp, regardless, that is why commercial Lisps like LispWorks and Allegro are still in business
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.
pjmlp 4 hours ago [-]
Siscog, a Portuguese company well known in the community.
> I haven't seen a real world problem solved in Lisp
Bruh... Nubank is literally the biggest effing digital bank in the world. Famously built on Clojure stack. Just because you have not seen shit it doesn't mean it's not happening.
Apple, Netflix, Amazon, Walmart, NASA - they all use Lisp, and that's just the States. There are tons of European startups building on it.
> Lisp missed its timing.
It is literally timeless. Emacs just turned 50. Name a single half-a-century old software product that's being actively used, developed and improved. r/emacs subreddit gets daily, daily! updates of new Emacs package announcements.
> most of that has been moved, copied, stolen, and adapted to mainstream programming languages.
Totally. Except homoiconicity. The point of which the majority of programmers miss, misunderstand, or ignore. The bigger point programmers miss is that Lisp effectively proves that largely the syntax of programming languages doesn't really matter. What matters is the runtime. And Lisp today runs practically on every possible runtime. Meaning that to be a polyglot, you don't really need to know dozens of PLs, you can just understand homoiconicity and voila - you can practically ship software for any runtime. Syntax is the cheap part, and Lisp shows it well: Clojure on the JVM and CLR, Clojurescript on JS, Fennel on Lua, Hy on Python, LFE on BEAM, Jank on LLVM, etc. The surface stays the same, and the host changes underneath. Then you learn runtimes and type systems, which is the real work of being a polyglot. That is a big win. Most programmers spend years on syntax and then mistake it for knowing a language. Learn the damn Lisp. It is enormously practical.
> still think the "hello world ...
Who the fuck cares about intricacies? In pretty much [almost] every Lisp dialect it would be just:
(print "Hello, World!")
For EVERY different runtime.
tiberious726 8 hours ago [-]
Or just "Hello World" running under the repl
CyberDildonics 20 hours ago [-]
Lots of people have used lisp, scheme or scripting languages and never go back. Lisp was created in the 50s, if it converted everyone it would have done it a long time ago.
iLemming 20 hours ago [-]
You probably have no idea how much Lisp is out there in real, production systems. Just because the majority is required to be on Python, doesn't mean it's the best stack for solving problems. Gathering language stats for Lisp is also challenging, because it's not a single PL - it's a whole family of dialects. And these dialects and communities are absolutely thriving. Modern Lisp landscape is very, very different from LISP you're talking about (invented in the 50s).
B4uler5 17 hours ago [-]
I just wanna throw myself in here and get some advice. I’ve started using lisp recently mostly for emacs configuration but also doing a bit of recreation game programming in Fennel. If I wanted to learn a lisp for general programming/application stuff like writing a shell, a compiler, something more user facing, what would be good to check out?
iLemming 16 hours ago [-]
It doesn't matter. Just start with a Lisp, any Lisp. Grok the idea of being REPL-driven, pick some structural editing idioms. That's all you need. Then, you pick a runtime for your needs. Depending on the runtime semantics you can choose a Lisp dialect for that runtime. Pick up some Clojure, it's enormously practical for any kind of data manipulation and analysis - small or big data. I don't even use jq anymore - studying http response in Clojure REPL is so much more convenient - you sort, filter and group data anyway you like.
bigfishrunning 16 hours ago [-]
I prefer the schemes.... Chicken scheme for standalone programs, s7 for embedding into larger systems. They're simple and easy to mold to whatever shape you want in my experience
Ygg2 16 hours ago [-]
That's kinda the problem of Lisp curse. You have several hundred slightly incompatible dialects instead of a one good language.
It's akin to how Linux isn't a OS but a family of OS with same core.
iLemming 14 hours ago [-]
In practice, it is exactly the opposite of a "curse". From many practical points of view, when you actually use it, it feels and behaves like "one good language". You probably have little idea how jaw-dropping it feels when you write the same piece of logic in Clojurescript, and it seamlessly runs on both JVM and Javascript - completely incompatible platforms. I have not seen this kind of code-reuse even with Node, where the runtime is basically the same on both sides, but you still have to write code for them separately.
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.
Ygg2 3 hours ago [-]
Your entire rave sounds like exactly like a NixOS heavy user ranting about the greatness of flakes and immutability.
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.
CyberDildonics 1 hours ago [-]
You probably have no idea how much Lisp is out there in real, production systems.
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.
assimpleaspossi 16 hours ago [-]
Not to mention this very web site.
jan_m_savage 13 hours ago [-]
I don't think these 'most people' you anecdotally cite have gone deep enough into Lisp to realize what it's all about, and why it turns users who do taste real Lisp into Lisp fanatics.
anthk 22 hours ago [-]
You forgot QuickLisp+Ultralisp, which is like PIP and PIP with daily builds or whatever it's called in Python.
Ygg2 22 hours ago [-]
I keep hearing this, but not really seeing it.
I've used more Rust tools, and jobs are outside few niches non-existent.
cestith 20 hours ago [-]
This "curse" is not unique to Lisp. There's an old saying something of the sort that for the first week after you install a Forth you have the same Forth as everybody else. After that, you have your own Forth dialect.
Any language that's powerful for creating new syntax and doesn't have an equally powerful community repository gets this same effect to some extent.
jedberg 20 hours ago [-]
This is absolutely correct. I recently found myself asking my agent to modify a local copy of an open source project to fix bugs that I found. It fixed the bugs, and it rebases against the public repo on occasion.
Why haven't I submitted my patches? Because my agent wrote them and I didn't review them. I would feel bad submitting my patches without looking at them, and I don't have time to look at them.
everforward 18 hours ago [-]
I've actually been doing this in Clojure and that avoids the major pitfall I've seen: the interfaces it makes are clunky. Re-using an existing library starts with a sane interface.
I've seen the same thing in Go, for what it's worth.
The code totally works, I'm not a denier there, but the interfaces are heinous if you don't keep an eye out. Mine wrote a Go function that passed a name variable as a string, but also embedded in 2 separate structs that were arguments. I've also seen it do re-validation of data multiple times in internal functions so everything has to return an error.
It's also stuff that sort of doesn't matter if an LLM is the only user. It probably costs some extra quantity of tokens, but not enough to be worth hand-grooming the code.
BeetleB 20 hours ago [-]
Same here.
KMyMoney stopped importing (some) OFX files for me. I asked an LLM to debug.
It was a wild journey. An obscure bug in some QT library that was triggered because of something completely unrelated that I had installed briefly in 2019 (and uninstalled years ago).
I had it fix the issue by cleaning the leftovers from 2019, but it's still a QT bug. I had it do a writeup, but I'll never submit it. It's fairly sophisticated and I don't know QT code at all.
fc417fc802 16 hours ago [-]
If it can put together a minimal reproduction of the bug I hope you might submit that. Tossing a commit full of slop over the fence is a dick move, sure, but tossing a small script over the fence that has approximately no dependencies and reliably reproduces the bug is pretty much guaranteed to be helpful. Leave it to the experts to figure out how to actually solve the problem.
BeetleB 12 hours ago [-]
I never fixed the bug. I just removed the thing that triggered it.
I believe I do have some sort of a reproducer, but I likely wouldn't understand even the reproducer script. I think it won't be taken well if someone files a bug, says "Here's a script that reproduces it", but himself doesn't understand what the script is doing.
fc417fc802 12 hours ago [-]
That logic is true of "contributions" - here's some undocumented code, it seems to fix my own poorly specified problem, I have no idea how it works, please merge.
For bug reports (at least IMO) a minimal example to reliably reproduce the error without any fuss is the basic building block. The reporter doesn't need to understand why it works let alone offer an explanation. In fact for complex projects more often than not any purported explanation will be subtly incorrect and actively misleading. If anything further "documentation" of bugs is unwelcome. Unambiguously demonstrate the defect and GTFO.
BeetleB 12 hours ago [-]
I think my point is that the response could be "This script is nonsense and should fail."
I'd still be wasting someone's time.
I'll probably put a write-up on my blog one day, though.
fc417fc802 11 hours ago [-]
Well sure, if you use a library in a borderline incomprehensible and clearly unintended manner and encounter an edge case then perhaps it isn't useful to report it. But while obscure, the usage you described (ie encountering stale config or cache data from a decommissioned install) can hardly be said to be unintended.
If an end user encounters an error while staying within the bounds of "expected usage" then the bug is guaranteed to be valid. You just don't necessarily know whose bug it actually is (for example a broken library versus broken usage of the library by the consuming program).
CyberDildonics 20 hours ago [-]
Why not ask someone involved if they want it or tell someone the prompt that made it? Someone who does the work of checking it and sanitizing it can take the credit.
cmrdporcupine 19 hours ago [-]
Depends on the project but some actually adopt an outright hostile response to this. Sometimes justifiably. Sometimes not.
It's honestly not worth it. I understand both sides here, but people are going to have to come up with new ways of collaborating. Pull requests are likely not it anymore.
gavinray 23 hours ago [-]
I wrote this same concern in February: what happens when it's easier to build custom software than spend one search looking for mature libraries?
One positive result is that you get a lot more variation in vulnerabilities. That probably sounds negative, but it isn't.
As an example, a black hat doesn't get 70% of web sites from one shared bug in PHP. They need to target specific sites, and the exploit isn't likely to work in very many other places.
andai 23 hours ago [-]
I don't get it, in this scenario, would people also vibe code (the equivalent of) the PHP interpreter?
AirMax98 22 hours ago [-]
I think a better comparison for the parent is probably left-pad.
dcss_gardener 22 hours ago [-]
I've been playing around with LLM red teaming different server stacks with known or intentionally vulns in there and seeing how much damage they can do.
The one situation where they really can't get anywhere profitable is a unikernel webapp. With no source and no shell they find the vuln but the worst they can do with it is possibly poison or exfiltrate data as a one off, or crash the server. Often they can't even figure that out. Can't even leave themselves a reliable way back in.
Of course the traditional problem with unikernels is that you have to port EVERYTHING you need yourself. But the cheapness of this is exactly what we're talking about so.
Looks like security through obscurity's back on the menu.
cestith 2 hours ago [-]
Obscurity as a tool in security has never left. It shouldn't be a tool you depend on by itself. Update your ssh server when there are patches available. Use strong keys or ssh certificates. Disallow old, broken key exchange methods. Having an allow list in your firewall ACLs helps. Maybe only allow ssh from your internal network and make users outside your network be on the VPN. Maybe even have dedicated bounce boxes between user networks and the production systems.
But putting ssh for those bounce boxes on a nonstandard port that doesn't even show up to a remote system within the network until they've port-knocked on another two or four ports in the proper order on top of all that does not hurt security. Using a separate internal DNS zone that nobody outside your network has access to resolve doesn't hurt. Having your firewall drop packets from invalid sources instead of rejecting them doesn't hurt.
sieve 21 hours ago [-]
These last few months, I have been building a capability-based language and runtime for fun based on the "port EVERYTHING" idea.
The language is restricted to permissions granted on startup and can only access the system via the runtime, which only supports a particular subset of linux syscalls. So, outside of the stdlib, whichever feature you need, you simply use an LLM to port an existing python/rust/JS/TS/Java library to the language and use it.
As the runtime has its own scheduler and GC, I have actually been wondering about the feasibility of skipping the linux kernel and making the runtime itself the "os." Given that so much modern hosting is actually done on virtual hardware, the drivers could be hosted within the runtime as well.
kragen 20 hours ago [-]
That's exciting! I'm interested to hear about the language design. I vibecoded a unikernel web server a few weeks ago, and I've been trying to extend it into a full capability-secure microkernel called KokalOS.
sieve 20 hours ago [-]
The language borrows syntax from Python (and a wee bit from Haskell) and is essentially syntactic sugar over facilities provided by the runtime:
- statically typed from end to end
- closed and open/extensible types
- closed types are immutable, open ones have two variants: immutable and mutable
- arrays have two variants: immutable and mutable
- no OOP/classes. inheritance is nominal and mainly exists to provide access to class membership (is X a Y?)
- functions operating on data
- UFCS exists to provide nice features like "apple".substr(...)
- first class functions and closures
- monomorphized generics
- tailcalls
- operator overloading
- modules and namespaces to control access
- erlang/beam style first class processes. So you `spawn` a function and communicate between processes using send/recv instead of async/await
Processes are completely isolated at the runtime level. Each has its own stack, heap, mailbox and GC.
The bytecode carries all type information. The VM will compile using AOT-on-load.
My own runtime-becomes-a-os idea is still just an idea. I haven't really pursued it with seriousness. Will probably do that once the language and runtime stabilize.
kragen 19 hours ago [-]
It sounds like you already have a pretty complete OS; you just don't have it running on bare metal (or on a hypervisor) yet. I hope I get a chance to see the language someday!
I started in March and have gone through nearly 300 spec revisions for the runtime and language. Thanks to LLMs, I think I will have something useful to share in 2027.
My problem is that I have ten things in the pipeline at any given moment and I switch between them as time permits. So things get delayed a bit.
MonkeyClub 17 hours ago [-]
> KokalOS
A bare bones microkernel?
kragen 17 hours ago [-]
What do you mean?
MonkeyClub 5 hours ago [-]
I was trying to guess the meaning of the name.
xscott 20 hours ago [-]
Obscurity in the sense that the bad guy doesn't have your code doesn't hurt, but I think the real win could be that they need to specifically target your system to find your vulnerabilities. That could be a lot of compute and time to dedicate to a single target. So that kind of obscurity changes the economics of it for them.
tlavoie 19 hours ago [-]
What sorts of vulns are they finding in unikernels? Logic bugs, that sort of thing, or are there areas where they could get that tiny scope to do anything at all?
The advantage there shouldn't be obscurity, so much as very limited attack surface in the whole exposed stack.
kragen 20 hours ago [-]
That sounds like a very reasonable thing to do, yes. If you ask Opus 5.5 to write you a dynamically typed interpreted language that can query a local SQL database, implicitly parse HTML form submissions, and be embedded in HTML templates interpreted by an Apache module, you'll probably have a usable alternative to PHP in 37 minutes. And if you ask it to do it in Rust with no unsafe, it won't have any memory error vulnerabilities.
xscott 20 hours ago [-]
You could have a new web server and database too. Maybe a new one every other day created from a cronjob so you aren't a stationary target.
fc417fc802 16 hours ago [-]
I assume that was sarcastic but I think it would actually work fairly well? At least if the ends could justify paying for that many tokens.
xscott 15 hours ago [-]
No, I sincerely try to avoid sarcasm, and I try to remember to down vote it when I see it. It's tough to get tone across in a text forum though, so I understand the confusion.
Big picture, I think we should explore what's possible when software is disposable.
kragen 13 hours ago [-]
I didn't think it was sarcastic, but it's far enough outside the Overton window that I could see why someone would.
kragen 19 hours ago [-]
I was saying that you could just not have exploitable bugs, at least of the memory-safety variety that was on display in PHP2hell, not that you could mitigate the exploitability of the exploitable bugs you will inevitably have.
Which, probably, you will also have to do.
I suspect that a more effective mitigation to having exploitable bugs would be to have an LLM read all your HTTP requests and the actions the web server proposes to take in response and give a Jev-like approve/disapprove decision.
xscott 18 hours ago [-]
All good, but I suspect we're thinking about different aspects. If I understand correctly, you're pointing out that nobody is tied to legacy software any more - they can spend 37 minutes to re-implement from scratch in a safe(r) language.
My point is that everyone doing their own thing their own way means an attacker doesn't get the next thousand sites for free after finding a vulnerability in one site.
Having an LLM as sentry is a fun idea too.
kragen 18 hours ago [-]
Right, I agree.
xscott 23 hours ago [-]
Yeah I guess, if they liked PHP. Could make a new version of ColdFusion if that's your thing too.
Genetic monocultures like bananas are at risk from a single species of fungus.
Choad_202611041 20 hours ago [-]
[dead]
andai 23 hours ago [-]
A few years ago, after ChatGPT but before agentic, I was asking AI for help with some projects. It kept recommending really good, well designed APIs, and gave me code snippets for them.
One small issue: they didn't exist! It had just hallucinated them!
Which was a real shame, since they were much nicer than the actual stuff I ended up finding.
I just realized, thinking about this now, that these days (and perhaps even back then), I could just say "ok now take this code and build the missing library so it actually works!"
freedomben 21 hours ago [-]
Heh I remember that well. It got me super excited quite a few times until I tried to find the actual library :-D
CamperBob2 20 hours ago [-]
Exactly. In almost all of those cases, the hallucinated functions absolutely should have been present in the API, and any reasonable developer would have expected them to be.
That was, in retrospect, an important bellwether.
hansvm 23 hours ago [-]
Even before LLMs I found building custom software to be easier than using mature libraries for almost every task. I don't think this is a new problem.
jayd16 22 hours ago [-]
Maybe take a step back and consider that your tastes or circumstances are rare.
hansvm 22 hours ago [-]
Perhaps. I just never found it useful to spend a day learning the failure modes and edge cases of a general-purpose library I could hack into my use case with enough wrapper code handling the impedence mismatch when I could spend a day building exactly what we need, with the added benefit of owning the code when requirements inevitably change. Like, I'll use numpy at least half the time for numeric code; I'm not a masochist; but most libraries just don't pull their weight.
anonreplier 19 hours ago [-]
Did anyone else have to maintain this code?
hansvm 17 hours ago [-]
Of course.
anonreplier 7 hours ago [-]
at least we have claude now I guess
WillAdams 22 hours ago [-]
When worldwideweb.app was first being developed an the RFCs and so forth for web servers and protocols were being discussed, one of the sticking point was what to call a URL --- the initial suggestion was "Universal Resource Locator", but the argument was made that users and writers were not librarians and that the distributed nature would preclude a given web page having a universally agreed-upon location and name, so instead the present "Uniform Resource Locator" was adopted.
What if there was a code sharing site where it was unambiguous what a given snippet of code would be named and where it would be stored, so that a user could just browse it and find a list of implementations for a given problem?
This of course runs up against one what John Ousterhout notes is one of the most difficult problems in computer science --- naming things --- in his book:
I've tried to do it on a small-scale with my own work, storing bits of (la).tex code in a single file, but on reviewing it, I'll often find that I have written a given solution a second time and given the macro a slightly different name....
skydhash 20 hours ago [-]
The thing is, solutions related to computing techniques, are few and can be found in algorithm textbooks. Some are then put into standard libraries.
Almost everything else is domain specific where you have to understand the domain first before understanding the code. And modeling a domain is all about tradeoffs between accuracy, performance, specific vs generic,…
Instead of collecting such solutions, a better approach is to master basic data structures, and then improve your modeling capabilities. After that, it’s mostly learning domain as they come (dsp, physic modeling, operating system concepts, relational database, graph theory, 3D geometry, accounting,…)
WillAdams 16 hours ago [-]
I am currently (re)reading Niklaus Wirth's book on data structures, and trying to work through the new Knuth fascicle on Constraint Satisfaction --- the idea here was that one could have a repository which one could search through to see/compare existing solutions as an alternative to using an existing library.
nonethewiser 23 hours ago [-]
Less external dependencies. I noticed Claude was vendoring (copy-pasting) Lucide icon svgs into my codebase (with proper attribution) because I was only using a small handful of them. That's awesome.
packetlost 23 hours ago [-]
Except when it's a license violation or in something that ends up having a security vulnerability.
nonethewiser 23 hours ago [-]
>Except when it's a license violation or in something that ends up having a security vulnerability.
What's more secure isn't so simple. If you vendor something with a vulnerability then it wont be patched. But vendoring may also mean you took the 2% of the library you need and not the 98% which reduces the surface area for vulnerabilities. And it can cut the other way - you may update a package that was previously good and is now vulnerable (regressions, supply chain attacks).
There is a balance that must be struck, and I think LLM's strike a better balance than people do. Dependencies are a convenience with a cost and LLM's can trivially copy or re-implement things that we cant.
packetlost 23 hours ago [-]
> But vendoring may also mean you took the 2% of the library you need and not the 98% which reduces the surface area for vulnerabilities
If you aren't using a library function you're not vulnerable to exploits in that code: unused but imported code is inert (possible usable as a gadget if you're vulnerable elsewhere, but at that point you're screwed anyways) and most compilers/runtimes completely eliminate it.
> you may update a package that was previously good and is now vulnerable (regressions, supply chain attacks)
There are better mitigations to this than not using a library.
You still completely ignore the license violations.
kragen 20 hours ago [-]
You might be exposing it to attackers without intending to use it.
nonethewiser 20 hours ago [-]
>You still completely ignore the license violations.
The ones that you are imagining to happen? Its not a problem because you could simply observe proper licensing.
>If you aren't using a library function you're not vulnerable to exploits in that code
Not true, just because you arent calling a function doesnt mean it cant run. Read up on Log4Shell.
kragen 20 hours ago [-]
In my experience so far Claude has been meticulous about avoiding license violations.
gavinray 23 hours ago [-]
Great for static assets, potentially not-so-great for "load bearing" ;^) code
andai 23 hours ago [-]
Every time I try to get a npm based project running (or one of my forks of one), half the packages don't exist anymore or I need to spend hours fixing breaking changes.
It's usually more straightforward to just rebuild it from scratch — not to mention infinitely more satisfying — and that was true before AI!
gavinray 23 hours ago [-]
Language ecosystems tend to exist on a continuum. I love TypeScript but dread the dependency management because it's so often bit-rotted.
On the other hand, I routinely build Java/JVM projects with dependencies that haven't been updated in a decade that compile without issues.
Somewhere in the middle are most languages, I think.
nonethewiser 23 hours ago [-]
Yes it does depend on the dependency, and a static asset is on one end of the extreme.
It depends on the "load bearing" code. Obviously something like crypto is not something we should implement ourselves but core business logic would be "load bearing" in another way and is probably not something you want to farm out to a dependency.
larodi 21 hours ago [-]
The real looking for libs often turns to be going down with potential security risks. In such cases is much preferable to not reuse unsigned and unclaimed code.
lou1306 21 hours ago [-]
I find this concern rather misguided. Telling the LLM to integrate a "mature library" is often cheaper and faster than rebuilding (a fraction of) their features from scratch. If you really cannot be bothered with searching yourself, these days you can even tell the agent to scan pip/npm/whatever registry for you and give you options.
otabdeveloper4 22 hours ago [-]
We've all been there. What happens is that you end up hiring someone to fix the unmaintainable mess a few years later when the pile of shit collapses.
(LLMs accelerate this and "a few years" can easily turn into "a few months".)
spapas82 23 hours ago [-]
Actually this is not a curse but a blessing! Being able to implement any functionality without the need to resort to dependencies is a godsend.
Yes, some dependencies are great. But unfortunately the vast majority are problematic: Not properly supported, badly tested, with unhelpful maintainers, funny licenses, undocumented and, definitely, not being able to cover your requirements 100% so you have to change your requirements to meet the dependencies instead of the other way around.
jdormit 22 hours ago [-]
> I’d rather rely on proven libraries with well-defined abstractions than generate hundreds of lines of code which solve a local problem for me.
I 100% disagree with this. Supply chain attacks are already at an all-time high due to agentic hacking assistance, and that trend shows no sign of slowing. Every dependency you add is another potential attack vector, and just checking the dependency’s code doesn’t solve the issue - your dependencies also have dependencies!
The cost of rolling your own has gotten so low that it’s almost always a better security tradeoff to reimplement the thing yourself. Is that a good thing? I’m not sure.
basch 22 hours ago [-]
If coding is anything like image generation, everybody is getting the same output anyway, which means we are back to nearly standard libraries just that are being dynamically produced. I see your claim as a new version of security through obscurity. It is way easier to patch all variants of a product when you can identify their lineage as variants in the first place.
jdormit 17 hours ago [-]
That’s not quite what I meant. The concern isn’t that dependency code will contain bugs or vulnerabilities directly. The concern is that introducing a dependency introduces a whole new supply chain, of which any link could become compromised. No new dependency, no new supply chain.
scottLobster 19 hours ago [-]
And rolling your own introduces brand new security holes. You're arguing security through obscurity, which is a particularly dead concept in the age of AI.
Also, you clearly don't work with products that have any sort of serious corporate liability. Being able to blame a supplier/library is almost always preferable to assuming the liability yourself
Capricorn2481 4 hours ago [-]
> You're arguing security through obscurity, which is a particularly dead concept in the age of AI
Most of these huge AI discoveries of vulnerabilities have not been through probing an unknown server with a custom stack. They've been through probing a known/discoverable tech stack that is open source. Security through obscurity is never good, but if anything, the next couple years on known tech stacks is going to be worse.
> Being able to blame a supplier/library is almost always preferable to assuming the liability yourself
This only works if it's Log4j, or PHP, or some big vulnerability that hits mainstream news. Clients do not care if the tiny library only you picked had a vulnerability in it, and they shouldn't either.
jdormit 17 hours ago [-]
> you clearly don't work with products that have any sort of serious corporate liability.
I work for a company that provides compliance services to banks, we take our security responsibilities very seriously.
The risk associated with introducing a new dependency to the codebase has now exceeded the risk associated with implementing something ourselves in most cases (the exceptions being the obvious ones: crypto, auth, server frameworks, etc.).
> Being able to blame a supplier/library is almost always preferable to assuming the liability yourself
We like to optimize for actually keeping our customer’s data safe, rather than covering our butts :)
scottLobster 12 hours ago [-]
Well if you have the time and money to do a full security audit of these new libraries you're rolling, more power to you. And you excluded a lot of stuff I was thinking of, so that changes the argument. If these are non-critical dependencies then sure, do whatever you like.
> We like to optimize for actually keeping our customer’s data safe, rather than covering our butts :)
If you have the budget to back that up I'm jealous. Otherwise, pride cometh before a fall. I'm curious how you conducted that risk analysis. Just because a common COTS library has more documented vulnerabilities doesn't inherently mean your hand-rolled option has less, and the difference would naturally vary from library to library.
For my part I work in defense, and our customers prefer to hear that we're using industry standard libraries and have tons of questions if we're rolling our own stuff (first of which is "why are you wasting our time and money reinventing the wheel?"). It reduces liability for them as well, they can tell their higher-ups that they approved proven, industry-standard solutions as much as possible and they're only paying us for our unique expertise.
natsucks 22 hours ago [-]
What about the vulnerabilities you yourself introduce when using AI? or is the assumption that (1) there will be zero or (2) you won't ever open source so no one will know about them?
jdormit 17 hours ago [-]
Right, it’s not about vulnerabilities that exist in our code or even vulnerabilities that exist in dependency code.
It’s about the relative chance that someone’s CI infrastructure somewhere in the dependency change gets pwned in a way that allows malware to get into our dev environments or production servers. If we roll our own library for some functionality we need, that risk is 0. My point is the cost of doing so is much lower than it used to be, both in terms of implementation time and maintenance effort.
dig1 22 hours ago [-]
> The cost of rolling your own has gotten so low that it’s almost always a better security tradeoff to reimplement the thing yourself. Is that a good thing? I’m not sure.
Why stop there? We could eliminate all external dependencies and even build our own compiler and OS, since the cost of rolling own solution has apparently gotten so low, right? Sometimes I feel like I'm living in a completely different dimension from some of the commenters here.
docandrew 20 hours ago [-]
Yes this, but unironically
gleenn 23 hours ago [-]
Seems a bit hyperbolic to call it a curse. Things like these are on a spectrum for all languages and languages like C and many others are afflicted by ecosystems that are more or less community driven and leverage libraries to a greater or lesser extent. Doesn't really have to do with Lisps per se.
boothby 23 hours ago [-]
I’m reminded of Chuck Moore’s practice of always reimplementing everything. There’s benefits and drawbacks to this; calling it a curse is certainly a strong opinion.
ordu 22 hours ago [-]
It is... a meme? I think it is an explanatory construct that was invented by lispers who were facing the declining Lisp popularity back then in 90s. It was looking very promising, and then it just lost its steam and now almost no one uses it. One can imagine "Lisp is a bad language" as an alternative explanation, but most lispers do not (and didn't) agree and they prefer the Lisp curse, because it paints Lisp as a language that it too good for its success.
I'm not taking sides here, I love Lisp, though I don't use it anymore (except elisp in emacs, but it doesn't count). My point is that debating the name itself distracts from the actual issue.
jgeada 23 hours ago [-]
It really applies to all languages where the very process of developing extends the language. It is the modern day variant of the Babel curse: you end up with a perfect language for your problem understood by a single individual.
antonvs 21 hours ago [-]
There was a variation of this with Scheme: the standard language was small, so each implementation extended it in different directions, and there was plenty of disagreement about which directions were good or bad.
lq9AJ8yrfs 21 hours ago [-]
Decades ago a relative showed me his Amiga. Before putting in the disk (these were on 3.5 inch floppies iirc) with the game I wanted to play on it, he put in another disk.
I asked him with the first disk was, and I remember distinctly he said it was an operating system. I asked him what an operating system was, and he said it was like a program, it was a program technically, that makes it easier to run other programs, just it was a program that didn't do much on its own and you wouldn't use it without another program right afterward. I said it didn't seem easier if you had to load a different disk than the one you wanted to use, and you still had to load the one you wanted afterward. He looked at me disdainfully and patiently explained that all or almost all the software in the future would use operating systems and they whole process would get easier or even invisible but there would always be an operating system in there somewhere at some point in the very near future. I was skeptical, but I nodded along.
I imagined an operating system as a dressed up software library, which was more intuitive to me as a concept.
zweifuss 20 hours ago [-]
Your intuition was right. That is how AmigaOS was designed. Your relative was also right, after the first model (Amiga 1000), all Amigas had Kickstart (the core OS) preinstalled in ROM.
Looking back, AmigaOS was remarkably complete and modern for 1985: preemptive multitasking microkernel, shared libraries, multimedia support, everything was modular.
doug_durham 23 hours ago [-]
So every Lisp developer creates their own time libraries and HTML DOM libraries because it's so easy? No. This is a myth.
agumonkey 23 hours ago [-]
well i can't say for the whole community but i remember someone blogging around 2010 about dropping mainstream languages for his project because all the graph libraries he found were complicated to assess and inadequate.. so he went to write his own tiny lib on commonlisp and was done in a short time.
the lisp dialect growth is also famous, it's less the case these days because people know about it, but it existed
drob518 23 hours ago [-]
After programming in multiple Lisp dialects over 20+ years, it’s only sorta true. The biggest problem is that “Lisp” is ambiguous. Common Lisp? Scheme? Emacs Lisp? Clojure? They are all legitimate Lisps, but they all have slightly different syntax, semantics, and standard libraries. Even among some Lisps, there are differences (notably Scheme, though Racket has helped by becoming somewhat dominant in some areas). Common Lisp helped reduce differences at the cost of supporting almost everything it was seeking to unify, and yet still has platform gaps that implementations have to fill in. But within a given Lisp, there is a lot of reuse. Racket has a large set of libs. Clojure runs on the JVM and it’s common to mix and match Clojure and Java libs.
agumonkey 22 hours ago [-]
note that i'm mostly pro-lisp, and wasn't criticizing, just reporting what i saw when reading about it.
i'd add one thing to your point, is that lispers know how to port concepts from lang a to lang b very easily, support libs, macro layer if need be (see goroutines in clojure) so fragmentation is not as hard it was in mainstream languages (ps: even though today everybody goes into ast / transpiler to experiment)
travisgriggs 15 hours ago [-]
> If we ignore the 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...
That last fragment. I fear increasingly less so. There's already been a number of posts pointing out that modern programming is often held up be a few key individuals. And now (some of) those individuals (Linus, people like Chris McCord of LiveView, etc), are sharing how they're now "doing more of the stuff they've always wanted to do", and offloading tedious stuff to AI tools (by the way, expertise comes through tedious reps).
caned 15 hours ago [-]
Wow, expertise through tedium. That resonates.
dtj1123 7 hours ago [-]
Thought it worth mentioning that having transitioned from software dev to bioinformatics two years ago, I've discovered that
> If we ignore the 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
is not true for essentially any of the infrastructure that cutting edge biological research builds upon. It's all a buggy mess.
Expect dramatic acceleration in basic research as a result of LLMs.
K0balt 14 hours ago [-]
This is so true. In my firmware work, we have written a ton of custom libs and drivers that I would have adapted before. Also in the js work, with the notable exception of three.js… basically zero libraries. When we run into a problem, I just rewrite from scratch to fit our application. I have definitely noticed that this means we are siloing our work.
samus 16 hours ago [-]
That's not really the problem with Lisp, or at least not the way TA presents it. The issue exists, but with Lisp implementations: the community is split across Common Lisp implementations, Emacs Lisp, Racket, and tons of other Lisp and Scheme dialects, and none have the momentum to ever become mainstream. After all, according to Greenspun's law
> Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.
there is an infinite proliferation of Lisp implementations, and for many people it is the first language that they write an interpreter for since it is so easy.
Ecosystem split is the same reason why Cobol fell out of being mainstream: there are multiple proprietary implementations that are intentionally mutually incompatible, therefore an ecosystem could never develop. Oracle (in the past Sun) tries to avoid Java sharing this fate by using trademark law to crack down on JVM implementations that call themselves Java without having run the TCK.
rmunn 13 hours ago [-]
Common Lisp solves this by being common, and any Common Lisp implementation can use the same libraries.
Emacs Lisp I can't speak to, having no experience there.
As for Scheme, you're correct that implementation fragmentation is one of its problems holding back adoption. But it's not a problem for Common Lisp, which has had much less fragmentation issues.
fierycatnet 21 hours ago [-]
I'm not a SE but I dabble with code. Lisp was really something else and I really liked it when I was reading SICP. Then I tried Clojure and things just clicked and it was fun to write.
GMoromisato 23 hours ago [-]
I've been reinventing the wheel since I started programming. Back then, we had no choice--there weren't any open-source libraries. But I also enjoy reinventing the wheel because (a) the wheel can be exactly how I want it, and (b) I get to learn and understand new things.
Coding agents have actually cut both ways for me. I can reinvent the wheel more easily and with higher quality, but I can also integrate an external library much more easily than before.
The other day I needed my system to download SFTP, so I had the agent build an SFTP client. It turned out that I actually needed FTPS, so I had the agent build that too.
Another time I wanted to integrate with Git repos, but instead of trying to reinvent that, I asked the agent to integrate libgit2. Of course, I asked it to add an API that matched the semantics of my system, so from my perspective, the wheel was exactly how I wanted it.
I think what's going to happen is that there will be more vertically integrated platforms that do it all. If you think about it, it's really annoying to cobble together a system from different libraries, each of which might have different semantics.
What we want, as developers, is to have a single, well-designed, integrated platform that exposes all the functionality we need in a consistent way. That's a lot easier now that LLMs can mold code to your exact specifications.
I'm biased, of course, because that's exactly what I'm building with GridWhale.
andai 23 hours ago [-]
Same except I had open source libraries, I just somehow always had a worse time with them than just building it myself. (Just even getting them set up in the first place, or updated, and so on... most of them seem to be someone's "always have stuff to do at my job" insurance policy!)
But even if they were pleasant and did what I needed (this one time I installed a 5000 line lib that was missing 20 lines to do the thing it was actually designed to do.. like, they couldn't have added 20 more lines?!), an issue I have is spoilers.
Like, at university, they constantly said, ok here's a big problem in computer science..
(3 seconds later) .. aaand here's how we solved it! And I'm like agh, no! Spoilers! I want to figure it out, jeez!
That's also how I feel about "computer, just magick my entire program into existence." Spoils the fun of figuring it out!
Choad_202611041 20 hours ago [-]
[dead]
baq 23 hours ago [-]
the irony is the repl way of working is extremely well suited for agentic workflows. rust is nice, but lisp is hiding in plain sight
cchase88 21 hours ago [-]
I'm currently working on a project that uses Tcl as its primary programming language. One of the great features about the Tcl interpreter is that it lets you introspect things like variables and procedures at runtime. You also get the full source code of procedures at runtime, even those that were themselves defined at runtime. Instead of the normal work flow of having Claude make changes, starting up a web service, testing the web service with some Javascript driver code, I instead work through Claude in Chrome and expose a web-based interpreter from within the running web service itself. I can instruct Claude to make changes at runtime and immediately after making that change, the code can be tested by Claude. Those changes can then be dumped to disk and reincorporated back into the base source code I have. Not something you'd want to expose to the wider internet, but it's let me move _very_ quickly and build out apps within minutes. I've considered making use of Tcl's safe-interpreter mechanism so other Claude instances could possible collaborate within the same primary app without stepping on each other.
sroerick 21 hours ago [-]
Yep, it's incredible. What you lose in typing and borrow checking you absolutely gain back in absolute raw power
kragen 20 hours ago [-]
Which models have you found most take advantage of this kind of capability? Opus 5.5 and GPT-6 Sol and Astra seem to like to minimize their tool calls, blatting out a single edit with dozens of lines of code in it rather than editing a few at a time. And they virtually never use things like the Python REPL, even though they use Python all the time.
It seems sort of wasteful of tokens!
iLemming 20 hours ago [-]
> And they virtually never use things like the Python REPL, even though they use Python all the time.
REPLs in non-homoiconic languages like Python, and homoiconic Lisp do differ. Every single step in Read-Eval-Print-Loop does. That's why Lispers sometimes refer to Lisp REPL as a "true REPL", because in practical comparison, Python's REPL is more like an "interactive shell". Homoiconic means that code-is-data, and the Read step in REPL doesn't need to do any acrobatics with parsing, building AST, etc, it's just directly reading the code and passing to Eval as is.
Here's a sense of what it looks like to be writing software with Lisp: https://youtu.be/tHgApFhevrQ?t=2272
I purposely moved the marker so you don't have to watch the whole talk. Jeaye here coded his entire presentation from inside a terminal, embedded into a game.
That's how typically Lispers write software - "from inside out". Lisp, uniquely fits for LLMs, because when you give them a Lisp REPL, they stop guessing and start empirically analyzing current state of things and produce working solution faster, costing fewer tokens.
The typical flow with non-homoiconic PLs is is roughly the Unix/pipe model - batch-style. Agent spawns process -> reads stdout/stderr -> spawns next process. State lives in-between the calls and in files. Each tool invocation technically stateless. It is a whole different story with Lisp.
This was referring to the LLMs' tendency to blat out hundreds of tokens into a single tool call, not to Clojure.
The REPL in the part of the presentation you link to only evaluates two forms, (range 10) and (bounce!), neither of which takes much advantage of homoiconicity.
cchase88 was talking about a degree of homoiconicity in Tcl that has been abandoned by most dialects of Lisp:
(That might look wrong, but it's actually correct. In Tcl the list {name} is exactly the same as the quasiquoted string "name" and the bare word name.)
You can't do that in Racket or SBCL, but it does exist in Clojure; it's clojure.repl/source. However, the part of the presentation you link to doesn't use anything similar, and it's not really a mainstream part of Lisp development anymore, the way it was 50 years ago.
iLemming 19 hours ago [-]
I don't think I'm missing the point. LLMs don't use Python's REPL because it's not that efficient, while properly built harness will eagerly utilize Clojure REPL if given a chance. Without "blating out hundreds of tokens".
kragen 18 hours ago [-]
You replied to my remark, which was about the token efficiency of a behavior I've observed LLMs engaging in when they use languages including Python and JavaScript, by claiming that Clojure has good token efficiency. Now, maybe Clojure has great token efficiency, or maybe it doesn't, but either way, that's irrelevant to the question I was talking about, which is whether this behavior wastes tokens when using non-Clojure languages such as Python and JavaScript. Nothing about Clojure could possibly be relevant to that question, so your reply suggests that you misunderstood what I was saying. There's no point in getting defensive about that — it's probably my fault in the first place for writing unclearly, and at any rate you aren't being evaluated on HermeneuticsBench, you're just trying to communicate with some jackass on HN.
However, the reason I thought this model behavior was relevant is that, if the LLMs are squandering tokens by failing to take advantage of the REPL facilities available in Python and Node, they might also squander tokens in the same way when attempting to use languages with better REPL facilities, such as (let's stipulate) Clojure. It sounds like you've observed that my prediction is incorrect in real life. Can you go into more detail? Which harness and which models have you seen good results with, and can you show an excerpt of a transcript?
Without evidence, I suspect that the behavior may be due to LLMs being trained to do well on noninteractive (one-shot) SWE benchmark tasks.
iLemming 18 hours ago [-]
[dead]
baq 18 hours ago [-]
in lisp the repl is the primary mode of development, you replace functions one at a time and only reload the whole system if you break structure layouts, and even then you don’t really restart the whole process (most of the time anyway, sbcl’s immobile code space is a bit of a pain) - agents can and do things by themselves, unprompted, which look like magic even if you’ve been piloting llms for as long as anyone here. I use gpt 6.1 sol for this, I’m sure opus would handle it perfectly, too.
iLemming 19 hours ago [-]
It's ridiculous how stubborn programmers could be. They'd cling to their beloved Blub paradigms and almost cultishly refuse to accept clearly pragmatic takes, sitting just in front of their eyes.
Of course, there's no tool without flaws. Nevertheless, oh boy, how amazingly practical Lisp-dialects can be in reality (even with all their imperfections), it's just astounding. Sometimes I think maybe it is some kind of ego-defeating stance or whatever, maybe smart programmers just can't believe how the stupidly simple idea of Lisp can ever satisfy their galaxy-sized brains? To me, Lisp is like a boundless sea of incredible idea generation on the spot, turning it into practical reality like some magic. Effortlessly, painlessly, and with joy.
I don't know, maybe I had to go through the pain of learning the intricacies of a dozen different stacks, using them for years, only to discover Lisp later in my life. Perhaps I wouldn't know the difference otherwise?
Just the other day, I was watching a YT video, which I of course fully control directly from Emacs - that is very useful for taking notes. I can mute, pause, speed-up, rewind, toggle subs, etc. All while typing a message, a note, or while looking at a PR diff. I thought, "hmm, floating window would be nice". Without even missing a beat, I opened eca-emacs buffer, I didn't even have to type the prompt - I used speech-recognition. Agent then (running in Elisp REPL), connected to my WMs REPL driven by Fennel, using tools in my Clojure-made harness with its own REPL, tapped into the lua-based mpv, analyzed things on the fly and just built the solution, right there. I didn't even have to compile, restart, reload, refresh anything. Now I can detach a video playing in the browser into mpv window and later put it back. With a press of a key.
It's almost as if Lisp has been quietly waiting for this moment. LLMs and Lisp REPLs make such a great duo - if you're a programmer and haven't seen it in practice yet, you should seriously be experiencing deep FOMO right now.
vegnus 23 hours ago [-]
preach
dimatura 18 hours ago [-]
This is an interesting analogy. I definitely can see this in effect already for software for work/personal projects, but also a different version of it in the the hardware synth world, where there's been an avalanche of custom firmwares for various synth. Some of them are based on official firmware source (rare so far, but increasingly common), but most are based on reverse engineering. See for example https://thefirmwarehub.com/ which catalogs custom firmware for the m-vave fm1, a particularly popular target.
pfdietz 23 hours ago [-]
So this means it's a new dawn for Common Lisp, right? :)
JonChesterfield 20 hours ago [-]
The effects are multiplicative, positive and negative.
pfdietz 14 hours ago [-]
So, two negative effects make a positive??
so-cal-schemer 19 hours ago [-]
LLMs and Lisp are like primordial soup, and programs, like life, emerge from them.
Natural selection says programs and libraries will stabilize and continue to evolve.
sobiolite 23 hours ago [-]
I do think the current ecosystem of open-source libraries won't survive as it is, as AI screws up the incentives too much. But agents recreating the wheel for every project isn't practical either.
What I think we'll see happen is that AI vendors will create private ecosystems for sharing code. I.e. you subscribe to Codex and you get access to a suite of libraries that speed up your development process. Behind the scenes there'll be a mirror of the how the current ecosystem works, with agents submitting bugs and feature requests and a private swarm of agents working the most popular / high priority.
nonethewiser 23 hours ago [-]
I suspect it will continue as it has. Where LLM's do use external dependencies, but quite a bit less than people do. Saving it more for the things that are complex and sensitive. They aren't perfect but overall it's better than the non-agent status quo (more dependencies, less re-implementing).
darkwi11ow 23 hours ago [-]
Not sure about this; what would be an incentive for AI vendors to do this ? More libraries used means less tokens spent, so it runs directly against their business model.
22 hours ago [-]
zero_shift 23 hours ago [-]
LLMs stop me using open source libraries for two reasons
(1) GitHub is now full of slop. The majority of new open source libraries are now generated by AI. Many come from students who are just looking for resume garnish. Others come from devs who are more excited about being an "open source developer" than actually doing open source development
(2) With AI I can probably build something better. And if it's crap? No problem! I can just wait 6 months and rewrite it with gpt_galaxy or Claude Torah or something
At the same time I have no real incentives to contribute back. Anything I create competes immediately with a sea of slop. Any actual work I do gets identified and swallowed up by the plagiarism machine. And to be honest I only occasionally had good experiences with OSS anyway
I think we are looking at the end of open source software. Not the end of free software - in fact that may end up flourishing with LLMs and reverse engineering and the like. But the idea of programmers sharing code, for communal interest and career building, is completely dead.
usrusr 22 hours ago [-]
How about (3): that in-house utility that you want to re-use across projects because it scratches one itch in precisely the way you want it scratched. Its raison d'être does not disappear from the appearance of LLM, it arguably gets stronger. You want the decisions that went into the library to be encoded in immutable form from the perspective of the contexts working on library dependents.
In the old days, both the investment in the library and the additional cost you'd want to sink on it to consider it publishing quality incentivised to keep it truly internal. LLM code however? It might be slop, but it's accurately groomed slop. Prompting the model to roleplay a public library author might even improve the output when it's in fact not published at all. The investment is low, the extra cost of sharing is low, worst that could happen is others actually picking it up and that would not be bad at all.
Is that spamming the public information universe on the faint hope that perhaps future models might come pre-trained with understanding of your library? Sure. But it's a very different thing from the scenarios described in (1).
krapp 23 hours ago [-]
>Not the end of free software - in fact that may end up flourishing with LLMs and reverse engineering and the like.
LLMs are antithetical to free software, which everyone seems to forget is as much an ethical and social movement as it is a classification of software licensing, and will be until one can examine and audit the training data of a model to exclude the possibility of including any non-free code, and until they include, document and respect the licenses for the sources they do use.
The degree to which they discourage people from actually being able to understand and modify code without an LLM also makes the code they generate implicitly nonfree. All of the freedoms of free software presuppose their utility to a human over their utility to a machine. If people aren't reading, writing and distributing code then it defeats the entire point. That's just proprietary software with extra steps.
I don't know what you call this new paradigm of vibe-coding and just not giving a damn about sources and licenses and copyright, but it isn't free software. And it's probably worth pointing out that said paradigm was created by and is most useful to corporations, not people. Using the plagiarism machine to plagiarize "the man" is still subject to the Rule of Goats[0].
> LLMs are antithetical to free software, which everyone seems to forget is as much an ethical and social movement...
At the core of Free Software there is one simple kernel: the user being in control. Licensing and copyright is used to achieve that, but they're the means, not the goal. The goal is that you, the user, should be in control of your computing, not the developers of the software you are using. Hence software that is free i.e. the software not being bound by the whims of its developers.
From that perspective, IMO, LLMs are far from antithetical to Free Software exactly because they let[0] their users do whatever they want with the software and their computers. That a user can instruct their agent to take the video playback code from MPV and combine it with the UI of XBMC[1] while ensuring it runs on the Raspberry Pi 4 they have connected to their TV (that they "jailbroke" to remove the intrusive ads and other user-hostile software that they replaced with software to their liking) even if they barely have any programming knowledge themselves is a sign of software freedom.
[0] at least the user-aligned ones not bound by restrictions placed on them by their own developers, so perhaps we need a Free Models movement too or something along these lines.
[1] random example, i don't even know of XBMC uses MPV's code already, so assume it doesn't
krapp 19 hours ago [-]
LLMs don't let their users do whatever they want, users are limited to whatever the model and its training allow, because it makes the decisions based on randomness, not them. Even open weight models have the same limitation. You don't have exact control over what the LLM does, much less (using any of the popular services) its training data therefore you can't even claim that you created, much less own, that code.
And because LLMs can't be audited and can't track or respect the licenses of the software they use as sources, no software generated by an LLM respects the freedoms of Free Software.
>That a user can instruct their agent (...) even if they barely have any programming knowledge themselves is a sign of software freedom.
It isn't, because as I said, freedom presupposes knowledge. If you barely have programming knowledge and you don't understand the code an LLM generates then you can't 1) read it, 2) edit it or 3) redistribute it without an LLM. You are not exercising any freedoms in that case, you're just being a consumer of a service.
>so perhaps we need a Free Models movement too or something along these lines
I said what I think would be the minimum requirements for a model to respect free software - at the very least it should only be trained on free software, it should be provably auditable without hallucination (I don't even think this is technically feasible) and it should respect the licenses of the software it incorporates, including attribution where necessary.
Beyond that there's still the problem that training even open weight models requires expensive infrastructure making it implicitly proprietary. As long as we need data centers at all it's never going to be as free as a text editor.
badsectoracula 18 hours ago [-]
You're looking at things from the perspective of being bound by the licenses and copyright, but as i wrote licenses are a means of getting control and giving more control within the confines of copyright. They are a means, not the goal.
LLMs, even by the limits they have from their training, can be used to give more control to their users than what they have.
Yes, being able to train an open source (not just open weight) model that is fully aligned with the user would be the best scenario, but even without that, LLMs can still give users more control over their computing than they previously had - even within the confines of current copyright laws, if they so desire.
krapp 17 hours ago [-]
>You're looking at things from the perspective of being bound by the licenses and copyright, but as i wrote licenses are a means of getting control and giving more control within the confines of copyright. They are a means, not the goal.
Because free software as a movement depends on the existence of licenses and copyright. Without the ability to legally enforce and defend those licenses it would be completely meaningless Just as any freedom is meaningless without a means to enforce and defend it. And as LLMs don't even allow the means, they can't be useful in reaching the goal.
The goal is for people to have control over their software - direct control, not control as determined by a mediator or service.
>LLMs, even by the limits they have from their training, can be used to give more control to their users than what they have.
We disagree on what "control" is in this context.
I don't believe prompting a service to generate code you can't understand and thus can't use without that service is control over code in any meaningful sense, any more than ordering food at MacDonalds is control over the menu.
>LLMs can still give users more control over their computing than they previously had - even within the confines of current copyright laws, if they so desire.
They can't, because LLMs don't respect those laws. It doesn't matter what license you use, it just gets sucked into the plagiarism machine like anything else.
Also, people had more control before LLMs because they didn't need to use LLMs. Knowledge is control. An empty text editor is infinitely more freeing than burning token on Claude (or whatever) will ever be.
kragen 20 hours ago [-]
This does seem to be the case in practice at present, but I wonder if it can be changed. AI models are happy to write you tutorials and explain code to you. And if courts are generally unwilling to enforce copyright on proprietary code that's been laundered through an LLM, so much the better!
krapp 16 hours ago [-]
The whole culture around vibe-coding would need to be changed. As it is, many people using LLMs are proud of the fact that they never touch the code, and almost no one seems to see any value in having any direct human involvement or knowledge at all.
It would be one thing if this were only the case for professional development, or if AI were really being used as "just a tool" but it seems to be the dominant paradigm with AI everywhere, that LLMs have to "win" and all human involvement in coding has to be eliminated. A world where the dominant culture around LLMs was to actually use them for education and aiding code generation instead of entirely abrogating oneself to a black box dopamine machine would be infinitely better than the world we have.
kragen 15 hours ago [-]
The Zeitgeist is fickle.
ChickeNES 18 hours ago [-]
Or one could realize that the whole Imaginary Property charade is rapidly headed to obsolescence. Good riddance.
krapp 17 hours ago [-]
You may prefer the world where everything you do is owned by one of two, maybe three AI silos but I don't.
ChickeNES 17 hours ago [-]
I don't see how that is at all relevant to what I said, seems like you just wanted a strawman to Don Quixote.
krapp 17 hours ago [-]
OK let me spell it out for you.
Ihe whole "Imaginary Property" (cute) charade is not rapidly headed to obsolescence. LLMs will only centralize control of IP to the corporations that will run their own LLM services, or license them to the services that will generate all of "your code" in the future. And under their terms of service, anything you generate will belong to those services, and not to you.
pfdietz 22 hours ago [-]
That link goes to a nonexistent message. Didn't Popehat leave X a while ago, if he's even still a thing?
When they have Claude Upanishads and GPT Dodecahedron we'll know the singularity is near
cmrdporcupine 21 hours ago [-]
IMHO that "career building" part of it was always a bit problematic because of the incentives it could add.
Instead of "here's some small bits of code you might find useful" or "let me share my approach", the personal glory building style of OSS construction can and has tended towards "behold my framework" and a brand, and often even a VC etc funded entity to go with it.
I don't love LLMs just conjuring half-assed things into existence, but I've also been burned too many times by someone else's frameworkization of something that should just be a small modular bit, or part of a standard library. Languages like Rust that have exempted a lot from their standard library that frankly should be there suffer from this the most.
i_s 22 hours ago [-]
I think there is some truth to this. But it may just be that the threshold for viable open-source collaborative projects increased by an order of magnitude or two. E.g., today if you make a cool datetime library, nobody will care, they can recreate the parts they need in 5 minutes. If you make something much harder to reproduce, then maybe they will. So I just file this under “you need to be more ambitious.”
firethief 22 hours ago [-]
> if we accept the assumption that it is easier to let an LLM generate functionality than to learn the interfaces of existing libraries and frameworks (or let the LLM integrate these libraries or frameworks)
This parenthetical seems like the weakness in the argument to me. Why have an LLM reinvent the wheel rather than let the LLM build on existing libraries?
Dr_Birdbrain 22 hours ago [-]
Because the LLM prefers to build its own. Unless you explicitly tell it not to, and even then you have to police it carefully. Most people won’t!
OhMeadhbh 16 hours ago [-]
Yes. Lisp's curse is you sort of have to know what you're doing to get the most out of it. If you don't want to learn computer science, there are other programming languages available.
weinzierl 22 hours ago [-]
Carmack once said something along the lines of him not reusing code a lot but rather rewriting it each time.
He is probably not alone, so this "curse" is has never restricted to Lisp completely. There always have been some wood and metal workers besides the many LEGO engineers.
"I also must confess to a strong bias against the fashion for reusable code. To me, “re-editable code” is much, much better than an untouchable black box or toolkit. I could go on and on about this. If you’re totally convinced that reusable code is wonderful, I probably won’t be able to sway you anyway, but you’ll never convince me that reusable code isn’t mostly a menace."
weinzierl 20 hours ago [-]
Good find, new to
me, thanks!
16 hours ago [-]
TurboHaskal 23 hours ago [-]
Well, if this means I will get to write code again, even indirectly with LLMs, instead of spending my whole workday merging renovate/dependabot pull requests, then I am all for it.
The possible upside is that it might lead to slower but more focused, thoughtful development of libraries by those who deeply care about it.
dsign 20 hours ago [-]
Why create a simple piece of code that does exactly what you want, when an LLM can smash libraries and frameworks together as well as anybody else? I can tell because I'm doing it right now. I'm not happy with the resulting bloat, but there's no denying that you can have the worst of both worlds if you really wanna.
athrowaway3z 20 hours ago [-]
If you want to talk about this, steel-man the opposition's argument.
scotty79 8 hours ago [-]
Libraries and shared code have drawbacks though. All software using a particular library likely shares its vulnerabilities.
Even if you need a small part of the functionality you bring in whole library when you use it increasing your exposure.
Standard way of doing things might impede better way of doing things for each particular application. And so on...
LLMs alter nearly every parameter in every value calculation.
Future software will often have single digit dependancies and userbase of 1.
shadowgovt 15 hours ago [-]
Here's the thing.
The curse actually exists in every codebase; LISP just makes it more obvious.
I previously administered a service in Python that included
- a postgres backend
- alembic to handle migrations and sqlalchemy to do ORM bindings
- strawberry to supply a GraphQL API
- an autogen library to create a Python wrapper for that API, and then additional hand-written glue atop that because the autogen had flaws.
There is some chance that if you get air-dropped into our codebase, you might be familiar with all those pieces. But if not, you still have a learning curve to get what's going on.
The only advantage Java, Python, etc. ecosystems have is popularity, which makes it more likely that someone's bespoke solution has become standard enough that you might have heard of it before. There are still probably 2 or 3 dominant frameworks that you might or might not have seen entering a new codebase (and then a bunch of special-casing and glue code to match the almost-there abstractions to the actual problem domain).
_doctor_love 18 hours ago [-]
I am not sure I feel so bleak as this.
A different way to frame this would be to say: why don't we all just pick one programming language and platform and use that? It's silly to reinvent the wheel!
The answer, of course, is obvious.
Diversity of solutions is good. Heterogenous diversity of solutions is even better. Good old Mother Nature is totally unafraid of solving the same problem, multiple ways, multiple times, through completely different means. That is true system redundancy.
It was true that anybody could create anything before the advent of LLMs as well. The barrier to entry was just higher than it is now. The bar for creating some quality is still pretty much as high as it ever was.
Tech is an eternal cycle always repeating itself. For example, did you know that it was a battle to create Fortran? John Backus had to go out and convince the high priests that there was value in using a language. Just like with LLMs, it was seen as as not being able to produce expert-level-quality-output and not something for serious people. Time flows like a river, and history repeats itself.
smitty1e 21 hours ago [-]
> As a second effect, the creation of new Open Source libraries would stagnate.
The very nature of training an LLM seems backward-looking.
Or, as a question: has an AI gotten around to generating the Final, One True Programming Language (FOTPL) yet?
measurablefunc 23 hours ago [-]
Application developers don't worry about binaries produced by compilers & in due time the same will be true for code produced by coding agents. I personally do not care what the code looks like as long as it actually has the features that I want & is secure enough for my limited use cases.
joe_the_user 23 hours ago [-]
It seems like there are advantages as well as problems to this situation. Notably it prevents "monoculture" in software which prevent global worms. If every website implements network protocols from scratch, it would have bugs but possibly not the same bugs and vulnerabilities as it's neighbor. The extreme is every app is its own OS - back to CP/M where running a program involved inserting a disk and turning on the machine, that "interface" had it's charm.
phyzix5761 22 hours ago [-]
The original wheel was reinvented continuously across different cultures and eras in history.
d-us-vb 23 hours ago [-]
This is rather interesting. But it misses the point somewhat.
The problem is whether or not we want to view code as a medium of communication between other humans vs code as an abstract machine that solves a problem. We know that "programs" in the general sense are fairly objective entities that can be studied objectively, which is where the famous Sussman line about this comes from.
But as a language for expressing execution semantics that a machine can then execute to produce a desirable effect on the real world (a solution to a problem), we would not expect such code to be written with other humans in mind, and as lisp is a strictly more expressive language (both for expressing the meaning of an algorithm that other humans will be able to study and understand and that a machine can execute), and that more people who program are concerned with producing a solution to a problem, the "curse of lisp" is the logical conclusion.
But it's overblown. There exist many excellent and fairly complete libraries for Lisp: Closer MOP, UIOP, ASDF, Bordeaux Threads, etc. And no surprise, these libraries are virtually ubiquitous and considered (at least by me) to be more or less extensions to the language. And these libraries are written in a fairly readable style that anyone can go and try to understand the code.
Secondly, the curse isn't really much of a curse at all. It is more likely to yield more robust programs. The assumption that code reuse through libraries increases software quality doesn't really hold up in practice: libraries that are "complete" tend to add bloat to applications; managing different versions of libraries on the same platform leads to arguments about static vs. dynamic linking, and so on and so forth. Ever had to debug .so versioning bugs on Linux? It's not fun. And yet, that is par for the course if you try to persist in the notion that "libraries and code reuse is always better than reinventing the wheel".
As a reaction to the utter failures that have occurred due to following that ideology, entire programming communities have popped up to fight it, particularly the "Handmade Hero" that became Better Software Conferences as well as "Software Should Work". And while those people aren't a huge fan of Lisp, they really do embody the Lisp mindset of "don't be afraid of building your own system in your own solution's language". And this does usually yield nicer systems to work with because programming is theory building: bringing in different ready-made libraries introduces conflicting theories that requires even more glue code to rectify and the glue code rarely foresees all the discrepancies. And so bugs appear in the integrations between them.
That's not to say that increasing "the curse of lisp" always yields higher quality. The kinds of developers that make great software with that mindset are the ones that are allergic to inconsistency at any level and so squash bugs as quickly as possible and that is what leads their software to be better. But on the practical side of programming work, you feel a lot less inhibited in trying to fix bugs when you're certain you understand the code and how the implementor decided to map the problem domain onto the range of possible solutions. This is where the issue with LLMs comes in: if programming is theory building (which I firmly believe), then what we're really after with using LLMs to generate code is a more effective technique of translating high level theory of the problem into the low level code that executes to solve the problem. As such, maybe vibe coding can work if the vibe coder diligently keeps in their mind what they're after. But usually what that means is writing notes about the desirable properties of the resultant application. And then they're just back to theory building... just at a somewhat higher level.
AnimalMuppet 22 hours ago [-]
In at least some cases, this is pretty clear cut. Don't roll your own crypto libraries. You may think you know what you're doing. You don't - not enough to produce genuinely secure crypto.
Don't roll your own numeric libraries. There are libraries with decades of improvements to handle corner cases and increase stability. You won't create a better one, not in one lifetime.
So, yes, in some cases code reuse through libraries really does improve software quality.
It fundamentally comes down to this question: Can I, the user of this library, produce a library that is more robust for my purpose than the existing libraries? Those who say "yes" often underestimate the amount of care needed to create code that actually works - that works solidly, that is robust against failures on certain inputs.
But, you say, you don't actually have any of those inputs, so why do you care? You don't - now. But the day may come when your program is going to have to handle those inputs, and when it does, then it's your problem, because you wrote the library.
lelanthran 20 hours ago [-]
I broadly agree, but... if I use my hand-rolled HTTP server that only supports a subset of the spec (and use nginx for TLS termination), I would be free and clear of the Brotli attack.
esafak 23 hours ago [-]
This is fragmentation. The advent of slop has caused many repos to stop accepting contributions, and people maintaining their own forks. I do it too, diligently maintaining repos that the original maintainers were unwilling to, or simply to add my desired features.
Since code is now cheap I think it is not the end of the world, but it does suck a bit for users, who may need to cobble together multiple forks.
jonahbenton 19 hours ago [-]
(March 2026)
lol but still true
znpy 22 hours ago [-]
I see two main issues with the point op is trying to make.
1. The lisp curse is very lisp-specific because there are so many lisp implementations. But you essentially only have one major rust/ruby/php/java/perl/erlang implementation. Languages like C/C++ only have two major implementations (gcc,llvm/clang).
2. I see so many projects every day where developers pull in gigabytes of software only to use a small number of features. Don’t even get me started on the whole left-pad clown show. Gigabytes of libraries pulled left and right only to use a few megabytes at most.
cmrdporcupine 21 hours ago [-]
"I’d rather rely on proven libraries with well-defined abstractions than generate hundreds of lines of code which solve a local problem for me. “Not generated here” is just a different version of “Not invented here”.
I disagree generally, and the problem is two fold..
I've just seen "well-defined" abstractions go wrong too many times. Over- encapsulation, over-abstraction, or just overall over-cleverness in third party packages that has led me to spend large parts of my career just frustrated trying to glue third party dependencies together in a sensible way... and the abstractions only adding complication.
The joy and temptation of having an LLM "just make it" is that this goes away. The functionality fits my existing structure and abstractions and I'm not fighting a war with the architecture that the third party maintainer decided worked best for them. And getting only the parts I need, not your whole giant framework with it. (And yes, I know the LLM could easily hallucinate something far far worse, but let's just... play pretend here for a minute)
The second part is that since the dawn of Maven, NPM, Crates.io generally there has just been this insane explosion in programs of transitive third party dependencies out into the stratosphere, and the cognitive, technical, and legal debt of so many deps generally is not sufficiently recognized by the community. Running "cargo tree" in my project is often frankly depressing. Multiple linked MD5/SHA256 implementations, random number generators, HTTP protocols, people dragging in tokio deps where I don't want them, multiple versions of the same thing compiled and linked... It's exceedingly frustrating, and with the explosion of security concerns we've seen recently, it's also potentially dangerous.
I don't love the idea of having LLMs "just yeet it" esp if people misapply this to things like security/cryptography domains. But I'm also more than skeptical about the actual real world quality of many hallowed third party packages. I've been burned too many times.
Perhaps potentially what replaces "widely used standard implementation of X in a library/npm/crate form" is an "LLM readable recipe for X along with a formal proof / automated test scenario that I can point my clanker at to get a community proven way of doing this" along with a set of prompts, licensing/credit requirements, etc.
iLemming 20 hours ago [-]
[dead]
Rendered at 16:12:38 GMT+0000 (Coordinated Universal Time) with Vercel.
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.
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
Code that is outside of the purview of Coalton—raw Common Lisp code—is run in explicit (LISP ...) forms [0] which require the user to annotate the type and they add dynamic type checks to ensure the enclosed code meets the contract the programmer specified (unless UNSAFE is used [1]).
[0] https://coalton-lang.github.io/manual/operators/lisp/
[1] https://coalton-lang.github.io/manual/operators/unsafe/
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.
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."
I see that sbcl itself is alive and doing rather well, but other than that the landscape is fairly grim.
Unironically the most successful modern day lisp is clojure, that mostly piggybacks the jvm and can reuse most java libraries and frameworks.
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”.
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:
when in reality it now looks like this: and in C# it looks like this: 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.
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 (edit: and we're not talking only about syntax) (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.
And I have seen many real problems solved with Lisp, regardless, that is why commercial Lisps like LispWorks and Allegro are still in business.
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.
https://www.siscog.pt/en-us/
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://www.itasoftware.com
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,
https://www.lispworks.com
https://www.lispworks.com
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.
https://interlisp.org
https://primer.interlisp.org/introduction
Bruh... Nubank is literally the biggest effing digital bank in the world. Famously built on Clojure stack. Just because you have not seen shit it doesn't mean it's not happening.
Apple, Netflix, Amazon, Walmart, NASA - they all use Lisp, and that's just the States. There are tons of European startups building on it.
> Lisp missed its timing.
It is literally timeless. Emacs just turned 50. Name a single half-a-century old software product that's being actively used, developed and improved. r/emacs subreddit gets daily, daily! updates of new Emacs package announcements.
> most of that has been moved, copied, stolen, and adapted to mainstream programming languages.
Totally. Except homoiconicity. The point of which the majority of programmers miss, misunderstand, or ignore. The bigger point programmers miss is that Lisp effectively proves that largely the syntax of programming languages doesn't really matter. What matters is the runtime. And Lisp today runs practically on every possible runtime. Meaning that to be a polyglot, you don't really need to know dozens of PLs, you can just understand homoiconicity and voila - you can practically ship software for any runtime. Syntax is the cheap part, and Lisp shows it well: Clojure on the JVM and CLR, Clojurescript on JS, Fennel on Lua, Hy on Python, LFE on BEAM, Jank on LLVM, etc. The surface stays the same, and the host changes underneath. Then you learn runtimes and type systems, which is the real work of being a polyglot. That is a big win. Most programmers spend years on syntax and then mistake it for knowing a language. Learn the damn Lisp. It is enormously practical.
> still think the "hello world ...
Who the fuck cares about intricacies? In pretty much [almost] every Lisp dialect it would be just:
(print "Hello, World!")
For EVERY different runtime.
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.
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.
I've used more Rust tools, and jobs are outside few niches non-existent.
Any language that's powerful for creating new syntax and doesn't have an equally powerful community repository gets this same effect to some extent.
Why haven't I submitted my patches? Because my agent wrote them and I didn't review them. I would feel bad submitting my patches without looking at them, and I don't have time to look at them.
I've seen the same thing in Go, for what it's worth.
The code totally works, I'm not a denier there, but the interfaces are heinous if you don't keep an eye out. Mine wrote a Go function that passed a name variable as a string, but also embedded in 2 separate structs that were arguments. I've also seen it do re-validation of data multiple times in internal functions so everything has to return an error.
It's also stuff that sort of doesn't matter if an LLM is the only user. It probably costs some extra quantity of tokens, but not enough to be worth hand-grooming the code.
KMyMoney stopped importing (some) OFX files for me. I asked an LLM to debug.
It was a wild journey. An obscure bug in some QT library that was triggered because of something completely unrelated that I had installed briefly in 2019 (and uninstalled years ago).
I had it fix the issue by cleaning the leftovers from 2019, but it's still a QT bug. I had it do a writeup, but I'll never submit it. It's fairly sophisticated and I don't know QT code at all.
I believe I do have some sort of a reproducer, but I likely wouldn't understand even the reproducer script. I think it won't be taken well if someone files a bug, says "Here's a script that reproduces it", but himself doesn't understand what the script is doing.
For bug reports (at least IMO) a minimal example to reliably reproduce the error without any fuss is the basic building block. The reporter doesn't need to understand why it works let alone offer an explanation. In fact for complex projects more often than not any purported explanation will be subtly incorrect and actively misleading. If anything further "documentation" of bugs is unwelcome. Unambiguously demonstrate the defect and GTFO.
I'd still be wasting someone's time.
I'll probably put a write-up on my blog one day, though.
If an end user encounters an error while staying within the bounds of "expected usage" then the bug is guaranteed to be valid. You just don't necessarily know whose bug it actually is (for example a broken library versus broken usage of the library by the consuming program).
It's honestly not worth it. I understand both sides here, but people are going to have to come up with new ways of collaborating. Pull requests are likely not it anymore.
https://gavinray97.github.io/blog/llm-build-cheaper-than-sea...
As an example, a black hat doesn't get 70% of web sites from one shared bug in PHP. They need to target specific sites, and the exploit isn't likely to work in very many other places.
The one situation where they really can't get anywhere profitable is a unikernel webapp. With no source and no shell they find the vuln but the worst they can do with it is possibly poison or exfiltrate data as a one off, or crash the server. Often they can't even figure that out. Can't even leave themselves a reliable way back in.
Of course the traditional problem with unikernels is that you have to port EVERYTHING you need yourself. But the cheapness of this is exactly what we're talking about so.
Looks like security through obscurity's back on the menu.
But putting ssh for those bounce boxes on a nonstandard port that doesn't even show up to a remote system within the network until they've port-knocked on another two or four ports in the proper order on top of all that does not hurt security. Using a separate internal DNS zone that nobody outside your network has access to resolve doesn't hurt. Having your firewall drop packets from invalid sources instead of rejecting them doesn't hurt.
The language is restricted to permissions granted on startup and can only access the system via the runtime, which only supports a particular subset of linux syscalls. So, outside of the stdlib, whichever feature you need, you simply use an LLM to port an existing python/rust/JS/TS/Java library to the language and use it.
As the runtime has its own scheduler and GC, I have actually been wondering about the feasibility of skipping the linux kernel and making the runtime itself the "os." Given that so much modern hosting is actually done on virtual hardware, the drivers could be hosted within the runtime as well.
- statically typed from end to end
- closed and open/extensible types
- closed types are immutable, open ones have two variants: immutable and mutable
- arrays have two variants: immutable and mutable
- no OOP/classes. inheritance is nominal and mainly exists to provide access to class membership (is X a Y?)
- functions operating on data
- UFCS exists to provide nice features like "apple".substr(...)
- first class functions and closures
- monomorphized generics
- tailcalls
- operator overloading
- modules and namespaces to control access
- erlang/beam style first class processes. So you `spawn` a function and communicate between processes using send/recv instead of async/await
Processes are completely isolated at the runtime level. Each has its own stack, heap, mailbox and GC.
The bytecode carries all type information. The VM will compile using AOT-on-load.
My own runtime-becomes-a-os idea is still just an idea. I haven't really pursued it with seriousness. Will probably do that once the language and runtime stabilize.
I started in March and have gone through nearly 300 spec revisions for the runtime and language. Thanks to LLMs, I think I will have something useful to share in 2027.
My problem is that I have ten things in the pipeline at any given moment and I switch between them as time permits. So things get delayed a bit.
A bare bones microkernel?
The advantage there shouldn't be obscurity, so much as very limited attack surface in the whole exposed stack.
Big picture, I think we should explore what's possible when software is disposable.
Which, probably, you will also have to do.
I suspect that a more effective mitigation to having exploitable bugs would be to have an LLM read all your HTTP requests and the actions the web server proposes to take in response and give a Jev-like approve/disapprove decision.
My point is that everyone doing their own thing their own way means an attacker doesn't get the next thousand sites for free after finding a vulnerability in one site.
Having an LLM as sentry is a fun idea too.
Genetic monocultures like bananas are at risk from a single species of fungus.
One small issue: they didn't exist! It had just hallucinated them!
Which was a real shame, since they were much nicer than the actual stuff I ended up finding.
I just realized, thinking about this now, that these days (and perhaps even back then), I could just say "ok now take this code and build the missing library so it actually works!"
That was, in retrospect, an important bellwether.
What if there was a code sharing site where it was unambiguous what a given snippet of code would be named and where it would be stored, so that a user could just browse it and find a list of implementations for a given problem?
This of course runs up against one what John Ousterhout notes is one of the most difficult problems in computer science --- naming things --- in his book:
https://www.goodreads.com/en/book/show/39996759-a-philosophy...
I've tried to do it on a small-scale with my own work, storing bits of (la).tex code in a single file, but on reviewing it, I'll often find that I have written a given solution a second time and given the macro a slightly different name....
Almost everything else is domain specific where you have to understand the domain first before understanding the code. And modeling a domain is all about tradeoffs between accuracy, performance, specific vs generic,…
Instead of collecting such solutions, a better approach is to master basic data structures, and then improve your modeling capabilities. After that, it’s mostly learning domain as they come (dsp, physic modeling, operating system concepts, relational database, graph theory, 3D geometry, accounting,…)
What's more secure isn't so simple. If you vendor something with a vulnerability then it wont be patched. But vendoring may also mean you took the 2% of the library you need and not the 98% which reduces the surface area for vulnerabilities. And it can cut the other way - you may update a package that was previously good and is now vulnerable (regressions, supply chain attacks).
There is a balance that must be struck, and I think LLM's strike a better balance than people do. Dependencies are a convenience with a cost and LLM's can trivially copy or re-implement things that we cant.
If you aren't using a library function you're not vulnerable to exploits in that code: unused but imported code is inert (possible usable as a gadget if you're vulnerable elsewhere, but at that point you're screwed anyways) and most compilers/runtimes completely eliminate it.
> you may update a package that was previously good and is now vulnerable (regressions, supply chain attacks)
There are better mitigations to this than not using a library.
You still completely ignore the license violations.
The ones that you are imagining to happen? Its not a problem because you could simply observe proper licensing.
>If you aren't using a library function you're not vulnerable to exploits in that code
Not true, just because you arent calling a function doesnt mean it cant run. Read up on Log4Shell.
It's usually more straightforward to just rebuild it from scratch — not to mention infinitely more satisfying — and that was true before AI!
On the other hand, I routinely build Java/JVM projects with dependencies that haven't been updated in a decade that compile without issues.
Somewhere in the middle are most languages, I think.
It depends on the "load bearing" code. Obviously something like crypto is not something we should implement ourselves but core business logic would be "load bearing" in another way and is probably not something you want to farm out to a dependency.
(LLMs accelerate this and "a few years" can easily turn into "a few months".)
Yes, some dependencies are great. But unfortunately the vast majority are problematic: Not properly supported, badly tested, with unhelpful maintainers, funny licenses, undocumented and, definitely, not being able to cover your requirements 100% so you have to change your requirements to meet the dependencies instead of the other way around.
I 100% disagree with this. Supply chain attacks are already at an all-time high due to agentic hacking assistance, and that trend shows no sign of slowing. Every dependency you add is another potential attack vector, and just checking the dependency’s code doesn’t solve the issue - your dependencies also have dependencies!
The cost of rolling your own has gotten so low that it’s almost always a better security tradeoff to reimplement the thing yourself. Is that a good thing? I’m not sure.
Also, you clearly don't work with products that have any sort of serious corporate liability. Being able to blame a supplier/library is almost always preferable to assuming the liability yourself
Most of these huge AI discoveries of vulnerabilities have not been through probing an unknown server with a custom stack. They've been through probing a known/discoverable tech stack that is open source. Security through obscurity is never good, but if anything, the next couple years on known tech stacks is going to be worse.
> Being able to blame a supplier/library is almost always preferable to assuming the liability yourself
This only works if it's Log4j, or PHP, or some big vulnerability that hits mainstream news. Clients do not care if the tiny library only you picked had a vulnerability in it, and they shouldn't either.
I work for a company that provides compliance services to banks, we take our security responsibilities very seriously.
The risk associated with introducing a new dependency to the codebase has now exceeded the risk associated with implementing something ourselves in most cases (the exceptions being the obvious ones: crypto, auth, server frameworks, etc.).
> Being able to blame a supplier/library is almost always preferable to assuming the liability yourself
We like to optimize for actually keeping our customer’s data safe, rather than covering our butts :)
> We like to optimize for actually keeping our customer’s data safe, rather than covering our butts :)
If you have the budget to back that up I'm jealous. Otherwise, pride cometh before a fall. I'm curious how you conducted that risk analysis. Just because a common COTS library has more documented vulnerabilities doesn't inherently mean your hand-rolled option has less, and the difference would naturally vary from library to library.
For my part I work in defense, and our customers prefer to hear that we're using industry standard libraries and have tons of questions if we're rolling our own stuff (first of which is "why are you wasting our time and money reinventing the wheel?"). It reduces liability for them as well, they can tell their higher-ups that they approved proven, industry-standard solutions as much as possible and they're only paying us for our unique expertise.
It’s about the relative chance that someone’s CI infrastructure somewhere in the dependency change gets pwned in a way that allows malware to get into our dev environments or production servers. If we roll our own library for some functionality we need, that risk is 0. My point is the cost of doing so is much lower than it used to be, both in terms of implementation time and maintenance effort.
Why stop there? We could eliminate all external dependencies and even build our own compiler and OS, since the cost of rolling own solution has apparently gotten so low, right? Sometimes I feel like I'm living in a completely different dimension from some of the commenters here.
I'm not taking sides here, I love Lisp, though I don't use it anymore (except elisp in emacs, but it doesn't count). My point is that debating the name itself distracts from the actual issue.
I asked him with the first disk was, and I remember distinctly he said it was an operating system. I asked him what an operating system was, and he said it was like a program, it was a program technically, that makes it easier to run other programs, just it was a program that didn't do much on its own and you wouldn't use it without another program right afterward. I said it didn't seem easier if you had to load a different disk than the one you wanted to use, and you still had to load the one you wanted afterward. He looked at me disdainfully and patiently explained that all or almost all the software in the future would use operating systems and they whole process would get easier or even invisible but there would always be an operating system in there somewhere at some point in the very near future. I was skeptical, but I nodded along.
I imagined an operating system as a dressed up software library, which was more intuitive to me as a concept.
Looking back, AmigaOS was remarkably complete and modern for 1985: preemptive multitasking microkernel, shared libraries, multimedia support, everything was modular.
the lisp dialect growth is also famous, it's less the case these days because people know about it, but it existed
i'd add one thing to your point, is that lispers know how to port concepts from lang a to lang b very easily, support libs, macro layer if need be (see goroutines in clojure) so fragmentation is not as hard it was in mainstream languages (ps: even though today everybody goes into ast / transpiler to experiment)
That last fragment. I fear increasingly less so. There's already been a number of posts pointing out that modern programming is often held up be a few key individuals. And now (some of) those individuals (Linus, people like Chris McCord of LiveView, etc), are sharing how they're now "doing more of the stuff they've always wanted to do", and offloading tedious stuff to AI tools (by the way, expertise comes through tedious reps).
> If we ignore the 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
is not true for essentially any of the infrastructure that cutting edge biological research builds upon. It's all a buggy mess.
Expect dramatic acceleration in basic research as a result of LLMs.
> Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.
there is an infinite proliferation of Lisp implementations, and for many people it is the first language that they write an interpreter for since it is so easy.
Ecosystem split is the same reason why Cobol fell out of being mainstream: there are multiple proprietary implementations that are intentionally mutually incompatible, therefore an ecosystem could never develop. Oracle (in the past Sun) tries to avoid Java sharing this fate by using trademark law to crack down on JVM implementations that call themselves Java without having run the TCK.
Emacs Lisp I can't speak to, having no experience there.
As for Scheme, you're correct that implementation fragmentation is one of its problems holding back adoption. But it's not a problem for Common Lisp, which has had much less fragmentation issues.
Coding agents have actually cut both ways for me. I can reinvent the wheel more easily and with higher quality, but I can also integrate an external library much more easily than before.
The other day I needed my system to download SFTP, so I had the agent build an SFTP client. It turned out that I actually needed FTPS, so I had the agent build that too.
Another time I wanted to integrate with Git repos, but instead of trying to reinvent that, I asked the agent to integrate libgit2. Of course, I asked it to add an API that matched the semantics of my system, so from my perspective, the wheel was exactly how I wanted it.
I think what's going to happen is that there will be more vertically integrated platforms that do it all. If you think about it, it's really annoying to cobble together a system from different libraries, each of which might have different semantics.
What we want, as developers, is to have a single, well-designed, integrated platform that exposes all the functionality we need in a consistent way. That's a lot easier now that LLMs can mold code to your exact specifications.
I'm biased, of course, because that's exactly what I'm building with GridWhale.
But even if they were pleasant and did what I needed (this one time I installed a 5000 line lib that was missing 20 lines to do the thing it was actually designed to do.. like, they couldn't have added 20 more lines?!), an issue I have is spoilers.
Like, at university, they constantly said, ok here's a big problem in computer science.. (3 seconds later) .. aaand here's how we solved it! And I'm like agh, no! Spoilers! I want to figure it out, jeez!
That's also how I feel about "computer, just magick my entire program into existence." Spoils the fun of figuring it out!
It seems sort of wasteful of tokens!
REPLs in non-homoiconic languages like Python, and homoiconic Lisp do differ. Every single step in Read-Eval-Print-Loop does. That's why Lispers sometimes refer to Lisp REPL as a "true REPL", because in practical comparison, Python's REPL is more like an "interactive shell". Homoiconic means that code-is-data, and the Read step in REPL doesn't need to do any acrobatics with parsing, building AST, etc, it's just directly reading the code and passing to Eval as is.
Here's a sense of what it looks like to be writing software with Lisp: https://youtu.be/tHgApFhevrQ?t=2272 I purposely moved the marker so you don't have to watch the whole talk. Jeaye here coded his entire presentation from inside a terminal, embedded into a game.
That's how typically Lispers write software - "from inside out". Lisp, uniquely fits for LLMs, because when you give them a Lisp REPL, they stop guessing and start empirically analyzing current state of things and produce working solution faster, costing fewer tokens.
The typical flow with non-homoiconic PLs is is roughly the Unix/pipe model - batch-style. Agent spawns process -> reads stdout/stderr -> spawns next process. State lives in-between the calls and in files. Each tool invocation technically stateless. It is a whole different story with Lisp.
> It seems sort of wasteful of tokens!
Clojure is proven to be one of the most token efficient languages. https://tokencalculator.ai/most-token-efficient-languages-fo...
> It seems sort of wasteful of tokens!
This was referring to the LLMs' tendency to blat out hundreds of tokens into a single tool call, not to Clojure.
The REPL in the part of the presentation you link to only evaluates two forms, (range 10) and (bounce!), neither of which takes much advantage of homoiconicity.
cchase88 was talking about a degree of homoiconicity in Tcl that has been abandoned by most dialects of Lisp:
(That might look wrong, but it's actually correct. In Tcl the list {name} is exactly the same as the quasiquoted string "name" and the bare word name.) You can't do that in Racket or SBCL, but it does exist in Clojure; it's clojure.repl/source. However, the part of the presentation you link to doesn't use anything similar, and it's not really a mainstream part of Lisp development anymore, the way it was 50 years ago.However, the reason I thought this model behavior was relevant is that, if the LLMs are squandering tokens by failing to take advantage of the REPL facilities available in Python and Node, they might also squander tokens in the same way when attempting to use languages with better REPL facilities, such as (let's stipulate) Clojure. It sounds like you've observed that my prediction is incorrect in real life. Can you go into more detail? Which harness and which models have you seen good results with, and can you show an excerpt of a transcript?
Without evidence, I suspect that the behavior may be due to LLMs being trained to do well on noninteractive (one-shot) SWE benchmark tasks.
Of course, there's no tool without flaws. Nevertheless, oh boy, how amazingly practical Lisp-dialects can be in reality (even with all their imperfections), it's just astounding. Sometimes I think maybe it is some kind of ego-defeating stance or whatever, maybe smart programmers just can't believe how the stupidly simple idea of Lisp can ever satisfy their galaxy-sized brains? To me, Lisp is like a boundless sea of incredible idea generation on the spot, turning it into practical reality like some magic. Effortlessly, painlessly, and with joy.
I don't know, maybe I had to go through the pain of learning the intricacies of a dozen different stacks, using them for years, only to discover Lisp later in my life. Perhaps I wouldn't know the difference otherwise?
Just the other day, I was watching a YT video, which I of course fully control directly from Emacs - that is very useful for taking notes. I can mute, pause, speed-up, rewind, toggle subs, etc. All while typing a message, a note, or while looking at a PR diff. I thought, "hmm, floating window would be nice". Without even missing a beat, I opened eca-emacs buffer, I didn't even have to type the prompt - I used speech-recognition. Agent then (running in Elisp REPL), connected to my WMs REPL driven by Fennel, using tools in my Clojure-made harness with its own REPL, tapped into the lua-based mpv, analyzed things on the fly and just built the solution, right there. I didn't even have to compile, restart, reload, refresh anything. Now I can detach a video playing in the browser into mpv window and later put it back. With a press of a key.
It's almost as if Lisp has been quietly waiting for this moment. LLMs and Lisp REPLs make such a great duo - if you're a programmer and haven't seen it in practice yet, you should seriously be experiencing deep FOMO right now.
Natural selection says programs and libraries will stabilize and continue to evolve.
What I think we'll see happen is that AI vendors will create private ecosystems for sharing code. I.e. you subscribe to Codex and you get access to a suite of libraries that speed up your development process. Behind the scenes there'll be a mirror of the how the current ecosystem works, with agents submitting bugs and feature requests and a private swarm of agents working the most popular / high priority.
(1) GitHub is now full of slop. The majority of new open source libraries are now generated by AI. Many come from students who are just looking for resume garnish. Others come from devs who are more excited about being an "open source developer" than actually doing open source development
(2) With AI I can probably build something better. And if it's crap? No problem! I can just wait 6 months and rewrite it with gpt_galaxy or Claude Torah or something
At the same time I have no real incentives to contribute back. Anything I create competes immediately with a sea of slop. Any actual work I do gets identified and swallowed up by the plagiarism machine. And to be honest I only occasionally had good experiences with OSS anyway
I think we are looking at the end of open source software. Not the end of free software - in fact that may end up flourishing with LLMs and reverse engineering and the like. But the idea of programmers sharing code, for communal interest and career building, is completely dead.
In the old days, both the investment in the library and the additional cost you'd want to sink on it to consider it publishing quality incentivised to keep it truly internal. LLM code however? It might be slop, but it's accurately groomed slop. Prompting the model to roleplay a public library author might even improve the output when it's in fact not published at all. The investment is low, the extra cost of sharing is low, worst that could happen is others actually picking it up and that would not be bad at all.
Is that spamming the public information universe on the faint hope that perhaps future models might come pre-trained with understanding of your library? Sure. But it's a very different thing from the scenarios described in (1).
LLMs are antithetical to free software, which everyone seems to forget is as much an ethical and social movement as it is a classification of software licensing, and will be until one can examine and audit the training data of a model to exclude the possibility of including any non-free code, and until they include, document and respect the licenses for the sources they do use.
The degree to which they discourage people from actually being able to understand and modify code without an LLM also makes the code they generate implicitly nonfree. All of the freedoms of free software presuppose their utility to a human over their utility to a machine. If people aren't reading, writing and distributing code then it defeats the entire point. That's just proprietary software with extra steps.
I don't know what you call this new paradigm of vibe-coding and just not giving a damn about sources and licenses and copyright, but it isn't free software. And it's probably worth pointing out that said paradigm was created by and is most useful to corporations, not people. Using the plagiarism machine to plagiarize "the man" is still subject to the Rule of Goats[0].
[0]https://www.urbandictionary.com/define.php?term=Popehat%27s+...
At the core of Free Software there is one simple kernel: the user being in control. Licensing and copyright is used to achieve that, but they're the means, not the goal. The goal is that you, the user, should be in control of your computing, not the developers of the software you are using. Hence software that is free i.e. the software not being bound by the whims of its developers.
From that perspective, IMO, LLMs are far from antithetical to Free Software exactly because they let[0] their users do whatever they want with the software and their computers. That a user can instruct their agent to take the video playback code from MPV and combine it with the UI of XBMC[1] while ensuring it runs on the Raspberry Pi 4 they have connected to their TV (that they "jailbroke" to remove the intrusive ads and other user-hostile software that they replaced with software to their liking) even if they barely have any programming knowledge themselves is a sign of software freedom.
[0] at least the user-aligned ones not bound by restrictions placed on them by their own developers, so perhaps we need a Free Models movement too or something along these lines.
[1] random example, i don't even know of XBMC uses MPV's code already, so assume it doesn't
And because LLMs can't be audited and can't track or respect the licenses of the software they use as sources, no software generated by an LLM respects the freedoms of Free Software.
>That a user can instruct their agent (...) even if they barely have any programming knowledge themselves is a sign of software freedom.
It isn't, because as I said, freedom presupposes knowledge. If you barely have programming knowledge and you don't understand the code an LLM generates then you can't 1) read it, 2) edit it or 3) redistribute it without an LLM. You are not exercising any freedoms in that case, you're just being a consumer of a service.
>so perhaps we need a Free Models movement too or something along these lines
I said what I think would be the minimum requirements for a model to respect free software - at the very least it should only be trained on free software, it should be provably auditable without hallucination (I don't even think this is technically feasible) and it should respect the licenses of the software it incorporates, including attribution where necessary.
Beyond that there's still the problem that training even open weight models requires expensive infrastructure making it implicitly proprietary. As long as we need data centers at all it's never going to be as free as a text editor.
LLMs, even by the limits they have from their training, can be used to give more control to their users than what they have.
Yes, being able to train an open source (not just open weight) model that is fully aligned with the user would be the best scenario, but even without that, LLMs can still give users more control over their computing than they previously had - even within the confines of current copyright laws, if they so desire.
Because free software as a movement depends on the existence of licenses and copyright. Without the ability to legally enforce and defend those licenses it would be completely meaningless Just as any freedom is meaningless without a means to enforce and defend it. And as LLMs don't even allow the means, they can't be useful in reaching the goal.
The goal is for people to have control over their software - direct control, not control as determined by a mediator or service.
>LLMs, even by the limits they have from their training, can be used to give more control to their users than what they have.
We disagree on what "control" is in this context.
I don't believe prompting a service to generate code you can't understand and thus can't use without that service is control over code in any meaningful sense, any more than ordering food at MacDonalds is control over the menu.
>LLMs can still give users more control over their computing than they previously had - even within the confines of current copyright laws, if they so desire.
They can't, because LLMs don't respect those laws. It doesn't matter what license you use, it just gets sucked into the plagiarism machine like anything else.
Also, people had more control before LLMs because they didn't need to use LLMs. Knowledge is control. An empty text editor is infinitely more freeing than burning token on Claude (or whatever) will ever be.
It would be one thing if this were only the case for professional development, or if AI were really being used as "just a tool" but it seems to be the dominant paradigm with AI everywhere, that LLMs have to "win" and all human involvement in coding has to be eliminated. A world where the dominant culture around LLMs was to actually use them for education and aiding code generation instead of entirely abrogating oneself to a black box dopamine machine would be infinitely better than the world we have.
Ihe whole "Imaginary Property" (cute) charade is not rapidly headed to obsolescence. LLMs will only centralize control of IP to the corporations that will run their own LLM services, or license them to the services that will generate all of "your code" in the future. And under their terms of service, anything you generate will belong to those services, and not to you.
https://www.threads.com/@kenpopehat
Instead of "here's some small bits of code you might find useful" or "let me share my approach", the personal glory building style of OSS construction can and has tended towards "behold my framework" and a brand, and often even a VC etc funded entity to go with it.
I don't love LLMs just conjuring half-assed things into existence, but I've also been burned too many times by someone else's frameworkization of something that should just be a small modular bit, or part of a standard library. Languages like Rust that have exempted a lot from their standard library that frankly should be there suffer from this the most.
This parenthetical seems like the weakness in the argument to me. Why have an LLM reinvent the wheel rather than let the LLM build on existing libraries?
He is probably not alone, so this "curse" is has never restricted to Lisp completely. There always have been some wood and metal workers besides the many LEGO engineers.
"I also must confess to a strong bias against the fashion for reusable code. To me, “re-editable code” is much, much better than an untouchable black box or toolkit. I could go on and on about this. If you’re totally convinced that reusable code is wonderful, I probably won’t be able to sway you anyway, but you’ll never convince me that reusable code isn’t mostly a menace."
Even if you need a small part of the functionality you bring in whole library when you use it increasing your exposure.
Standard way of doing things might impede better way of doing things for each particular application. And so on...
LLMs alter nearly every parameter in every value calculation.
Future software will often have single digit dependancies and userbase of 1.
The curse actually exists in every codebase; LISP just makes it more obvious.
I previously administered a service in Python that included
- a postgres backend
- alembic to handle migrations and sqlalchemy to do ORM bindings
- strawberry to supply a GraphQL API
- an autogen library to create a Python wrapper for that API, and then additional hand-written glue atop that because the autogen had flaws.
There is some chance that if you get air-dropped into our codebase, you might be familiar with all those pieces. But if not, you still have a learning curve to get what's going on.
The only advantage Java, Python, etc. ecosystems have is popularity, which makes it more likely that someone's bespoke solution has become standard enough that you might have heard of it before. There are still probably 2 or 3 dominant frameworks that you might or might not have seen entering a new codebase (and then a bunch of special-casing and glue code to match the almost-there abstractions to the actual problem domain).
A different way to frame this would be to say: why don't we all just pick one programming language and platform and use that? It's silly to reinvent the wheel!
The answer, of course, is obvious.
Diversity of solutions is good. Heterogenous diversity of solutions is even better. Good old Mother Nature is totally unafraid of solving the same problem, multiple ways, multiple times, through completely different means. That is true system redundancy.
It was true that anybody could create anything before the advent of LLMs as well. The barrier to entry was just higher than it is now. The bar for creating some quality is still pretty much as high as it ever was.
Tech is an eternal cycle always repeating itself. For example, did you know that it was a battle to create Fortran? John Backus had to go out and convince the high priests that there was value in using a language. Just like with LLMs, it was seen as as not being able to produce expert-level-quality-output and not something for serious people. Time flows like a river, and history repeats itself.
The very nature of training an LLM seems backward-looking.
Or, as a question: has an AI gotten around to generating the Final, One True Programming Language (FOTPL) yet?
The problem is whether or not we want to view code as a medium of communication between other humans vs code as an abstract machine that solves a problem. We know that "programs" in the general sense are fairly objective entities that can be studied objectively, which is where the famous Sussman line about this comes from.
But as a language for expressing execution semantics that a machine can then execute to produce a desirable effect on the real world (a solution to a problem), we would not expect such code to be written with other humans in mind, and as lisp is a strictly more expressive language (both for expressing the meaning of an algorithm that other humans will be able to study and understand and that a machine can execute), and that more people who program are concerned with producing a solution to a problem, the "curse of lisp" is the logical conclusion.
But it's overblown. There exist many excellent and fairly complete libraries for Lisp: Closer MOP, UIOP, ASDF, Bordeaux Threads, etc. And no surprise, these libraries are virtually ubiquitous and considered (at least by me) to be more or less extensions to the language. And these libraries are written in a fairly readable style that anyone can go and try to understand the code.
Secondly, the curse isn't really much of a curse at all. It is more likely to yield more robust programs. The assumption that code reuse through libraries increases software quality doesn't really hold up in practice: libraries that are "complete" tend to add bloat to applications; managing different versions of libraries on the same platform leads to arguments about static vs. dynamic linking, and so on and so forth. Ever had to debug .so versioning bugs on Linux? It's not fun. And yet, that is par for the course if you try to persist in the notion that "libraries and code reuse is always better than reinventing the wheel".
As a reaction to the utter failures that have occurred due to following that ideology, entire programming communities have popped up to fight it, particularly the "Handmade Hero" that became Better Software Conferences as well as "Software Should Work". And while those people aren't a huge fan of Lisp, they really do embody the Lisp mindset of "don't be afraid of building your own system in your own solution's language". And this does usually yield nicer systems to work with because programming is theory building: bringing in different ready-made libraries introduces conflicting theories that requires even more glue code to rectify and the glue code rarely foresees all the discrepancies. And so bugs appear in the integrations between them.
That's not to say that increasing "the curse of lisp" always yields higher quality. The kinds of developers that make great software with that mindset are the ones that are allergic to inconsistency at any level and so squash bugs as quickly as possible and that is what leads their software to be better. But on the practical side of programming work, you feel a lot less inhibited in trying to fix bugs when you're certain you understand the code and how the implementor decided to map the problem domain onto the range of possible solutions. This is where the issue with LLMs comes in: if programming is theory building (which I firmly believe), then what we're really after with using LLMs to generate code is a more effective technique of translating high level theory of the problem into the low level code that executes to solve the problem. As such, maybe vibe coding can work if the vibe coder diligently keeps in their mind what they're after. But usually what that means is writing notes about the desirable properties of the resultant application. And then they're just back to theory building... just at a somewhat higher level.
Don't roll your own numeric libraries. There are libraries with decades of improvements to handle corner cases and increase stability. You won't create a better one, not in one lifetime.
So, yes, in some cases code reuse through libraries really does improve software quality.
It fundamentally comes down to this question: Can I, the user of this library, produce a library that is more robust for my purpose than the existing libraries? Those who say "yes" often underestimate the amount of care needed to create code that actually works - that works solidly, that is robust against failures on certain inputs.
But, you say, you don't actually have any of those inputs, so why do you care? You don't - now. But the day may come when your program is going to have to handle those inputs, and when it does, then it's your problem, because you wrote the library.
Since code is now cheap I think it is not the end of the world, but it does suck a bit for users, who may need to cobble together multiple forks.
lol but still true
1. The lisp curse is very lisp-specific because there are so many lisp implementations. But you essentially only have one major rust/ruby/php/java/perl/erlang implementation. Languages like C/C++ only have two major implementations (gcc,llvm/clang).
2. I see so many projects every day where developers pull in gigabytes of software only to use a small number of features. Don’t even get me started on the whole left-pad clown show. Gigabytes of libraries pulled left and right only to use a few megabytes at most.
I disagree generally, and the problem is two fold..
I've just seen "well-defined" abstractions go wrong too many times. Over- encapsulation, over-abstraction, or just overall over-cleverness in third party packages that has led me to spend large parts of my career just frustrated trying to glue third party dependencies together in a sensible way... and the abstractions only adding complication.
The joy and temptation of having an LLM "just make it" is that this goes away. The functionality fits my existing structure and abstractions and I'm not fighting a war with the architecture that the third party maintainer decided worked best for them. And getting only the parts I need, not your whole giant framework with it. (And yes, I know the LLM could easily hallucinate something far far worse, but let's just... play pretend here for a minute)
The second part is that since the dawn of Maven, NPM, Crates.io generally there has just been this insane explosion in programs of transitive third party dependencies out into the stratosphere, and the cognitive, technical, and legal debt of so many deps generally is not sufficiently recognized by the community. Running "cargo tree" in my project is often frankly depressing. Multiple linked MD5/SHA256 implementations, random number generators, HTTP protocols, people dragging in tokio deps where I don't want them, multiple versions of the same thing compiled and linked... It's exceedingly frustrating, and with the explosion of security concerns we've seen recently, it's also potentially dangerous.
I don't love the idea of having LLMs "just yeet it" esp if people misapply this to things like security/cryptography domains. But I'm also more than skeptical about the actual real world quality of many hallowed third party packages. I've been burned too many times.
Perhaps potentially what replaces "widely used standard implementation of X in a library/npm/crate form" is an "LLM readable recipe for X along with a formal proof / automated test scenario that I can point my clanker at to get a community proven way of doing this" along with a set of prompts, licensing/credit requirements, etc.