I disagree. "Boring" languages leave a lot of assumptions in code, which will start to compound the more changes model (and programmers) make to the code. The more assumptions I can move to compile time the better models are at dealing with emerging complexity. I would go the other way with LLMs and I wish for liquid types and effects in Rust to make type specifications even more strict. P.S. effects and liquid types…
The problem is that most of Rust annotations are related to memory management in special conditions aka solving problems that don't even exist in JS or Java. That's not going help the AI solve problem space issues, it just helps the AI (and us) do things in the solution space aka solve lower level things we consider important.
Use boring languages with LLMs
91–100 of 180 posts
Re: Use boring languages with LLMs
#92LLMs have a limited context window - similar to the limited attention span and memory of humans. LLMs also have trouble attending to many constraints at once. Therefore the best language for agents is likely the one that, on one hand erases all irrelevant details (ie. raises the level of abstraction and does not force focusing on eg. memory management), and on the other hand encodes any domain-relevant details in the…
Re: Use boring languages with LLMs
#93LLMs have a limited context window - similar to the limited attention span and memory of humans. LLMs also have trouble attending to many constraints at once. Therefore the best language for agents is likely the one that, on one hand erases all irrelevant details (ie. raises the level of abstraction and does not force focusing on eg. memory management), and on the other hand encodes any domain-relevant details in the…
I know Clojure misses the mark for you in some major areas, but having a real, proper REPL for an agent to interact with makes for an extremely strong feedback loop. IMO, a strong candidate for an "agent endgame" language has this.
And yeah, if Clojure had a better static safety story, it would actually rank high, since it's high-abstraction with metaprogramming capabilities, excellent runtime specifications, and has a good "garden path" ie. natural code is good code.
(As a devil's advocate though, REPLs can be replaced with gluing together scripts with ad-hoc state/caching via the file system, which LLMs seem to be pretty good at already...)
So as an addendum, introspectability is also important ie. allowing to discover the state and composition of the system at any moment - though that's partially a language (eg. reflection) and partially a tooling (eg. debuggers) issue.
Re: Use boring languages with LLMs
#94My experience a year ago (back when half of HN was still in denial about what was already working, let alone what was to come) was that Python was the linqua franca of LLMs. You could achieve almost anything that fit in 700 lines or less if you told it to write it in Python. Times change, and I work more in R&D space than on legacy codebases, but I still ask it to write something in Python then convert it to the actu…
My experience with LLMs is that they perform best in one of two modes - either one carefully scoped context or translating between two different contexts without modification - so this modality lines up with that fairly nicely: think in the programming language the LLM thinks "best" in and then translate that to the one you want.
That said, there's often enough structural and conceptual differences between languages that a direct "transliteration" between, say, Python and Go is going to result in some fairly crummy Go, so I'm curious what you see in terms of the fidelity of that translation - do you mostly get "Python written in Go," or does the LLM really do a proper conversion from one language to the other?
Re: Use boring languages with LLMs
#95I can probably fix package manager issues by hand, and quickly with a little rubber ducking with the LLM itself. I'm not sure that's a huge problem in the grand scheme. There's a lot of stuff in Python's favor in regard to coding with LLMs: its wildly popular so there's a lot of references for the right and wrong ways to use it, it can be typed using included libraries - its as simple as telling the LLM "use typing f…
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
Re: Use boring languages with LLMs
#96I disagree. "Boring" languages leave a lot of assumptions in code, which will start to compound the more changes model (and programmers) make to the code. The more assumptions I can move to compile time the better models are at dealing with emerging complexity. I would go the other way with LLMs and I wish for liquid types and effects in Rust to make type specifications even more strict. P.S. effects and liquid types…
Re: Use boring languages with LLMs
#97Earlier quoted context omitted.
RE the article you've linked: > everyone knows goto was bad. Absolutely hard disagree. You can write extremely clean and resilient C with C89, goto, and a handful of rules. Telling people `goto` is bad is how we get shitty C programs and paradigms where goto would have been better. Goto isn't bad, its misuse is bad. Beginners will write shit code regardless of whether you tell them they can or can't use goto. That's…
> > everyone knows goto was bad. > Absolutely hard disagree. You can write extremely clean and resilient C with C89, goto, and a handful of rules. That's a different goto. The one in C89 can only jump around within functions, but the article is talking about goto that can jump between any two points in the whole codebase arbitrarily. It stresses that point a bit more later on in the article, but you can already see i…
// 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/sub-state
// Implementation: normal call
#DEFINE go_do
// Syntax: { ... go_terminate(y); }
// Meaning: State machine termination
// Implementation: normal return
#DEFINE go_terminate return
// Syntax: int state3 state(int x, ...) { ... }
// Meaning: Structured state definition
// Implementation: normal function
#DEFINE state
// SYNTAX: if (GOTO_NOT_HARMFUL) { ... };
// Meaning: GOTO is now cleaned up
// Derivation: Achieved
#DEFINE GOTO_NOT_HARMFUL true
Example: int state1 state() { ...; go_to state2(m); }
int state2 state(int m) { ...; y = go_do substate2a(); go_to state3(); }
int substate2a state() { ... ; go_to substate2b(q); }
int substate2b state() { ... ; go_terminate(q); }
int state3 state() { ...; switch (...) { case 1: go_to state4(v); case 2: go_to state5(); ...} }
int state4 state(int v) { ...; go_terminate(r); }
int state5 state() { ...; go_to state3(); } // State cycle
So now you can have your #include EDIT: Compressed/cleaned up my mess
Re: Use boring languages with LLMs
#98My experience a year ago (back when half of HN was still in denial about what was already working, let alone what was to come) was that Python was the linqua franca of LLMs. You could achieve almost anything that fit in 700 lines or less if you told it to write it in Python. Times change, and I work more in R&D space than on legacy codebases, but I still ask it to write something in Python then convert it to the actu…
> Times change, and I work more in R&D space than on legacy codebases, but I still ask it to write something in Python then convert it to the actual language on occasion. I don't know if I'm tricking the context window, forcing alternate pathways, or both, but it works. My experience with LLMs is that they perform best in one of two modes - either one carefully scoped context or translating between two different cont…
Re: Use boring languages with LLMs
#99Without any typechecking, LLMs obviously find it harder to work agentically and validate their work.
With too much typechecking (I'm looking at you, rust), I've found agents get themselves stuck in local "architectural minima" and end up doing insane shit to mitigate ownership/borrow-checker issues inherent in the design they ended up with.
That said, if you're hands-on I think rust is a fantastic language for pairing with an LLM.
Re: Use boring languages with LLMs
#100I can probably fix package manager issues by hand, and quickly with a little rubber ducking with the LLM itself. I'm not sure that's a huge problem in the grand scheme. There's a lot of stuff in Python's favor in regard to coding with LLMs: its wildly popular so there's a lot of references for the right and wrong ways to use it, it can be typed using included libraries - its as simple as telling the LLM "use typing f…
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
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.