Rendered at 17:24:18 GMT+0000 (Coordinated Universal Time) with Cloudflare Workers.
quietbritishjim 8 hours ago [-]
> Python is the same story but sung in a different key. Asking a simple question like “which package manager are you using?”
This is annoying but only needs to be solved once at the start, either by the LLM or the human guiding it. A single prompt of "Set up a uv project in this directory with Python 3.13" is enough that it's never an issue again for that repo.
> Goroutines are a far more tractable primitive for coding agents than threads, callbacks, async/await, or any of the colored-function regimes that dominate elsewhere.
I disagree with this. Goroutines, along with threads, callbacks, and traditional async, are all in the same category: spaghetti of unbounded background tasks. Structured concurrency [1] on the other hand is dramatically easier to reason about. Python has support for this (in Trio and asyncio.TaskGroup) as do other languages like Kotlin and Swift. Function colouring a red herring; if anything, it's useful because it highlights the scheduling/cancellation points in your code.
This really does read as "Go is my favourite language". In fairness, that's a good reason to choose a language to use with an LLM (so long as it's powerful enough and not too obscure). But let's not pretend it's the best language for everyone.
pyrale 6 hours ago [-]
> This really does read as "Go is my favourite language".
Because it always is that.
People advocating for boring languages always advocate for their boring language. For instance, if you tell a gopher that you agree with the point, and therefore the project is going to use java, they won’t be happy about it.
lionkor 7 hours ago [-]
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 also exactly what Dijkstra was arguing, if you read past the much misquoted "goto considered harmful", which he never said (it was an editorialized title, and not even the full version).
quietbritishjim 6 hours ago [-]
> > 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 it from the FLOW-MATIC code quoted above (which doesn't even have functions).
Your point actually still stands: it's theoretically possible to write clean code using even the more general goto. (Probably by building abstractions with it like "function" and "for loop".) But would you be happy doing that with someone else - or especially with a coding agent? It's better that the "handful of rules" are enforced by the language, in my opinion.
---
Edit:
> That's also exactly what Dijkstra was arguing, if you read past the much misquoted "goto considered harmful", which he never said
I just re-read the original "GOTO considered harmful" article (it's short and clear) and, while the title might not have been his, Dijkstra was definitely making a very plain argument that goto is bad for everyone and should be scrapped. He says in the introduction:
> I [have] become convinced that the go to statement should be abolished from all "higher level" programming languages (i.e. everything except, perhaps, plain machine code).
And in the conclusion:
> The go to statement as it stands is just too primitive; it is too much an invitation to make a mess of one's program.
jmiskovic 7 hours ago [-]
Bad code is result of not following enough good practices rather than following one too many. Goto creates too much cognitive load. It had to be phased out to make room for better ideas on describing the intention with code more clearly.
kibwen 7 hours ago [-]
> Function colouring a red herring
Any time you see anyone overly fixating on "function coloring" for any context other than ancient versions of Javascript it's a clue that the speaker has no idea what they're talking about.
dminik 8 hours ago [-]
> Goroutines are a far more tractable primitive for coding agents than threads
Goroutines are literally threads. Yeah, this really is a "go is my fav" article.
bfivyvysj 7 hours ago [-]
I use both go and python in my day job. The code that Sonnet produces for Go is much better than the Python it creates.
This could be because our go code is typically smaller more defined services but I don't really believe that since even the isolated python services are pretty spaghetti looking.
p2detar 6 hours ago [-]
As someone below said, they might be from programming perspective, but technically they are not. See GOMAXPROCS for more info.
That being said the whole `tractable primitive` thing used in the article sounds somewhat sloppy to me. I don't quite get it. Yeah, they could be easier for an agent to write than async/await, but threads are also trivial in that matter, and you'd still need a mutex with go routines.
Retr0id 8 hours ago [-]
Goroutines are not directly equivalent to threads.
quietbritishjim 6 hours ago [-]
If 100 goroutines are handled by 10 threads, the effect on correctness is identical: any two can be running in parallel with each other (not just concurrently). From the point of view of this discussion, that's all that matters.
Retr0id 4 hours ago [-]
Correctness is nice but performance characteristics exist too.
IshKebab 7 hours ago [-]
They used to not be, because they were cooperatively scheduled and threads can be preempted. But they added goroutine preemption in Go 1.14 so in practice there aren't really any significant differences to threads, at least in semantics. (At least as far as I remember; been a while since I wrote any Go.)
You can be pedantic and say they aren't technically threads but that doesn't really matter from a programming perspective.
cyanydeez 6 hours ago [-]
no, i believe it needs to be solved in finetuning. collectively, the OSS community should be pooling local LLM resources and providing a route to models that inately choose best practices as a "full stack" engineer would see them.
in your mind, you think a harness and prompt is sufficient framing to keep the LLM output to design goals. but no matter your context size, as it grows, anomolous gradients appear that try to normalize competing patterns of development.
the only real way is directly training out unwanted crosswise options.
quietbritishjim 6 hours ago [-]
I think you replied to the wrong comment. (Or, at least, I have no idea what you're saying.)
eithed 15 minutes ago [-]
I think that this not only applies to languages, but general patterns that you use. Don't mix functional with OO. Don't mix repositories with DAOs. Don't mix MVC and MVVM. Code should be predictable in what it does and what you expect from other developers how to code. If you don't have that then you shouldn't blame LLM when it goes haywire and starts doing whatever
keepamovin 8 hours ago [-]
I agree with the idea that boringly predictable should be what is preferred but anecdotally my experience in using Go with LLMs is that they trip up a lot on the races and locking from go’s thread model. I haven’t seen the same problem in rust which is now why I’m doing all my LLM work for tooling in rust.
The parallelism issue in particular was also not something I noticed agent struggling with in JavaScript, although JavaScript concurrency model is clearly fundamentally different.
The concurrency issues that I saw LMM‘s face was one reason why I created freelang which uses a very boring and audible concurrency model of OS processes that use the file system to talk instead of IPC, shared state, or anything like that. Higher overhead, lower throughput, but more boring and hopefully less bugs: https://github.com/DO-SAY-GO/freelang
nathannaveen 8 hours ago [-]
Personally I generally try to avoid concurrency when writing code with AI since I feel AI makes concurrency unnecessary complex in Golang.
quietbritishjim 6 hours ago [-]
Probably reasonable, but that means you're disagreeing with the article's point about goroutines being good for LLMs (since goroutines are a form of concurrency). I've never seriously used Go so I don't know how easy it is to avoid using them.
keepamovin 8 hours ago [-]
Right. But for things like GUI or orchestration tooling it’s unavoidable
lmm 9 hours ago [-]
Rather than "boring", this seems to be reaching for something like the concept of a "pit of success", or https://haskellforall.com/2016/04/worst-practices-should-be-... . I don't think the fact that the most common pitfalls in Go are well known should be taken as a sign that it doesn't have more esoteric pitfalls as well; it's just that the common cases (like nil) are the ones that everyone sees all the time.
sheepianka 8 hours ago [-]
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 and type specifications in general add a lot of busywork, but models have higher level of tolerance to busywork compared to developers.
wryoak 4 days ago [-]
Contradictory anecdote: there’s basically only one way to write Elm, as it is a very trend-resistant language with minimal updates over long timespans, but most agents in my experience will throw Haskell syntax and Prelude functions into their Elm output. Compiler or LSP will often set them right but they still try it initially
gampleman 8 hours ago [-]
I do agentic Elm development every day (it's my job). I feel like what you describe was a problem with models perhaps two years ago. Today's models don't seem to struggle with it at all and in fact do seem to benefit from what the author describes.
BoumTAC 9 hours ago [-]
I’ve just started a new app with an Elm frontend. I’m using Grok Build, and it integrates really well.
The compiler is incredibly helpful because it catches errors and gives clear explanations and the LLM can iterate over it. I’ve also added the elm-review package with the default configuration, which is fantastic for ensuring code quality.
djohnmustard 9 hours ago [-]
Interesting, what models are you using? My use with sonnet 4.6 has been a breeze for the most part
epolanski 10 hours ago [-]
Interesting, I have a different experience.
I have worked extending the Elm compiler and both Opus 4.6, GPT 5.4 and GLM 5 had no issues both with the Elm compiler (written in Haskell) and my extended Elm.
I didn't see them hallucinate much, not more than on mainstream languages.
tracker1 2 hours ago [-]
For myself, I've generally setup a few boundaries... for JS projects, I tend to use Deno for tooling, even targeting npm lately. Similarly, I've favored modern TypeScript over JS. Often Hono + OpenAPI + Zod as a set for services.
I've also been doing quite a bit of Rust for web services and wasm targets, which has worked exceedingly well... similarly with Tokio + Axum, etc.
I have seen very few issues with either of the above... that said, C# has been a bit more painful by comparison... I often rely on FastEndpoints for services and Grate for database migrations, and LLMs often get a bit tangled with those libraries in practice.
jmull 7 hours ago [-]
This is an interesting idea, but I'd want to see something solid before acting on it.
From what I can tell, LLMs know/use patterns above the syntax and idioms of specific languages and the syntax and idioms of specific languages and how to apply the former to the latter.
The bottleneck isn't what languages the LLM can handle, but what I can handle coming out of the LLM. The general advice, then, is to use the language (and related setup/environment) you're familiar with.
embedding-shape 7 hours ago [-]
Yeah, probably that last point would depend on how you actually use LLMs, if you don't review the code at all, not even glancing on it (aka "vibe coding") then it probably doesn't matter so much, yolo and deploy.
But for the rest of us who aren't vibe coding, but pairing with LLMs and actively steer them, correct things and iterate while reviewing the code, design and architecture deeply then yes, I agree a lot, matters more that you're familiar with the language than the LLM, they can pick up new programming languages in a message so doesn't really matter, knowledge seems to come from programming, not locked into a specific language's syntax.
zitterbewegung 9 hours ago [-]
I haven’t had an issue using Python with LLMs where I have to decide “Should one use pip, poetry, or uv?” Since there is enough training data using pip or just choose that since it is the most boring solution and many of the commands map to uv since uv has a superset of features. Not that go is a bad solution honestly I would just say use what you know best.
ChrisMarshallNY 8 hours ago [-]
I program in two languages: Swift (my main language), for client work, and PHP, for backend work. It’s overwhelmingly Swift.
In the last year or so, I have been using LLMs, to assist my work, with generally, excellent results.
I have noticed that the LLM delivers much better PHP, than Swift. I seldom need to rewrite or correct, the PHP code I get from it, and am constantly correcting the Swift. Part of the reason, may be that I am a much better Swift programmer, than PHP programmer, and there’s just a lot more Swift code. I haven’t really taken the time to analyze it.
I have my theories, as to why, but it’s not something I’m really into researching. I’ve just noted the trend.
sleepy_keita 8 hours ago [-]
I think it's pretty simple - there's just so much more open source PHP code out there in the LLM's training dataset. Swift has been around for much less, and most Swift is closed-source - not that many years have passed since Swift has been able to run on non-Apple platforms, too.
iamcalledrob 8 hours ago [-]
I would also bet that 90% of Swift training data is UI code.
And UI code quality tends to be technically pretty crummy/low-discipline. Your UI code doesn't need much consideration around data races, for example.
ChrisMarshallNY 7 hours ago [-]
You wouldn't know that, if you looked at the UI code the LLM gives me. It loves threads; often mixing GCD and async/await, in one function.
A lot of the code I need to tear out, looks like that.
Most of the code I write is UI. It's actually fairly intense work, but relies on the underlying SDK, rather than language tricks.
I find the UIKit code I get, is a lot more robust and performant, than the SwiftUI code.
psychoslave 7 hours ago [-]
PHP changed a lot since its early days. To the point where anything old would be considered bad practice by contemporary ecosystem point of view. So duration is not all. Comparatively, C seems to have stick to the same idiom all the way. That's not to praise C style form here to be clear, which is ridiculously obfuscating and feeling like pointless collection of linguistic awkward atrocities. But at least it's consistent in doing it.
dust-jacket 8 hours ago [-]
> Part of the reason, may be that I am a much better Swift programmer, than PHP programmer
Hard not to think that's a major part of it. IME you make loads more corrections in languages you're more opinionated about (and opinionated usually follows more experience & confidence).
I correct AI Python all the time. When it cranks out TypeScript I just check it works.
ChrisMarshallNY 7 hours ago [-]
Yes and no. I have been working with PHP for over 25 years, but I've never loved the language. It's always been a "necessary evil." I know it fairly well. I've only been writing Swift for half that time, but I like the language, and play with it more.
I feel that the reason posited by another poster is more likely. There's a ton of mature, well-written, shipping, PHP out there, due to the open nature of most PHP, as opposed to Swift; where the more robust and mature implementation is likely behind proprietary walls. Most of the public Swift that I see, tends to be folks showing off its fancier features, in relatively small code samples.
sd9 8 hours ago [-]
I wonder if the training data for some languages has higher quality code. I can imagine some niche languages having a higher standard than, for example Python, which surely has a bunch of random buggy scripts in the mix.
On the other hand, even if that were true, I don’t know how important it would actually be since LLMs can generalise across languages well.
It might be best to pick languages where it’s just harder to screw up, the canonical example being to prefer typescript over JavaScript.
Yokohiii 8 hours ago [-]
> Languages and ecosystems with low variance in their training corpus are represented better and executed more reliably by coding agents.
So I think the author is saying that go is a simple language that tends to have less solutions to the same problem. I personally agree to that to a degree.
What I don't agree on is that we can choose what "low variance" is. There is a lot of go code out there, it's shape may have little "noise", but the variance is massive.
Havoc 9 hours ago [-]
> From a model’s standpoint, there are simply too many ways to write any of this
They seem quite good at figuring this out in my experience
wewewedxfgdf 9 hours ago [-]
Has Go become a "boring language"?
pjmlp 9 hours ago [-]
It has been boring from the start.
It would be an interesting language, had it been released at the time of any of its influences, Oberon in 1987, Limbo in 1995.
Back when the type system ideas from CLU, Standard ML, Cedar were still taking off among industrial programming languages.
ncruces 9 hours ago [-]
The most non boring thing you can say about it is that it's terrible for ignoring most of what we've learned in the past couple decades of programming language design.
That generates plenty of excitement.
dist-epoch 9 hours ago [-]
Become? Always has been.
It was intentionally designed for programmers with limited skill.
Go language creator Rob Pike:
> The key point here is our programmers are Googlers, they’re not researchers. They’re typically, fairly young, fresh out of school, probably learned Java, maybe learned C or C++, probably learned Python. They’re not capable of understanding a brilliant language but we want to use them to build good software. So, the language that we give them has to be easy for them to understand and easy to adopt.
p2detar 6 hours ago [-]
> It was intentionally designed for programmers with limited skill.
No. That is not true. It was designed as a language so programmers of all levels can be productive at the scale of what Google does and across possibly many different teams, no matter your prior background. Google does a lot at scale and a language that is easy to pick up and handles concurrency seamlessly is definitely a helpful tool.
pjmlp 5 hours ago [-]
Nope, it was designed by one Oberon, and two UNIX heads, disgruntled to be faced with C++ at their work, they happened to be working at Google, and got support from their managers for developing it further.
Thanks to Docker pivoting from Python into Go, and Kubernetes from Java into Go, while it was still pre-1.0, it managed to take off, and has more users outside Google than at Google itself, where Java, Kotlin, C++, Python still dominate most projects outside Kubernetes ecosystem.
There is a certain irony that Google would need a language like Go, given their hiring process.
anthk 5 hours ago [-]
Go it's just condensed Plan9 C philosophy (and Limbo/Alef) for legacy Unix users. If we ditched Unix in the 90's being Inferno and Plan9 under a libre licenses GNU would be running Emacs under an Inferno kernel.
Also, proper namespaces from the start, Unicode, 9p even under Emacs and who knows what. Oh, and fore sure far less exploits, and with no Kubernetes or Docker nonsense. Half of VC's would be bankrupt today because damn namespaces would do the 90% of today's backends seamlessly.
And maybe we would be using some Inferno based smartphone with custom UI's and programming in Limbo for that. Oh, and batteries lasting a week for sure.
pjmlp 3 hours ago [-]
Except that it throws away many nice things about Inferno and Limbo, and also proves the point that techonlogy needs good sponsors to make it out into the market..
anthk 5 hours ago [-]
Not that true; it was dessigned as the C succesor for Unix. The Go counterpart for the Post-Unix OS would be Inferno and Limbo. 9front has a C and compiler suite (among CSP) which is like the link between their Unix/C and modern Go. Literally as the first Go releases used C plan9 compilers.
antonvs 8 hours ago [-]
> They’re not capable of understanding a brilliant language
What a coincidence, since Rob Pike wasn't capable of designing a brilliant language.
boxed 8 hours ago [-]
Such a weird take from him since Go has a bunch of pit falls that are not needed at all.
snikeris 7 hours ago [-]
I was a little surprised to find when I gave an LLM REPL access to the running program, it readily started using it during development and debugging.
citbl 8 hours ago [-]
We are the point now where we let LLM dictate the language?
badgersnake 7 hours ago [-]
Yeah, but then generally you pick the language your dev team are most familiar with.
Or you hire a team of specialists for the language you want. Perhaps niche languages should have fine-tuned LLMs in the same way.
tern 7 hours ago [-]
Rust, Elixir, and Go are the way to go for LLMs in my testing and experience, for this and other reasons
mohamedkoubaa 7 hours ago [-]
I have no professional experience in Rust and over 10 years in c++ but to me the decision to use rust in a greenfield project written by agents was obvious.
cpursley 7 hours ago [-]
Here’s some of the reasons it’s so good with Elixir:
* 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 conclusion, because I hate boilerplate).
Then the question is: what kind of language can you use that buys safety with boilerplate? Probably a statically typed one, possibly with lots of asserts... Eiffel? I don't know if there's enough Eiffel code around the Internet to train LLMs, so maybe a more popular one would be better.
Maybe Java or C#? Haskell? OCaml?
The article suggests golang, and I think there are use cases where golang would be a good candidate.
It would be quite interesting to run an experiment: give separate instances of the same LLM coding agent the task to implement a specific application, and use different languages. Then compare quality, code size, runtime performance and token cost. Ideal would be a multi-stage development that better simulates a real development workflow (bug reports and new feature requests come in over time).
xnx 7 hours ago [-]
Also use boring languages without LLMs
shantnutiwari 7 hours ago [-]
What??
Python __is__ a boring language (it is mature and well supported) with a somewhat convoluted package manager that has gotten a lot better since that xkcd came out.
Yeah, I get it, Go is better for distributing your code-- just one binary you can copy. But what does that have to do with "boring"?
This is annoying but only needs to be solved once at the start, either by the LLM or the human guiding it. A single prompt of "Set up a uv project in this directory with Python 3.13" is enough that it's never an issue again for that repo.
> Goroutines are a far more tractable primitive for coding agents than threads, callbacks, async/await, or any of the colored-function regimes that dominate elsewhere.
I disagree with this. Goroutines, along with threads, callbacks, and traditional async, are all in the same category: spaghetti of unbounded background tasks. Structured concurrency [1] on the other hand is dramatically easier to reason about. Python has support for this (in Trio and asyncio.TaskGroup) as do other languages like Kotlin and Swift. Function colouring a red herring; if anything, it's useful because it highlights the scheduling/cancellation points in your code.
[1] https://vorpus.org/blog/notes-on-structured-concurrency-or-g...
-----
This really does read as "Go is my favourite language". In fairness, that's a good reason to choose a language to use with an LLM (so long as it's powerful enough and not too obscure). But let's not pretend it's the best language for everyone.
Because it always is that.
People advocating for boring languages always advocate for their boring language. For instance, if you tell a gopher that you agree with the point, and therefore the project is going to use java, they won’t be happy about it.
> 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 also exactly what Dijkstra was arguing, if you read past the much misquoted "goto considered harmful", which he never said (it was an editorialized title, and not even the full version).
> 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 it from the FLOW-MATIC code quoted above (which doesn't even have functions).
Your point actually still stands: it's theoretically possible to write clean code using even the more general goto. (Probably by building abstractions with it like "function" and "for loop".) But would you be happy doing that with someone else - or especially with a coding agent? It's better that the "handful of rules" are enforced by the language, in my opinion.
---
Edit:
> That's also exactly what Dijkstra was arguing, if you read past the much misquoted "goto considered harmful", which he never said
I just re-read the original "GOTO considered harmful" article (it's short and clear) and, while the title might not have been his, Dijkstra was definitely making a very plain argument that goto is bad for everyone and should be scrapped. He says in the introduction:
> I [have] become convinced that the go to statement should be abolished from all "higher level" programming languages (i.e. everything except, perhaps, plain machine code).
And in the conclusion:
> The go to statement as it stands is just too primitive; it is too much an invitation to make a mess of one's program.
Any time you see anyone overly fixating on "function coloring" for any context other than ancient versions of Javascript it's a clue that the speaker has no idea what they're talking about.
Goroutines are literally threads. Yeah, this really is a "go is my fav" article.
This could be because our go code is typically smaller more defined services but I don't really believe that since even the isolated python services are pretty spaghetti looking.
That being said the whole `tractable primitive` thing used in the article sounds somewhat sloppy to me. I don't quite get it. Yeah, they could be easier for an agent to write than async/await, but threads are also trivial in that matter, and you'd still need a mutex with go routines.
You can be pedantic and say they aren't technically threads but that doesn't really matter from a programming perspective.
in your mind, you think a harness and prompt is sufficient framing to keep the LLM output to design goals. but no matter your context size, as it grows, anomolous gradients appear that try to normalize competing patterns of development.
the only real way is directly training out unwanted crosswise options.
The parallelism issue in particular was also not something I noticed agent struggling with in JavaScript, although JavaScript concurrency model is clearly fundamentally different.
The concurrency issues that I saw LMM‘s face was one reason why I created freelang which uses a very boring and audible concurrency model of OS processes that use the file system to talk instead of IPC, shared state, or anything like that. Higher overhead, lower throughput, but more boring and hopefully less bugs: https://github.com/DO-SAY-GO/freelang
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 and type specifications in general add a lot of busywork, but models have higher level of tolerance to busywork compared to developers.
The compiler is incredibly helpful because it catches errors and gives clear explanations and the LLM can iterate over it. I’ve also added the elm-review package with the default configuration, which is fantastic for ensuring code quality.
I have worked extending the Elm compiler and both Opus 4.6, GPT 5.4 and GLM 5 had no issues both with the Elm compiler (written in Haskell) and my extended Elm.
I didn't see them hallucinate much, not more than on mainstream languages.
I've also been doing quite a bit of Rust for web services and wasm targets, which has worked exceedingly well... similarly with Tokio + Axum, etc.
I have seen very few issues with either of the above... that said, C# has been a bit more painful by comparison... I often rely on FastEndpoints for services and Grate for database migrations, and LLMs often get a bit tangled with those libraries in practice.
From what I can tell, LLMs know/use patterns above the syntax and idioms of specific languages and the syntax and idioms of specific languages and how to apply the former to the latter.
The bottleneck isn't what languages the LLM can handle, but what I can handle coming out of the LLM. The general advice, then, is to use the language (and related setup/environment) you're familiar with.
But for the rest of us who aren't vibe coding, but pairing with LLMs and actively steer them, correct things and iterate while reviewing the code, design and architecture deeply then yes, I agree a lot, matters more that you're familiar with the language than the LLM, they can pick up new programming languages in a message so doesn't really matter, knowledge seems to come from programming, not locked into a specific language's syntax.
In the last year or so, I have been using LLMs, to assist my work, with generally, excellent results.
I have noticed that the LLM delivers much better PHP, than Swift. I seldom need to rewrite or correct, the PHP code I get from it, and am constantly correcting the Swift. Part of the reason, may be that I am a much better Swift programmer, than PHP programmer, and there’s just a lot more Swift code. I haven’t really taken the time to analyze it.
I have my theories, as to why, but it’s not something I’m really into researching. I’ve just noted the trend.
And UI code quality tends to be technically pretty crummy/low-discipline. Your UI code doesn't need much consideration around data races, for example.
A lot of the code I need to tear out, looks like that.
Most of the code I write is UI. It's actually fairly intense work, but relies on the underlying SDK, rather than language tricks.
I find the UIKit code I get, is a lot more robust and performant, than the SwiftUI code.
Hard not to think that's a major part of it. IME you make loads more corrections in languages you're more opinionated about (and opinionated usually follows more experience & confidence).
I correct AI Python all the time. When it cranks out TypeScript I just check it works.
I feel that the reason posited by another poster is more likely. There's a ton of mature, well-written, shipping, PHP out there, due to the open nature of most PHP, as opposed to Swift; where the more robust and mature implementation is likely behind proprietary walls. Most of the public Swift that I see, tends to be folks showing off its fancier features, in relatively small code samples.
On the other hand, even if that were true, I don’t know how important it would actually be since LLMs can generalise across languages well.
It might be best to pick languages where it’s just harder to screw up, the canonical example being to prefer typescript over JavaScript.
So I think the author is saying that go is a simple language that tends to have less solutions to the same problem. I personally agree to that to a degree.
What I don't agree on is that we can choose what "low variance" is. There is a lot of go code out there, it's shape may have little "noise", but the variance is massive.
They seem quite good at figuring this out in my experience
It would be an interesting language, had it been released at the time of any of its influences, Oberon in 1987, Limbo in 1995.
Back when the type system ideas from CLU, Standard ML, Cedar were still taking off among industrial programming languages.
That generates plenty of excitement.
It was intentionally designed for programmers with limited skill.
Go language creator Rob Pike:
> The key point here is our programmers are Googlers, they’re not researchers. They’re typically, fairly young, fresh out of school, probably learned Java, maybe learned C or C++, probably learned Python. They’re not capable of understanding a brilliant language but we want to use them to build good software. So, the language that we give them has to be easy for them to understand and easy to adopt.
No. That is not true. It was designed as a language so programmers of all levels can be productive at the scale of what Google does and across possibly many different teams, no matter your prior background. Google does a lot at scale and a language that is easy to pick up and handles concurrency seamlessly is definitely a helpful tool.
Thanks to Docker pivoting from Python into Go, and Kubernetes from Java into Go, while it was still pre-1.0, it managed to take off, and has more users outside Google than at Google itself, where Java, Kotlin, C++, Python still dominate most projects outside Kubernetes ecosystem.
There is a certain irony that Google would need a language like Go, given their hiring process.
Also, proper namespaces from the start, Unicode, 9p even under Emacs and who knows what. Oh, and fore sure far less exploits, and with no Kubernetes or Docker nonsense. Half of VC's would be bankrupt today because damn namespaces would do the 90% of today's backends seamlessly.
And maybe we would be using some Inferno based smartphone with custom UI's and programming in Limbo for that. Oh, and batteries lasting a week for sure.
What a coincidence, since Rob Pike wasn't capable of designing a brilliant language.
Or you hire a team of specialists for the language you want. Perhaps niche languages should have fine-tuned LLMs in the same way.
https://dashbit.co/blog/why-elixir-best-language-for-ai
* 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 conclusion, because I hate boilerplate).
Then the question is: what kind of language can you use that buys safety with boilerplate? Probably a statically typed one, possibly with lots of asserts... Eiffel? I don't know if there's enough Eiffel code around the Internet to train LLMs, so maybe a more popular one would be better.
Maybe Java or C#? Haskell? OCaml?
The article suggests golang, and I think there are use cases where golang would be a good candidate.
It would be quite interesting to run an experiment: give separate instances of the same LLM coding agent the task to implement a specific application, and use different languages. Then compare quality, code size, runtime performance and token cost. Ideal would be a multi-stage development that better simulates a real development workflow (bug reports and new feature requests come in over time).
Python __is__ a boring language (it is mature and well supported) with a somewhat convoluted package manager that has gotten a lot better since that xkcd came out.
Yeah, I get it, Go is better for distributing your code-- just one binary you can copy. But what does that have to do with "boring"?