Live data from Hacker News

Use boring languages with LLMs

jry.io

171–180 of 180 posts

Re: Use boring languages with LLMs

#171
post #100

Earlier quoted context omitted.

Why choose a significantly worse language when you are writing it in the same English either way. It’s increasingly obvious that whole swaths of developers will just continue using the language they did before LLMs “just cause” It’s more identity based at this point. My LLMs write Rust for me and I couldn’t tell you the difference outside of it being way faster and more reliable

For immediate term you should stick with what you know. I think that makes for much better prompting where you are coming in with experience with the language and the general style you'd like to see. Rust is a language I would like to adopt longterm, but its not one I can easily grok and so my output would be worse for it.

I think that's fair, but I honestly can't tell you if I'm writing python or rust anymore. When I review I just ask Claude to add comments to all the code to make things clear as I review

Re: Use boring languages with LLMs

#172
post #169

Earlier quoted context omitted.

It sounds almost squarely written by someone without practical experience of REPL-driven development. Specifically with Lisp REPLs. Sure, other languages also have REPLs, but if you dig just a bit deeper, you'd learn that every single step there in R[ead] E[val] P[rint] L[oop] has differences. That makes the entire holistic experience of using the language drastically different. Not universally better for every domai…

Your intuition is not right, I have plenty of experience with REPL-driven development, even having used all the tools you have mentioned in your post. (and Clojure Spec is exactly the runtime specification part I was referring to in my comment...) Logically, it's more the other way around - REPLs are in that sense a compensation for static types, since nothing forbids having a REPL and static types (see: eg. Julia. O…

[dead]

Re: Use boring languages with LLMs

#173

Earlier quoted context omitted.

I ran a little test with Go, TypeScript, Clojure, F#, Haskell, and Rust. Token count was roughly in the same ballpark, but it used the fewest for TypeScript, then Go. The rest required a bit more. Clojure always won in terms of lines of code though, generally coming in at 1/2 the size of the Go or Typescript solutions.

I bet you have not tested it with live Clojure REPL. When you give the LLM living, breathing REPL, it stops guessing and starts empirically analyzing current state of things and produces working solution faster, costing far less tokens. This article doesn't seem to mention it either https://martinalderson.com/posts/which-programming-languages... even though states Clojure to be the most token efficient. I personally,…

As someone who hasn’t felt that magic with a repl and LLM’s, how do you integrate the two? Does it have to be in emacs and every buffer is accessible by a LLM?

Re: Use boring languages with LLMs

#174

Try to apply first principles to LLM coding: * Chances are that fewer people (maybe even none) will look at the code when it's LLM-generated * Amount of code being written isn't all that critical anymore * Keeping patches small isn't that big of a deal anymore (because it's now the LLM's job to maintain it, not the human's) All of this implies: boilerplate isn't a good reason to avoid a language anymore. (I hate this…

Excessively verbose syntax to express concepts is something I can let an LLM paper over, but a language that does not even function properly without the ceremony is still a non-starter. I want to refactor chains of operations without having to check for errors myself after each step, and I want that with or without an LLM.

Re: Use boring languages with LLMs

#175

Earlier quoted context omitted.

I bet you have not tested it with live Clojure REPL. When you give the LLM living, breathing REPL, it stops guessing and starts empirically analyzing current state of things and produces working solution faster, costing far less tokens. This article doesn't seem to mention it either https://martinalderson.com/posts/which-programming-languages... even though states Clojure to be the most token efficient. I personally,…

As someone who hasn’t felt that magic with a repl and LLM’s, how do you integrate the two? Does it have to be in emacs and every buffer is accessible by a LLM?

It depends. If you're building an Emacs package or extending your own customizations, having "every buffer accessible" helps, because that way LLM is not dealing with Emacs (so to say), but with Emacs REPL, that has access to everything running within it.

That however doesn't really work well with other languages like Clojure - LLM can poke into clj REPL from the Emacs REPL by tapping to it through emacsclient, in practice - these layers start leaking pretty quickly. For Clojure (or Lisps in general), you need something that changes the fundamental model of how agents work, which is roughly the Unix/pipe model. Agent spawns process -> reads stdout/stderr -> spawns next process. State lives in files. Each tool invocation is stateless. This works for languages with batch-style toolchains (compile, test, run - pretty much any non-lispy lang). An agent that edits files and re-runs `clj` is doing something fundamentally different from what a Clojure developer does.

For Lisps, you need persistent nrepl connection, eval-in-namespace as the primary tool, ability to inspect live values, hot-reload awareness - not "run clj test and parse the output". For that you need specialized MCP. There are plenty of existing solutions. I built mine in Clojure (in babashka)¹. But that's because I use Emacs. If I was using VSCode, I'd probably use BackSeatDriver²

The main point is - Lisp REPLs are great and powerful, and there's no significant obstacle not to utilize them with LLMs. If you're using a homoiconic language and not utilizing the full power of the REPL, really, why?

---

¹ https://github.com/agzam/death-contraptions/tree/main/tools/...

² https://github.com/BetterThanTomorrow/awesome-backseat-drive...

Re: Use boring languages with LLMs

#176

Earlier quoted context omitted.

> Languages with a single way to do things benefit the most: Rust I posit that Rust is the optimal language to emit from LLMs unless you have to target web, a specific platform, or a legacy project: - The required error handling for Option , Result , and required destructuring of sum types naturally reduces errors by an order of magnitude - If it compiles, chances are higher the code is correct. Especially if you're…

>I posit that Rust is the optimal language to emit from LLMs unless you have to target web, a specific platform, or a legacy project: What would you suggest is optimal for targeting web?

LLMs seem to have an easy time with Elixir and Phoenix in my testing.

Re: Use boring languages with LLMs

#177

Earlier quoted context omitted.

Personally I generally try to avoid concurrency when writing code with AI since I feel AI makes concurrency unnecessary complex in Golang.

I don't have this issue in elixir.

Neither do I.

Re: Use boring languages with LLMs

#178

Earlier quoted context omitted.

Here is a structured cross-codebase GOTO for C++, with optional declared & typed continuation values, sub-tasks/states/state-machines, and optional delegated typed termination values. // Syntax: { ...; y = go_to state1(x, ...); } // Meaning: Cross-codebase GOTO w/continuation values // Implementation: tail call #DEFINE go_to return // Syntax: { ... y = go_do state2(x, ...); ... } // Meaning: Cross-codebase sub-task/s…

That's not the same: you have to cooperate in the game, so if you have a library that uses it internally and you call one of its functions in the normal way then it will still just return as usual. So it still provides the usual guarantees of function calling, even if you don't want it to. (It also doesn't allow you to jump into the middle of a function, or to take more than a finite number of steps unless you're usi…

Just to add:

If you want to have proper jump-anywhere goto in C, you can do it a lot more simply than that: just put all your code in one function and use regular goto. If you want to use only structured programming constructions, use a while(true) loop with a switch statement inside.

The fact remains that code outside that function can still call it safely in the normal way.

Re: Use boring languages with LLMs

#179

Earlier quoted context omitted.

As someone who hasn’t felt that magic with a repl and LLM’s, how do you integrate the two? Does it have to be in emacs and every buffer is accessible by a LLM?

It depends. If you're building an Emacs package or extending your own customizations, having "every buffer accessible" helps, because that way LLM is not dealing with Emacs (so to say), but with Emacs REPL, that has access to everything running within it. That however doesn't really work well with other languages like Clojure - LLM can poke into clj REPL from the Emacs REPL by tapping to it through emacsclient, in pr…

Thank you for sharing. I never played with Clojure before but I’m very intrigued by this repl driven workflow from an agentic perspective given it changed the nature and relationship to the program/code.

I’ll look into the links and mentioned programs. Thank you.

Re: Use boring languages with LLMs

#180

Earlier quoted context omitted.

It depends. If you're building an Emacs package or extending your own customizations, having "every buffer accessible" helps, because that way LLM is not dealing with Emacs (so to say), but with Emacs REPL, that has access to everything running within it. That however doesn't really work well with other languages like Clojure - LLM can poke into clj REPL from the Emacs REPL by tapping to it through emacsclient, in pr…

Thank you for sharing. I never played with Clojure before but I’m very intrigued by this repl driven workflow from an agentic perspective given it changed the nature and relationship to the program/code. I’ll look into the links and mentioned programs. Thank you.

I've been programming for over four decades as a hobby and more than twenty years professionally. I have gone through dozens of languages and still trying to learn more. Getting into Clojure still remains one of the best decisions I made in my life. I don't know why mainstream programming media - publishers, meetups, major conferences don't talk about Lisp (as if it doesn't matter at all). Common Lisp perhaps has created this aura of elitist culture (similar to Haskell) - "you have to be this tall to ride this rollercoaster", etc. Turns out, Lisp really is not that difficult. You don't need years of accumulated knowledge to start programming in it. If you know just a single mainstream PL - you already have almost everything you need to start, because pretty much every single programming language has been influenced by Lisp.

And Clojure, unlike Haskell, is way more down-to-earth and enormously practical. I'm not saying Haskell is not, but let's be honest, for anyone to start writing production-grade Haskell would take weeks, not hours. While Clojure needs minutes. These days you can just download the Calva VSCode extension and start playing with it.

Even if one thinks "there's just no way to use it at work", there are so many smaller things they could use it to improve their personal workflows. "Of course, when you only know a hammer, everything looks like a nail", someone might say. Yet, for me, who has seen, learned and used dozens of different "hammers", this one does look quite interesting. For a bunch of pragmatic reasons. And my message to any "hammer-wielding craftsman" - you really don't need to try dozens of hammers to see the value in a good one, and Clojure is a pretty darn good one, I promise.

Post reply on HN