Remix.run Logo
▲ Why Common Lisp is now the best programming language(vivienhenz.com)
113 points by misterchocolat 4 hours ago | 158 comments
▲peri-cl 17 minutes ago | parent | next [-]

Lots of comments praising LLM's understanding of Common Lisp macros. I've seen them break badly at the macros-writing-macros level. I saw a current frontier model get so disoriented by one (a simple one!), it created something that expanded into a "(let (((".

(That's an impossible count (3) of parentheses on the RHS—like a six-fingered hand).

▲WalterBright 24 minutes ago | parent | prev | next [-]

> Lisp programs are often much more concise because macros let you abstract away recurring patterns and make them part of the language itself

This is why Lisp never catches on. Each programmer invents their own ad-hoc, undocumented, barely working language in the form of those macros. The same thing happens in other languages with macros (like C and assembler).

▲stackghost 4 minutes ago | parent [-]

>This is why Lisp never catches on.

>[…]The same thing happens in other languages with macros (like C and assembler).

Uh, C definitely caught on.

▲alexjurkiewicz 2 hours ago | parent | prev | next [-]

I think half the article talks about why CL is good because it can resume from an exception, and half the article talks about why DSLs are good.

I think others have pointed out that most modern scripting languages can halt at exceptions without unwinding the stack. Python & Node both support this with core tooling.

As for DSLs, they constrain the LLM which generally helps with code quality. However why implement your DSL in the unconstrained chaos of CL? You can write DSLs in Rust which gives you static typing, a borrow checker, and clippy.

▲marviter an hour ago | parent | next [-]

Common Lisp has these capabilities _without_ dev tooling, via its:

- Conditions[0]

- Evaluation and Compilation[1]

I use both extensively while developing, debugging and analysing. With SLIME (this is a standard and very very slimmed out development aid) you add a debugger hook that allows restart, return from, move down, move up and etc into your available RESTARTs.

[0] https://www.lispworks.com/documentation/HyperSpec/Body/09_.h...

[1] https://www.lispworks.com/documentation/HyperSpec/Body/03_.h...

▲baq an hour ago | parent | prev [-]

What’s missing in most languages is truly native hot reload. Python, for all its dynamicism and being lisp for dictionaries, surprisingly can’t really do it. Maybe node can, but as far as I can tell typescript can’t and I’m not letting the shoggoths touch plain js.

▲gblargg 40 minutes ago | parent | next [-]

I've never understood this. You can't just combine the state of an old program with new code, without lots of weird things potentially happening. The algorithms and all intermediate products would have to match, at every step of the programs.

▲baq 31 minutes ago | parent [-]

That’s why working with lisp feels like touching alien tech - it works, it’s designed for that exact workflow.

(It’s also essentially pointless when your unit of deployment is a disposable container and not a long running lisp system, but it at least makes development a bit nicer)

▲cyberax an hour ago | parent | prev [-]

Uhh.... TS/JS definitely can: https://bjornlu.com/blog/hot-module-replacement-is-easy

▲kelnos 32 minutes ago | parent | prev | next [-]

I feel like everyone has some sort of justification for why their pet language is now the best because LLMs can work in it better for a bunch of reasons.

Javascript/Python is the best because there's so much code out there that the LLMs can train on, and LLMs can write lots of tests to make sure everything is correct. There's nothing to compile, so the LLM can iterate quickly.

Rust is the best because the LLM gets great feedback from the compiler because of its strong type system, and it can deal with the borrow checker for you.

Go is the best because it's a simpler language with a decent type system, and the LLM can reason about that well, and will never forget to check an `err` return. The compiler is fast, so the LLM can iterate quickly.

I could write similar praise for C, C++, Java...

At this point I don't think any language is the best "because LLMs". I think there are quite a few languages that LLMs are probably not good at, but you have lots of choices if you want something they are good at.

▲jaggederest 2 hours ago | parent | prev | next [-]

I've had some of the same ideas, I would love a full macro system on a dependently typed language. My stab at it earlier in January was not quite the right thing, but I do think this is the way. Weirdly enough concision is even more important in LLM context than in regular human context.

▲6gvONxR4sf7o 2 hours ago | parent | next [-]

You might be interested in Lean. It's my favorite lisp, even though it's really not at all a lisp. It's a nice programming language, and it lets you really hack on commands, macros, syntax, and elaboration.

▲ducktective an hour ago | parent [-]

It's often suggested that Lean is a general programming language but I don't see typical libraries to do basic stuff in it, like an arg parser, web server, GUI, SQL integrations etc.

Can lean generate small static binaries the same way Go/Rust/C/C++ can?

How practical is rewriting, say, grep in Lean?

▲hargup 28 minutes ago | parent [-]

Building a suite of libraries for basic stuff like webserver, sql integration, writing react components etc in Lean here https://github.com/orgs/theoriclabs/repositories?q=sort%3Ast...

> Can lean generate small static binaries the same way Go/Rust/C/C++ can?

Lean compiles to C and the binaries aren't huge, though haven't benchmarked this part yet.

> How practical is rewriting, say, grep in Lean?

Very, you should probably try it.

▲dang 2 hours ago | parent | prev | next [-]

One thing that has surprised me is how good LLMs are writing Lisp macros. All the annoying boilerplate and backtick-comma arithmetic (',' anyone?) that has ground my gears over the years, they cheerfully churn out correctly. I still review it to make sure they haven't done it in a needlessly complicated way, but I wonder if that is just me being superstitious.

I shouldn't have been surprised, because that part of macro writing is purely mechanical syntax transformation—just a "take these tokens and return those tokens" function that one should expect LLMs to be good at. But I was surprised, because for me that was always the hard part.

So now I can think up new macros to abstract over patterns in my code—the part of macro-writing that I enjoy—and then push a magic "implement this" button to make it work.

What I'm not sure of yet is whether this is an evolutionary dead end—a train stop on the way to "you'll never look at code again, so what does it matter what programming language you used to use". Yes, I still look at my code, and this is a pretty nice train stop, wherever the tracks lead to.

▲gr_norm an hour ago | parent | prev | next [-]

Lean is the dependently typed language with a SotA metaprogramming system. Lean itself is a language written using this system.

▲hargup 27 minutes ago | parent [-]

+1

▲sroerick 2 hours ago | parent | prev [-]

Have you looked into tree calculus at all?

▲onion2k an hour ago | parent | prev | next [-]

For LLMs, less code means fewer tokens, and tokens are what you pay for so you spend less on development.

I don't think that's strictly true.

What you need is for your LLM to be able to understand enough context to be able to make a change with as few token as possible, so if your code isn't expressive enough or if it has a tendrils calling lots of different functions/methods all over the place, then you'll have to give it much more code (context) than if you've got nice encapsulated modules that don't depend on other parts.

The design of your architecture (probably?) has a greater impact on token use in a large app than the language it's written in. Although, obviously, languages lend themselves to particular architectures so it's correlated.

▲teleforce an hour ago | parent | next [-]

>What you need is for your LLM to be able to understand enough context to be able to make a change with as few token as possible, so if your code isn't expressive enough

Recently there's an article on language plasticity in the era of AI/LLM and why D language is very well suited for this era [1].

Perhaps we need a proper benchmark similar to Beaver but for AI assisted coding for different programming languages instead of Text-to-SQL [2].

[1] Language Plasticity is More Important Than Ever:

https://blog.dlang.org/2026/08/10/language-plasticity-is-mor...

[2] BEAVER: An Enterprise Benchmark for Text-to-SQL:

https://beaverbench.github.io/#overview

▲seer an hour ago | parent | prev | next [-]

I remember the old discussion between clojure programmers and someone who works in a strongly typed language. The argument was “types allow you to be certain that if you change some code, an unrelated but affected part of the codebase will also be flagged and it is not missed” the clojure guy response was “why would you ever design a program where a change in one place affects the other”.

I do think this is an unrelated win of functional languages that hasn’t yet been “discovered” by the vibe coder crowd - FP’s whole premise was that it makes your code depend on much much less things so you can “fit it in your head and reason about”… that’s like the perfect sweet spot for agentic as well, we just haven’t seen tools utilize that in earnest.

▲groestl 44 minutes ago | parent [-]

> why would you ever design a program where a change in one place affects the other

If that would be possible, there would be no function signatures.

▲DanHulton 40 minutes ago | parent | prev | next [-]

Additionally, if there’s more “knowledge” of the code and best practices and such baked into your model, it has to spend fewer tokens reasoning about it or even potentially looking it up. I think even one web search to retrieve additional information not also in the model will probably blow up any supposed benefit you’d get by a slightly more token-efficient language.

▲onion2k 9 minutes ago | parent [-]

That could be mitigated by using a much smaller non-reasoning model for searches and reading. There's no reason why a search should take loads of tokens.

▲asxndu an hour ago | parent | prev [-]

APL would win in that regard.

▲clx75 an hour ago | parent | prev | next [-]

I have similar experiences in Clojure. I use Pi and created an extension which teaches the LLM how to start a JVM with a Clojure nREPL listening in it. Added a tool which lets the agent evaluate any Clojure form inside the JVM. Sprinkled the setup with clj-reload and now the agent is using the nREPL as if it were its second nature.

What I like most is how fast testing goes: it modifies test code on disk, asks clj-reload to reload all affected namespaces, then reruns the tests. It's also fun to see how it verifies its assumptions by evaluating short programs through the nREPL.

I asked it to organize the various subsystems inside my playground repo into Integrant systems and make it possible for me to say things like "restart the http subsystem".

It also understands shadow-cljs: I replicated the necessary parts of the shadow CLI tooling in Clojure; now I can compile, watch and serve any number of CLJS apps located in various namespaces from inside the same JVM. There is no need to touch the command line any more: I just instruct the agent to start a particular CLJS app and it's there.

▲chartered_stack 5 minutes ago | parent | next [-]

I came across a very similar project recently.

https://github.com/DeadMeme5441/arrodes

It seems to be a bit more integrated than what you describe here because it's completely built around a Clojure REPL

▲miroljub 43 minutes ago | parent | prev [-]

Which extension do you use?

▲clx75 12 minutes ago | parent [-]

I developed my own:

https://github.com/cellux/pi-extensions/tree/master/extensio...

Note that this may not work for you standalone as it relies on my other agent-sandbox extension (which ensures all agent operations happen inside a sandbox container).

But point an LLM to its source code and it will extract the gist of it.

▲Hobrot 6 minutes ago | parent | prev | next [-]

AI needs a new Lisp Machine (like but not equal), the future computing principal part should be AI rather than human, env should be abstracted to AI.

▲artpar 29 minutes ago | parent | prev | next [-]

> because writing code used to be the slow part

I don't understand how people have that stated as a fact. Coding was never the slow part. Neither pre-llm, nor now. How it needs to be done is software engineering. And that corresponds now to the "thinking" part of llms, so unless you are making the llm "think in lisp" its not useful. How would that even work. training data to be completely in lisp ?

> Lisp programs are often much more concise because macros let you abstract away recurring patterns and make them part of the language itself

functions ?

> So the bigger the program gets, the bigger the difference. In my own experience the apps I've built in Common Lisp end up about six to seven times shorter than the Python versions

By that logic writing code in this concept language made up completely of symbols would take you even further ( https://github.com/artpar/guage ) but in practice it doesnt because llms arent trained to that extent on this.

▲miohtama 16 minutes ago | parent | prev | next [-]

Lisp has existed more than 50 years, more than most programming languages.

If it were a good programming language people would be using it more at this point.

▲stevoski 29 minutes ago | parent | prev | next [-]

I remember this guy back in the dotcom boom days, more than 25 years ago, who made an app that got acquired by Yahoo.

He claimed that Common Lisp was the best programming language for web apps, and that it gave him a massive advantage in creating his app.

What was his name again? Paul something? Oh yeah, Paul Graham.

▲librasteve 33 minutes ago | parent | prev | next [-]

Soon, hopefully, we will have evidence based analysis of those programming languages best suited for LLM authoring. Fwiw I doubt that CL will make the cut - but happy to be proven wrong. Obviously a large factor remains the facility of the human driver for a particular language.

Until then, I subscribe to the view that strong types fit LLM coding well since LLMs are prone to make silly mistakes when they patch together code examples in dynamic languages.

[Disclosure, my new language https://bil-lang.org aims to add “strong typing” around parallel programming to help weed out deadlock conditions.]

▲mstep 2 hours ago | parent | prev | next [-]

related: https://opusmodus.com/forums/blogs/entry/4-connecting-an-ai-...

▲gorgoiler 2 hours ago | parent | prev | next [-]

”Would you agree that some programming languages are better than others? If so then one of them must be the best.”

False. A partial ordering doesn’t guarantee a maximum element!

▲misterchocolat 2 hours ago | parent [-]

Fair enough haha you got me

▲Revanche1367 9 minutes ago | parent | prev | next [-]

A very big claim backed with poor arguments and easily disputed evidence.

▲SolubleSnake an hour ago | parent | prev | next [-]

An ERP system in...LISP? None of the reasons given as to why that would be a good idea are really very convincing or specific to LISP?

The main things you want for ERP are just to simplify database interactions as far as possible and to give you as many and as customizable options as possible for data visualization and curating information for a non techie user. I dont really get why LISP?

▲copperx 2 minutes ago | parent [-]

[delayed]

▲long____cat 18 minutes ago | parent | prev | next [-]

Autolith is great with LLMs exactly because it's written in Common Lisp.

https://autolith.rocks

▲varjag 29 minutes ago | parent | prev | next [-]

I use agents heavily on Common Lisp in some parts of production projects. Typically Codex on whatever is the current top model with vibe-patched Tron MCP. REPL-based agent development via MCP does feel faster but I haven't ever bothered to benchmark it.

▲brainless 15 minutes ago | parent | prev | next [-]

I am not an expert, just an engineer with years of experience. I switched to Rust a couple years ago. I was still learning before LLM generated Rust was good enough that I stopped coding by hand.

Again, not a language expert, but: if you can describe your domain or business logic as clearly as a strongly typed language with a rich type system, most of your issues are gone. Enum and Struct with all the other core types plus the match expressions does most of my mental heavy lifting. I do not even track any of the recent language changes.

What I really care about is the shape of what I am describing - does it translate to code? How much do I lose in the translation? I want to try other languages, particularly Lisp but Rust is at this moment my choice. I have my own UI framework (1), my own provenance based business domain generator and a few simple language parsers.

I am building apps where you can, for example, throw a CSV file (2), ask questions in English and get answers - without using an LLM. Parser. Rust is no doubt a great language to express - not as a programmer, but as a prompter. I do not write the code. I ask LLMs to generate it using only basic knowledge of Rust and its type system. This will be the key to work with LLMs for majority of people.

1. https://github.com/brainless/akar

2. https://github.com/brainless/baho

▲pulkitbanta an hour ago | parent | prev | next [-]

Are you saying this based on the fact that no-one will read or understand the code manually? That might be the case but on some areas, having a product understanding and knowing what to build, why to build matters a lot and sometimes the LLMs will write code that is not correct, doesn't make sense and they will continue down that path without explaining it.

I still believe that other languages which are understood by developers are and will be required and LLMs are trained on the same dataset so it can write the code.

▲thenoblesunfish an hour ago | parent | prev | next [-]

It seems like an assumption here is that any language will be equally performant at runtime, for a given number of tokens burned to produce the code. I have never used any functional language for anything real (except maybe Mathematica). Is that true?

▲Jach an hour ago | parent | next [-]

Bad performance is much less excusable these days (https://danluu.com/perf-opt/) and usually it's more the result of architecture and data structure choice than presence/absence of things out of the box of some language (though in the case of C++, it seems that everyone who gets obsessed with performance just says to avoid the included stdlib no matter the compiler; so much for that box). Your question seems to me to betray an assumption that Common Lisp is particularly functional (and overall suffers from some sort of functional programming performance trade-offs), when it's not. Common Lisp is unopinionated, multi-paradigm, but at its core is mutation-friendly, compilation friendly (compile is a function available to call at runtime), and object-oriented (CLOS being the first ANSI standardized OOP system, it's more flexible than most OO systems and methods do not belong to classes). There are also many implementations of Common Lisp, including two long-standing commercial ones, so should performance (whether raw throughput, or memory size, or whatever your metrics) not quite be to your liking out of the box with one, you might consider another before giving up and choosing an entirely different language or spending time/tokens trying to better optimize your existing code. That said, SBCL is probably the most popular, and has a pretty sophisticated optimizing compiler that produces pretty fast native code by default, while allowing you to specify your own assembly ops without actually having to write separate assembly files. (You can specify the assembly with more Lisp code.) See for instance https://www.stylewarning.com/posts/nbody/

▲stackghost an hour ago | parent | prev [-]

Common Lisp is not a functional language. You can write functional-paradigm code in CL but it will happily let you write old-school imperative style, OOP, etc.

The de facto open source implementation, SBCL, has a solid compiler and garbage collector. It produces fast code.

▲Karrot_Kream 2 hours ago | parent | prev | next [-]

I keep bouncing the idea around of building a core in C or Rust then writing everything atop it using Janet. I love how readable lisps are (with macros, you can really move up the abstraction ladder quickly) and working on a live image should make iteration a breeze in an LLM.

▲phillc73 20 minutes ago | parent | next [-]

Interesting take and similar to something I've recently been working on. Have a look at janet-num.[1] Plain numeric C kernels under Janet.

Janet for orchestration, C for the frame loop.

[1] https://github.com/jennystats/janet-num

▲sroerick 26 minutes ago | parent | prev | next [-]

https://pricklypear.rocks/

Folks have found it useful to just point gippity at the page and ask questions

▲sroerick an hour ago | parent | prev [-]

I built a OCaml core with a webserver - then made my scripting language on top a custom scheme. I love your idea! I think you would find that a solid interpreted language living in a webserver is an extremely useful think to have. Let me know if you build it!

▲Karrot_Kream 38 minutes ago | parent [-]

What did you write with your webserver? Hosting a personal blog? I'm thinking of a good usecase for this. I'm thinking about a game of some sort but not sure yet.

▲sroerick 29 minutes ago | parent [-]

I've just been dogfooding whatever I can to build it out.

Webpages, zettelkasten, todo, workout, diet tracker. It's a web framework! Creating an endpoint is just like making a function in emacs.

Since lisp is homoiconic the AST is just raw JSON. I save the AST in JSON stores in Postgres. But you can clone the AST down and then eval against a local copy of the REPl. So you get local eval for free.

Of course you have to rebuild git to manage a branching REPL in this way.

▲qalmakka an hour ago | parent | prev | next [-]

I don't really agree with this. Having strong types and guardrails like in Haskell, Rust or OCaml helps _massively_ with LLMs because they get very clear messages back, and can express their logic using semantic types they can easily follow. Conversely, I've noticed that AIs (just like humans) tend to kind of lose the thread with very dynamic code

▲pseudony 10 minutes ago | parent | next [-]

And I think this point is a poor as any made in the article.

Last I attempted to write some smaller ocaml project I used LLMs for support (but wrote myself). They generally weren’t excellent.

Honestly, types don’t help as much as people want them to. The LLM does best on popular languages, especially those whose use and feel is also mainstream.

That is to say, pick a niche language like Odin, and it may incorrectly start to over-apply Go’isms - knowledge from one language bleeds into how it approaches others.

▲sroerick 22 minutes ago | parent | prev | next [-]

OCaml core + interpreted Lisp on top really feels like total enlightment, I have to say.

The dynamic features you get with a full blown REPL are, in some specific cases, worth the trade off you get by losing the guardrails (which I call Rubber Baby Buggy Bumpers).

You're right though - strong typing feels like a cheat code.

▲brabel 3 minutes ago | parent | prev | next [-]

What the heck this thread is about, Common Lisp has types and you can use them in ways most strongly typed languages wouldn’t let you! They are basically expressions, which gives a lot of flexibility. It may not be always checked statically, but in practice SBCL does a great job at doing it or at least emitting warnings when it can’t prove the code will fail at runtime.

Also if you really want Haskell types you can use Coalton, which is essentially Common Lisp with Haskell types, but lets you interop with Common Lisp seamlessly as Kotlin with Java.

▲unprovable 21 minutes ago | parent | prev | next [-]

Absolutely this. Plus, LLMs are surprisingly adept (in my experience) at handling gnarly syntactic corners of most widespread strongly typed languages, esp. C++ and Rust.

▲nylonstrung an hour ago | parent | prev | next [-]

I've found the same: strong types are disproportionately valuable in LLM coding vs human coding because they essentially function as context and the typechecker actively enforces correctness

▲WalterBright 27 minutes ago | parent | next [-]

In aviation, there is the notion of "dual path", which means two ways to do anything. Each functions as a backup to the other.

The best dual path systems are when they use different technology. Hence, an error in one is highly unlikely to infect the other.

This is what static typing provides.

▲ozim 15 minutes ago | parent [-]

I guess people who are against static typing are not working on aviation type projects - more like worst thing that can happen on what they work is a div slightly off.

▲groestl an hour ago | parent | prev | next [-]

It's basically a myriad of unit tests without writing them down (in full).

▲georgemcbay 35 minutes ago | parent | prev | next [-]

> strong types are disproportionately valuable in LLM coding vs human coding because they essentially function as context and the typechecker actively enforces correctness

One could argue that this was a large benefit for human coding long before LLMs became useful.

It is why I always preferred strongly-typed languages.

And once we had practical strongly-typed languages with implicit type inference I really couldn't wrap my head around why anyone would prefer dynamic typing other than just inertia due to that being what they were used to.

▲IshKebab 22 minutes ago | parent | prev [-]

I wouldn't say it's disproportionate. Strong static typing is massively valuable for humans too. Maybe it's just more obvious to some people because you actually can write the same large program twice using the same "person" and a different language.

Previously studies into the benefits of static typing for humans were always a bit flawed because you can't do that with people. And tbh I don't know why but there are a surprising number of people that don't appreciate static typing. My guess is a combination of ego and laziness, which doesn't apply to LLMs.

▲xlii 33 minutes ago | parent | prev | next [-]

And there is a super power to it.

It's possible to write the whole system only by defining the types.

The "glue" can be sloppy but as long as it keeps on the edges the output is most often fine.

Recently I'm on the fence about Rust vs OCaml (but plan to write about it soon) because I have ~700k LoC in Rust but my workflow starts to get seriously dragged down by compilation/tests in isolated worktrees.

I recently also dab with Gluon (as embeddable type safe scripting) and rule-based-development for maximum code control/agents output leverage.

▲sroerick 22 minutes ago | parent [-]

OCaml is really good.

▲sheepscreek 44 minutes ago | parent | prev [-]

Yes! Maybe the current limitation is due to their limited context and frequent compaction. Where they can lose track of (abc-xyz A B) and what A and B need to be.

I’m not sure if the Common Lisp compiler can be very helpful either, since it’s a dynamic language and A and B could be many different types (duck typing).

Strong types are the way to go, at least for now.

▲Jach 10 minutes ago | parent [-]

CL is strongly typed. It is quite refreshing to not have to worry about implicit type conversion (or worse) all over the place, unlike some other languages...

Type declarations are also optional and compilers can create compile-time warnings about them. Thus for many trivial cases, when using SBCL some obviously wrong types, or typos, or miscounted arguments, can be caught ahead of time without having to execute code. CL is also not duck typed. If abc-xyz is a generic function, selecting which method to call relies on the actual class hierarchy of the given A and B objects, there's no "duck shape" shenanigans.

For static types, well, CL is flexible enough to bolt such a system on top as a library, where you'll have a full ML/Haskell style type system. https://coalton-lang.github.io/ But it seems the relevance for LLMs is rather mixed, much like studies from the last few decades on static/dynamic typing in general: https://danluu.com/pl-tokens/

▲nickm12 an hour ago | parent | prev | next [-]

This post reads like it was written by a Common Lisp fan who is looking for a reasons to say that Common Lisp is good for AI agents, rather than an AI agent user evaluating what languages are really best.

I've heard fans of both statically typed and dynamically typed languages advocate for their language. The static type fans say that the rigorous compilation process gives the LLM a fast iteration loop with clear messages from the compiler on what invariants aren't being upheld. The dynamically typed languages advocates talk about fewer tokens, the popularity of the language in the training data, and so forth. Guess what, these are the exact same arguments these communities made for human developers.

Personally, I don't know the answer. The industry has swung back and forth on this over the decades. Before AI code-gen static languages were on the upswing for a variety of reasons, including runtime efficiency and much better ergonomics thanks to modern type inference engines. I suspect those reasons are still valid, and also that statically typed languages give LLMs a leg up because it is easier to reason about them locally thanks to declared types and information hiding.

▲sroerick an hour ago | parent [-]

Yeah, I mean it's tough to describe how good it is to use agents with a lisp REPL, but it's really great using agents with a Lisp REPL.

▲cookiengineer 37 minutes ago | parent | prev | next [-]

This is written by a person who never used LLMs.

LLMs need a language that:

- has opinions about how to write standard code

- has opinions about one way of formatting and codestyle

- has opinions about linting and integrated debugging

- has predictable strong types

- has opinions about integrated unit testing and a standard way to write them

- has an integrated toolchain

- has a strong stdlib and an upstreamed way to unify libraries

- (recommended) has a standard project layout _where_ to put its code (types, structs, helpers, utils, etc)

Go and Rust fit all these checkmarks except the last one. That's why those languages don't need kilometer long prompts to tell the LLM how to write code. Most of the prompting in those languages focuses around architecture and design, and not about style, tooling, or other artificially vague decisions.

Lisp is the most unopinionated language there is, therefore it is the worst in terms of lack of decisions encoded in its tooling.

And I'm not writing that as an opponent of the language, I've written scheme bindings for a couple of years in (academic) robotics.

The point that I am making here is that you _need_ an opinionated language for an LLM to make sense. Write linters and tools before code [1].

[1] https://cookie.engineer/weblog/articles/write-linters-and-to...

▲ellg 2 hours ago | parent | prev | next [-]

cant you do most of this with smalltalk too, or erlang?

I dont really understand what macros get you when llms exist since a llm doesnt really need to create dsls to get work done

▲0xpgm 2 hours ago | parent | next [-]

Presumably a DSL would allow you to do more heavy lifting in your specific domain with less tokens.

Let's way you wanted to do a web application using LLMs. Using a web framework would cost less tokens than using the vanilla underlying language (Python, PHP, whatever..), which is again way less tokens than building up from assembly (an LLM should be able to do this given enough time and compute).

▲dang an hour ago | parent [-]

I hadn't thought of that! Writing a program in fewer tokens* has been Lisp's advantage all along. If, because of token economics, the same advantage accrued at the LLM level, I dare say certain people would be pleased (as would I):

https://news.ycombinator.com/item?id=21232352 (Oct 2019)

https://news.ycombinator.com/item?id=4766191 (Nov 2012)

https://news.ycombinator.com/item?id=694700 (July 2009)

* in the older sense of "token", meaning that one measures a program in AST size rather than lines of code

---

Edit: ok, this is what I get for not reading the article:

> For LLMs, less code means fewer tokens, and tokens are what you pay for so you spend less on development

▲Karrot_Kream an hour ago | parent | prev | next [-]

Readability for yourself. I find the biggest issue with lots of LLM assisted development is that the agent harness can generate code faster than I can read it. I'm the bottleneck.

There's a "zen" moment felt by folks who've written lots of macros (experienced in Lisps and Forths) where, when designed properly, you really feel like you've "grown" a language and have really walked up the abstraction ladder. My thesis is that macro heavy code when the author designs the macros well are very readable. That an agent's output when stacked upon macros can be a lot simpler to read and understand than in languages where the syntax is less fungible. And if you leave a project for a while and come back, an agent is a perfect tool to help you read your macros and familiarize yourself with the abstraction surface again.

Just a theory though.

▲misterchocolat 2 hours ago | parent | prev | next [-]

sure I agree the LLM doesn't need a DSL to get work done. The point is more that the DSL holds the opinions of whoever built the product

▲UncleOxidant 2 hours ago | parent | prev | next [-]

I think what they're saying is that in CL you create DSLs that are tailored for the domain and that will result in lower token use. Not sure about that claim, would like to see some data to backup that assertion. Wouldn't you then need to supply the LLM with a "programming manual" for this new DSL? Wouldn't that cost tokens?

▲invalidOrTaken 2 hours ago | parent | next [-]

sure, but input tokens are way cheaper than output.

There is also a phenomenon I've named "brevity collapse." Often, when shrinking a codebase, you find you need less glue. Additionally, because it is smaller, you can hold more of it in your head and see more opportunities for shrinkage. Surprising things happen when the bones of your language get more efficient---it's more like going from elephant to flea than elephant to grizzly bear. The smaller scale means there's less "overhead" code, which means you can go smaller still.

▲ellg 2 hours ago | parent | prev [-]

im saying the inverse, if your thesis is "cl is the best language for AI" I dont think macros really are a killer feature here

I agree with your point

▲jaggederest 2 hours ago | parent | prev [-]

Smalltalk, in image based systems, absolutely. Erlang not as much, it's more of a "crash the actor and try again" than "rewind, pause, and handle errors in-system"

▲dexterlagan 39 minutes ago | parent | prev | next [-]

Seems to be written by somebody who has never worked within a team, never published a commercial piece of software (with the said team), and never used an LLM to write code. How is that possible? I love Common List and Racket. Love them to bits. I'd use them all day every day if it weren’t for that pesky LISP curse and the fact that nobody would want to work with me. LLMs, until recently were consistently forgetting parens, couldn't close functions properly. Somehow LLMs can't really count in their head, so it makes for a really... fun time with LISPs.

▲drivebyhooting 2 hours ago | parent | prev | next [-]

Won’t you have to write entire stacks of code from scratch for lack of prior art in CL?

▲Jach 41 minutes ago | parent | next [-]

While the open source library ecosystem for CL pales in comparison to Python's or JS's or Java's (or even Julia's, if you talk about certain domain specific stuff), it's not like there's nothing. It really depends on what you're doing, but many sorts of common tasks have a library to help. https://github.com/CodyReichert/awesome-cl Plus, it's straightforward to make use of libraries with a C API, there are a few slower ways to call out to Python libraries, and there's a whole CL implementation built on the JVM if you really need Java libraries...

▲literalAardvark an hour ago | parent | prev [-]

Common misconception but no.

The models learned to code, the actual language is just a tiny adapter on top.

▲ball_of_lint 18 minutes ago | parent | prev | next [-]

Lots of bad reasoning in this article.

So long as your feedback loop isn't slow enough to be taking you out of flow, it's fast enough. Having it be a few seconds vs a few hundred milliseconds mostly doesn't matter for a human, and will matter even less for an LLM.

On macros and DSLs, yes they're cool and even useful sometimes, but most of the software industry is working quite happily without them. And LLMs aren't going to change that because they are best when there's a lot of relevant patterns in their training data. That ends up being a far more important factor in their effectiveness than whether the language itself is token-efficient. It's much easier for an LLM to reason through how to do XYZ in Python where it already knows all the semantics and syntax than it is for it to do it in your DSL it's never seen before. To be clear, it can probably do both but will make mistakes an order of magnitude more in the DSL, and that's what will matter most for the LLM iteration time.

▲rspeele 2 hours ago | parent | prev | next [-]

I recently wrote a comment on another thread that I think fits even better here:

In my circles I've noticed it's very easy for us to rationalize why our previous favorite language is also the perfect language for the agent era.

If your favorite language before was Python, why, LLMs are fluent in it! So much training data! So many libraries! Home of machine learning! None of that pesky compile time, agents don't need compile time safety anyway, they write such good test coverage! It's The Perfect Agentic Coding Language.

If it was Rust, by jove, an agent can easily handle the headache of satisfying the borrow checker, and now you get the best of all worlds! Safety! Near-C runtime performance! Abstractions! The only reason people didn't use Rust before was it was Too Hard and there were Too Many Furries and now it's not hard and you don't have to interact with them, so get on board. It's The Perfect Agentic Coding Language.

If it was Golang, oh my goodness, what a choice. Pretty fast compile time and pretty fast runtime. Agents get a tight feedback loop with build->run->test->edit. Not very complicated, code has to be written in a straightforward banging-rocks-together way. Good stable ecosystem! Rob Pike designed the language for people he said were "not capable of understanding a brilliant language but we want to use them to build good software." That's an arrogant, demeaning way to describe your colleagues but if they're LLM agents it's dead on! It's The Perfect Agentic Coding Language.

I could go on and on. I'm not immune either! My own favorite language is F# and when I feel like self-justifying, I play the same game:

It has access to the .NET ecosystem like C#, but I don't have to constantly remind the agents to prefer a style with immutable data and pure functions, they idiomatically do that in F#. Files have to be in order and can only refer to symbols defined "earlier" in order, if you want mutually-referential types or functions they have to be declared as such in a joint statement, so spaghetti is hard to create: each project's codebase naturally ends up in a layered bottom-to-top architecture. The language is terse enough to be token efficient, without being symbol soup. FSX scripts can be generated during agentic code reviews to demonstrate repros for discovered issues. If there's any type of code that still warrants me jumping in and writing some myself, that code would be data type definitions/domain modelling, and F# is a joy to write those in. It's The Perfect Agentic Coding Language.

▲sshine an hour ago | parent | next [-]

Why, you are right on all of these. I used Rust a lot before AI, and I use it a lot after. But I recognise the shortcoming of long compilation: it doesn't just shorten how many times I can have feedback in one day, it is also difficult to fit compilation into constrained environments. Like when an ultra secure Kubernetes cluster doesn't let me compile source code anywhere near it, and I have to compile inside of it; my colleagues insistence on using Go here because "Rust is difficult" (it surely is 100% longer to type when prompting an LLM) really has the main benefit that this code compiles fast and easily within the cluster.

So picking languages for their compilation and especially runtime properties is key.

What I've learned, though, is that languages with reckless error handling produce more errors at runtime. My Rust programs just don't crash because I don't need it to be explicit about reaching a "total" approach.

If you're in a C# environment, I see a case for F#. And if you want fast but more solid than Python, why not Mojo? Although who reads code.

This article convinces me. But I suspect like my lack of domain knowledge of Lisp makes me spend time learning the runtime: how and when can I switch to JIT, what's the async story, how does the harness become part of the Lisp program, etc.

▲sroerick an hour ago | parent | prev | next [-]

But no seriously F# might actually be the perfect agentic coding language. I had the good fortune of learning OCaml a few years ago as the models were getting good. Had a blast.

I think Lisp and an ML are kind of the dynamic (static) duo. I still think MLs are the best for complex projects, but interpreted languages are pretty neat too. Python, Rust, and Golang are all great, also.

I think a tree calculus language might be the actual best - but it's too soon to say

Really, languages are great for LLMs.

▲mod50ack an hour ago | parent | prev | next [-]

The truth is that it really doesn't matter that much.

Use the language that you like (enjoy your favorites!) and that binds well with other tools you're using. I'm currently working on a project that's all C++ (wxWidgets frontend, plus C++ backend). I've used LLM tools with it, no issues. Would be the same with any other language, from what I can tell. I have another project in Go I'll probably try it on at some point soon.

▲ChadNauseam an hour ago | parent | prev | next [-]

I must be proving your point because I'm a rust head and the argument you gave for rust just seems like the best one haha. And if I had the choice between two vibe-coded pieces of software, and one was written in rust and the other was written in python, I would far prefer to use the rust one.

▲tommica an hour ago | parent | prev | next [-]

Spot on! People do really enjoy NOT having to change. We can come up with many excuses why we do not have to do anything different. I'm finding multiple rrasons why I should stick to laravel.

Could be said that it was the path of least resistance, but the funny thing is that most of that resistance is you just being in your own way.

▲literalAardvark an hour ago | parent | prev | next [-]

I hated Rust before because it reminded me how inadequate a programmer I am.

It's probably the best language for AI coding though. By far, as far as I can tell.

▲prophesi an hour ago | parent | prev | next [-]

So now we're believing it's great that LLM's can write macros, thus further obfuscating human maintenance of the code-base, because LLM's can understand and implement it than better than humans.

This isn't the future I wanted, and is why I advocate for trade schools these days.

I miss the days I could listen to music and use my adhd/autism to its fullest potential reading documentation and figuring things out myself.

Of course, these are same people you'd want managing these AI agents in the first place, but reviewing code written by others always kind of sucks, especially when it's assumed the language model knows better than you do which isn't often the case!

Was the PRD perfected on the requirements? Only God knows, and I personally want to be there when it's written.

▲sroerick an hour ago | parent | prev [-]

I noticed you left typescript out

▲insin an hour ago | parent [-]

A strange omission given that it's also The Perfect Agentic Coding Language.

▲bitwize 2 hours ago | parent | prev | next [-]

Astronaut 1: So... now Lisp is the best programming language?

Astronaut 2: Always has been...

▲GuestFAUniverse an hour ago | parent | prev | next [-]

Zero visible experience with CL on top of a project list where half of the links give a 404. Others are unmaintained slop output. Sprinkled with Paul Graham references and the Harvard badge.

Sorry, I'm not impressed. How did that /run/ to the top of HN? [pun intended]

"Vorschusslorbeeren"? A clique of voters?

Boring.

▲VikramBhamre 2 hours ago | parent | prev | next [-]

I mean its cool but what about all of the extra infra I need to write because support for the lang is not as extensive and so more code I need to maintain?

▲misterchocolat 2 hours ago | parent [-]

I mean if we're heading towards a future where code gen gets super cheap and super good what stops you from porting the libraries you want?

▲ehe78qhe 2 hours ago | parent [-]

Mostly, having to rediscover all of the underdocumented quirks and features in whatever I'm trying to interface with.

Partly, having to do my own pentesting and red team work instead of using someone else's work that has already been pentested.

▲frollogaston 2 hours ago | parent [-]

Yeah, I'll use LLMs to write all application code, but not so sure about libraries. Especially more foundational ones.

▲Jach 22 minutes ago | parent [-]

What to you are the foundational ones? Perhaps CL has them already, or if it's actually a C lib that every other lang uses, CL can use that too. If not, the feedback would at least give people ideas.

From the parent's security standpoint I'm more sympathetic, there's been a lot fewer eyes on CL code, there's no central place to keep track of discovered security issues, and perhaps more vigilance is required against untrusted input compared to other languages. At the same time, every time I've exposed a CL-powered website I've noticed various attempts at e.g. wordpress endpoint discovery and I sleep soundly knowing a wordpress deployment is something I'll never have to worry about or take extra precautions against. Every time I hear about a supply chain attack I also am happy about the choice of CL. (Though in truth it's not to say that such attacks aren't possible, but for various reasons, one of them rather quite embarrassing to the overall ecosystem, pulling a big one off is going to be more difficult.)

▲misterchocolat 4 hours ago | parent | prev | next [-]

Happy to discuss

▲invalidOrTaken 2 hours ago | parent | next [-]

Loved the post, have been batting around similar ideas w/clojure. I have two questions:

1. Have you had much success w/moar macros in the age of the LLM? I've been impressed by the models' ability to write good ones, but I can tell my taste/judgement for macros isn't quite there. But they tend to be pretty good at writing gnarly ones, and I would love to work more macros into my workflow. Would love your thoughts. (Have I taken "Simple Made Easy" too far and left macro value on the table?)

2. Do your models ever get confused with image-based dev, and state? It's seemed dumb to me to have models keep running `sed` to change files, but it is nice to have a human-readable, filesystem-backed record of definitions. Would love to hear your experience here.

▲misterchocolat 2 hours ago | parent [-]

Thanks!

I've seen a big improvement in LLMs writing macros since Opus 5.5 came out. What really helps I think is that I've written skill files with my own examples and instructions.

Same thing for image-based dev. without an agent.md file with good instructions on how to work with a live image it will do dumb things. this sort of workflow is jsut so far off the training distribution.

I think what changed recently isn't that LLMs got better at CL, they just got way better at taking my skill/agent.md files and reasoning through them.

▲frollogaston 2 hours ago | parent | prev | next [-]

  Also, in most languages an error will crash your program. So if you’re writing code with an LLM it will have to read your crash logs to make some changes and run your program again. In Common Lisp your program won’t crash, it’ll stop and open a debugger with the whole stack and all the variables. You can just point your LLM at the debugger, and it’ll make its fix and resume the program.
What does this look like in a real example system that you're maintaining? I can't imagine you'd always be able to resume like that if it's something like a webserver.
▲chrchr 2 hours ago | parent | next [-]

Test driven developmet practitioners in Smalltalk used to (still do?) write the test before writing the implementation, run the test, and, when the "method not implemented" error shows up in the debugger, type the implementation and continue the execution. Common Lisp can do that too.

So, in practice, it might look like you hit any kind of runtime failure, and then the LLM writes some code to fix it, and the user's request completes successfully with no errors.

▲rmunn 2 hours ago | parent | prev | next [-]

Not the author, but unless the server was running in a short-lived ephemeral container (in which case the management system probably killed the container and started a new one), the CL process would still be around in a paused state, waiting for you to connect to it and tell it how to resume.

https://comp-348.github.io/lisp-debugging.html has an example of what it looks like. A toy example, to be sure, but the basics of a real example would still look the same. You're given a choice of several options, very reminiscent of the "Abort, Retry, Ignore?" choice that used to be oh-so-familiar in the days of DOS. Except this one is more useful, because it offers ways to specify how to resume. E.g., the toy project is halting on a `(print X)` call where the value of X is not defined. And the choices are:

0. Continue. (Retry using X).

In the toy example, this would fail, because nothing else has defined X. But in real code, the name might have been undefined because the data needed to define it hadn't arrived yet, from the database or the filesystem. In which case retrying the statement might work the second time.

1. Use-value. (Use specified value).

This one prompts you to enter a value for the undefined variable, and continues, but it does not modify the value of X in the program. The next time the program tries to use X, it will halt again with another "unbound variable" error.

2. Store-value. (Set specified value and use it).

This one, just like Use-value, will prompt you to enter a value to use... but then it will set X to that value and continue running the program. Next time the program tries to read the value of X, it will have one, and the program won't halt.

3. Abort. (Exit debugger, returning to top level).

This is what you would choose if there's no good way to fix the error, and you just have to quit the program and restart. Though note that choosing this option isn't going to exit the program you're debugging, just take you out of the debugger. You'll still need to kill-and-restart it some other way... or come back an hour later when the value is finally available, and then choose options 1 or 2.

Hopefully that gives you a taste for what the CL debugger is like to use in practice.

▲frollogaston 2 hours ago | parent [-]

This looks like a good debugger, but it's similar to ones I've used in other languages. What's special about this one? I thought the idea was you use the debugger in prod, but now I don't think that's what the article meant.

▲rmunn 2 hours ago | parent [-]

Yes, you use the debugger in prod. I've read many articles by Common Lisp users talking about how great that feature is: they can quickly get production back up and running, then go to the code and implement the same fix they just did on live prod.

And it's not editing files on the server, it's actually reaching into the running code and tweaking its values.

That, I think, is the difference here. In many languages, the debugger can pause on the exception and let you inspect the code. But in every other language I've used, once you edit the code to fix the bug, you can't resume from where the debugger paused. You have to recompile the code and resume from the top. In CL, you can resume from exactly the state you were in when the debugger paused, only this time with the correct data in place. (Or even with a code fix having been applied, live, to the code).

▲darkwi11ow 2 hours ago | parent | prev [-]

You can do this in many other interpreted languages like Python interpreter when running with --pdb flag will do the same. I imagine CL does this by default when running code in interpreted mode and omits the behaviour for compiled (production) binaries.

▲frollogaston 2 hours ago | parent | next [-]

Yeah but what happens to your server then? The connection it was handling times out I guess, then is the rest of it frozen or what?

▲rmunn 2 hours ago | parent [-]

I mean, that entirely depends on the server design. Is it running one connection per process? One connection per thread? Presumably you've designed the server in a way that one slow connection doesn't block other connections from being handled fast, which means that this one connection whose handler went into the debugger is just now a really, really slow connection taking minutes (or hours!) to handle, but the other connections are running just fine.

Now, if your entire server is taken down because one connection threw an exception, that's bad design. But pretty much no major language works that way. All of them allow you to set things up so that an exception handling connection A won't affect connection B. And if you've done that in Common Lisp, then connection A halting and waiting for the debugger won't affect connection B either.

▲Jtsummers 2 hours ago | parent | prev [-]

In CL, this works with compiled code.

▲sroerick 2 hours ago | parent | prev | next [-]

I was just explaining this exact thing to somebody a couple days ago - even used ERP as the example. Hear hear, sir

▲whartung an hour ago | parent | next [-]

I dunno.

When it comes to back office business programming, there’s just a lot of code tasked with copying a litany of bits of data from one structure to another.

Whether it’s copying a web form into a database, or converting Their JSON to Your JSON, it’s a lot of detail that does not abstract well. It’s all shapes and sizes and formats, and it almost always has to be enumerated in excruciating detail and, typically, twice.

Sure, there’s logic and whatnot involved, but it, too, is specific to some subdomain of the larger system and it, too, does not abstract well. Not in the large context of the overall system.

Accounts Payable and Accounts Receivable, at 10,000 feet look almost identical. They’re almost literally the same thing with the sign flipped. But in practice, they don’t share code well. You end up with two similar systems, but not similar enough where sharing is actually worthwhile.

At best they can leverage a common API to the GL.

Turns out a lot of languages can manifest a decent level of abstraction. But even then, folks push back.

Consider the love/hate relationship with ORMs. Or the annotation driven markup in Java programs and the underlying “magic” that they enable. Like scribing mystic runes onto things.

Those are both very powerful, yet folks experience that and toss their hands in the air and throw out the baby with the bath water and jump into something “magic free” like Go.

Just because you can use something like CL to “make your own magic”, doesn’t mean it’s a good idea. Doesn’t mean it scales. Doesn’t mean it communicates well to others. AI or no.

It’s not the AIs world yet. We already know that if the AIs want a better language suited to AI efficiency, they’ll come up with their own. I’ve already seen crass examples of “code only an AI could love”. Completely impenetrable, at least to me. May as well have represented it as a color image and collection of RGB values. Opaque to me, but the AI could “read” it.

There is much more to programming and systems than token density, and AI is still getting cheaper by the day, so less reason to even pre-optimize for it anyway.

▲sroerick an hour ago | parent [-]

There's lots of examples of DSLs being unreasonably useful in industry even prior to LLMs.

While I am extremely taken with Lisps and the lisp way of doing DSLs, I would probably go with an OCaml to make a DSL for a company specific ERP. It seems a better way to go about the problem.

Lisp, on the other hand, I have found to be extremely good at domains which seem the same but which are tremendously different. For example, a workout app is a surprisingly complex domain. Different exercises have different storage models and functions, as do different training sessions and different programs. Rather than try to build a monoprogram, one training app to rule them all, I find lisp wonderful for making "microprograms".

This bears resemblance to Accounts Payable and Accounts Receivable but I don't think Lisp would be a good fit for those. Perhaps a Lean or a Rocq, something with proofs.

> We already know that if the AIs want a better language suited to AI efficiency, they’ll come up with their own.

My agents seem to really like Tree Calculus and have bullied me into working on a language which uses it.

▲tzmudzin 2 hours ago | parent | prev [-]

... and I think you will both find it intellectually stimulating to explore the complexity behind ERP systems that makes a common DSL near impossible across industries, or as businesses change.

DSL presumes agreement on semantics, and that's often the most difficult part.

▲sroerick an hour ago | parent [-]

So why not a DSL for a specific business?

▲tzmudzin 24 minutes ago | parent [-]

At least two reasons:

- economies of scale no longer work, and you end up doing a custom ERP for your business from scratch.

- your business changes might invalidate your model quickly. You sell through distributors, but open an online shop -- and suddenly your customer is not one of few dozen well-known businesses with a known address and tax number, but user2252 who bought something late at night last night. And you want to understand the needs and behaviors of both.

▲ 2 hours ago | parent | prev | next [-]
[deleted]
▲TacticalCoder an hour ago | parent | prev [-]

I'm convinced we'll be moving at some point to n-modular redundancy systems, using different languages implementation, simultaneously. For the cost of writing code in n languages tends towards zero now (due to the use of LLMs) and the various stacks and implementations shall then cross-check each others.

There shall be one minimal, ultra-hardened, tiny attack surface, "majority gate" picking the answers that most implementation agrees on.

This shall not only detect a great many implementation issues but also it'll help find security issues and platform defects (say the Common Lisp, Haskell, Rust and Python all agree but the Java one fails: in rare case it'll be due to a JVM bug and finding that out shall be simplified).

Code shall be generated from specs in n languages and ran on n stacks. The gate shall return the answer as soon as a quorum is met and, later on, any bogus answer arriving shall be cause for enquiry.

We'll have such systems, it's just a matter of time.

▲mumin00 2 hours ago | parent | prev | next [-]

don't think software companies will user change their software

▲aussieguy1234 2 hours ago | parent | prev | next [-]

That's a lot of power to mess things up that I wouldn't be putting into the hands of an LLM I don't trust.

▲nurettin 2 hours ago | parent | prev | next [-]

In my experience, LLMs instantly find the reason for the crash and fix. They don't even need to go through the debugging phase anymore. It doesn't matter if you're generating c++ lisp or cobol.

▲fithisux 2 hours ago | parent | prev | next [-]

In the benchmarks though here it is slow and consumes too much memory

https://benchmarksgame-team.pages.debian.net/benchmarksgame/...

But I find ideas like Carp very attractive.

Still common lisp is designed very good.

▲shikck200 2 hours ago | parent | prev | next [-]

Lisp allows for some really, really complex and spaghetti code bases. I have seen the ultimate macro-hell from top to bottom. I know syntax does not matter, but i just cant honestly say i read lisp code as clear as something like Go. I guess it boils down to style. I have seen 100 lisp styles, and only one Go style.

▲djtango an hour ago | parent [-]

Lisp is a sharp tool and I think it struggles to scale with large organisations. You would need incredible tech leadership and a very considered org structure and architecture for it to work.

Culturally, I feel a place like Valve could make it work but you could turn around and ask why does an org need to be in service to and arrange itself around a tool.

▲giancarlostoro 2 hours ago | parent | prev | next [-]

> In Common Lisp your program won’t crash, it’ll stop and open a debugger with the whole stack and all the variables. You can just point your LLM at the debugger, and it’ll make its fix and resume the program.

> To my knowledge Common Lisp is the only mainstream language that does all of this.

Sounds like someone who has never used C# and Visual Studio? Even JavaScript is capable of doing this, honestly JavaScript might be the one language with the richest developer tooling of all time (possibly?), sad to say because there's nicer to work with languages out there.

▲rootnod3 2 hours ago | parent | next [-]

I think what is referred to here is that an exception doesn't unwind the stack. Even if the exception is uncaught, you can fix the line or value and then resume where the stack was.

▲frollogaston 2 hours ago | parent | prev [-]

IF you're running a debug build. I guess Common Lisp can do this in prod?

▲giancarlostoro 2 hours ago | parent [-]

I mean, so can JavaScript then? Why would I want a debugging window to open up for a customer in production? I remember when Windows used to try to open a debugger when certain programs crashed on me as if I knew what the heck any of that was supposed to mean.

▲frollogaston 2 hours ago | parent [-]

Was assuming it was a backend. I still don't understand the advantage though. It'd help to have an example.

▲giancarlostoro 2 hours ago | parent | next [-]

Thing is with .NET you can debug a release build, and even do remote debugging... So it's all a weird claim to me. Definitely someone who only uses Common Lisp and maybe a language with a less impressive debugging background wrote this article.

To be fair, I love Lisp, I dont do a lot with it, though I'm mostly a fan of Racket which is the most modern one outside of maybe Clojure.

▲Capricorn2481 2 hours ago | parent [-]

Yeah, you don't want a lisp debugging window in production. The absence of stack unwinding does enable editing behavior with wrappers. You could have different error handling without changing any code downstream, and I guess an LLM could theoretically change that depending on the bug it's responding to.

But I'm not positive the juice is worth the squeeze, and this article was unconvincing. I mean if you want macros and terse code and a bigger ecosystem, wouldn't Clojure make more sense?

▲rmunn 2 hours ago | parent | prev | next [-]

Just finished typing up an example as you wrote this. Rather than duplicate it, here's the link:

https://news.ycombinator.com/item?id=49974251

▲ 2 hours ago | parent [-]
[deleted]
▲anonair 2 hours ago | parent | prev [-]

I imagine production backend with LLM connected using debug interface and patching the code continuously on any exception encounter.

(not a CL expert here)

▲ 2 hours ago | parent [-]
[deleted]
▲andrewstuart 2 hours ago | parent | prev | next [-]

Now as ever, there is no “best programming language”.

There’s the right tool for the job, there’s compliance with requirements, there’s personal preference.

Don’t let anyone ever tell you you are programming wrong.

▲hota_mazi 2 hours ago | parent | prev | next [-]

Yeah... no. I don't think there is a best programming language, but I do think dynamically typed languages are worse for AI to code in compared to statically typed ones.

▲kcirtapfrmspc 13 minutes ago | parent | prev | next [-]

[dead]

▲ 2 hours ago | parent | prev | next [-]
[deleted]
▲vincnetas an hour ago | parent | prev | next [-]

"Would you agree that some programming languages are better than others? If so then one of them must be the best."

Unless of course there are multiple dimensions of "Good". I in my opinion this is exactly the case. There are best languages per dimension, but not absolutely best.

▲rf15 an hour ago | parent | next [-]

Ah, but you forget the attention economy that the internet amplified: only controversial takes are discussed, nobody wants to read your reasonable and nuanced blog post because everybody can silently agree with it already. Without any crucial insight or big controversy nobody will read it. And the latter likes to masquerade as the former most of the time.

▲asp_hornet 3 minutes ago | parent | next [-]

It makes me sad how right you are. Particularly: > And the latter likes to masquerade as the former most of the time.

▲pseudony 2 minutes ago | parent | prev [-]

Hear hear !

▲n4r9 34 minutes ago | parent | prev | next [-]

Even if there's one dimension, this is not a logically correct statement. Some numbers are bigger than others, but there is no biggest number. Or it could be a partial ordering - say that a number x is "better" than y if y divides x. Then out of the first hundred numbers, some are better than others but there's no single "best".

▲Someone 34 minutes ago | parent | prev | next [-]

It need not even be multiple dimensions. https://en.wikipedia.org/wiki/Partially_ordered_set:

“a partial order on a set is an arrangement such that, for certain pairs of elements, one precedes the other. The word partial is used to indicate that not every pair of elements needs to be comparable; that is, there may be pairs for which neither element precedes the other”

▲bambax an hour ago | parent | prev | next [-]

Yes! It depends. That's why there are so many languages that still exist. Otherwise it would be a winner-takes-all situation and there would be just one left standing.

▲tgv 42 minutes ago | parent | prev [-]

Even per dimension there will be different preferences. There's no objectivity in most of them, perhaps even none.

▲wtf676767 an hour ago | parent | prev | next [-]

[dead]

▲ltbarcly3 2 hours ago | parent | prev | next [-]

Common Lisp isn't even a good programming language. There's nothing in CL that isn't in a ton of other languages now. When it was being designed it was way ahead, but now it's just way behind.

Maybe you could take CL as a foundation, introduce modern features and uniformity to the language, remove some of the insane complexity, tame the unhygienic macros, and come up with a pretty good language. Since about 7392 different flavors of scheme have tried to do this and mostly failed, I think this is very unlikely.

▲bobanrocky an hour ago | parent | prev | next [-]

This is one of the most inane, fluff articles I’ve seen dumped in this site in a while. Nothing original, just a simplistic regurgitation of known stuff. Reads like lame, lazy LLM slop :(

▲BurnerBurner 2 hours ago | parent | prev [-]

Nah with llms the most used lang prolly has the best output

▲dang 2 hours ago | parent | next [-]

That was my assumption too (not that long ago, laggard that I am), so I expected LLMs to be less good at Common Lisp than, say, Javascript or Java, and surely to suck at Arc (the Lisp that HN is written in). But it's not so. They excel at Common Lisp—which, ok, has decades of history and documentation which the models have all slurped up. But they're even good at Arc, which is pretty far down the long tail. And when they mess up, I put something in agents.md and that issue mostly just goes away.

▲Karrot_Kream 2 hours ago | parent | prev | next [-]

Not quite, though there does seem to be an advantage for a popular language. Dan Luu explored this at https://danluu.com/pl-tokens/

▲SatvikBeri 2 hours ago | parent | prev [-]

That really hasn't been my experience, LLMs have done well with Julia since Claude 3.7